From ecfeb0019c1085c58ddd77a833f7a75df8628c23 Mon Sep 17 00:00:00 2001 From: Crista Lopes Date: Thu, 17 Oct 2013 20:30:30 -0700 Subject: [PATCH] Better version of reactive style. Added README.md --- 32-reactive/README.md | 13 ++++++++++ 32-reactive/tf-32.py | 55 ++++++++++++++++++++++++++++--------------- 2 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 32-reactive/README.md diff --git a/32-reactive/README.md b/32-reactive/README.md new file mode 100644 index 0000000..12321c8 --- /dev/null +++ b/32-reactive/README.md @@ -0,0 +1,13 @@ +Style #32 +============================== + +Constraints: + +- Variables are updated automatically based on changing values of + other variables. Variable values possibly depend on data streams + (keyboard, mouse, etc.) + +Possible names: + +- Reactive +- Data-to-data diff --git a/32-reactive/tf-32.py b/32-reactive/tf-32.py index bc9d272..8cdd9a3 100644 --- a/32-reactive/tf-32.py +++ b/32-reactive/tf-32.py @@ -1,21 +1,44 @@ #!/usr/bin/env python -import sys, operator, string, os +import sys, operator, string, os, threading from util import getch, cls from time import sleep -def refresh_screen(data): - # clear screen - cls() - print data - sys.stdout.flush() +# +# The reactive infrastructure +# +class FreqObserver(threading.Thread): + def __init__(self, freqs): + threading.Thread.__init__(self) + self.daemon = True + # freqs is the data to be observed and reacted to + self._freqs = freqs + self._freqs_0 = sorted(self._freqs.iteritems(), key=operator.itemgetter(1), reverse=True) + self.start() -def update_display(tuples): - data_str = "" - for tf in tuples: - data_str += str(tf[0]) + ' - ' + str(tf[1]) + '\n' - refresh_screen(data_str) + def run(self): + while True: + freqs_1 = sorted(self._freqs.iteritems(), key=operator.itemgetter(1), reverse=True) + if (freqs_1[0:25] != self._freqs_0[0:25]): + self._update_display(freqs_1[0:25]) + self._freqs_0 = freqs_1 + sleep(0.01) + def _update_display(self, tuples): + def refresh_screen(data): + # clear screen + cls() + print data + sys.stdout.flush() + + data_str = "" + for tf in tuples: + data_str += str(tf[0]) + ' - ' + str(tf[1]) + '\n' + refresh_screen(data_str) + +# +# The active part, dataflow-like +# automatic = False def get_input(): global automatic @@ -72,25 +95,19 @@ def non_stop_words(filename): yield w def count_and_sort(filename): - freqs_0 = () - freqs_1 = () freqs = {} + # The declaration for reactive observation of freqs + FreqObserver(freqs) while get_input(): try: w = non_stop_words(filename).next() freqs[w] = 1 if w not in freqs else freqs[w]+1 - freqs_0 = freqs_1 - freqs_1 = sorted(freqs.iteritems(), key=operator.itemgetter(1), reverse=True) - if (freqs_1[0:25] != freqs_0[0:25]): - update_display(freqs_1[0:25]) except StopIteration: break - return freqs_1 # # The main function # - print "Press space bar to fetch words from the file one by one" print "Press ESC to switch to automatic mode" count_and_sort(sys.argv[1])