Syllabic Poetry Generator

This is a program that generates syllabic poetry based on a provided list of words. The program will generate one of the following based on input from the user:

  1. haiku(a 5-7-5 pattern of syllables per line )
  2. tanka(a 5-7-5-7-7 pattern of syllables per line )
  3. a 5 line syllabic poem with a random number of syllables per line
  4. a poem whose lines and syllables per line are supplied by the user

listutils.py


def get_duplicates(lst):
    new_lst = []
    for i in lst:
        if lst.count(i) == 1:
            pass
        elif lst.count(i) > 1:
            if i in new_lst:
                pass
            else:
                new_lst += [i]

    return new_lst


# duplicates = get_duplicates([1, 2, 3, 1, 4, 2])
# print(duplicates) # --> [1, 2] because both 1 and 2 have duplicates
# print(get_duplicates(['cat', 'cat', 'cat', 'cat', 'dog', 'bat', 'ant', 'ant']))


def has_duplicates(lst):
    for i in lst:
        if lst.count(i) == 1:
            return False
        elif lst.count(i) > 1:
            return True


# result1 = has_duplicates([1, 2, 3, 1, 4])
# print(result1) # --> True
# result2 = has_duplicates([1, 2, 3, 4, 5])
# print(result2) # --> False

def join_elements_with(glue, lst):
    new_st = ""

    for i in lst:
        new_st += i + glue
    new_st = new_st[0:-1]
    return new_st


# result = join_elements_with('X', ['cat', 'dog', 'bat'])
# print(result) # --> catXdogXbat


def fill(size, fill_value=0):
    new_lst = []
    new_lst += [fill_value] * size
    print(new_lst)


# lst1 = fill(5)        # [0, 0, 0, 0, 0]
# lst2 = fill(3, 'hi')  # ['hi', 'hi', 'hi']


def random_choose(lst):
    max = len(lst)
    import random
    index = random.randint(0, max - 1)
    result = lst[index]
    return result


"""
weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri']
weekday = random_choose(weekdays)

# should print out a single weekday from list of weekdays
print(weekday)
"""


def random_fill(min_val, max_val, list_length):
    new_lst = []
    import random
    for i in range(0, list_length):
        number = random.randint(min_val, max_val)
        new_lst += [number]

    return new_lst


# new_list = random_fill(1, 10, 4)

# should print out a list with 4 elements...
# each w/ number from 1 - 10
# print(new_list)


def stringify_elements(lst):
    new_lst = []

    for i in lst:
        new_lst.append(str(i))
    return new_lst


# result = stringify_elements([1, 2, 3])
# print(result) # --> should print out ['1', '2', '3'] (all elements are strings!)


def mean(lst):
    number = 0
    for i in lst:
        number += i
    average = float(number / len(lst))
    return average
# print(mean([1, 2, 3, 4, 5])) # 3

syllabic_poetry.py

"""
syllabic_poetry.py
"""
# add your imports here
import random

import listutils


# this is a partial implementation of generate_word
# it contains a list of lists, with each sub list
# containing words with the same number of syllables
# ...the first sub list contains words with only one
# syllable, the second, two syllables, etc.
def generate_word(syllables):
    available_words = [
        ['age', 'roof', 'plain', 'slime', 'floor', 'fig', 'rode', 'oomph', 'flab', 'chit', 'creek', "we'll", 'brail',
         'bay', 'big', 'salve', 'yaws', 'heal', 'bring', 'stir', 'bah', 'con', 'rone', 'team', 'nought', 'gill', 'rare',
         'plains', 'bowls', 'wee', 'queue', 'gun', 'etch', 'set', 'mode', 'miss', 'ate', 'darn', 'rusk', 'mast', 'box',
         'their', 'duds', 'depth', 'lien', 'rob', 'deek', 'word', 'quell', 'hark', 'home', 'pledge', 'brown', 'rune',
         'pike', 'sprout', 'trace', 'cot', 'nob', 'nonce', 'dear', 'sense', 'sleek', 'poke', 'hut'],
        ['stunner', 'sucrose', 'begone', 'scorecard', 'humble', 'crouton', 'trimming', 'pudding', 'henchman', 'cackle',
         'coffee', 'coma', 'aces', 'prudence', 'rematch', 'hipper', 'chopper', 'imprint', 'purple', 'second', 'lowbrow',
         'faucet', 'bureau', 'commune', 'endive', 'stakeout', 'sourpuss', 'cave-in', 'shipyard', 'honors', 'kowtow',
         'okra', 'haler', 'rattan'],
        ['echoless', 'fluidly', 'catchier', 'cathartic', 'lawnmower', 'physicist', 'huntedly', 'unzipping',
         'centigrade', 'cheekily', 'tectonics', 'clearheaded', 'seditious', 'anodized', 'vehicle', 'sprightliest',
         'prevention', 'vehement', 'mnemonics', 'steamroller', 'spikiest', 'persuasive', 'randomly', 'forensics',
         'uneasy', 'dizziness', 'nonhuman', 'ethanol', 'connection', 'shrewishly', 'fingerprint'],
        ['nongalactic', 'lacerating', 'optometer', 'troglodytic', 'regradated', 'uniformize', 'chlorination',
         'retotaling', 'acceptable', 'culmination', 'forbiddingness', 'immoveable', 'disconcerted', 'prosperity',
         'vapourizing', 'profitably', 'envelopment', 'unsealable', 'librarian', 'transmissiveness', 'willowpattern',
         'nationalise', 'devotedness', 'clangorously', 'likeableness', 'troubleshooting', 'weakheartedly',
         'obsoleteness'],
        ['unsublimated', 'hyperanarchy', 'cylindrically', 'irrationally', 'quasipractical', 'sulfurization',
         'undermeasuring', 'victoriously', 'disquietingly', 'metaphysical', 'quasihistoric', 'undesirably',
         'soporiferous', 'underrespected', 'unsymmetrical', 'reliberating', 'curability', 'nonrevolution',
         'nonscientific', 'marbleization', 'wearability', 'supervexation', 'misconjugating', 'inattentiveness',
         'unruinable', 'incorporeal', 'stereoscopic', 'overpolicing', 'noncombustible', 'communicable', 'janitorial',
         'etymologist', 'unconnectedness', 'personality', 'unmaintainable', 'geodesical', 'sociologist',
         'fortitudinous', 'elimination'],
        ['disaffiliated', 'redeemability', 'misauthorization', 'renegotiated', 'zootomically', 'microbacteria',
         'malleability', 'intermediaries', 'supportability', 'eliminatory', 'nonhierarchical', 'quasiadvantageous',
         'palaeontology', 'typographically', 'radioactively', 'hyperpotassemic', 'collapsibility', 'selfdramatization',
         'hallucinatory', 'megalomania', 'communicativeness', 'quasisatirical', 'nontechnological', 'electrosensitive',
         'overintensity', 'excommunicating', 'fundamentality', 'photoelectrical', 'visualization', 'incommensurable',
         'noncontinuity', 'etymological', 'overemotional'],
        ['electrometallurgist', 'discreditability', 'nonperfectibility', 'etherealization', 'inexhaustibility',
         'unautomatically', 'overdeliberated', 'nonuniversality', 'encyclopaedically', 'paradoxicality',
         'hieroglyphically', 'hypercivilization', 'biogenetically', 'incompatibility', 'unconstitutionalism',
         'unutilitarian', 'overidealizing', 'transcendentalization']
    ]
    if syllables > 7 or syllables < 1:
        return None
    else:
        lst = available_words[syllables - 1]
        word = listutils.random_choose(lst)
        return word


