Skip to content

Commit 4b05e15

Browse files
authored
Merge pull request CloudBotIRC#173 from linuxdaemon/gonzobot+pluralize
Add new pluralize functions to handle non-standard english pluralization
2 parents 250c590 + 041f537 commit 4b05e15

8 files changed

Lines changed: 77 additions & 21 deletions

File tree

cloudbot/util/formatting.py

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import copy
4848
import html.entities
4949
import re
50+
import warnings
5051
from html.parser import HTMLParser
5152

5253
from cloudbot.util.colors import strip_irc
@@ -247,11 +248,65 @@ def pluralize(num=0, text=''):
247248
Takes a number and a string, and pluralizes that string using the number and combines the results.
248249
:rtype: str
249250
"""
250-
return "{:,} {}{}".format(num, text, "s"[num == 1:])
251+
warnings.warn(
252+
"formatting.pluralize() is deprecated, please use one of the other formatting.pluralize_*() functions",
253+
DeprecationWarning
254+
)
255+
return pluralize_suffix(num, text)
251256

252257

253-
# alternate form
254-
pluralise = pluralize
258+
def pluralise(num=0, text=''):
259+
"""
260+
Takes a number and a string, and pluralizes that string using the number and combines the results.
261+
:rtype: str
262+
"""
263+
warnings.warn(
264+
"formatting.pluralise() is deprecated, please use one of the other formatting.pluralise_*() functions",
265+
DeprecationWarning
266+
)
267+
return pluralise_suffix(num, text)
268+
269+
270+
def pluralize_suffix(num=0, text='', suffix='s'):
271+
"""
272+
Takes a number and a string, and pluralizes that string using the number and combines the results.
273+
:rtype: str
274+
"""
275+
return pluralize_select(num, text, text + suffix)
276+
277+
278+
pluralise_suffix = pluralize_suffix
279+
280+
281+
def pluralize_select(count, single, plural):
282+
return "{:,} {}".format(count, single if count == 1 else plural)
283+
284+
285+
pluralise_select = pluralize_select
286+
287+
288+
def pluralize_auto(count, thing):
289+
if thing.endswith(('s', 'ss', 'sh', 'ch', 'x', 'z')):
290+
return pluralize_suffix(count, thing, 'es')
291+
elif thing.endswith(('f', 'fe')):
292+
return pluralize_select(count, thing, thing.rsplit('f', 1)[0] + 'ves')
293+
elif thing.endswith('y') and thing[-2:-1].lower() not in "aeiou":
294+
return pluralize_select(count, thing, thing[:-1] + 'ies')
295+
elif thing.endswith('y') and thing[-2:-1].lower() in "aeiou":
296+
return pluralize_suffix(count, thing)
297+
elif thing.endswith('o'):
298+
return pluralize_suffix(count, thing, 'es')
299+
elif thing.endswith('us'):
300+
return pluralize_select(count, thing, thing[:-2] + 'i')
301+
elif thing.endswith('is'):
302+
return pluralize_select(count, thing, thing[:-2] + 'es')
303+
elif thing.endswith('on'):
304+
return pluralize_select(count, thing, thing[:-2] + 'a')
305+
else:
306+
return pluralize_suffix(count, thing)
307+
308+
309+
pluralise_auto = pluralize_auto
255310

256311

257312
def dict_format(args, formats):

cloudbot/util/test/test_formatting.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
from cloudbot.util.formatting import munge, dict_format, pluralize, strip_colors, truncate, truncate_str, \
2-
strip_html, multi_replace, multiword_replace, truncate_words, smart_split, get_text_list, ireplace, chunk_str
1+
from cloudbot.util.formatting import munge, dict_format, strip_colors, truncate, truncate_str, \
2+
strip_html, multi_replace, multiword_replace, truncate_words, smart_split, get_text_list, ireplace, chunk_str, \
3+
pluralize_suffix
34

45
test_munge_input = "The quick brown fox jumps over the lazy dog"
56
test_munge_count = 3
@@ -55,8 +56,8 @@ def test_dict_format():
5556

5657

5758
def test_pluralize():
58-
assert pluralize(test_pluralize_num_a, test_pluralize_text) == test_pluralize_result_a
59-
assert pluralize(test_pluralize_num_b, test_pluralize_text) == test_pluralize_result_b
59+
assert pluralize_suffix(test_pluralize_num_a, test_pluralize_text) == test_pluralize_result_a
60+
assert pluralize_suffix(test_pluralize_num_b, test_pluralize_text) == test_pluralize_result_b
6061

6162

6263
def test_strip_colors():

plugins/chain.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from cloudbot import hook
88
from cloudbot.event import CommandEvent
99
from cloudbot.util import database
10-
from cloudbot.util.formatting import chunk_str, pluralize
10+
from cloudbot.util.formatting import chunk_str, pluralize_auto
1111

1212
commands = Table(
1313
'chain_commands',
@@ -103,7 +103,7 @@ def chainallow(text, db, notice_doc, bot):
103103
res = db.execute(commands.delete().where(commands.c.hook == hook_name))
104104
db.commit()
105105
load_cache(db)
106-
return "Deleted {}.".format(pluralize(res.rowcount, "row"))
106+
return "Deleted {}.".format(pluralize_auto(res.rowcount, "row"))
107107
else:
108108
return notice_doc()
109109

plugins/duckhunt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from cloudbot import hook
1111
from cloudbot.event import EventType
1212
from cloudbot.util import database
13-
from cloudbot.util.formatting import pluralize
13+
from cloudbot.util.formatting import pluralize_auto
1414

1515
duck_tail = "・゜゜・。。・゜゜"
1616
duck = ["\_o< ", "\_O< ", "\_0< ", "\_\u00f6< ", "\_\u00f8< ", "\_\u00f3< "]
@@ -392,7 +392,7 @@ def attack(event, nick, chan, message, db, conn, notice, attack):
392392
event.reply("An unknown error has occurred.")
393393
raise
394394

395-
message(msg.format(nick, shoot - deploy, pluralize(score, "duck"), chan))
395+
message(msg.format(nick, shoot - deploy, pluralize_auto(score, "duck"), chan))
396396
set_ducktime(chan, conn.name)
397397

398398

plugins/reddit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ def format_output(item, show_url=False):
4949
raw_time = datetime.fromtimestamp(int(item["created_utc"]))
5050
item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)
5151

52-
item["comments"] = formatting.pluralize(item["num_comments"], 'comment')
53-
item["points"] = formatting.pluralize(item["score"], 'point')
52+
item["comments"] = formatting.pluralize_auto(item["num_comments"], 'comment')
53+
item["points"] = formatting.pluralize_auto(item["score"], 'point')
5454

5555
if item["over_18"]:
5656
item["warning"] = " \x02NSFW\x02"

plugins/reddit_info.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from cloudbot import hook
88
from cloudbot.util import colors
9-
from cloudbot.util.formatting import pluralize
9+
from cloudbot.util.formatting import pluralize_auto
1010
from cloudbot.util.pager import paginated_list
1111

1212
search_pages = defaultdict(dict)
@@ -115,7 +115,7 @@ def karma(text, reply):
115115
if age > 365:
116116
age //= 365
117117
age_unit = "year"
118-
out += "redditor for {}.".format(pluralize(age, age_unit))
118+
out += "redditor for {}.".format(pluralize_auto(age, age_unit))
119119
return colors.parse(out)
120120

121121

@@ -143,7 +143,7 @@ def cake_day(text, reply):
143143
if age > 365:
144144
age //= 365
145145
age_unit = "year"
146-
out += "they have been a redditor for {}.".format(pluralize(age, age_unit))
146+
out += "they have been a redditor for {}.".format(pluralize_auto(age, age_unit))
147147
return out
148148

149149

plugins/voat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ def format_output(item, show_url=False):
3939
raw_time = isodate.parse_date(item['Date'])
4040
item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)
4141

42-
item["comments"] = formatting.pluralize(item["CommentCount"], 'comment')
43-
item["points"] = formatting.pluralize(item["Likes"], 'point')
42+
item["comments"] = formatting.pluralize_auto(item["CommentCount"], 'comment')
43+
item["points"] = formatting.pluralize_auto(item["Likes"], 'point')
4444

4545
if item["Type"] == 2:
4646
item["warning"] = " \x02Link\x02"

plugins/youtube.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from cloudbot import hook
88
from cloudbot.util import timeformat
9-
from cloudbot.util.formatting import pluralize
9+
from cloudbot.util.formatting import pluralize_auto
1010

1111
youtube_re = re.compile(r'(?:youtube.*?(?:v=|/v/)|youtu\.be/|yooouuutuuube.*?id=)([-_a-zA-Z0-9]+)', re.I)
1212

@@ -47,8 +47,8 @@ def get_video_description(video_id):
4747

4848
if total_votes != 0:
4949
# format
50-
likes = pluralize(int(statistics['likeCount']), "like")
51-
dislikes = pluralize(int(statistics['dislikeCount']), "dislike")
50+
likes = pluralize_auto(int(statistics['likeCount']), "like")
51+
dislikes = pluralize_auto(int(statistics['dislikeCount']), "dislike")
5252

5353
percent = 100 * float(statistics['likeCount']) / total_votes
5454
out += ' - {}, {} (\x02{:.1f}\x02%)'.format(likes,

0 commit comments

Comments
 (0)