Renumbered again so that the messaging OO style comes immediately after the hash OO style

This commit is contained in:
Crista Lopes
2013-12-26 10:27:15 -08:00
parent 636f4ca855
commit a8760fbcb3
8 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
Style #13
==============================
Constraints:
- Larger problem is decomposed into entities using some form of abstraction
(objects, modules or similar)
- The entities are never called on directly for actions
- Existence of an infrastructure for publishing and subscribing to
events, aka the bulletin board
- Entities post event subscriptions (aka 'wanted') to the bulletin
board and publish events (aka 'offered') to the bulletin board. the
bulletin board does all the event management and distribution
Possible names:
- Bulletin board
- Publish-Subscribe

104
14-bulletin-board/tf-14.py Executable file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env python
import sys, re, operator, string
#
# The event management substrate
#
class EventManager:
def __init__(self):
self._subscriptions = {}
def subscribe(self, event_type, handler):
if event_type in self._subscriptions:
self._subscriptions[event_type].append(handler)
else:
self._subscriptions[event_type] = [handler]
def publish(self, event):
event_type = event[0]
if event_type in self._subscriptions:
for h in self._subscriptions[event_type]:
h(event)
#
# The application entities
#
class DataStorage:
""" Models the contents of the file """
def __init__(self, event_manager):
self._event_manager = event_manager
self._event_manager.subscribe('load', self.load)
self._event_manager.subscribe('start', self.produce_words)
def load(self, event):
path_to_file = event[1]
with open(path_to_file) as f:
self._data = f.read()
pattern = re.compile('[\W_]+')
self._data = pattern.sub(' ', self._data).lower()
def produce_words(self, event):
data_str = ''.join(self._data)
for w in data_str.split():
self._event_manager.publish(('word', w))
self._event_manager.publish(('eof', None))
class StopWordFilter:
""" Models the stop word filter """
def __init__(self, event_manager):
self._stop_words = []
self._event_manager = event_manager
self._event_manager.subscribe('load', self.load)
self._event_manager.subscribe('word', self.is_stop_word)
def load(self, event):
with open('../stop_words.txt') as f:
self._stop_words = f.read().split(',')
self._stop_words.extend(list(string.ascii_lowercase))
def is_stop_word(self, event):
word = event[1]
if word not in self._stop_words:
self._event_manager.publish(('valid_word', word))
class WordFrequencyCounter:
""" Keeps the word frequency data """
def __init__(self, event_manager):
self._word_freqs = {}
self._event_manager = event_manager
self._event_manager.subscribe('valid_word', self.increment_count)
self._event_manager.subscribe('print', self.print_freqs)
def increment_count(self, event):
word = event[1]
if word in self._word_freqs:
self._word_freqs[word] += 1
else:
self._word_freqs[word] = 1
def print_freqs(self, event):
word_freqs = sorted(self._word_freqs.iteritems(), key=operator.itemgetter(1), reverse=True)
for (w, c) in word_freqs[0:25]:
print w, ' - ', c
class WordFrequencyApplication:
def __init__(self, event_manager):
self._event_manager = event_manager
self._event_manager.subscribe('run', self.run)
self._event_manager.subscribe('eof', self.stop)
def run(self, event):
path_to_file = event[1]
self._event_manager.publish(('load', path_to_file))
self._event_manager.publish(('start', None))
def stop(self, event):
self._event_manager.publish(('print', None))
#
# The main function
#
em = EventManager()
DataStorage(em), StopWordFilter(em), WordFrequencyCounter(em)
WordFrequencyApplication(em)
em.publish(('run', sys.argv[1]))