Skip to content

API Reference

This page covers everything you call directly: the Readability class, the result types it returns, the StatSummary object, and the ReadabilityMetric enum. Detailed explanations of what each metric measures and when to use it live in the metrics section.


The single entry point for the library. Pass text to the constructor, then call metric methods on the resulting object.

Readability(text: str, min_words: int = 100)

Parameters

ParameterTypeDefaultDescription
textstrThe text to analyze. Plain prose works best. Accepts any Unicode string.
min_wordsint100Minimum word count required before calling metric methods.

Text analysis runs at construction time. By the time __init__ returns, the full StatSummary is available via r.stats.

r.stats -> StatSummary

Returns the StatSummary computed at construction. All 10 statistical fields are available immediately after creating a Readability instance. Use stats when you want direct access to the underlying counts. See the StatSummary section for all fields.

All nine metric methods take no required parameters and return a frozen result dataclass. Each raises ValueError if the text is shorter than min_words.

r.ari() -> ARIResult

Calculates the Automated Readability Index. Returns a grade level and a corresponding reader age range. Uses character count and sentence length — no syllable counting.

r.coleman_liau() -> ColemanLiauResult

Calculates the Coleman-Liau Index. Uses letters per word and sentences per 100 words. Character-based, like ARI.

r.dale_chall() -> DaleChallResult

Calculates the Dale-Chall Readability Score. Compares words against a list of 3,000 familiar words to count unfamiliar vocabulary.

r.flesch() -> FleschResult

Calculates the Flesch Reading Ease score. Returns a 0–100 score where higher means easier, plus an ease label and grade levels. This is the only metric in the library where a higher score means simpler text.

r.flesch_kincaid() -> FleschKincaidResult

Calculates the Flesch-Kincaid Grade Level. Uses the same inputs as Flesch but outputs a US grade level rather than an ease score.

r.gunning_fog() -> GunningFogResult

Calculates the Gunning Fog Index. Counts polysyllabic words, excluding proper nouns and hyphenated compounds.

r.linsear_write() -> LinsearWriteResult

Calculates the Linsear Write Formula. Designed for technical writing. Counts words with two or fewer syllables against words with three or more.

r.smog(all_sentences: bool = False, ignore_length: bool = False) -> SmogResult

Calculates the SMOG Index. Requires at least 30 sentences by default.

Parameters

ParameterTypeDefaultDescription
all_sentencesboolFalseWhen False (default), SMOG samples 10 sentences from the beginning, middle, and end of the text. When True, uses all sentences.
ignore_lengthboolFalseWhen False (default), raises ValueError if the text has fewer than 30 sentences. When True, issues a UserWarning instead and computes a score anyway.
r.spache() -> SpacheResult

Calculates the Spache Readability Formula. Designed for primary school texts (grades 1–3). Compares vocabulary against a word list calibrated for young readers.

r.statistics() -> dict

Returns a plain dictionary with six of the most commonly needed statistics:

KeyTypeDescription
"num_letters"intTotal letter count (excludes spaces and punctuation)
"num_words"intTotal word count
"num_sentences"intTotal sentence count
"num_polysyllabic_words"intWords with three or more syllables
"avg_words_per_sentence"floatAverage words per sentence

| "avg_syllables_per_word" | float | Average syllables per word |

This is a convenience method for quick inspection or serialization. It is a subset of what r.stats provides. Use r.stats when you need word-list-based counts (num_gunning_complex, num_dale_chall_complex, num_spache_complex) or direct attribute access.

from readscore import Readability
r = Readability("The cat sat on the mat. Simple words make simple text." * 5)
stats = r.statistics()
print(stats["num_words"]) # 55
print(stats["avg_syllables_per_word"]) # 1.18

Metric methods return frozen dataclasses. You cannot modify them after construction. All result types are comparable and orderable by score.

Seven of the nine metrics return a GradeResult or a subclass. These fields are present on every result except FleschResult and ARIResult (which add extra fields):

FieldTypeDescription
scorefloatRaw formula output
grade_levelslist[str]One or more US grade level strings
grade_levelstr (property)The first item in grade_levels; "na" if the list is empty

grade_levels values. The list contains strings from this set: "K", "1" through "12", "college", "college_graduate". Some formulas return a range (e.g., ["8", "9"] for a Flesch score of 60–69) and some return a single value. The grade_level property always returns the first item.

result = r.flesch_kincaid()
print(result.score) # 8.4
print(result.grade_levels) # ['8']
print(result.grade_level) # '8'

Returned by r.flesch(). Adds one field to GradeResult:

FieldTypeDescription
scorefloatFlesch ease score, typically 0–100 (can exceed range)
easestrReading ease label (see table below)
grade_levelslist[str]US grade level(s) for this score range
grade_levelstr (property)Primary grade level

ease values by score range:

