#!/usr/bin/env python # -*- coding: -*- ''' 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: . ''' 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 from colored import fg, attr ## Text attributes bold = attr(1) underlined = (4) reset = attr(0) ## Text colors black = fg(0) spring_green = fg(48) light_gray = fg(7) sky_blue = fg(109) yellow = fg(3) 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.{}".format(sky_blue, reset) 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.{}".format(sky_blue, reset) """ 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]) return re.sub(r'\s[\.,:;\(\)]', '', tree) def show (state, length=1): os.system('clear') # Optionally vertically align here print(state) time.sleep(length) def grow (tree, generation = 1): 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']) # Make new tree placeholder for the bud show we can show it in two states and then grow out next_tree = '{} {{}} {}'.format(trim_tree(branches[:max(0, position)]), trim_tree(branches[position+1:])) new_branch = grow_new_branch(bud) show(tree, 3 if generation == 1 else 1) # Mark the bud, underlined and orange show(next_tree.format("{}{}{}{}{}".format(bold, yellow, bud, reset, black)), 2) # Mark the new branch green show(next_tree.format("{}{}{}".format(spring_green, new_branch, black)), 2) show(next_tree.format("{}{}{}".format(fg(82), new_branch, black)), 1) show(next_tree.format("{}{}{}".format(fg(120), new_branch, black)), 1) show(next_tree.format("{}{}{}".format(fg(157), new_branch, black)), 1) show(next_tree.format("{}{}{}".format(fg(195), new_branch, black)), 1) # Let it grow again return next_tree.format(new_branch) if __name__ == '__main__': while True: gardener, source, tree = choose_a_tree(trees) short_bio = bio_offline(gardener) show( 'Using a quote by {}{}{}\n\n'.format(bold, gardener, reset) \ + short_bio, 3 ) generation = 1 while len(tree) < 1500: next_tree = grow(tree, generation) if next_tree == tree: break else: tree = next_tree generation += 1