Using AI

How I Batch-Scan My Kids' Worksheets and Let AI Sort Them Out Automatically

How I Batch-Scan My Kids' Worksheets and Let AI Sort Them Out Automatically

Photo: public.resource.org (CC0 1.0) via Flickr

Good morning. It’s まさきん.

We have more than one kid in our house, and each of them is working through different worksheets and materials. Manually sorting the pile of printouts every time was a quietly heavy chore.

So I built a system where I scan everything in one batch and let AI handle the sorting afterward. This time I want to walk through the actual code and rules I’m using, in concrete detail.

It Started With “Sorting Alone Eats Up So Much Time”

Finished worksheets and drills come in as many varieties as there are kids. Different subjects, different grade levels. If I just pile them all up together, I eventually lose track of whose is whose.

Flipping through each sheet by hand to check is simple work, but it takes forever. So I started wondering whether I could automate just that one “sorting” step.

The Overall Structure

The flow is simple. I’ve split it into three stages:

  1. Batch-scan the finished worksheets into a single PDF
  2. Convert the PDF into images page by page, and have AI judge whose worksheet it is and which subject it belongs to, based on header and layout characteristics
  3. Reflect the judged results into per-child, per-subject tools

The key point is that you don’t need to think about sorting at all at scan time. Just scan everything in one big batch, and leave the judgment call to AI afterward.

Converting the PDF Into Page-by-Page Images

Feeding a scanned PDF straight to AI doesn’t always work well. That’s especially true for scans with handwritten scoring marks on them — they’re often just a collection of images with no text layer at all.

So the first step is converting each page into a PNG image using PyMuPDF (fitz).

import fitz

doc = fitz.open("scan.pdf")
for i in range(doc.page_count):
    pix = doc[i].get_pixmap(matrix=fitz.Matrix(2, 2))  # 2x resolution
    pix.save(f"page_{i+1}.png")

Doubling the resolution with Matrix(2, 2) before converting to an image improves how accurately AI reads text and check marks. This matters especially for handwritten scoring — at low resolution, it’s easy to miss things.

An Easy Trap to Fall Into: Coordinate Units

When you want to zoom in on just the check-mark column, you can specify a range with the clip argument to get_pixmap. There’s one trap here: clip coordinates are given in the PDF’s point coordinates — the original page size — not in the pixel coordinates of the zoomed-in image.

# Even zoomed 2x or 4x, clip values are still given in the page's actual size (roughly 590x836pt for A4)
pix = doc[i].get_pixmap(matrix=fitz.Matrix(4, 4), clip=fitz.Rect(0, 140, 589, 600))

If you scale up the clip numbers just because you applied a zoom factor, the range ends up outside the image and you get nothing back. Mix this up and you’ll run straight into the mysterious “why is my cropped image all white” phenomenon — knowing this ahead of time saves a lot of wasted effort.

The Judgment Logic

Here’s a generalized version of the instructions I give the AI.

The following is an image of a scanned worksheet.
Using the hints below, judge which child's worksheet this is and which subject it belongs to.

- The design of the logo or heading at the top of the page
- The ruling and layout style (grid size, line spacing, etc.)
- The unit name or question format written on the page
- The name written in the name field

Return the result as three fields: "child ID," "subject," and "unit."
If you can't tell, answer "unknown" rather than forcing a guess.

For the actual sorting, I first build an “identification table” that combines heading text, layout characteristics, and the name field, and have the AI cross-reference against that table. For example, “a kanji-writing drill with the grade level printed in the upper right” and “a calculation drill with a small symbol printed in the lower-left corner of each question indicating the problem type” can be told apart almost uniquely just from appearance. Keeping a table like this made the AI’s judgments noticeably more consistent.

The idea of using a system to cut down on sorting effort might apply beyond worksheets, too. Reviewing a mobile plan you’ve been putting off feels like a similar story.

Try the fee simulator and get 100 points, no sign-up required Take a peek at 'systemizing' your phone bill too

Clicking this opens the Rakuten login page. Once you log in, you’ll see the campaign details.

The Scoring Rule: Unified Around “Just the Check Mark”

There’s one more thing I’ve settled on for handling multiple kids’ materials: keep the scoring criteria the same no matter which child it is.

Specifically, the only thing I use to judge right or wrong is whether the check box to the left (or upper-left) of each question is filled in.

Handwriting neatness and eraser marks don’t factor into the judgment at all. The reason is simple: whether a check mark is present can be read mechanically, but the moment you mix in an evaluation of how neat the handwriting is, the standard immediately starts to wobble.

So I’ve spelled this out explicitly to the AI up front, as a rule: “Judge correctness only by whether the check box is filled in — handwriting quality and red-ink corrections are not factors.” Whether or not that one sentence is included makes a real difference in how consistent the judgments turn out to be.

The Zoom Procedure That Prevents Missed Check Marks

If you look at the whole scanned image shrunk down, filled-in check boxes can end up too small to read clearly. To avoid jumping to the conclusion that “everything’s filled in, so it must all be correct,” I always follow these steps:

  1. Look at the whole page first to get a rough sense of the layout
  2. Crop out just the column of check boxes and zoom in (using the clip trick from earlier)
  3. Go through the zoomed image question by question to check whether each one is filled in
  4. For any check box that’s ambiguous, or anywhere the text simply can’t be read, have a human confirm it rather than guessing

I’ve learned firsthand that relying only on a thumbnail-sized image makes it easy to miss filled-in check boxes.

Changing the “Unit of Mistake” Depending on the Subject

There’s one more thing I’ve put thought into: changing the unit at which I record mistakes, depending on the subject.

