This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 2 (Side Hustle).
What I Built
My friend Akash Agrawal (@baniyaman) teaches at a coaching centre. Every time he needs a test paper for a class, a subject or a unit, he does the same thing: picks questions from books and old papers, screenshots them, marks them up, and sends the pile to a DTP operator.
The DTP operator's whole job is turning those screenshots into a paper. They retype every question in proper maths notation, redraw the figures, drop it all into the coaching centre's branded template with its logo, and send back a PDF to review and print. Akash's centre pays ₹5 for a plain question and ₹10 and up for anything with a diagram. And it takes about a week: 2 days of the teacher picking questions, then 5 days waiting on the operator.
TestMadeEasy removes that middle layer. The teacher photographs a page (or marks a section of one), and the app gives back every question as clean, consistent text:
- the question in LaTeX, so maths and chemistry notation looks like a real exam paper
- options, kept separate from the question
- a generated answer and solution
- subject, chapter, topic, difficulty and marks
- the diagram, cropped straight out of the photo
Then the teacher picks questions, applies their institute's branding (logo, colours, header, watermark) and prints the paper and its answer key. Same day, no operator.
There's one more piece that makes it smarter over time: a shared master question bank. Every extracted question is checked against it, so a question someone has already scanned gets matched and synced instead of extracted again. The bigger the bank gets, the less anyone needs to scan. You start changing values in existing questions instead of typing new ones.
Who pays for it
Small coaching institutes, the kind with a few teachers running weekly JEE, NEET and board-exam tests. They already pay for this work today, per question, to a DTP operator, or as a salary (some operators get ₹15,000 to 20,000 per exam cycle).
Our plan is a subscription in tiers:
- Free: 5 question papers, kept on the account for good.
- Paid: teacher accounts and up to 100 papers a month, priced per paper generated. With 10 to 15 questions per paper, we're aiming for ₹1 to 2 per question, against the ₹5 to ₹10+ they pay now.
- Premium: access to the shared master bank, so you can build papers from questions other teachers have already extracted.
- Bring your own key: bigger centres can plug in their own API key and a stronger model if they want.
That ₹1 to 2 number is only possible because of the model this week's rebuild runs on. More on that below.
Demo
Live: testmadeeasy.tech
Judge login (a teacher account with sample data already loaded):
- Email:
testinguseramrit@gmail.com - Password:
hacktoberfest
It has 18 questions extracted from 4 practice sheets, a "Shree Science Academy" brand, and 3 test papers with answer keys. To try it yourself, go to Add Questions and upload any page (or one of the sample sheets in the repo). A page usually takes under a minute.
Code
amrit-dash
/
testmadeeasy
Turn a photo of a textbook page into a branded, print-ready test paper. Gemma 4 extracts questions as LaTeX.
TestMadeEasy is a question-paper builder for coaching teachers. You photograph a page from a reference book, and the open-weight Gemma 4 model pulls every question off it as clean LaTeX: options, subject, chapter, topic, difficulty, marks, and where any diagram sits. The questions land in your own question bank. You pick the ones you want, add your institute's logo, colour and watermark, and print a test paper plus its answer key.
It's built for the small coaching institutes in India that run weekly JEE, NEET and board-exam tests and currently pay a DTP operator to retype every question by hand.
Demo video: youtu.be/lA2mvoYwOtQ
Want to try it without your own pages? The 4 practice sheets in docs/images (physics, chemistry, maths, biology, all original questions) are what the demo uses.
What it does
…Where this week fits
I want to be upfront about the timeline. TestMadeEasy started as a private project earlier in 2026, built on Gemini. Akash built the first UI in Replit, and I built the backend, the AI pipeline and the infrastructure around it.
We pitched it to an IIT-prep coaching centre at ₹5,000. They didn't say no. They paid ₹1,000 for a trial, we set them up with accounts, fed in their previous papers, and scraped previous-year IIT papers to pre-fill the master bank. The extraction was good enough that the papers came out right.
They still didn't really use it. They kept sending us question papers on WhatsApp, so we'd run them through the platform ourselves and send the paper back. What they actually asked for was a WhatsApp bot: send photos, get a paper back. It was habit, plus a platform they never quite got comfortable with, and we didn't move past the trial. Akash, though, uses it every day for his own classes, and he's passed it on to other teachers who use it too.
The lesson I took from that pitch was price. ₹5,000 for a centre that's used to paying an operator per question is a hard sell. This week was the turning point: we rebuilt the AI core on open-weight Gemma 4 to get the cost low enough to pitch ₹1 to 2 per question next time, and we opened the code.
How I Built It
React and Vite on the front, Express on the back, Postgres, auth and image storage on Supabase. It all runs as one container on Google Cloud Run behind Firebase Hosting, on a .tech domain.
Swapping in Gemma 4
Every AI call used to go to Gemini. Gemma 4 is served through the same Gemini API, with the same key, and it accepts the same system prompts and JSON response schemas. So the first step was mostly configuration:
-
gemma-4-31b-itdoes extraction, answers and diagram redraws. -
gemma-4-26b-a4b-it(the mixture-of-experts one, 4B active) scores teacher edits to shared questions. - An admin can switch any task back to a Gemini model from a dropdown, and nothing else in the code knows which one is running.
Then we tested it on real pages, and that's where the work was.
Diagrams without image generation
Gemma doesn't generate images, and we don't want it to. Redrawing a diagram loses detail and costs tokens. Instead, the model tells us where each diagram is, and we crop it out of the original photo. Nothing is lost, and it's cheap.
The old prompt asked for boxes as {x, y, width, height} in percent. Gemma kept returning half a box ({x: 61, y: 158}, no width or height) or raw pixels, so the app had nothing to crop with and showed the whole page. We switched to [ymin, xmin, ymax, xmax] on a 0 to 1000 grid. That's the format Google's vision models are trained on for detection; Google AI's post on Detecting and Editing Visual Objects with Gemini and Native Bounding Boxes Changes Everything for Visions Devs by amirhosseinghanipour both explain it well. The server converts the box back to percent:
// [ymin, xmin, ymax, xmax] on a 0-1000 grid -> {x, y, width, height} in percent
function boxToBounds(box: unknown, padPct: number) {
if (!Array.isArray(box) || box.length !== 4) return null;
const [ymin, xmin, ymax, xmax] = box.map((v) => Math.min(1000, Math.max(0, v)) / 10);
const x = Math.max(0, xmin - padPct);
const y = Math.max(0, ymin - padPct);
return { x, y, width: Math.min(100, xmax + padPct) - x, height: Math.min(100, ymax + padPct) - y };
}
The boxes went from garbage to tight on the first try.
The model also tends to stop a question's box one line early, so the last row of options got cut off. Rather than add another paragraph of "PLEASE INCLUDE THE OPTIONS" to the prompt, the server grows each box with plain geometry: it takes in the question's own diagram and reaches down to just above the next question in the same column.
Making Gemma reliable
A few more things broke, and each fix was small once we found it:
-
Pages that "failed" for no reason. Gemma sometimes wraps its JSON in a markdown fence even in JSON mode. Our "was this cut off?" check looked for a closing
}, found a fence, retried twice and gave up. Stripping the fence fixed 2 of our 4 test pages. - Pages that came back with 1 question out of 4. Now the schema makes the model list every question number on the page first, then extract. If it lists 4 and returns 1, the server retries once and tells it what it missed.
- Calls that hung for 15 minutes. Every AI call now has a 150-second timeout, so a stalled request gets retried instead of blocking the job.
-
Jobs that froze halfway. Extraction runs in the background after the upload request returns. Cloud Run, by default, only gives a container CPU while a request is in flight, so jobs crawled whenever nobody was polling. One flag,
--no-cpu-throttling, fixed it. - Free-tier limits. Gemma on the Gemini API has a low tokens-per-minute cap and a page costs 3 to 5k tokens, so Gemma calls now run 2 at a time.
After all that: 4 practice sheets in, 18 of 18 questions out, each with a working crop.
Why open innovation matters here
Cost is the whole business. Our pitch failed partly on price. On Gemini 3 Flash a page cost about $0.003 in tokens, small until a teacher scans a 200-page question book. Gemma 4 on the Gemini API costs nothing right now, which is what makes ₹1 to 2 per question (and a real free tier) work. The app still records token counts on every question, so if that ever changes, we'll see it.
No lock-in on what matters. The question bank is the product. If the free tier goes away, the weights are open: we can run the same Gemma 4 on our own GPU and keep every prompt and schema as they are, because it's the same model, not a "similar" one.
Privacy is the next step, and I'll be straight about it. Right now the hosted free tier is what keeps cost at zero, and Google says free-tier prompts can be used to improve its products. For schools that don't want exam papers leaving the building, self-hosting the same open model is the honest answer, and it's on our list.
What we'd build next: the WhatsApp flow our trial centre asked for (send photos, get a paper back), and upscaling for cropped diagrams from low-quality phone photos.
Prize Categories
- Best Use of Gemma: Gemma 4 31B and Gemma 4 26B A4B run every AI task by default: reading photos into structured questions, finding question and diagram boxes for cropping, generating answers, redrawing simple diagrams as TikZ, and scoring edits to the shared bank.
- Best Use of a .tech Domain: the app lives at testmadeeasy.tech.
Team
Built by @amrit-dash and @baniyaman (Akash Agrawal).


Top comments (1)
Nice.