Score rangeease value
90 and above"very_easy"
80–89"easy"
70–79"fairly_easy"
60–69"standard"
50–59"fairly_difficult"
30–49"difficult"
Below 30"very_confusing"
result = r.flesch()
print(result.score) # 74.3
print(result.ease) # 'fairly_easy'

Returned by r.ari(). Adds one field to GradeResult:

FieldTypeDescription
scorefloatRaw ARI score
ageslist[int]Two-element list [lower, upper] for typical reader age range
grade_levelslist[str]US grade level(s) for this score
grade_levelstr (property)Primary grade level

The ages list always has exactly two elements. For example, an ARI score in the grade 8 range returns [13, 14]. College-level scores return [18, 24] and graduate-level scores return [24, 100].

result = r.ari()
print(result.score) # 9.1
print(result.grade_levels) # ['10']
print(result.ages) # [15, 16]

The remaining seven metrics each have a named result type that inherits directly from GradeResult without adding fields. They exist as distinct types for clarity in type annotations and isinstance checks.

MethodResult type
coleman_liau()ColemanLiauResult
dale_chall()DaleChallResult
flesch_kincaid()FleschKincaidResult
gunning_fog()GunningFogResult
linsear_write()LinsearWriteResult
smog()SmogResult
spache()SpacheResult

A frozen dataclass with all statistical counts computed from the text. Access it via r.stats.

All fields are read-only. The object is computed once at construction and shared across all metric calls.

FieldTypeDescription
num_lettersintTotal letter count, excluding spaces and punctuation
num_wordsintTotal word count
num_sentencesintTotal sentence count
num_syllablesintTotal syllable count across all words
num_poly_syllable_wordsintWords with three or more syllables
avg_words_per_sentencefloatAverage words per sentence
avg_syllables_per_wordfloatAverage syllables per word
num_gunning_complexintPolysyllabic words excluding proper nouns and hyphenated compounds (Gunning Fog definition)
num_dale_chall_complexintWords not found on the Dale-Chall familiar word list
num_spache_complexintWords not found on the Spache familiar word list

The difference between num_poly_syllable_words and num_gunning_complex: both count words with three or more syllables, but num_gunning_complex applies Gunning Fog’s exclusion rules (proper nouns and compound words do not count as complex, even if polysyllabic).

r = Readability(text)
s = r.stats
print(s.num_words) # 312
print(s.num_poly_syllable_words) # 47
print(s.num_gunning_complex) # 39
print(s.num_dale_chall_complex) # 28

Provides programmatic access to all nine metrics by name. Useful for iterating over metrics, building dynamic reporting, or resolving a metric by string name.

Members

MemberString representation
ReadabilityMetric.ARI"ARI"
ReadabilityMetric.COLEMAN_LIAU"Coleman-Liau"
ReadabilityMetric.DALE_CHALL"Dale-Chall"
ReadabilityMetric.FLESCH"Flesch"
ReadabilityMetric.FLESCH_KINCAID"Flesch-Kincaid"
ReadabilityMetric.GUNNING_FOG"Gunning Fog"
ReadabilityMetric.LINSEAR_WRITE"Linsear Write"
ReadabilityMetric.SMOG"SMOG"
ReadabilityMetric.SPACHE"Spache"

metrics() classmethod

ReadabilityMetric.metrics() -> list[str]

Returns a sorted list of all enum member names as strings (the Python attribute names, not the short display names):

from readscore.types.enums import ReadabilityMetric
print(ReadabilityMetric.metrics())
# ['ARI', 'COLEMAN_LIAU', 'DALE_CHALL', 'FLESCH', 'FLESCH_KINCAID',
# 'GUNNING_FOG', 'LINSEAR_WRITE', 'SMOG', 'SPACHE']

measure_class property

Returns the internal measure class for a given enum member. This is an advanced use case for callers who want to instantiate a metric directly using a StatSummary rather than going through Readability:

from readscore.types.enums import ReadabilityMetric
metric = ReadabilityMetric.FLESCH
cls = metric.measure_class # <class 'readscore.metrics.flesch.Flesch'>

Iterating over all metrics

from readscore import Readability
from readscore.types.enums import ReadabilityMetric
r = Readability(text)
for member in ReadabilityMetric:
method_name = member._names.var # e.g. "flesch_kincaid"
method = getattr(r, method_name, None)
if method:
result = method()
print(f"{member}: {result.score:.1f}")

SignalTypeWhen raised
UserWarningwarningReadability(text, min_words=N) where N < 100
ValueErrorexceptionAny metric method when r.stats.num_words < min_words
ValueErrorexceptionr.smog() when sentence count is below 30 and ignore_length=False
UserWarningwarningr.smog(ignore_length=True) when sentence count is below 30

Lowering min_words at construction only suppresses the constructor warning. It also lowers the threshold that metric methods check against. Setting min_words=50 means metric methods will accept texts with as few as 50 words without raising ValueError.