SubjectUnit of RecordExample
Kanji / hiragana practicePer individual characterThe character itself becomes the key — for example, a single kanji, like the one meaning “school,” or a single hiragana character
MathPer problem patternThe problem type becomes the key, such as “unit conversion,” “division with remainder,” or “place value”
Science / social studiesPer theme + sub-itemA hierarchical key like “theme name:section:number”

Even for the same “missed question,” the right granularity for review differs by subject. Lump kanji together at the unit level, and the precision of the next review session drops. Break math “patterns” down to the level of individual questions, on the other hand, and it gets harder to narrow down what actually needs review.

For math, I print a small symbol representing the problem type in the corner of each question, and when reading the scoring results, I tally mistakes by that symbol. The rule is simple: if there are multiple questions of the same type and even one of them is wrong, the whole type gets flagged as “needs review.”

For science and social studies, the review section at the end of a worksheet sometimes draws its questions from a different unit than the day’s main theme, so I cross-reference the question text against a list of themes before deciding which theme it’s actually reviewing. This is one place where I never assume — I always cross-check before recording anything.

This whole mechanism was actually repurposed from a system I’d originally built for a different purpose: recording missed items and bringing them back for repeated practice. Even though the purpose changed, the underlying logic carried over as-is.

Why the Setup Spans Two Separate Environments

This system uses a two-tier setup: the actual back-and-forth with AI happens in a cloud sandbox environment, while the real file operations and state management are handled by a background process running on my home computer.

The reason is simple — the database that stores scoring results, along with the scripts that generate drills, only exist on my home computer. The cloud side reaches the home side through a lightweight client script that just sends simple commands across.

# Example: reflect a missed word based on the judged result
python3 tools/kanji_drill/kanji_bridge_client.py mark-miss schoolyard music
python3 tools/kanji_drill/kanji_bridge_client.py mark-correct classroom

# Before reflecting anything, check that the home-side background process is alive
python3 tools/kanji_drill/kanji_bridge_client.py health

I always run this health command right before actually reflecting anything. If the home-side process has gone down without my noticing and I keep sending mark-miss commands anyway, they look like they succeed but actually reflect nothing at all — and that’s exactly the kind of accident this check is there to prevent.

What I’ve Noticed Since Doing This

What’s helped the most is that the work of checking “whose is this, and which subject” has simply disappeared. Now I just scan everything in a batch and look at the results afterward.

That said, I don’t fully trust the AI’s judgment. Anything marked “unknown,” or any check box the AI seemed unsure about, I always double-check with my own eyes. I’ve found that letting the AI say “I don’t know” when it doesn’t know, rather than forcing it to sort everything regardless, ends up making the whole system more trustworthy in the long run.

Who This Is a Good Fit For

Wrapping Up

With materials from multiple kids, the more volume there is, the heavier the sorting burden gets. By combining scanning with AI-driven sorting, I was able to carve out just that piece and automate it.

Unglamorous details — like getting coordinate units right and spelling out scoring criteria explicitly — are, I think, actually what stabilizes accuracy the most. When you’re designing a system like this, the work of deciding on the judgment criteria themselves might matter more than you’d expect.

Worksheet sorting probably isn’t the only burden a system like this can lighten. Next, I’m planning to give my mobile phone plan the same kind of review.

Try the fee simulator and get 100 points, no sign-up required Give your phone bill the same 'systemizing' treatment

Clicking this opens the Rakuten login page. Once you log in, you’ll see the campaign details.

This article contains affiliate advertising. If you sign up for a product or service through a link on this site, we may receive compensation from the partner company. The site operator is also an employee of Rakuten Group and may receive compensation through an employee referral program. The content and opinions here are based on the operator’s own experience and research regardless of any advertising relationship, but please read with the above in mind. See the Disclaimer & Affiliate Disclosure for details. Disclaimer & Affiliate Disclosure

This article includes machine-translated content. Please check the official Rakuten Mobile multilingual page for exact terms.

If you have concerns about Rakuten Mobile coverage or signal quality, you can consult through the official signal improvement request form .

ABOUT THE AUTHOR
まさきん

Rakuten Group employee · Digital Marketer (holds a Financial Planner qualification)

In his early 40s, part of a dual-income household with four kids. Works as a digital marketer at Rakuten Group, while also using his Financial Planner (FP) qualification to focus on household finances and building assets.

View Profile

Related Articles

RELATED
I Subscribed to X Premium for Grok, and It Turned Out to Work in My Tesla Too Using AI

I Subscribed to X Premium for Grok, and It Turned Out to Work in My Tesla Too

I signed up for X's paid plan mainly to get Grok. Around the same time, I was surprised to discover the same Grok had become available inside my Tesla too. Here's everything I found out, from choosing a plan to actually using it in the car.

2026.09.01 · 3 min read
A simple way to turn verbal family plans into Google Calendar events with AI Using AI

A simple way to turn verbal family plans into Google Calendar events with AI

I'll share how I turn plans I hear through family LINE chats or conversations, like 'next month's sports day starts at 9am on 10/25,' into a Google Calendar link just by telling an AI. No scanning, no app install needed.

2026.07.10 · 5 min read
How I Have AI Build Me a One-Page 'Today's Briefing' While I Get Ready in the Morning Using AI

How I Have AI Build Me a One-Page 'Today's Briefing' While I Get Ready in the Morning

I built a system that has AI pull together my schedule, email, and chat messages into a single briefing I can glance at while getting ready. Here's how I gather the information and keep the layout from breaking, in enough detail that you could build it yourself.

2026.06.22 · 5 min read
Switch to Rakuten Mobile, get up to 14,000 points Try the fee simulator and get 100 points, no sign-up required →
Apply Now →