Skip to content
Fondazione ITS INCOM

Examples · General

Flashcards from your notes

Turn your notes into question-and-answer cards with Gemma, and import them into Anki or Quizlet to study.

Intermediate · 30 min

What you need

A key and the openai library, as in Your first API call in Python, and your notes in a text file, notes.txt.

The model

Gemma 4 26B (gemma-4-26b), the default model: fast, and good at turning free text into structured data.

The program

import csv
import json
import os
import pathlib

from openai import OpenAI

client = OpenAI(
    base_url="https://api.ai.itsincom.org/v1",
    api_key=os.environ["API_KEY"],
)

notes = pathlib.Path("notes.txt").read_text()

schema = {
    "type": "object",
    "properties": {
        "cards": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {"question": {"type": "string"}, "answer": {"type": "string"}},
                "required": ["question", "answer"],
            },
        },
    },
    "required": ["cards"],
}

answer = client.chat.completions.create(
    model="gemma-4-26b",
    temperature=0.3,
    messages=[
        {"role": "system", "content": "You make study flashcards. One fact per card, short answers, "
                                      "and only facts that are written in the notes."},
        {"role": "user", "content": "Make 15 flashcards from these notes:\n\n" + notes},
    ],
    response_format={"type": "json_schema", "json_schema": {"name": "flashcards", "schema": schema}},
)

# "length" means the answer was cut off by a limit: its JSON is not complete.
if answer.choices[0].finish_reason != "stop":
    raise SystemExit("The answer was cut off: ask for fewer cards, or send a shorter part of your notes.")

cards = json.loads(answer.choices[0].message.content)["cards"]
with open("flashcards.txt", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f, delimiter="\t")
    for card in cards:
        writer.writerow([card["question"], card["answer"]])

print(f"{len(cards)} cards in flashcards.txt")

The school's machines make the answer follow the JSON schema, so json.loads works, as long as the answer is complete: that is why the program looks at finish_reason first. The schema checks the shape of the cards, not what they say.

Import them

Exercise

All examples