close
Itxperts

Online Exam System using Python

This project will involve creating an Online Exam System where students can log in, take exams with multiple-choice questions, and get instant feedback on their scores. Python will be used for the backend logic, Tkinter for the GUI, and SQLite for managing user data, questions, and results.

1. Project Setup

Modules Required:

  • tkinter: For the graphical user interface.
  • sqlite3: For database management.

To install the necessary modules, run the following:

pip install tkinter

2. Project Features

  1. User Login/Registration: Students can register and log in to take the exam.
  2. Multiple Choice Questions (MCQs): Students answer a set of MCQs within a specified time.
  3. Instant Result: The system calculates the score and displays it at the end of the exam.
  4. Question Bank: Store a list of questions and their correct answers.
  5. View Results: Students can view their previous exam scores.
  6. Admin Panel: The admin can add, update, or delete questions.

3. Database Design

We’ll use SQLite to manage three tables: users, questions, and results.

  • users:
  • id (INTEGER PRIMARY KEY AUTOINCREMENT)
  • username (TEXT)
  • password (TEXT)
  • questions:
  • id (INTEGER PRIMARY KEY AUTOINCREMENT)
  • question (TEXT)
  • option_a (TEXT)
  • option_b (TEXT)
  • option_c (TEXT)
  • option_d (TEXT)
  • correct_answer (TEXT)
  • results:
  • id (INTEGER PRIMARY KEY AUTOINCREMENT)
  • user_id (INTEGER)
  • score (INTEGER)

4. Code Structure

A. Database Connection

import sqlite3

def connect_db():
    conn = sqlite3.connect('online_exam_system.db')
    c = conn.cursor()
    # Create Users Table
    c.execute('''CREATE TABLE IF NOT EXISTS users
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  username TEXT,
                  password TEXT)''')
    # Create Questions Table
    c.execute('''CREATE TABLE IF NOT EXISTS questions
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  question TEXT,
                  option_a TEXT,
                  option_b TEXT,
                  option_c TEXT,
                  option_d TEXT,
                  correct_answer TEXT)''')
    # Create Results Table
    c.execute('''CREATE TABLE IF NOT EXISTS results
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                  user_id INTEGER,
                  score INTEGER)''')
    conn.commit()
    conn.close()

connect_db()

B. User Registration and Login

def register_user(username, password):
    conn = sqlite3.connect('online_exam_system.db')
    c = conn.cursor()
    c.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password))
    conn.commit()
    conn.close()

def login_user(username, password):
    conn = sqlite3.connect('online_exam_system.db')
    c = conn.cursor()
    c.execute("SELECT * FROM users WHERE username=? AND password=?", (username, password))
    user = c.fetchone()
    conn.close()
    return user

C. Add Questions

def add_question(question, option_a, option_b, option_c, option_d, correct_answer):
    conn = sqlite3.connect('online_exam_system.db')
    c = conn.cursor()
    c.execute("INSERT INTO questions (question, option_a, option_b, option_c, option_d, correct_answer) VALUES (?, ?, ?, ?, ?, ?)",
              (question, option_a, option_b, option_c, option_d, correct_answer))
    conn.commit()
    conn.close()

D. Fetch Questions for Exam

def get_questions():
    conn = sqlite3.connect('online_exam_system.db')
    c = conn.cursor()
    c.execute("SELECT * FROM questions")
    questions = c.fetchall()
    conn.close()
    return questions

E. Save Exam Results

def save_results(user_id, score):
    conn = sqlite3.connect('online_exam_system.db')
    c = conn.cursor()
    c.execute("INSERT INTO results (user_id, score) VALUES (?, ?)", (user_id, score))
    conn.commit()
    conn.close()

5. GUI Design using Tkinter

Now, let’s build a simple user interface using Tkinter for registration, login, and taking the exam.

A. User Login and Registration

from tkinter import *
from tkinter import messagebox

root = Tk()
root.title("Online Exam System")
root.geometry("400x300")

# Function to Register a New User
def register():
    username = entry_username.get()
    password = entry_password.get()
    if username and password:
        register_user(username, password)
        messagebox.showinfo("Success", "User registered successfully!")
    else:
        messagebox.showerror("Error", "Please fill in all fields!")

# Function to Login
def login():
    username = entry_username.get()
    password = entry_password.get()
    user = login_user(username, password)
    if user:
        messagebox.showinfo("Success", "Login successful!")
        start_exam(user[0])  # Pass user ID to start exam
    else:
        messagebox.showerror("Error", "Invalid credentials!")

# GUI Elements for Login/Registration
Label(root, text="Username").pack(pady=10)
entry_username = Entry(root)
entry_username.pack()

Label(root, text="Password").pack(pady=10)
entry_password = Entry(root, show="*")
entry_password.pack()

Button(root, text="Register", command=register).pack(pady=10)
Button(root, text="Login", command=login).pack(pady=10)

root.mainloop()

B. Exam Interface

def start_exam(user_id):
    exam_window = Toplevel(root)
    exam_window.title("Online Exam")
    exam_window.geometry("400x300")

    questions = get_questions()  # Fetch the questions from the database
    score = 0
    current_question_index = 0

    def next_question():
        nonlocal current_question_index, score
        selected_option = var.get()
        if selected_option == questions[current_question_index][6]:  # Check if answer is correct
            score += 1
        current_question_index += 1
        if current_question_index < len(questions):
            show_question(current_question_index)
        else:
            save_results(user_id, score)
            messagebox.showinfo("Result", f"Exam finished! Your score: {score}")
            exam_window.destroy()

    var = StringVar()

    def show_question(index):
        question_label.config(text=questions[index][1])
        rb1.config(text=questions[index][2], value=questions[index][2])
        rb2.config(text=questions[index][3], value=questions[index][3])
        rb3.config(text=questions[index][4], value=questions[index][4])
        rb4.config(text=questions[index][5], value=questions[index][5])

    question_label = Label(exam_window, text="", wraplength=300)
    question_label.pack(pady=10)

    rb1 = Radiobutton(exam_window, text="", variable=var, value="")
    rb1.pack(anchor=W)
    rb2 = Radiobutton(exam_window, text="", variable=var, value="")
    rb2.pack(anchor=W)
    rb3 = Radiobutton(exam_window, text="", variable=var, value="")
    rb3.pack(anchor=W)
    rb4 = Radiobutton(exam_window, text="", variable=var, value="")
    rb4.pack(anchor=W)

    Button(exam_window, text="Next", command=next_question).pack(pady=10)

    show_question(0)

6. Final Enhancements

To make the Online Exam System more comprehensive, you can add the following features:

  1. Exam Timer: Implement a countdown timer to limit the exam duration.
  2. Results Page: Provide a feature for users to view all past results with their scores.
  3. Randomized Questions: Shuffle the questions each time a new exam is started.
  4. Admin Panel: Add an admin panel for managing users and adding/editing questions.
  5. Enhanced User Interface: Improve the look and feel of the exam interface with advanced layouts and design elements.

7. Conclusion

This is a basic Online Exam System built using Python and Tkinter for the graphical interface and SQLite for storing exam questions, user data, and results. The system allows users to register, log in, take exams, and receive instant feedback on their scores.

Would you like to add specific features or explore a particular functionality in more detail?