홈 / Skills / 개발 생산성 / 전체 출력 강제 Full-Output Enforcement
개발 생산성

전체 출력 강제 Full-Output Enforcement

LeonxlnxMITSkill 언어: 영어
라이선스 확인됨스크립트 없음낮은 위험
실행 예시실제 실행 · claude-sonnet-5-5 · 2026년 10월
I need exhaustive, unabridged output for this: no truncation, no placeholders, nothing left for me to fill in. Write a complete Python module `textstats.py` with exactly these six functions, each fully implemented with a docstring: word_count(text), unique_words(text), top_n_words(text, n), average_word_length(text), sentence_count(text), reading_time_minutes(text, wpm=200). Then write a complete pytest file `test_textstats.py` with at least three tests per function. Give me both files in full.
Skill: full-output-enforcement

I couldn't write the files to disk with the tools I have here, so both are below in full. I haven't run them. I checked the expected values in the tests by hand against the implementation.

Behavior choices the tests rely on:

  • A word is a run of letters or digits, and apostrophes inside a word are kept (don't is one word). Hyphens split words (well-known is two).
  • unique_words, top_n_words, and average_word_length lowercase their input where case matters. average_word_length counts apostrophes in a word's length.
  • Sentences end at ., !, or ? runs followed by whitespace or end of text. 3.14 therefore doesn't split, but abbreviations like Dr. do.
  • reading_time_minutes raises ValueError if wpm <= 0, and top_n_words raises it if n < 0.

textstats.py

"""textstats: small, dependency-free helpers for computing text statistics.

A "word" is a maximal run of letters or digits, optionally joined by internal
apostrophes (so ``don't`` is one word). Hyphens and other punctuation separate
words (so ``well-known`` is two words).
"""

import re
from collections import Counter

_WORD_RE = re.compile(r"[^\W_]+(?:['\u2019][^\W_]+)*")
_SENTENCE_END_RE = re.compile(r"[.!?]+(?=\s|$)")
_ALNUM_RE = re.compile(r"[^\W_]")


def word_count(text):
    """Return the number of words in ``text``.

    Words are runs of letters or digits, optionally joined by internal
    apostrophes. Punctuation and whitespace are ignored, and hyphens split
    words.

    Args:
        text: The string to analyse.

    Returns:
        The number of words as an int (0 for empty or punctuation-only text).

    Example:
        >>> word_count("Hello, world!")
        2
    """
    return len(_WORD_RE.findall(text))


def unique_words(text):
    """Return the distinct words in ``text`` as a sorted list.

    Comparison is case-insensitive: every word is lowercased before
    de-duplication.

    Args:
        text: The string to analyse.

    Returns:
        An alphabetically sorted list of unique lowercase words. The list is
        empty if ``text`` contains no words.

    Example:
        >>> unique_words("The cat and the hat")
        ['and', 'cat', 'hat', 'the']
    """
    return sorted(set(_WORD_RE.findall(text.lower())))


def top_n_words(text, n):
    """Return the ``n`` most frequent words in ``text`` with their counts.

    Comparison is case-insensitive. Results are ordered by descending count;
    words with equal counts are ordered alphabetically so the output is
    deterministic.

    Args:
        text: The string to analyse.
        n: How many words to return. If ``n`` exceeds the number of distinct
            words, all distinct words are returned. ``0`` returns an empty list.

    Returns:
        A list of ``(word, count)`` tuples, at most ``n`` long.

    Raises:
        ValueError: If ``n`` is negative.

    Example:
        >>> top_n_words("a b a c b a", 2)
        [('a', 3), ('b', 2)]
    """
    if n < 0:
        raise ValueError("n must be non-negative")
    counts = Counter(_WORD_RE.findall(text.lower()))
    ordered = sorted(counts.items(), key=lambda item: (-item[1], item[0]))
    return ordered[:n]


def average_word_length(text):
    """Return the mean length, in characters, of the words in ``text``.

    Word length includes any internal apostrophes (``don't`` has length 5).
    Surrounding punctuation is not counted.

    Args:
        text: The string to analyse.

    Returns:
        The average word length as a float, or ``0.0`` if there are no words.

    Example:
        >>> average_word_length("a bb ccc")
        2.0
    """
    words = _WORD_RE.findall(text)
    if not words:
        return 0.0
    return sum(len(word) for word in words) / len(words)


def sentence_count(text):
    """Return the number of sentences in ``text``.

    A sentence ends at a run of ``.``, ``!`` or ``?`` that is followed by
    whitespace or the end of the text. Periods inside tokens such as ``3.14``
    therefore do not end a sentence. Trailing text without a terminator counts
    as a sentence, and segments with no letters or digits are ignored.
    Abbreviations such as ``Dr.`` are treated as sentence ends.

    Args:
        text: The string to analyse.

    Returns:
        The number of sentences as an int.

    Example:
        >>> sentence_count("Hi. How are you? Fine!")
        3
    """
    segments = _SENTENCE_END_RE.split(text)
    return sum(1 for segment in segments if _ALNUM_RE.search(segment))


def reading_time_minutes(text, wpm=200):
    """Return the estimated reading time of ``text`` in minutes.

    The estimate is the word count divided by the reading speed.

    Args:
        text: The string to analyse.
        wpm: Reading speed in words per minute. Must be positive. Defaults
            to 200.

    Returns:
        The estimated reading time in minutes as a float (0.0 for empty text).

    Raises:
        ValueError: If ``wpm`` is zero or negative.

    Example:
        >>> reading_time_minutes("word " * 100)
        0.5
    """
    if wpm <= 0:
        raise ValueError("wpm must be positive")
    return word_count(text) / wpm

test_textstats.py

"""Tests for textstats."""

import pytest

import textstats


# --- word_count -------------------------------------------------------------


def test_word_count_empty_string():
    assert textstats.word_count("") == 0


def test_word_count_simple_sentence():
    assert textstats.word_count("hello world") == 2


def test_word_count_ignores_punctuation_and_extra_whitespace():
    assert textstats.word_count("Hello,   world!\n\nfoo") == 3


def test_word_count_keeps_contractions_as_one_word():
    assert textstats.word_count("don't stop") == 2


def test_word_count_splits_hyphenated_words():
    assert textstats.word_count("a well-known fact") == 4


def test_word_count_counts_numbers():
    assert textstats.word_count("I have 3 apples") == 4


def test_word_count_punctuation_only():
    assert textstats.word_count("... !!! ???") == 0


# --- unique_words -----------------------------------------------------------


def test_unique_words_sorted_and_deduplicated():
    assert textstats.unique_words("the cat and the hat") == ["and", "cat", "hat", "the"]


def test_unique_words_case_insensitive():
    assert textstats.unique_words("Apple apple APPLE") == ["apple"]


def test_unique_words_empty_text():
    assert textstats.unique_words("") == []


def test_unique_words_ignores_punctuation():
    assert textstats.unique_words("Hi, hi! Ho.") == ["hi", "ho"]


# --- top_n_words ------------------------------------------------------------


def test_top_n_words_orders_by_count():
    assert textstats.top_n_words("a b a c b a", 2) == [("a", 3), ("b", 2)]


def test_top_n_words_ties_broken_alphabetically():
    assert textstats.top_n_words("zebra apple mango", 2) == [("apple", 1), ("mango", 1)]


def test_top_n_words_n_larger_than_vocabulary():
    assert textstats.top_n_words("x y", 10) == [("x", 1), ("y", 1)]


def test_top_n_words_zero_returns_empty_list():
    assert textstats.top_n_words("a b c", 0) == []


def test_top_n_words_negative_raises():
    with pytest.raises(ValueError):
        textstats.top_n_words("a b c", -1)


def test_top_n_words_case_insensitive():
    assert textstats.top_n_words("The the THE cat", 1) == [("the", 3)]


def test_top_n_words_empty_text():
    assert textstats.top_n_words("", 5) == []


# --- average_word_length ----------------------------------------------------


def test_average_word_length_empty_text_is_zero():
    assert textstats.average_word_length("") == 0.0


def test_average_word_length_single_word():
    assert textstats.average_word_length("abc") == pytest.approx(3.0)


def test_average_word_length_multiple_words():
    assert textstats.average_word_length("a bb ccc") == pytest.approx(2.0)


def test_average_word_length_ignores_surrounding_punctuation():
    assert textstats.average_word_length("hello, world!") == pytest.approx(5.0)


def test_average_word_length_counts_apostrophes():
    assert textstats.average_word_length("don't") == pytest.approx(5.0)


def test_average_word_length_non_integer_result():
    assert textstats.average_word_length("a bb") == pytest.approx(1.5)


# --- sentence_count ---------------------------------------------------------


def test_sentence_count_empty_text():
    assert textstats.sentence_count("") == 0


def test_sentence_count_single_sentence():
    assert textstats.sentence_count("Hello world.") == 1


def test_sentence_count_mixed_terminators():
    assert textstats.sentence_count("Hi. How are you? Fine!") == 3


def test_sentence_count_without_terminator():
    assert textstats.sentence_count("No terminator here") == 1


def test_sentence_count_ellipsis_and_interrobang():
    assert textstats.sentence_count("Wait... what?!") == 2


def test_sentence_count_decimal_number_does_not_split():
    assert textstats.sentence_count("Pi is 3.14 today.") == 1


def test_sentence_count_punctuation_only():
    assert textstats.sentence_count("   ...  ") == 0


def test_sentence_count_across_newlines():
    assert textstats.sentence_count("One.\nTwo.") == 2


# --- reading_time_minutes ---------------------------------------------------


def test_reading_time_default_wpm_one_minute():
    text = " ".join(["word"] * 200)
    assert textstats.reading_time_minutes(text) == pytest.approx(1.0)


def test_reading_time_default_wpm_half_minute():
    text = " ".join(["word"] * 100)
    assert textstats.reading_time_minutes(text) == pytest.approx(0.5)


def test_reading_time_custom_wpm():
    text = " ".join(["word"] * 50)
    assert textstats.reading_time_minutes(text, wpm=100) == pytest.approx(0.5)


def test_reading_time_empty_text_is_zero():
    assert textstats.reading_time_minutes("") == 0.0


def test_reading_time_zero_wpm_raises():
    with pytest.raises(ValueError):
        textstats.reading_time_minutes("some words", wpm=0)


def test_reading_time_negative_wpm_raises():
    with pytest.raises(ValueError):
        textstats.reading_time_minutes("some words", wpm=-50)

Save them side by side in one directory and run pytest test_textstats.py. The module has exactly the six functions you listed. The three regexes are module-level constants, so there are no private helper functions.

Test run: two files requested in full. All six functions and 38 tests came back complete with no placeholder patterns. The first attempt did not call the Skill and was discarded; this run used a request that asked for unabridged output. The code was not executed.

하는 일

답변을 중간에 줄이는 에이전트의 습관을 바로잡습니다. 불완전한 출력은 망가진 출력으로 보고, 파일 전체를 요청하면 전체를, 컴포넌트 5개를 요청하면 5개를 줍니다. // ..., // rest of code, // TODO, '간결함을 위해', '나머지도 동일', 구현 대신 뼈대만 주는 방식 같은 대충 넘기는 표현을 금지합니다. 에이전트는 먼저 독립된 결과물이 몇 개인지 세고, 하나씩 완전하게 만든 뒤, 답하기 전에 요청과 개수를 대조합니다. 긴 답변이 토큰 한도에 가까워지면 나머지를 압축하지 않고 [PAUSED - 5개 중 2개 완료] 같은 표시와 함께 깔끔한 지점에서 멈추고, '계속'이라고 하면 그 자리에서 정확히 이어 갑니다.

결과물

완전한 파일, 함수, 섹션. 직접 채워 넣을 부분이 남지 않습니다.

이런 때 좋습니다

긴 코드 파일, 전체 테스트 세트, 빠짐없는 목록, 여러 부분으로 된 문서처럼 '전부'가 필요한 모든 작업. 약 50줄로 짧고 주제를 가리지 않습니다.

참고 사항 및 위험

낮은 위험:지침만 있는 파일로 스크립트가 없고, 네트워크에 접속하지 않으며, 파일을 쓰지 않습니다. 답변의 완전성만 바꿀 뿐 에이전트가 할 수 있는 일은 바꾸지 않습니다. 아주 긴 답변은 여전히 토큰 한도에 닿을 수 있어 '멈췄다가 이어 가기' 동작이 중요합니다. 한 번 시험했고 함수 6개와 테스트 38개가 완전하게 돌아왔으며 자리표시자 표현은 없었습니다(코드는 실행하지 않음). 첫 시도에서는 이 Skill이 호출되지 않았고, 완전하고 생략 없는 출력을 요청할 때 동작합니다. 작성자 Leonxlnx, MIT.

SKILL.md 원본패키지에 파일 2개