About The Project
Inspiration
As students, we're all too familiar with the late-night "cram session"—passively re-reading the same 50-page PDF lecture slides, hoping something sticks. This is an incredibly inefficient way to learn. Our inspiration was to solve this problem by transforming passive study materials into an active learning tool. We wanted to take any lecture PDF and instantly turn it into an interactive quiz, leveraging the power of generative AI to do the heavy lifting. We built this app to help us (and other students) study smarter, not just harder.
How We Built It
This is a full-stack application with a Python backend and a React frontend.
Backend (Flask): We built a lightweight Flask server to act as the "brain." It has one main API endpoint (/api/generate-quiz) that:
Accepts a PDF file upload from the user.
Uses the PyMuPDF (fitz) library to quickly and accurately extract all text content from the PDF.
Takes this text and the user's desired number of questions, and crafts a specific prompt for the Google Gemini API.
The most crucial part: We used Gemini's JSON Schema mode. This forces the AI to return a perfectly structured JSON array of questions, options, and correct answers every single time, eliminating any unpredictability.
It then sends this clean JSON data back to the frontend.
Frontend (React): The user interface is a clean, single-page application built with React.
It uses useState to manage the app's state (the uploaded file, loading status, and the final quiz).
It features a drag-and-drop file uploader (or a standard file picker) for a smooth user experience.
It uses axios to send the file to the backend as FormData and displays a loading spinner while the quiz is being generated.
Once the quiz data is received, it dynamically renders the questions, allows the user to select answers, and finally reveals the correct answers on submission.
All styling was done with plain, modern CSS for a simple and fast-loading UI.
What We Learned
Controlling AI is Key: Getting a generative AI to return exactly what you need is the biggest challenge. At first, the AI would send back messy text around the quiz data. The "Aha!" moment was discovering and implementing JSON Schema mode with the Gemini API, which gave us 100% reliable, parsable JSON output.
Full-Stack Debugging: We learned to trace a bug from start to finish. An error message in the browser ("404 Not Found") led us to the React code, which in turn led us to the Flask server, where we realized our frontend URL was missing the /api prefix.
The Right Tool for the Job: PyMuPDF is incredibly fast and effective for text-based PDFs. We also learned that our app's main limitation is that it doesn't work on scanned (image-based) PDFs, which would require a separate OCR (Optical Character Recognition) engine.
Challenges We Faced
Reliable AI Output: Our biggest challenge by far. Before using JSON Schema mode, we spent hours writing complex Python functions to "clean" the AI's messy response. Switching to schema mode solved this completely and made our code much simpler.
Frontend Setup: We initially tried to use Tailwind CSS but ran into a series of frustrating npx and npm cache-related build errors. With the hackathon clock ticking, we made the pragmatic decision to pivot: we dropped the dependency and rewrote all the styling in plain CSS in under an hour, getting us back on track.
Connecting the "Pipes": We spent time debugging CORS (Cross-Origin Resource Sharing) issues and making sure the FormData from React was being correctly interpreted by Flask, which was a great full-stack learning experience.
Log in or sign up for Devpost to join the conversation.