Skip to content

Lorem Ipsum Generator — Python source

Generate placeholder Lorem Ipsum text - paragraphs and sentences with adjustable counts. Classic Latin word pool, instant copy.

This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.

"""Lorem Ipsum generator — Python polyglot showcase port.

Pure-structure generator: random words drawn from the canonical Lorem
Ipsum pool and assembled into capitalized sentences, paragraphs, and
multi-paragraph blocks. Behaviour mirrors the TypeScript reference in
``src/lib/lorem.ts`` 1:1 (same word pool, same defaults, same edge-case
handling, same non-crypto randomness).

Ported from src/lib/lorem.ts.
Display source — part of CosmoDev's polyglot tool pages.
"""

from __future__ import annotations

import random

# The canonical Lorem Ipsum word pool — identical across every port so
# output is drawn from the same vocabulary.
WORDS: list[str] = (
    "lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor "
    "incididunt ut labore et dolore magna aliqua enim ad minim veniam quis nostrud exercitation "
    "ullamco laboris nisi aliquip ex ea commodo consequat duis aute irure in reprehenderit voluptate "
    "velit esse cillum eu fugiat nulla pariatur excepteur sint occaecat cupidatat non proident sunt "
    "culpa qui officia deserunt mollit anim id est laborum"
).split(" ")


def _rand_below(max_exclusive: int) -> int:
    """Uniform integer in [0, max_exclusive).

    ``random.randrange`` returns ``[0, n)`` — the exact analogue of the
    TypeScript source's ``Math.floor(Math.random() * max)``. Python's
    ``random`` is non-cryptographic (Mersenne Twister), matching that
    source; do not use it for security purposes. A non-positive bound
    yields 0, so ``randrange`` never receives zero.
    """
    if max_exclusive <= 0:
        return 0
    return random.randrange(max_exclusive)


def sentence(min_words: int = 8, max_words: int = 16) -> str:
    """Build one sentence of ``min_words``..``max_words`` words.

    When ``max_words < min_words`` the range collapses to exactly
    ``min_words`` words: the ``max(1, ...)`` guard keeps the span
    positive so ``randrange`` never receives zero.
    """
    span = max(1, max_words - min_words + 1)
    word_count = min_words + _rand_below(span)

    body = " ".join(random.choice(WORDS) for _ in range(word_count))
    # Capitalize only the first character and terminate with a period.
    # A slice is used (not body[0]) so a zero-word sentence yields "."
    # rather than an IndexError, matching the TS source. str.capitalize()
    # is intentionally avoided — it would also lowercase the tail.
    return body[:1].upper() + body[1:] + "."


def paragraph(sentences: int = 5) -> str:
    """Join ``sentences`` default-length (8..16 word) sentences into a paragraph."""
    return " ".join(sentence() for _ in range(sentences))


def lorem(paragraphs: int = 3, sentences_per_para: int = 5) -> str:
    """Build ``paragraphs`` paragraphs of ``sentences_per_para`` sentences each."""
    return "\n\n".join(paragraph(sentences_per_para) for _ in range(paragraphs))

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →