Last active
November 5, 2020 06:32
-
-
Save ptmcg/ee97e8f037937ce1c47c5b2d767381c3 to your computer and use it in GitHub Desktop.
A python racter-like
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# py_rac.py | |
# | |
# Copyright 2020, Paul McGuire | |
# | |
names = ("Voltaire|Samuel Johnson|Valery|Dante|" | |
"Nietzsche|Kant|Lao Tzu|Macchiavelli|Einstein|" | |
"Russell|Leonardo|Plato|Aristotle|Socrates|Diderot|" | |
"Descartes|Thomas Aquinas|Hawking|Emerson|Faulkner|" | |
"Chamberlain|Livy|Caesar|Holmes|Moriarty|Edison|Tesla".split('|')) | |
concepts = """Wit Vitality Vigor Ambiguity Sexuality Philosophy | |
Ambition Mercy Morality Truth Folly Emotion Art Politics | |
Commerce Industry Beauty Instinct Reason Fortune Fate Destiny | |
Guile Chance Purpose Luck Misfortune Triviality Fashion | |
Passion Awareness Consciousness""".split() | |
opposites1 = """Envy/Kindness | |
Vanity/Modesty Lust/Chastity | |
Conceit/Humility Famine/Plenty | |
Pleasure/Pain | |
Sin/Virtue Vice/Virtue Love/Hate | |
Man/Woman Risk/Certainty | |
Foolishness/Wisdom Harmony/Conflict | |
Success/Failure Weakness/Strength | |
Loyalty/Treachery Danger/Safety | |
Illusion/Reality""".split() | |
for opp in opposites1: | |
concepts.extend(opp.split('/')) | |
opposites2 = """Gluttony/Moderation | |
Pride/Humility Life/Death Wrath/Patience | |
Greed/Charity Sloth/Endeavor Lust/Chastity | |
Good/Evil Courage/Fear Abstinence/Indulgence | |
Change/Stagnation Knowledge/Ignorance Victory/Defeat | |
Prosperity/Want Wealth/Poverty Depression/Levity | |
Masculinity/Feminity Pride/Shame Freedom/Slavery | |
Conformity/Individuality Justice/Injustice""".split() | |
opposites = opposites1 + opposites2 | |
a_nouns = """truth shield weapon talent skill character person flame blade | |
flower reward curse blessing mistress wife lover enemy light husband | |
friend idea thought concept obstacle chain shackle bird abyss | |
arrow threat promise garment debt surplus voice secret whim | |
abyss obsession agenda constraint restraint lion snake crime | |
ambition study remedy reason thought bullet regret mystery | |
viper cow dog cat bush lie father mother child cousin fantasy process horse | |
sheep tiger locust moth disguise veil dream basis picture word | |
device nuisance comrade itch dagger ash gesture moment shield spear | |
force ant illusion charade fellow doubt instrument purpose antidote | |
weapon tool sword word legend awareness vision consciousness""".split() | |
coll_nouns = """food stone lead steel gold silver bread money meat poison | |
debt wealth energy power beauty truth flesh fire rust math science | |
decay luck dust ash grass water essence health medicine chaos | |
people innocence blood""".split() | |
coll_nouns += concepts | |
nouns = a_nouns + coll_nouns | |
body = """arm leg head chest breast soul foot hand neck eye | |
ear tongue shoulder stomach heart brain mind loins | |
gut brow""".split() | |
#~ nouns += body | |
nums = """10,000 10,000 a_million a_thousand a_thousand a_hundred a_couple_of two three seven a_dozen a_score_of""".split() | |
nouns += map(lambda s:s.replace('_',' '), | |
"""nom_de_plume nom_de_guerre sine_qua_non raison_d'etre | |
coup_de_grace summa_cum_laude magnum_opus fait_accompli | |
quid_pro_quo""".split()) | |
plurals = [] | |
irreg_plurals = dict(foot='feet',sheep='sheep',man='men', | |
woman='women',child='children',basis='bases') | |
for n in a_nouns+concepts: | |
if n.lower() in irreg_plurals: | |
plurals.append(irreg_plurals[n.lower()]) | |
elif n.endswith('y') and not any(n.endswith(v+'y') for v in "aeiou"): | |
plurals.append(n[:-1]+"ies") | |
elif n.endswith('ey'): | |
plurals.append(n[:-2]+"ies") | |
elif any(n.endswith(suf) for suf in ('s','tch','sh','ch')): | |
plurals.append(n+'es') | |
elif n.endswith('fe'): | |
plurals.append(n[:-2]+'ves') | |
else: | |
plurals.append(n+'s') | |
plurals.remove("Politicses") | |
plurals.append("Politics") | |
plurals.extend(coll_nouns) | |
#~ print plurals | |
time_periods = """year day season hour minute second age eon week moment | |
""".split() | |
adjs = """golden lovely deadly sinister pleasant sensuous austere harsh loyal | |
treacherous leaden dull bright shiny broken cracked iron whimsical | |
frail grim cheerful flimsy brief tender true false great trivial | |
strong weak firm soft hard healthy sickly youthful weary inscrutable | |
welcome reluctant resistant persistent intelligent wise unwise foolish gentle | |
fragile shallow imaginary undeniable unreasonable tender determined | |
hidden secret childish relentless merciless ruthless futile deliberate | |
prudent imprudent practical impractical pointless brash idle secret | |
precious opposing overwhelming true deceitful faithful hollow | |
imaginary lucky vain humble welcome unwelcome""".split() | |
advs = """never ever always just purely heartily reluctantly vehemently | |
vigorously unflinchingly really blindly foolishly | |
truly wisely hardly relentlessly mercilessly | |
compassionately ruthlessly tenderly gently | |
carefully cautiously wildly carelessly recklessly | |
artfully temporarily permanently partially totally | |
completely randomly""".split() | |
ob_pros = """everyone no_one someone anyone everybody everything nothing all""".split() | |
sub_pros = """everyone no_one yourself someone anyone everybody one everything nothing all""".split() | |
v_t = """question challenge need have dispute want distrust trust love hate embrace treasure | |
indulge welcome engage know betray spoil kill destroy enrage pursue fight play | |
consume defeat conquer cut control make break keep disappoint feed""".split() | |
prog_v_t = [v + 'ing' if not v.endswith('e') else v[:-1]+'ing' for v in v_t] | |
v_i = "run walk talk be eat drink laugh cry sing dance breathe worry relax debate confer sleep rise stay".split() | |
prog_v_i = [v + 'ing' if not v.endswith('e') else v[:-1]+'ing' for v in v_i] | |
prog_v_i.remove('runing') | |
prog_v_i.append('running') | |
prog_v_i.remove('bing') | |
prog_v_i.append('being') | |
preps = """about above across after against along among around beside between | |
before behind below beneath beyond by for from in inside | |
into near on onto outside over past under underneath unlike until upon | |
versus via with within without""".split() | |
v_passive = """trusted contained wanted disguised loved | |
hated idolized ignored embraced | |
beloved despised impressed respected | |
revered considered heeded denied | |
convinced avoided denied indulged known | |
welcomed admired recognized rewarded made | |
cherished forgotten overlooked | |
beaten imagined dreamt_of | |
""".split() | |
neg_v_passive = """unrewarded unimpressed unconvinced | |
unloved unknown unwanted unheeded undone | |
unrecognized undreamed_of unimagined unprepared | |
disappointed shunned ridiculed betrayed | |
""".split() | |
v_passive += neg_v_passive | |
adjs += v_passive | |
intros = """\ | |
By the way, | |
That reminds me, | |
In other words, | |
One other thing, | |
In conclusion, | |
According to {nm1}, | |
Even {nm1} would have to admit, | |
Now | |
On a good day, | |
On any given day, | |
It is often said, | |
As {pl} go, | |
In the end, | |
But in the end, | |
In time, | |
Over time, | |
Some day, | |
In the future, | |
It goes without saying, | |
I have no doubt, | |
More than {np}, | |
As I've said {num} times, | |
Without {np}, | |
In every {tp}, | |
Every {num} {tp}s, | |
Every {num} {tp}s or so, | |
For a single {tp},""".splitlines() | |
templates = """\ | |
What becomes of a man who {v_t}s {ob_pro} but is himself {v_passive}? | |
What becomes of a man who {v_t}s {ob_pro} but is not himself {v_passive}? | |
What becomes of a woman who {v_t}s {ob_pro} but is herself {v_passive}? | |
What becomes of a woman who {v_t}s {ob_pro} but is not herself {v_passive}? | |
Every {n} is a {a} {c}. | |
After {o1}, my favorite {n} is {c}. | |
A {a} {n} cannot be {v_passive}. | |
A {a} {n} should not be {v_passive}. | |
One's {b} must be {a}. | |
One's {b} must {adv} be {a}. | |
{o1} and {o2} are {a} {pl}. | |
From {pl} come {np}. | |
{nm1} and {nm2} will {v_t} each other. | |
You must {v_t} your {n}. | |
You must {v_t} your {pl}. | |
Behind every {n1} is a {n2}. | |
{c} {v_t}s {ob_pro}. | |
{c} will {v_t} {ob_pro}. | |
{v_t} your {n}. | |
Don't {v_t} {pl1} you can't {v_t2}. | |
{v_t} {pl1} even if you can't {v_t2} them. | |
Must all {pl} be {v_passive}? | |
Can any {n} be truly {v_passive}? | |
The {n} often goes {neg_v_passive}. | |
Some day, {ob_pro} will be {v_passive}. | |
Some day, {ob_pro} will be {a}. | |
Some day, {ob_pro} will be {a} for {num} {tp}s. | |
Some day, {ob_pro} will be {a} for just one {tp}. | |
Some day, {ob_pro} will be {a} for a single {tp}. | |
{ob_pro} can be {v_passive}. | |
{ob_pro} can be {a}. | |
{ob_pro} can be {a} for {num} {tp}s. | |
{ob_pro} can be {a} for just one {tp}. | |
{ob_pro} can be {a} for a single {tp}. | |
In the future, {ob_pro} will be {v_passive}. | |
In the future, {ob_pro} will be {a}. | |
In the future, {ob_pro} will be {a} for {num} {tp}s. | |
{nm1} would {v_t} {np}. | |
{pl1} are {pl2}. | |
{pl2} are really {pl1}. | |
Our {pl1} are really our {a} {pl2}. | |
{pl1} are {a} {pl2}. | |
{pl2} are really just {pl1}. | |
{pl2} are just {pl1}. | |
{pl} are {a}. | |
{pl} can be {a}. | |
{pl} can be {a1} if you are not {a2}. | |
{pl} can become {a1} if you do not {v_t} them. | |
{nm1} {v_t}s {c}. | |
{nm1} {v_t}s {pl}. | |
Your {n1} is your {n2}. | |
{pl} lead to {c}. | |
All {c1} is just {c2}. | |
All {c} is just {np}. | |
{o1} is really just {o2} having a bad day. | |
{o1} is really just {o2} in disguise. | |
{o1} is really just {o2} in a mirror. | |
Every {o1} hides a {a} {o2}. | |
Be as {np} to {ob_pro}. | |
Be {np} to {ob_pro}. | |
{c} is just {np}. | |
{prog_v_i} with {pl} is {np}. | |
{v_t} your {n} or your {n} will {v_t} you. | |
{v_t} your {n} before your {n} {v_t}s you. | |
{v_t}. | |
{v_t}, just {v_t}. | |
{v_t} or be {v_passive}. | |
{v_t} and be {v_passive}. | |
{v_t} {c}. | |
{v_t} {ob_pro}. | |
{v_t} {ob_pro}, as {ob_pro} {v_t}s you. | |
{v_t} {np}. | |
{v_t} {np}, just {v_t} it. | |
{v_t} {np}, as {np} {v_t}s you. | |
{v_t} {np}, or {np} will {v_t} you. | |
{v_t} {np}, and {np} will {v_t} you. | |
{v_t} {np1} or {np2}. | |
{np1} is {np2}. | |
{np1} is {np2} to be {v_passive}. | |
{np1} is a {a_n2} to {v_t}. | |
{num} {pl} are not equal to a single {n}. | |
{np} equals {num} {pl}. | |
{np} is equal to {num} {pl}. | |
{np} is greater than {num} {pl}. | |
One {n} will lead to {num} {pl}. | |
A {n1} in the {n2} is worth {num} in the {n3}. | |
One must {v_t} {np}. | |
One must {v_t} {np} or {v_i}. | |
You are {np}. | |
You are your own {c}. | |
My {c1} is exceeded only by my {c2}. | |
{v_t} your inner {n}. | |
{v_t} your inner {n}, just as your inner {n} {v_t}s you. | |
{v_t} your {pl}. | |
{v_t} {pl}. | |
We are all {np}. | |
{v_t} {pl}, as the {pl} {v_t} you. | |
{v_t} your {pl}, at all costs. | |
{v_i} with the {pl}. | |
{v_i} with your {pl}. | |
{o1} becomes {o2}. | |
{np} is {a}. | |
{np} is {a} to {v_t}. | |
{n} will not be {v_passive}. | |
Too much {coll_n} will {v_t} {np}. | |
Too many {a_n}s {v_t} {np}. | |
To {v_t} {c1}, one must first {v_t} {c2}. | |
It is {a} to {v_t} {np}. | |
It is {c} to {v_t} {np}. | |
{pl} are {a} to {v_t}. | |
{ob_pro} is {np}. | |
{ob_pro} can be {np}. | |
{ob_pro} has {np}. | |
All {c1} is {c2}. | |
{c1} is {c2}, {c2} {c1}. | |
{sub_pro} must have the courage to {v_t} their {coll_n}. | |
{sub_pro} must have the courage to {v_t} their {n}. | |
{v_i} {prep} {np}.""".splitlines() | |
emp_patt = """\ | |
I {v_t} {c} | |
{nm1} must {v_t} {np} | |
{c} cannot be {v_passive} | |
{c} can only be {v_passive} | |
{pl} can only be {v_passive} | |
only {c} can be {v_passive} | |
{nm1} must be {v_passive} | |
{nm1} must not be {v_passive} | |
{adv} | |
even if just for a {tp} | |
{adv1} and {adv2} | |
without {c} | |
without exception""".splitlines() | |
from random import random, choice, shuffle | |
def mutate(fill=None): | |
if not fill: | |
fill = {} | |
fill['nm1'] = choice(names) | |
fill['nm2'] = fill['nm1'] | |
while fill['nm2'] == fill['nm1']: | |
fill['nm2'] = choice(names) | |
for key in 'n n1 n2 n3'.split(): | |
if key == 'n2': | |
fill[key] = fill['n1'] | |
while fill[key] == fill['n1']: | |
fill[key] = choice(nouns+concepts) | |
else: | |
fill[key] = choice(nouns+concepts) | |
while random() < 0.1: | |
fill[key] = choice(adjs) + ' ' + fill[key] | |
if random() < 0.1: | |
fill[key] = fill[key] + ' of ' + choice(concepts) | |
elif random() < 0.1: | |
fill[key] = fill[key] + ' for ' + gen('{np}') | |
fill['c'] = choice(concepts) | |
fill['c1'] = choice(concepts) | |
fill['c2'] = fill['c1'] | |
while fill['c2'] == fill['c1']: | |
fill['c2'] = choice(concepts) | |
fill['o1'],fill['o2'] = (choice(opposites).split('/'))[::choice((1,-1))] | |
fill['ob_pro'] = choice(ob_pros) | |
fill['sub_pro'] = choice(sub_pros) | |
fill['prog_v_i'] = choice(prog_v_i) | |
fill['a'] = choice(adjs) | |
if random() < 0.1: | |
fill['a'] = choice(advs) + ' ' + fill['a'] | |
for key in 'a1 a2'.split(): | |
fill[key] = choice(adjs) | |
fill['b'] = choice(body) | |
fill['v_passive'] = choice(v_passive) | |
fill['neg_v_passive'] = choice(neg_v_passive) | |
while random() < 0.1: | |
fill['v_passive'] = choice(advs) + ' ' + fill['v_passive'] | |
for key in 'v_t v_t1 v_t2'.split(): | |
fill[key] = choice(v_t) | |
while random() < 0.1: | |
fill[key] = choice(advs) + ' ' + fill[key] | |
fill['v_i'] = choice(v_i) | |
while random() < 0.1: | |
fill['v_i'] = choice(advs) + ' ' + fill['v_i'] | |
for key in 'pl pl1 pl2'.split(): | |
fill[key] = choice(plurals) | |
while random() < 0.1: | |
fill[key] = choice(adjs) + ' ' + fill[key] | |
for key in 'adv adv1 adv2'.split(): | |
if key == 'adv2': | |
fill[key] = fill['adv1'] | |
while fill[key] == fill['adv1']: | |
fill[key] = choice(a_nouns) | |
else: | |
fill[key] = choice(a_nouns) | |
articles = 'a_ a_ the_ the_ the_ your_ your_own_'.split() | |
for key in 'np np1 np2'.split(): | |
if key == 'np2': | |
fill[key] = fill['np1'] | |
while fill[key] == fill['np1']: | |
fill[key] = choice((choice(coll_nouns), choice(articles) + choice(a_nouns))) | |
else: | |
fill[key] = choice((choice(coll_nouns), choice(articles) + choice(a_nouns))) | |
fill['a_n'] = choice(a_nouns) | |
fill['coll_n'] = choice(coll_nouns) | |
for key in 'a_n a_n1 a_n2'.split(): | |
if key == 'a_n2': | |
fill[key] = fill['a_n1'] | |
while fill[key] == fill['a_n1']: | |
fill[key] = choice(a_nouns) | |
else: | |
fill[key] = choice(a_nouns) | |
fill['num'] = choice(nums) | |
fill['prep'] = choice(preps) | |
fill['tp'] = choice(time_periods) | |
if random() < 0.1: | |
fill['tp'] = choice(adjs) + ' ' + fill['tp'] | |
else: | |
fill2 = mutate() | |
if random() < 0.8: | |
fill['v_t'] = fill2['v_t'] | |
while random() < 0.7: | |
key = choice(list(fill2.keys())) | |
if key.endswith('1') or key.endswith('2'): | |
key,other = key[:-1]+'1', key[:-1]+'2' | |
fill[key] = fill2[key] | |
fill[other] = fill2[other] | |
else: | |
fill[key] = fill2[key] | |
return fill | |
def uncap(s): | |
if any(s.startswith(nm) for nm in names): | |
return s | |
if s.startswith("I "): | |
return s | |
return s[0].lower() + s[1:] | |
def gen(s=None, fill=None, lastpatt=['']): | |
if fill is None: | |
fill = mutate() | |
if s is None: | |
patt = choice(templates) | |
while patt==lastpatt[0]: | |
patt = choice(templates) | |
lastpatt[0] = patt | |
while random() < 0.1 and patt[-1] != '?': | |
patt = (gen(s=choice(intros)) + | |
' ' + (patt[0].lower() | |
if not patt.startswith("I ") | |
else patt[0]) + patt[1:]) | |
while random() < 0.1: | |
patt = patt[:-1] + ', ' + uncap(gen(s=choice(emp_patt))) + patt[-1] | |
else: | |
patt = s | |
#~ ret = patt.format(**fill) | |
import re | |
patt = re.sub(r'{([^}]+)}',r'%(\1)s', patt) | |
ret = patt % fill | |
ret = ret.replace('_',' ') | |
for v in "aeiouAEIOU": | |
if ret.lower().startswith('a '+v): | |
ret = 'an ' + ret[2:] | |
ret = ret.replace(' a '+v, ' an '+v) | |
ret = ret.replace(' to I,', ' to my way of thinking,') | |
if s is None and random() < 0.05: | |
ret = ret[:-1]+'!' | |
return ret[0].upper() + ret[1:] | |
def pyrac(): | |
sentences = [] | |
for j in range(3): | |
fill = mutate() | |
for i in range(12): | |
sentences.append(gen(fill=fill)) | |
fill = mutate(fill) | |
sentences.append('') | |
return sentences | |
if __name__ == "__main__": | |
for s in pyrac(): | |
print(s) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment