Merge lp:~max-rabkin/ibid/bucket into lp:~ibid-core/ibid/old-trunk-1.6

Proposed by Max Rabkin
Status: Merged
Approved by: Stefano Rivera
Approved revision: 931
Merged at revision: 931
Proposed branch: lp:~max-rabkin/ibid/bucket
Merge into: lp:~ibid-core/ibid/old-trunk-1.6
Diff against target: 211 lines (+161/-1)
3 files modified
docs/api/ibid.utils.rst (+6/-0)
ibid/plugins/fun.py (+102/-1)
ibid/utils/__init__.py (+53/-0)
To merge this branch: bzr merge lp:~max-rabkin/ibid/bucket
Reviewer Review Type Date Requested Status
Michael Gorven Approve
Jonathan Hitchcock Approve
Stefano Rivera Approve
Ibid Core Team Pending
Keegan Carruthers-Smith Pending
Max Rabkin Pending
Review via email: mp+23997@code.launchpad.net

This proposal supersedes a proposal from 2010-04-11.

Commit message

Add feature for exchanging objects with people, inspired by XKCD's Bucket

Description of the change

This feature works like this, in case you were confused:

<Taejo> Ibido: have a pear
* Ibido takes Taejo's pear but has nothing to give in exchange
<Taejo> Ibido: have this dog
* Ibido hands Taejo a pear in exchange for Taejo's dog
<Taejo> Ibido: have these apples
* Ibido hands Taejo a dog in exchange for Taejo's apples
<Taejo> Ibido: have sex
* Ibido hands Taejo apples in exchange for Taejo's sex
<Taejo> Ibido: have a box of chocolate
* Ibido hands Taejo sex in exchange for Taejo's box of chocolate
<Taejo> Ibido: have casted's face
* Ibido hands Taejo a box of chocolate in exchange for casted's face
<Taejo> Ibido: have nothing
* Ibido hands Taejo casted's face in exchange for Taejo's nothing
* Taejo gives Ibido a hand
* Ibido hands Taejo nothing in exchange for Taejo's hand

To post a comment you must log in.
Revision history for this message
Stefano Rivera (stefanor) wrote : Posted in a previous version of this proposal

unicode?

Revision history for this message
Max Rabkin (max-rabkin) wrote : Posted in a previous version of this proposal

Didn't notice any unicode problems, but there are other problems.

review: Needs Fixing
Revision history for this message
Max Rabkin (max-rabkin) wrote : Posted in a previous version of this proposal

Fixed addressing issues, and improved language handling.

review: Needs Resubmitting
Revision history for this message
Stefano Rivera (stefanor) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Michael Gorven (mgorven) wrote : Posted in a previous version of this proposal

<aside>People might confuse the exchange feature with currency.</aside>
 review approve

review: Approve
Revision history for this message
Stefano Rivera (stefanor) wrote : Posted in a previous version of this proposal

> <aside>People might confuse the exchange feature with currency.</aside>

Yeah, I was also a little worried about that

Revision history for this message
Max Rabkin (max-rabkin) wrote : Posted in a previous version of this proposal

Called "bucket" in r917

Revision history for this message
Jonathan Hitchcock (vhata) wrote : Posted in a previous version of this proposal

Line 48 still says:

48 + feature = ('exchange',)

review: Needs Fixing
Revision history for this message
Jonathan Hitchcock (vhata) wrote : Posted in a previous version of this proposal

I'm also not sure what situation you'll have a plural nick (re: "# giver's name is a plural ending in 's'").

Finally - indefinite_article is broken for cases like "hour".

review: Needs Fixing
Revision history for this message
Max Rabkin (max-rabkin) wrote : Posted in a previous version of this proposal

I'm still planning to fix indefinite_article, eventually.

review: Needs Resubmitting
Revision history for this message
Stefano Rivera (stefanor) wrote : Posted in a previous version of this proposal

Can you credit the original author in the copyright headre (if appropriate) and also mention the upstream licence

should you not be using unicode literals in indefinite_article? (and re.UNICODE)

What about noun_phrases beginning with numerals? (you can tell me to piss off)

> if word in 'aedhilmnorsx':

Is that really what you want? It'd match "mno" for example

Silly style side-note, you are oscillating between single and double quotes

review: Needs Fixing
Revision history for this message
Keegan Carruthers-Smith (keegan-csmith) wrote : Posted in a previous version of this proposal

