You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.9 KiB
Python

#!/usr/bin/env python
# -*- coding: <utf-8> -*-
'''
It automatises the Oulipo constraint Litterature Definitionelle:
http://oulipo.net/fr/contraintes/litterature-definitionnelle
invented by Marcel Benabou in 1966
In a given phrase, one replaces every significant element (noun, adjective, verb, adverb)
by one of its definitions in a given dictionary ; one reiterates the operation on the newly received phrase,
and again.
Copyright (C) 2018 Constant, Algolit, An Mertens, Gijs de Heij
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details: <http://www.gnu.org/licenses/>.
'''
import nltk
from nltk.corpus import wordnet as wn
from nltk import word_tokenize
import nltk.data
import random
import re
import time
import wikipedia
from trees import trees
import os
import os.path
import sys
from io import StringIO
def choose_a_tree(dict):
collection = random.choice(list(trees.items()))
# Give name gardener
gardening = collection[0]
cut = " in "
if cut in gardening:
index = re.search(cut, gardening).start()
gardener = gardening[:index]
source = gardening[index+3:]
else:
gardener = gardening
source = 'Unknown'
# Trees (s)he planted
tree = collection[1]
# if (s)he planted more than 1 tree, pick 1
if type(tree) == list:
tree = random.choice(tree)
return gardener, source, tree
# find bio gardener on Wikipedia
def bio(gardener):
try:
bio = wikipedia.page(gardener)
short_bio = bio.summary
except:
short_bio = "There is no English Wikipedia page about this person."
return short_bio
def bio_offline(gardener):
filename = os.path.join('bios', re.sub(r'\W', '', gardener))
if os.path.exists(filename):
with open(filename, 'r') as h:
return h.read()
return "There is no English Wikipedia page about this person."
"""
Return blossoming version of the knot.
knot string
return string
"""
def grow_new_branch (bud):
branch = wn.synsets(bud)
if branch:
return branch[0].definition()
return bud
# Turn nltk tree back into a sentence
def trim_tree (branches):
tree = " ".join([branch[0] for branch in branches])
# Remove spaces in html tags
tree = re.sub(r'\<\s*(\/?\w+)\s*\>', '<\\1>', tree)
return re.sub(r'\s[\.,:;\(\)]', '', tree)
def graft_a_tree (years = 3):
gardener, source, tree = choose_a_tree(trees)
short_bio = bio_offline(gardener)
print(
'<section>'
+ 'Using a quote by <em>{}</em><br><br>'.format(gardener) \
+ short_bio
+ '</section>'
)
year = 1
print('<p class="tree first">{}</p>'.format(tree))
while year <= years:
branches = nltk.pos_tag(word_tokenize(tree))
# Filter out nouns, pick one
position, bud = random.choice([(position, bud[0]) for position, bud in enumerate(branches) if bud[1] == 'NN'])
tree_with_bud = '{} <em>{}</em> {}'.format(
trim_tree(branches[:max(0, position)]),
bud.strip(),
trim_tree(branches[position+1:]))
print('<p class="tree" data-year="{}">{}</p>'.format(year, tree_with_bud))
# Make new tree placeholder for the bud show we can show it in two states and then grow out
grown_tree = '{} <strong>{}</strong> {}'.format(
trim_tree(branches[:max(0, position)]),
grow_new_branch(bud).strip(),
trim_tree(branches[position+1:]))
# Let it grow again
print('<p class="tree" data-year="{}">{}</p>'.format(year, grown_tree))
grown_tree = re.sub(r'\<\/?\w+\>', '', grown_tree)
if grown_tree == tree:
break
else:
tree = grown_tree
year += 1
if __name__ == '__main__':
graft_a_tree(3)