-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhaiku.py
144 lines (124 loc) · 2.95 KB
/
haiku.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from module import XMPPModule
# rough count of number of syllables in a given word
def sylcnt(word):
lastvowel = False
syl = 0
exceptions = {
'maybe': 2,
'something': 2,
'sometimes': 2
}
if word in exceptions:
return exceptions[word]
# remove e, es from end of words
if word[-1] == 'e':
word = word[0:-1]
elif word[-2:] == 'es':
word = word[1:-2]
for i in range(len(word)):
c = word[i]
vowel = (c == 'a' or c == 'e' or c == 'i' or c == 'o' or c == 'u' or c == 'y')
if not lastvowel and vowel:
syl += 1
lastvowel = vowel
if syl == 0:
syl = 1
return syl
# filters non-alphanumeric characters and lowercases everything
def clean(x):
y = ''
for i in range(len(x)):
if x[i].isalpha():
y += x[i]
return y.lower()
# This function determines is a string can be split into lines deterministic of a given structure
# Returns false if it cannot be so, the stanza of poem if it can
def haiku(line, counts):
words = filter(lambda w: len(w) > 0, line.split(' '))
i = 0
cnt = 0
stanza = [[]]
for w in words:
if i >= len(counts):
return False
w = clean(w)
if len(w) > 0:
cnt += sylcnt(w)
stanza[i].append(w)
if cnt == counts[i]:
i += 1
cnt = 0
stanza.append([])
elif cnt > counts[i]:
return False
if i == len(counts):
stanza.pop()
return stanza
return False
# makes a string from a stanza
def make_poem(stanza):
formed = ''
for line in stanza:
first = True
for word in line:
if first:
formed += word[0].upper() + word[1:]
first = False
else:
formed += ' ' + word
formed += '\n'
return formed
class Haiku(XMPPModule):
def init(self):
if 'haiku' in self.xmpp.config.keys():
self.forms = self.xmpp.config['haiku']['forms']
else:
self.forms = [{
'name': 'haiku',
'form': [5, 7, 5]
}, {
'name': 'tanka',
'form': [5, 7, 5, 7, 7]
}]
def help(self, feature):
if feature == 'sylcnt' or feature == '!syscnt':
return '''
Counts syllables in words as a debug tool.
usage: !sylcnt [words...]
'''
for p in self.forms:
if feature == p['name']:
return p['name'] + 's are of the form ' + ', '.join([str(i) for i in p['form']])
s = '''
This module makes poems.
When your words are in poem form.
Quite many forms there are.
Debug subfeatures:
sylcnt
Poems recognized ("!help haiku [form]" for more information):
'''
s += '\n'.join([' ' + p['name'] for p in self.forms])
return s + '\n'
def handleMessage(self, msg):
if msg['body'][0:8] == '!sylcnt ':
words = msg['body'][8:].split(' ')
reply = ''
first = True
for w in words:
if first:
first = False
else:
reply += '\n'
w = clean(w)
c = sylcnt(w)
reply += w + ': ' + str(c)
self.xmpp.reply(msg, reply)
else:
for pair in self.forms:
name = pair['name']
form = pair['form']
s = haiku(msg['body'], form)
if s:
reply = make_poem(s)
reply = 'I proffer that your prose is a poem, a ' + name + ':\n' + reply
self.xmpp.reply(msg, reply)