Query: have my keys
Action: takes keegan's keys but has nothing to give in exchange
Query: have france
Action: hands keegan keegan's keys in exchange for keegan's france

review: Needs Fixing
Revision history for this message
Stefano Rivera (stefanor) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Stefano Rivera (stefanor) wrote : Posted in a previous version of this proposal

Indefinite article needs to appear in the API documentation

review: Needs Fixing
Revision history for this message
Stefano Rivera (stefanor) :
review: Approve
Revision history for this message
Jonathan Hitchcock (vhata) wrote :

Line 64 - the usage for "what are you carrying?" is just "carrying|have", which won't work (and anyway, by convention, if we allow pidgin requests, we put the full English into our usage anyway).

review: Needs Fixing
lp:~max-rabkin/ibid/bucket updated
931. By Max Rabkin

Don't use pidgin version in usage

Revision history for this message
Jonathan Hitchcock (vhata) :
review: Approve
Revision history for this message
Michael Gorven (mgorven) wrote :

Looks fine.
 review approve

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'docs/api/ibid.utils.rst'
2--- docs/api/ibid.utils.rst 2010-03-15 20:36:57 +0000
3+++ docs/api/ibid.utils.rst 2010-04-26 15:47:25 +0000
4@@ -66,6 +66,12 @@
5 It's recommended to use complete words for *singular* and *plural*
6 rather than suffixes.
7
8+.. function:: indefinite_article(phrase)
9+
10+ Use heuristics to determine whether the pronunciation of *phrase* starts
11+ with a vowel or consonant (assuming it is English) and return 'an' or 'a'
12+ respectively.
13+
14 .. function:: decode_htmlentities(text)
15
16 Return *text* with all HTML entities removed, both numeric and
17
18=== modified file 'ibid/plugins/fun.py'
19--- ibid/plugins/fun.py 2010-03-27 15:50:58 +0000
20+++ ibid/plugins/fun.py 2010-04-26 15:47:25 +0000
21@@ -4,13 +4,14 @@
22 from unicodedata import normalize
23 from random import choice, random
24 import re
25+from threading import Lock
26
27 from nickometer import nickometer
28
29 import ibid
30 from ibid.plugins import Processor, match
31 from ibid.config import IntOption, ListOption
32-from ibid.utils import human_join
33+from ibid.utils import human_join, indefinite_article
34
35 features = {}
36
37@@ -247,4 +248,104 @@
38
39 event.addresponse(u' '.join(swearage) + u'!', address=False)
40
41+carrying = None
42+carrying_lock = Lock()
43+
44+object_pat = r"(?:(his|her|their|its|my|our|\S+(?:'s|s')|" \
45+ r"the|a|an|this|these|that|those|some)\s+)?(.*)"
46+
47+features['bucket'] = {
48+ 'description': u'Exchanges objects with people',
49+ 'categories': ('fun',),
50+}
51+class ExchangeAction(Processor):
52+ features = ('bucket',)
53+ event_types = (u'action',)
54+
55+ addressed = False
56+
57+ @match(r"^(?:gives|hands)\s+(\S+)\s+" + object_pat + "$")
58+ def give(self, event, addressee, determiner, object):
59+ if addressee in ibid.config.plugins['core']['names']:
60+ return exchange(event, determiner, object)
61+
62+class ExchangeMessage(Processor):
63+ usage = u"""(have|take) <object>
64+ what are you carrying?"""
65+ features = ('bucket',)
66+
67+ @match(r"^(?:have|take)\s+" + object_pat + "$")
68+ def have(self, event, determiner, object):
69+ if determiner in ('his', 'her', 'their', 'its'):
70+ event.addresponse("I don't know whose %s you're talking about",
71+ object)
72+ else:
73+ return exchange(event, determiner, object)
74+
75+ @match(r'^(?:what\s+(?:are|do)\s+you\s+)?(?:carrying|have)$')
76+ def query_carrying(self, event):
77+ carrying_lock.acquire()
78+
79+ if carrying is None:
80+ event.addresponse(u"I'm not carrying anything")
81+ else:
82+ event.addresponse(u"I'm carrying %s", carrying)
83+
84+ carrying_lock.release()
85+
86+def exchange(event, determiner, object):
87+ global carrying
88+
89+ who = event.sender['nick']
90+
91+ if determiner is None:
92+ determiner = ''
93+
94+ detl = determiner.lower()
95+
96+ # determine how to refer to the giver in the genitive case
97+ if detl in ('their', 'our') and who[-1] in 'sS':
98+ # giver's name is a plural ending in 's'
99+ genitive = who + "'"
100+ elif detl.endswith("s'") or detl.endswith("'s"):
101+ genitive = determiner
102+ else:
103+ genitive = who + "'s"
104+
105+ if detl == 'the':
106+ taken = u'the ' + object
107+ else:
108+ taken = genitive + u' ' + object
109+
110+ carrying_lock.acquire()
111+
112+ if carrying is None:
113+ event.addresponse(u'takes %s but has nothing to give in exchange',
114+ taken, action=True)
115+ else:
116+ event.addresponse(u'hands %(who)s %(carrying)s '
117+ u'in exchange for %(taken)s',
118+ {'who': who,
119+ 'carrying': carrying,
120+ 'taken': taken},
121+ action=True)
122+
123+ # determine which determiner we will use when talking about this object in
124+ # the future -- we only want to refer to it by the giver's name if the giver
125+ # implied that it was theirs, and we don't want to use demonstratives
126+ if detl in ('this', 'that'):
127+ # object is definitely singular
128+ determiner = indefinite_article(object)
129+ elif detl in ('my', 'our', 'his', 'her', 'its', 'their'):
130+ determiner = genitive
131+ elif detl in ('these', 'those'):
132+ determiner = u'some'
133+
134+ if determiner:
135+ carrying = determiner + u' ' + object
136+ else:
137+ carrying = object
138+
139+ carrying_lock.release()
140+
141 # vi: set et sta sw=4 ts=4:
142
143=== modified file 'ibid/utils/__init__.py'
144--- ibid/utils/__init__.py 2010-03-15 21:05:39 +0000
145+++ ibid/utils/__init__.py 2010-04-26 15:47:25 +0000
146@@ -1,5 +1,9 @@
147 # Copyright (c) 2009-2010, Michael Gorven, Stefano Rivera
148 # Released under terms of the MIT/X/Expat Licence. See COPYING for details.
149+#
150+# The indefinite_article function follows an algorithm by Damian Conway
151+# as published in CPAN package Lingua-EN-Inflect-1.891 under the GNU GPL
152+# (version 1 or later) and Artistic License 1.0.
153
154 import codecs
155 from gzip import GzipFile
156@@ -291,6 +295,55 @@
157 code = process.wait()
158 return output, error, code
159
160+def indefinite_article(noun_phrase):
161+ # algorithm adapted from CPAN package Lingua-EN-Inflect-1.891 by Damian Conway
162+ m = re.search('\w+', noun_phrase, re.UNICODE)
163+ if m:
164+ word = m.group(0)
165+ else:
166+ return u'an'
167+
168+ wordi = word.lower()
169+ for anword in ('euler', 'heir', 'honest', 'hono'):
170+ if wordi.startswith(anword):
171+ return u'an'
172+
173+ if wordi.startswith('hour') and not wordi.startswith('houri'):
174+ return u'an'
175+
176+ if len(word) == 1:
177+ if wordi in 'aedhilmnorsx':
178+ return u'an'
179+ else:
180+ return u'a'
181+
182+ if re.match(r'(?!FJO|[HLMNS]Y.|RY[EO]|SQU|'
183+ r'(F[LR]?|[HL]|MN?|N|RH?|S[CHKLMNPTVW]?|X(YL)?)[AEIOU])'
184+ r'[FHLMNRSX][A-Z]', word):
185+ return u'an'
186+
187+ for regex in (r'^e[uw]', r'^onc?e\b',
188+ r'^uni([^nmd]|mo)','^u[bcfhjkqrst][aeiou]'):
189+ if re.match(regex, wordi):
190+ return u'a'
191+
192+ # original regex was /^U[NK][AIEO]?/ but that matches UK, UN, etc.
193+ if re.match('^U[NK][AIEO]', word):
194+ return u'a'
195+ elif word == word.upper():
196+ if wordi[0] in 'aedhilmnorsx':
197+ return u'an'
198+ else:
199+ return u'a'
200+
201+ if wordi[0] in 'aeiou':
202+ return u'an'
203+
204+ if re.match(r'^y(b[lor]|cl[ea]|fere|gg|p[ios]|rou|tt)', wordi):
205+ return u'an'
206+ else:
207+ return u'a'
208+
209 def get_country_codes():
210 filename = cacheable_download(
211 'http://www.iso.org/iso/list-en1-semic-3.txt',

Subscribers

People subscribed via source and target branches