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
147 lines
3.9 KiB
Python
4 years ago
|
#!/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
|
||
|
|
||
3 years ago
|
import sys
|
||
|
from io import StringIO
|
||
4 years ago
|
|
||
|
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:
|
||
3 years ago
|
short_bio = "There is no English Wikipedia page about this person."
|
||
4 years ago
|
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()
|
||
|
|
||
3 years ago
|
return "There is no English Wikipedia page about this person."
|
||
4 years ago
|
|
||
|
|
||
|
"""
|
||
|
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])
|
||
3 years ago
|
# Remove spaces in html tags
|
||
|
tree = re.sub(r'\<\s*(\/?\w+)\s*\>', '<\\1>', tree)
|
||
4 years ago
|
return re.sub(r'\s[\.,:;\(\)]', '', tree)
|
||
|
|
||
3 years ago
|
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
|
||
4 years ago
|
|
||
|
if __name__ == '__main__':
|
||
3 years ago
|
graft_a_tree(3)
|