CoolFace
Apppublic

Rittik101/Sstudize

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py312 linesDownload Raw Back to root
1import streamlit as st2import pandas as pd3import matplotlib.pyplot as plt4import seaborn as sns5import numpy as np6 7# Load data from the CSV file8data = pd.read_csv('https://raw.githubusercontent.com/forittik/test_analysis_100_updated/refs/heads/main/final_mereged_data.csv')9 10# Set up constants11CORRECT_MARK = 412WRONG_MARK = -113UNATTEMPTED_MARK = 014 15# Define question ranges for each subject16PHYSICS_REQUIRED = list(range(1, 21))         # Questions 1-2017PHYSICS_OPTIONAL = list(range(21, 31))        # Questions 21-3018 19CHEMISTRY_REQUIRED = list(range(31, 51))      # Questions 31-5020CHEMISTRY_OPTIONAL = list(range(51, 61))      # Questions 51-6021 22MATHEMATICS_REQUIRED = list(range(61, 81))    # Questions 61-8023MATHEMATICS_OPTIONAL = list(range(81, 91))    # Questions 81-9024 25# Function to calculate scores based on rules26def calculate_subject_score(data, student_id, required_questions, optional_questions):27    score = 028 29    # Calculate required questions score30    for q in required_questions:31        if q in data['Question_no'].values:32            correct_answer = data.loc[data['Question_no'] == q, 'correct_answer_key'].values[0]33            student_answer = data.loc[data['Question_no'] == q, student_id].values[0]34 35            if student_answer == correct_answer:36                score += CORRECT_MARK37            elif pd.isna(student_answer):38                score += UNATTEMPTED_MARK39            else:40                score += WRONG_MARK41 42    # Calculate optional questions score43    optional_attempts = []44    for q in optional_questions:45        if q in data['Question_no'].values:46            student_answer = data.loc[data['Question_no'] == q, student_id].values[0]47            if not pd.isna(student_answer):48                optional_attempts.append((q, student_answer))49 50    for q, student_answer in optional_attempts:51        correct_answer = data.loc[data['Question_no'] == q, 'correct_answer_key'].values[0]52        score += CORRECT_MARK if student_answer == correct_answer else WRONG_MARK53 54    return min(score, 100)55 56# Streamlit UI57st.title("JEE Mock Test Score Analysis")58 59# Select multiple student IDs60student_ids = st.multiselect("Select Student IDs", options=data.columns[3:])61 62if student_ids:63    physics_scores = []64    chemistry_scores = []65    mathematics_scores = []66    total_scores = []67 68    # Loop through selected students and calculate scores69    for student_id in student_ids:70        physics_score = calculate_subject_score(data, student_id, PHYSICS_REQUIRED, PHYSICS_OPTIONAL)71        chemistry_score = calculate_subject_score(data, student_id, CHEMISTRY_REQUIRED, CHEMISTRY_OPTIONAL)72        mathematics_score = calculate_subject_score(data, student_id, MATHEMATICS_REQUIRED, MATHEMATICS_OPTIONAL)73 74        physics_scores.append(physics_score)75        chemistry_scores.append(chemistry_score)76        mathematics_scores.append(mathematics_score)77        total_scores.append(physics_score + chemistry_score + mathematics_score)78 79    # Display score format for each selected student80    for i, student_id in enumerate(student_ids):81        st.subheader(f"Scores of {student_id}")82        st.write(f"Physics Score: {physics_scores[i]}")83        st.write(f"Chemistry Score: {chemistry_scores[i]}")84        st.write(f"Mathematics Score: {mathematics_scores[i]}")85        st.write(f"Total Score: {total_scores[i]} / 300")86        st.write("---")87 88    # The rest of your existing code for plotting can remain as it is89 90 91    all_student_columns = data.columns[3:]92    all_total_scores = [93        calculate_subject_score(data, student_id, PHYSICS_REQUIRED, PHYSICS_OPTIONAL) +94        calculate_subject_score(data, student_id, CHEMISTRY_REQUIRED, CHEMISTRY_OPTIONAL) +95        calculate_subject_score(data, student_id, MATHEMATICS_REQUIRED, MATHEMATICS_OPTIONAL)96        for student_id in all_student_columns97    ]98    avg_all_students = np.mean(all_total_scores)99    avg_selected_students = np.mean(total_scores)100 101    # Total Score Distribution - Bar Plot with Average Lines102    st.subheader("Total Score Distribution (Bar Plot)")103    plt.figure(figsize=(10, 6))104    plt.bar(student_ids, total_scores, color='purple', label='Total Scores')105    plt.axhline(avg_all_students, color='red', linestyle='--', linewidth=1.5, label='Average for All Students')106    plt.axhline(avg_selected_students, color='blue', linestyle='--', linewidth=1.5, label='Average for Selected Students')107    plt.text(len(student_ids) - 0.5, avg_all_students + 5, f"{avg_all_students:.2f}", color='red', ha='center', fontweight='bold')108    plt.text(len(student_ids) - 0.5, avg_selected_students + 5, f"{avg_selected_students:.2f}", color='blue', ha='center', fontweight='bold')109    plt.xlabel("Student IDs")110    plt.ylabel("Total Score")111    plt.title("Total Score Comparison Across Students")112    plt.ylim(0, 300)113    plt.legend()114    st.pyplot(plt)115 116    # Subject-wise Average Comparison Plot117    st.subheader("Subject-wise Average Scores (Selected vs All Students)")118    avg_physics_all_students = np.mean([119        calculate_subject_score(data, student_id, PHYSICS_REQUIRED, PHYSICS_OPTIONAL)120        for student_id in all_student_columns121    ])122    avg_chemistry_all_students = np.mean([123        calculate_subject_score(data, student_id, CHEMISTRY_REQUIRED, CHEMISTRY_OPTIONAL)124        for student_id in all_student_columns125    ])126    avg_mathematics_all_students = np.mean([127        calculate_subject_score(data, student_id, MATHEMATICS_REQUIRED, MATHEMATICS_OPTIONAL)128        for student_id in all_student_columns129    ])130 131    avg_physics_selected = np.mean(physics_scores)132    avg_chemistry_selected = np.mean(chemistry_scores)133    avg_mathematics_selected = np.mean(mathematics_scores)134 135    subjects = ['Physics', 'Chemistry', 'Mathematics']136    avg_all_students = [avg_physics_all_students, avg_chemistry_all_students, avg_mathematics_all_students]137    avg_selected_students = [avg_physics_selected, avg_chemistry_selected, avg_mathematics_selected]138 139    x = np.arange(len(subjects))140    width = 0.35141 142    fig, ax = plt.subplots(figsize=(10, 6))143    bars1 = ax.bar(x - width/2, avg_all_students, width, label='All Students', color='skyblue')144    bars2 = ax.bar(x + width/2, avg_selected_students, width, label='Selected Students', color='orange')145 146    for bar in bars1:147        ax.text(148            bar.get_x() + bar.get_width() / 2,149            bar.get_height() + 2,150            f'{bar.get_height():.2f}',151            ha='center', color='black', fontweight='bold'152        )153 154    for bar in bars2:155        ax.text(156            bar.get_x() + bar.get_width() / 2,157            bar.get_height() + 2,158            f'{bar.get_height():.2f}',159            ha='center', color='black', fontweight='bold'160        )161 162    ax.set_xlabel("Subjects")163    ax.set_ylabel("Average Scores")164    ax.set_title("Average Scores by Subject for All Students vs Selected Students")165    ax.set_xticks(x)166    ax.set_xticklabels(subjects)167    ax.legend()168    st.pyplot(fig)169 170    # Subject-wise Performance Comparison - Side-by-Side Column Chart171    st.subheader("Subject-wise Performance Comparison (Side-by-Side Column Chart)")172 173    # Ensure the lists match the length of student_ids174    if len(student_ids) == len(physics_scores) == len(chemistry_scores) == len(mathematics_scores):175        subjects = ['Physics', 'Chemistry', 'Mathematics']176        subject_scores = [physics_scores, chemistry_scores, mathematics_scores]177 178        # Create a side-by-side bar chart179        width = 0.25  # Width of bars180        x = np.arange(len(student_ids))  # Position of bars on x-axis181 182        fig, ax = plt.subplots(figsize=(10, 6))183        ax.bar(x - width, physics_scores, width, label='Physics', color='blue')184        ax.bar(x, chemistry_scores, width, label='Chemistry', color='green')185        ax.bar(x + width, mathematics_scores, width, label='Mathematics', color='orange')186 187        # Label the bars with their scores188        for i, v in enumerate(physics_scores):189            ax.text(x[i] - width, v + 1, str(v), ha='center', fontweight='bold')190        for i, v in enumerate(chemistry_scores):191            ax.text(x[i], v + 1, str(v), ha='center', fontweight='bold')192        for i, v in enumerate(mathematics_scores):193            ax.text(x[i] + width, v + 1, str(v), ha='center', fontweight='bold')194 195        ax.set_xlabel("Student IDs")196        ax.set_ylabel("Scores")197        ax.set_title("Subject-wise Scores (Side-by-Side Comparison)")198        ax.set_xticks(x)199        ax.set_xticklabels(student_ids)200        ax.legend()201        st.pyplot(fig)202 203    # Chapter-wise Average Score Analysis204        # Chapter-wise Average Score Analysis205    # Chapter-wise Average Score Analysis206st.subheader("Chapter-wise Average Score Analysis")207 208# Create a dictionary to store chapter-wise scores209chapter_scores = {}210chapter_question_counts = {}211 212# Iterate through the questions in the data and calculate the scores for each chapter213for student_id in student_ids:214    for q in data['Question_no']:215        # Get the chapter name directly from the 'Chapter_name' column216        chapter = data.loc[data['Question_no'] == q, 'Chapter_name'].values[0]217        correct_answer = data.loc[data['Question_no'] == q, 'correct_answer_key'].values[0]218        student_answer = data.loc[data['Question_no'] == q, student_id].values[0]219 220        # Update chapter scores and counts221        if chapter not in chapter_scores:222            chapter_scores[chapter] = 0223            chapter_question_counts[chapter] = 0224 225        if student_answer == correct_answer:226            chapter_scores[chapter] += CORRECT_MARK227        elif pd.isna(student_answer):228            chapter_scores[chapter] += UNATTEMPTED_MARK229        else:230            chapter_scores[chapter] += WRONG_MARK231 232        chapter_question_counts[chapter] += 1233 234# Calculate average score per chapter235chapter_avg_scores = {236    chapter: chapter_scores[chapter] / chapter_question_counts[chapter] 237    for chapter in chapter_scores238}239 240# Plot Chapter-wise Average Scores241chapters = list(chapter_avg_scores.keys())242avg_scores = list(chapter_avg_scores.values())243 244fig, ax = plt.subplots(figsize=(10, 6))245ax.barh(chapters, avg_scores, color='teal')246 247ax.set_xlabel("Average Score")248ax.set_ylabel("Chapters")249ax.set_title("Chapter-wise Average Scores")250 251# Display the plot252st.pyplot(fig)253 254# Chapter-wise Question Distribution for Physics, Chemistry, and Mathematics255st.subheader("Chapter-wise Question Distribution for Physics, Chemistry, and Mathematics")256 257# Function to calculate the number of questions per chapter for each subject258import streamlit as st259import matplotlib.pyplot as plt260 261# Function to calculate the number of questions per chapter for each subject262import streamlit as st263import matplotlib.pyplot as plt264 265# Function to calculate the number of questions per chapter for each subject266def chapter_question_distribution(subject_required, subject_optional):267    # Combine required and optional questions for the subject268    subject_questions = subject_required + subject_optional269    chapter_counts = {}270 271    for q in subject_questions:272        if q in data['Question_no'].values:273            chapter = data.loc[data['Question_no'] == q, 'Chapter_name'].values[0]274            if chapter not in chapter_counts:275                chapter_counts[chapter] = 0276            chapter_counts[chapter] += 1277 278    return chapter_counts279 280# Get chapter-wise question distribution for each subject281physics_chapter_distribution = chapter_question_distribution(PHYSICS_REQUIRED, PHYSICS_OPTIONAL)282chemistry_chapter_distribution = chapter_question_distribution(CHEMISTRY_REQUIRED, CHEMISTRY_OPTIONAL)283mathematics_chapter_distribution = chapter_question_distribution(MATHEMATICS_REQUIRED, MATHEMATICS_OPTIONAL)284 285# List of subjects and their respective chapter distributions286subjects = ['Physics', 'Chemistry', 'Mathematics']287chapter_distributions = [physics_chapter_distribution, chemistry_chapter_distribution, mathematics_chapter_distribution]288 289# Streamlit UI for subject navigation290subject_selection = st.selectbox("Select Subject", options=subjects)291 292# Determine which subject's chapter distribution to plot293if subject_selection == 'Physics':294    chapter_distribution = physics_chapter_distribution295elif subject_selection == 'Chemistry':296    chapter_distribution = chemistry_chapter_distribution297else:298    chapter_distribution = mathematics_chapter_distribution299 300# Plot the selected subject's chapter distribution301fig, ax = plt.subplots(figsize=(10, 6))302 303ax.bar(chapter_distribution.keys(), chapter_distribution.values(), color='teal')304ax.set_title(f"{subject_selection} Chapter-wise Question Distribution")305ax.set_xlabel("Chapters")306ax.set_ylabel("Number of Questions")307 308# Rotate x-axis labels and align them309ax.set_xticklabels(chapter_distribution.keys(), rotation=45, ha='right')310 311# Display the plot312st.pyplot(fig)