Writing Functions
2025-11-14
book_path = "austen/pride_and_prejudice.txt"
with open(book_path, mode="r", encoding="utf-8") as book_file:
book_lines = book_file.readlines()
clean_lines = [line.strip().lower() for line in book_lines]
pride_and_prejudice = [word for line in clean_lines for word in line.split() if word]
book_path = "austen/sense_and_sensibility.txt"
with open(book_path, mode="r", encoding="utf-8") as book_file:
book_lines = book_file.readlines()
clean_lines = [line.strip().lower() for line in book_lines]
sense_and_sensibility = [word for line in clean_lines for word in line.split() if word]from collections import Counter
import spacy
nlp_en = spacy.load("en_core_web_sm")
nlp_es = spacy.load("es_core_news_sm")
def is_preposition(tok):
# True for tokens that are prepositions or postpositions
return tok.pos_ == "ADP"
def prep_stats(nlp, text, lang_label):
doc = nlp(text)
# word-like tokens only for the denominator
word_tokens = [t for t in doc if t.is_alpha]
total = len(word_tokens)
preps = [t.text for t in doc if is_preposition(t)]
n = len(preps)
rate = (n / total) if total else 0.0
print(f"{lang_label}: {n} prepositions / {total} word tokens ({rate:.2%})")
print("Top forms:", Counter(w.lower() for w in preps).most_common())
# Run on English and Spanish samples
prep_stats(nlp_en, text_en, "English")
prep_stats(nlp_es, text_es, "Spanish")import spacy
from spacy.matcher import PhraseMatcher
from nltk.corpus import wordnet as wn
nlp = spacy.load("en_core_web_sm")
# WordNet helpers (via NLTK) – returns only verb synsets
def verb_senses(word):
return wn.synsets(word, pos='v') # verb synsets only
# Collects all (recursive) hyponyms for a verb synset (troponyms in WN terms).
# This function recursively collects all *hyponyms* (a.k.a. “troponyms” for verbs)
# of a given synset. A hyponym is a more *specific* instance of an action.
# Example: the verb “attack.v.01” has hyponyms like “bomb.v.01”, “invade.v.01”, etc.
def all_verb_hyponyms(root):
seen, stack = set(), [root]
while stack:
cur = stack.pop()
if cur in seen:
continue
seen.add(cur)
# For verbs, .hyponyms() are the troponyms
stack.extend(cur.hyponyms())
return {s for s in seen if s.pos() == 'v'}
# This function extracts lemma names (the “canonical” word forms)
# from a set of synsets, e.g. 'strike.v.01' → ['strike', 'hit', 'smite', ...].
# Optionally filters out multiword expressions like "shoot_down".
def lemmas_from_synsets(synsets, keep_multiword=False):
out = set()
for s in synsets:
for lem in s.lemmas():
name = lem.name().lower()
if not keep_multiword and "_" in name:
continue
out.add(name.replace("_", " "))
return out
# Build a violence lexicon from WordNet using a few intuitive seeds
seed_verbs = ["attack", "assault", "hit", "strike", "punch", "kick", "stab", "shoot", "beat"]
base_synsets = []
for w in seed_verbs:
ss = verb_senses(w)
if ss:
# take the most “central” sense by picking the one with most hyponyms
ss_scored = sorted(ss, key=lambda s: len(s.hyponyms()), reverse=True)
base_synsets.append(ss_scored[0])
# expand via hyponyms (troponyms)
expanded = set()
for s in base_synsets:
expanded |= all_verb_hyponyms(s)
# collect lemmas (single-token by default)
violent_verb_lemmas = sorted(lemmas_from_synsets(expanded, keep_multiword=False) | set(seed_verbs))
print(f"{len(violent_verb_lemmas)} violent verb lemmas (sample):", violent_verb_lemmas[:25])
# 4) spaCy PhraseMatcher by lemma — IMPORTANT: run full pipeline on patterns
matcher = PhraseMatcher(nlp.vocab, attr="LEMMA")
patterns = list(nlp.pipe(violent_verb_lemmas)) # not make_doc: we need lemmas
matcher.add("VIOLENCE", patterns)return()?.py scriptinitialize.pybook_path = "austen/pride_and_prejudice.txt"
book_file = open(book_path, mode = 'r')
book_lines = book_file.readlines()
clean_lines = [line.rstrip().lower() for line in book_lines]
pride_and_prejudice = [w for w in clean_lines if w]
book_path = "austen/sense_and_sensibility.txt"
book_file = open(book_path, mode = 'r')
book_lines = book_file.readlines()
clean_lines = [line.rstrip().lower() for line in book_lines]
sense_and_sensibility = [w for w in clean_lines if w]Our script needs to:
alice.txt)def read_book(path):
with open(path, mode="r", encoding="utf-8") as book_file:
book_lines = book_file.readlines()
clean_lines = [line.strip().lower() for line in book_lines]
# Split each line into words and flatten the list
words = [word for line in clean_lines for word in line.split() if word]
return words
alice = read_book("alice.txt")
print(alice[:200])import spacy
from nltk.corpus import wordnet as wn
from nltk.corpus.reader.wordnet import NOUN, VERB, ADJ, ADV
# Load spaCy
nlp = spacy.load("en_core_web_sm")
# Sentence with both noun and verb "bear"
text = "The bears bear their burdens bravely."
doc = nlp(text)
# Map spaCy POS tags to WordNet POS tags -- this is a **function**, we'll get to these soon
def get_wordnet_pos(spacy_pos):
if spacy_pos.startswith("N"):
return NOUN
elif spacy_pos.startswith("V"):
return VERB
elif spacy_pos.startswith("J"):
return ADJ
elif spacy_pos.startswith("R"):
return ADV
return None
# Loop through tokens and look up WordNet entries
for token in doc:
wn_pos = get_wordnet_pos(token.tag_)
lemma = token.lemma_.lower()
if wn_pos and not token.is_stop and not token.is_punct:
synsets = wn.synsets(lemma, pos=wn_pos)
print(f"\n{token.text.upper()} ({token.pos_}) → lemma: {lemma}")
for s in synsets[:3]: # show just the first 3 senses
print(f" - {s.definition()} [examples: {s.examples()}]")nlp_it) we are going to:
return() anything here