Basic statistics¶
BasicStats(source, sents_extractor=None, words_extractor=None, normalize=False, complex_syl_factor=3, long_word_letter_factor=7)
The basic statistics of a text: the counts of its sentences, words, characters, syllables and punctuation marks and the distributions of its words. The data source is a text, a Doc object of spaCy or a Document of anySeg. Letters are counted by str.isalpha, so digits, hyphens and marks inside a word are not letters.
The words and the sentences come from the document of the source (parse): its tokens without punctuation marks and symbols such as € or % (doc_words) and its sentences; an extractor given is used on the text instead. A Doc keeps its sentence starts, and one with none or only partial ones (has_sents) gets those of parse. A blank line ends a sentence of every source, since it ends a paragraph of the document. A sentence without words, such as punctuation alone, is not counted.
Raises:
SourceTypeError- a source that is neither a string, aDocnor aDocument, aparsethat returns noDocument, an extractor of another type;SourceError- a source without words;ParameterError- a threshold that is not an integer of at least one, anormalizethat is not abool.
A subclass with the syllables of a language - here the groups of vowels, a rough rule for English.
import re
from anyts.basic_stats import BasicStats
class Stats(BasicStats):
def count_syllables(self, word):
return len(re.findall(r"[aeiouy]+", word, re.IGNORECASE))
bs = Stats("The cat sat on the mat. A beautiful day!")
bs.print_stats()
Statistic | Value
-----------------------------------------------------------
Sentences | 2
Words | 9
Unique words | 8
Long words | 1
Complex words | 1
Simple words | 8
Monosyllabic words | 8
Polysyllabic words | 1
Characters | 40
Letters | 30
Spaces | 8
Syllables | 11
Punctuation marks | 2
Entropy of the word lengths in letters (bits) | 1.45
Entropy of the word lengths in syllables (bits) | 0.50
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
source |
str / Doc / Document |
- | Data source |
sents_extractor |
SentsExtractor |
None |
Sentence extraction tool, used on the text in place of the sentences of the document |
words_extractor |
WordsExtractor |
None |
Word extraction tool, used on the text in place of the words of the document |
normalize |
bool |
False |
Compute normalized statistics |
complex_syl_factor |
int |
COMPLEX_SYL_FACTOR |
Minimum number of syllables in a complex word |
long_word_letter_factor |
int |
LONG_WORD_LETTER_FACTOR |
Minimum number of letters in a long word |
The object keeps normalize, complex_syl_factor and long_word_letter_factor under their names.
The thresholds of the core are COMPLEX_SYL_FACTOR = 3 and LONG_WORD_LETTER_FACTOR = 7 of anyts.constants.
Statistics¶
| Statistic | Type | Description | Normalized |
|---|---|---|---|
c_letters |
dict[int, int] |
Distribution of words by number of letters | - |
c_syllables |
dict[int, int] |
Distribution of words by number of syllables | - |
n_sents |
int |
Number of sentences containing words | - |
n_words |
int |
Number of words | - |
n_unique_words |
int |
Number of unique words, case ignored | p_unique_words |
n_long_words |
int |
Number of long words, of at least long_word_letter_factor letters |
p_long_words |
n_complex_words |
int |
Number of complex words, of at least complex_syl_factor syllables |
p_complex_words |
n_simple_words |
int |
Number of simple words: with a syllable, below the complex ones | p_simple_words |
n_monosyllable_words |
int |
Number of monosyllabic words | p_monosyllable_words |
n_polysyllable_words |
int |
Number of polysyllabic words, of two syllables or more | p_polysyllable_words |
n_chars |
int |
Number of characters without the line breaks | - |
n_letters |
int |
Number of letters | p_letters |
n_spaces |
int |
Number of spaces of Unicode (category Zs), such as the no-break space, and tabs | p_spaces |
n_syllables |
int |
Number of syllables | - |
n_punctuations |
int |
Number of punctuation marks | p_punctuations |
letters_entropy |
float |
Shannon entropy in bits of the word lengths in letters, of c_letters: 0 when the words have one length; the estimate by the shares runs lower on a short text, by tenths of a bit on tens of words |
- |
syllables_entropy |
float |
Shannon entropy in bits of the word lengths in syllables, of c_syllables, with the same bias |
- |
c_punctuations |
dict[str, int] |
Distribution of punctuation marks by type (count_punctuations) |
- |
With normalize=True the object has the normalized statistics too, of the type float: the counts of the words divided by the number of words, those of the characters by the number of characters.
Methods¶
count_words_by_syllables(min_syllables) and count_words_by_letters(min_letters) return the number of words with at least the given number of syllables or letters; a minimum that is not an integer raises ParameterError.
get_stats(flat) returns a dictionary with the distributions c_letters and c_syllables, the statistics of stats_desc, the distribution c_punctuations and, with normalize=True, the normalized counts, as a copy: editing it does not change the object. With flat=True the distributions give a key for every value the text has, such as c_letters_3 and c_punctuations_comma.
print_stats() prints a table with the statistics of stats_desc, their descriptions and the headers from stats_headers.
bs.count_words_by_syllables(2), bs.count_words_by_letters(4)
bs.get_stats()["c_letters"]
(1, 1)
{1: 1, 2: 1, 3: 6, 9: 1}
The frame of the statistics (to_dataframe) and their reading (describe) are those of the statistics interface.
Punctuation marks¶
count_punctuations(text, marks=PUNCTUATION_MARKS, dash_pattern=DASH_PATTERN)
Counts punctuation marks by type, the distribution of c_punctuations: commas, periods, question and exclamation marks, ellipses, colons, semicolons, dashes, hyphens, guillemets, quotation marks, parentheses and other marks. Dashes typed with hyphens (dash_pattern) are counted first, then ellipses - …, three or more periods, or two after ? and !, one mark whose periods are not counted as periods (Who?.. is a question and an ellipsis) - then each mark by its type in marks; any other character of the Unicode categories P and S is another mark (§, €, °).
| Parameter | Type | Default | Description |
|---|---|---|---|
text |
str |
- | Text string |
marks |
dict[str, str] |
PUNCTUATION_MARKS |
Type of every mark, among PUNCTUATION_TYPES |
dash_pattern |
Pattern |
DASH_PATTERN |
Dashes typed with hyphens |
A mark of marks that is not a single character or has an unknown type raises ParameterError; a text that is not a string, marks that are not a mapping and a dash_pattern that is not a compiled regular expression raise SourceTypeError.
In the core the types are anyts.constants.PUNCTUATION_TYPES, and marks and dash_pattern are PUNCTUATION_MARKS and DASH_PATTERN of anyts.basic_stats. The marks count ¿ and ¡ as question and exclamation marks (¿So? has two), —, – and the horizontal bar ― as dashes, «» as guillemets and "“”‘’ as quotation marks; a hyphen inside a word, before a digit or at a line break inside a word is a hyphen (well-known, -5). A dash typed with hyphens is a run of two or more hyphens, or a hyphen after whitespace, a closing mark or at the start of a line, before a space of a line (a Unicode separator such as the no-break space, or a tab: SPACES) or the end of the text, or between a letter and an opening or a closing mark (--Hello --said John, - They left - he said).
from anyts.basic_stats import count_punctuations
counts = count_punctuations('"Well..." - he said - "a well-known cat?!"')
{kind: count for kind, count in counts.items() if count}
{'question': 1, 'exclamation': 1, 'ellipsis': 1, 'dash': 2, 'hyphen': 1, 'straight_quotes': 4}
Dashes typed with hyphens¶
dash_pattern(conjunctions=(), hanging_before_comma=False)
Builds the dash_pattern of count_punctuations. A hanging hyphen glued to a letter or a digit and carried on to a later word (pre- and post-war, 5- and 10-year) stays a hyphen before spaces of a line and one of the conjunctions, case ignored, and with hanging_before_comma before a comma (two-, three- and four-year). A language whose dialogue closes a line with a hyphen before a comma (-Come -he said-, and left) leaves hanging_before_comma off. Without the parameters the pattern is DASH_PATTERN.
| Parameter | Type | Default | Description |
|---|---|---|---|
conjunctions |
Collection[str] |
() |
Conjunctions after a hanging hyphen |
hanging_before_comma |
bool |
False |
Take a hyphen between a letter and a comma for a hanging one |
Conjunctions that are not a collection of strings raise SourceTypeError, and an empty conjunction ParameterError.
from anyts.basic_stats import count_punctuations, dash_pattern
text = "pre- and post-war, two-, three- and four-year - he said"
counts = count_punctuations(text, dash_pattern=dash_pattern(["and"], hanging_before_comma=True))
counts["dash"], counts["hyphen"]
(1, 5)
For library developers¶
Language hooks of a subclass
A language library subclasses BasicStats:
| Hook | Kind | Description |
|---|---|---|
count_syllables(word) |
method | The syllables of a word; abstract |
doc_words(document) |
method | The words of a document; document_words by default, overridden to normalize the forms of the words of a language |
count_punctuations(text) |
method | The punctuation marks by type; count_punctuations of the module by default |
stats_desc |
class attribute | The counts of get_stats with their descriptions for print_stats; anyts.constants.BASIC_STATS_DESC by default |
The other hooks, parse, stats_headers, level_scales and messages, come from Stats. The thresholds of the complex and the long words are parameters; a library sets its own defaults in its __init__ and passes them on.