-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtemplatemethod_patterns.py
159 lines (126 loc) · 5.54 KB
/
templatemethod_patterns.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""The main idea of Template Method is to create a method that will hold a
sequence of steps (primitive operations) for our algorithm to achieve some goal.
These primitive operations will be implemented in separate methods. Some
methods are the same for every kind of algorithm and some methods are different.
The same methods will be implemented in the abstract class, whereas,
the implementation of different methods will be in separate classes for
every kind of algorithm.
So, the sequence of steps to implement the Template Method is as follows:
Create a method for the algorithm.
Split the algorithm's implementation into several methods.
Methods that are the same for every class should be implemented in the
base class, whereas, specific methods should be implemented
in the inherited class.
"""
from xml.dom import minidom
import urllib2 #to make http request to RSS and Atom feeds
class AbstractNewsParser(object):
def __init__(self):
#prohibit creating class instance
if self.__class__ is AbstractNewsParser:
raise TypeError('abstract class can nott be instantiated')
def print_top_news(self):
"""A template method - returns 3 latest news for every sites"""
url = self.get_url()
raw_content = self.get_raw_content(url)
content = self.parse_content(raw_content)
cropped = self.crop(content)
for item in cropped:
print 'Title: ', item['title']
print 'Content: ', item['content']
print 'Link: ', item['link']
print 'Published: ', item['published']
print 'Id: ', item['id']
def get_url(self):
raise NotImplementedError()
def get_raw_content(self, url):
return urllib2.urlopen(url).read()
def parse_content(self, content):
raise NotImplementedError()
def crop(self, parsed_content, max_items=3):
return parsed_content[:max_items]
#get_url, and parse is not implemented because it is specific to feed(rss/atom)
class YahooParser(AbstractNewsParser):
def get_url(self):
return 'http://news.yahoo.com/rss/'
def parse_content(self, raw_content):
parsed_content = []
dom = minidom.parseString(raw_content)
for node in dom.getElementsByTagName('item'):
parsed_item = {}
try:
parsed_item['title'] = node.getElementsByTagName('title')\
[0].childNodes[0].nodeValue
except IndexError:
parsed_item['title'] = None
try:
parsed_item['content'] = node.getElementsByTagName\
('description')[0].childNodes[0].nodeValue
except IndexError:
parsed_item['content'] = None
try:
parsed_item['link'] = node.getElementsByTagName\
('link')[0].childNodes[0].nodeValue
except IndexError:
parsed_item['link'] = None
try:
parsed_item['id'] = node.getElementsByTagName\
('guid')[0].childNodes[0].nodeValue
except:
parsed_item['id'] = None
try:
parsed_item['published'] = node.getElementsByTagName\
('pubDate')[0].childNodes[0].nodeValue
except IndexError:
parsed_item['published'] = None
parsed_content.append(parsed_item)
return parsed_content
class GoogleParser(AbstractNewsParser):
def get_url(self):
return 'https://news.google.com/news/feeds?output=atom'
def parse_content(self, raw_content):
parsed_content = []
dom = minidom.parseString(raw_content)
for node in dom.getElementsByTagName('entry'):
parsed_item = {}
try:
parsed_item['title'] = node.getElementsByTagName('title')\
[0].childNodes[0].nodeValue
except IndexError:
parsed_item['title'] = None
try:
parsed_item['content'] = node.getElementsByTagName('content')\
[0].childNodes[0].nodeValue
except IndexError:
parsed_item['content'] = None
try:
parsed_item['link'] = node.getElementsByTagName('link')\
[0].childNodes[0].nodeValue
except IndexError:
parsed_item['link'] = None
try:
parsed_item['id'] = node.getElementsByTagName('id')\
[0].childNodes[0].nodeValue
except IndexError:
parsed_item['id'] = None
try:
parsed_item['published'] = node.getElementsByTagName('updated')\
[0].childNodes[0].nodeValue
except IndexError:
parsed_item['published'] = None
parsed_content.append(parsed_item)
return parsed_content
if __name__ == '__main__':
google = GoogleParser()
yahoo = YahooParser()
print 'Google: \n', google.print_top_news()
print
print 'Yahoo: \n', yahoo.print_top_news()
"""Summary....
The Template Method is a design pattern that defines the basis of an algorithm
and enables successors to redefine some steps of the algorithm without changing
its structure. The Template Method pattern allows good extensibility of the
algorithm, but only where permitted. This design pattern is well applied when
you have an algorithm whose behavior is common but the implementation may vary
and you have some steps that need to be adapted to different contexts.
"""