"""
word = generate_word(3)
another_word = generate_word(1)

# the following prints out a three syllable word
# ... and a one syllable word (randomly chosen from
# a set of words)
print(word, another_word)  # --> prints out randomly and word

# this will return None because the number of syllables is less than 1
yet_another_word = generate_word(0)  # --> None!
"""


def generate_line(syllables_in_line):
    total = 0  # count the current number of syllables in line
    max1 = 7
    line1 = ""
    while total < syllables_in_line:
        if syllables_in_line - total < 7:
            max1 = syllables_in_line - total

        number = random.randint(1, max1)
        line1 += (generate_word(number) + " ")
        total += number

    return line1

    # max_syllables_word = syllables_required - cur_syllables
    # generate word whose max syllables fits criteria above
    #   add word to line
    #   update current syllable count


# line = generate_line(5)
# print(line)  # --> immoveable age (or some other random series of words!)

def generate_lines(all_lines):
    new_line = []
    for i in all_lines:
        line_n = generate_line(i)
        new_line += [line_n]

    # print(new_line)
    return '\n'.join(new_line)


# the following should return a list of lines of a
# randomly generated poem...
# for example, it may return (as a single list,
# and formatted with new lines for readability):
# [
#    'persuasive pudding',
#    'misauthorization flab',
#     'acceptable queue'
# ]
# syllables_per_line = [5, 7, 5]

# print(generate_lines(syllables_per_line))

ask = input(
    "I would like to write some poetry for you. Would you like a..." + "\n" + " * (h)aiku" + "\n" + " * (t)anka" + "\n" + " * (r)andom 5 line poem, or do you want to" + "\n" + " * (s)pecify lines and syllables for each line?")

# response for different options
if ask == "h":
    print("Here is your poem ( 5-7-5 ):")
    print("=====")
    print(generate_lines([5, 7, 5]))

elif ask == "t":
    print("Here is your poem ( 5-7-5-7-7 ):")
    print("=====")
    print(generate_lines([5, 7, 5, 7, 7]))

elif ask == "r":
    new_list = []
    for i in range(0, 5):
        new_list.append(random.randint(1, 10))
    a = str(new_list[0])
    b = str(new_list[1])
    c = str(new_list[2])
    d = str(new_list[3])
    e = str(new_list[4])
    string = a + "-" + b + "-" + c + "-" + d + "-" + e
    print("Here is your poem (", string, "):")
    print("=====")
    print(generate_lines(new_list))

elif ask == "s":
    nex_list = []
    strings = ""
    check = True
    while check:
        ask1 = input("How many syllables for lines 1?")
        ask2 = input("There are currently 1 lines. Add another line (y/n)?")
        nex_list.append(int(ask1))
        strings += (ask1 + "-")

        if ask2 == "y":
            check = True
        elif ask2 == "n":
            check = False
    strings = strings[:-1]
    print("Here is your poem (", strings, "):")
    print("=====")
    print(generate_lines(nex_list))

else:  # error message
    print("ERROR")
    print("=====")
    print("A crash reduces" + "\n" +
          "Your expensive computer" + "\n" +
          "To a simple stone.")

Leave a Reply

%d bloggers like this: