"""Side-by-side page for reading the predicament pilot: the scene, its summary, and what each model made of it.
python3 strip_names.py pilot-predicaments-3b.json pilot-3b-clean.json
python3 strip_names.py pilot-predicaments-14b.json pilot-14b-clean.json
python3 pilot_page.py pilot-3b-clean.json pilot-14b-clean.json > pilot-compare.html
Takes strip_names.py's output, so the page shows what the full run would actually embed. (strip_names
runs as a script on import, so it is not imported here.) Job, relationship and place words are
highlighted. A pick per scene is kept in the browser only; the tally at the top is what to report
back. No inference.
"""
import collections, html, json, pathlib, re, sys
from topic_words import TOPIC_WORDS
def clean(text):
return text # inputs are already name-stripped
a_path, b_path = sys.argv[1], sys.argv[2]
cols = [json.loads(pathlib.Path(p).read_text(encoding='utf-8')) for p in (a_path, b_path)]
labels = [c['model'] for c in cols]
chunks = json.loads(pathlib.Path('chunks.json').read_text(encoding='utf-8'))
summary = {x['chunk']: x['summary'] for x in
json.loads(pathlib.Path('summaries_clean.json').read_text(encoding='utf-8'))['summaries']}
def marked(text):
out = []
for part in re.split(r"([A-Za-zé]+)", text):
esc = html.escape(part)
out.append(f'{esc}' if part.lower() in TOPIC_WORDS else esc)
return ''.join(out)
def leaks(text):
return len(set(re.findall(r"[a-zé]+", text.lower())) & TOPIC_WORDS)
def opening(text):
return ' '.join(text.split()[:3])
rows, stats = [], []
for col in cols:
texts = [clean(x['summary']) for x in col['summaries']]
stats.append({
'leaky': sum(leaks(t) > 0 for t in texts),
'city': sum('city' in t.lower() for t in texts),
'words': sum(len(t.split()) for t in texts) / len(texts),
'openings': collections.Counter(opening(t) for t in texts).most_common(3),
})
n = min(len(c['summaries']) for c in cols)
for i in range(n):
x = cols[0]['summaries'][i]
ch = chunks[x['chunk']]
cells = ''.join(
f'
'
for j in range(2))
rows.append(f'''{i + 1}{html.escape(ch["title"])}Scene summary: {marked(summary.get(x["chunk"], ""))}
{html.escape(ch["text"][:1200])}{"…" if len(ch["text"]) > 1200 else ""}
{cells}
''')
stat_rows = ''.join(
f'
{html.escape(labels[j])}
{s["leaky"]} of {n}
{s["city"]}
'
f'
{s["words"]:.0f}
{"; ".join(f"“{html.escape(o)}…” ×{c}" for o, c in s["openings"])}
'
for j, s in enumerate(stats))
print(f'''
Predicament pilot
Predicament pilot
The first {n} scenes, each re-described by two models as the main person's predicament. Names are
already removed as the full run would. Highlighted words are jobs, relationships and places, the
words the old groups formed around. Pick the better sentence in each scene, or "neither". The column order
is fixed: {html.escape(labels[0])} on the left.
What to look for: does the sentence say what the person is up against and what they want? Could
it happen to anyone, anywhere? Would two scenes with the same predicament end up with similar sentences?