-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnews_merge_sort.py
More file actions
219 lines (176 loc) · 7 KB
/
Copy pathnews_merge_sort.py
File metadata and controls
219 lines (176 loc) · 7 KB
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
"""
File: fake_news_ms.py
Author: Ethan Huang
Purpose: Takes a csv file of fake news articles and counts how many times
each word occurs in the title of each line of the file and stores this
information in an object called Word. Then uses merge sort to sort the
list.
CSC 120 FA22 001
"""
import csv, string, sys
class Word():
def __init__(self, word):
"""Instanstiates a Word object with a string passed through it as its
word attribute and the count attribute set to 1.
Parameters: word is a string.
Returns: None."""
self._word = word
self._count = 1
def word(self):
"""Getter method for the word attribute of a Word object.
Parameters: None.
Returns: None."""
return self._word
def count(self):
"""Getter method for the count attribute of a Word object.
Parameters: None.
Returns: None."""
return self._count
def incr(self):
"""Increases the count attribute of a Word object by 1.
Parameters: None.
Returns: None."""
self._count += 1
def __lt__(self, other):
"""Determines if the word attribute of a Word object is less than
the word attribute of another word attribute.
Parameters: other is another Word object.
Returns: True if the Word object's word attribute is less than the
other Word object's.
False if the Word object's word attribute is greater than the
other Word object's."""
if self.word() < other.word():
return True
return False
def __str__(self):
"""Represents the string representation of a Word object.
Parameters: None.
Returns: The Word object's word attribute followed by a colon, and
its count attribute."""
return self._word + ": " + str(self._count)
def merge_word(list1, list2, merged):
"""Takes two lists of Word objects and sorts in descending order based
on their count attributes. If two objects have the same count, then
they are sorted in alphabetical order.
Parameters: list1 is a list of Word objects.
list2 is a list of Word objects.
merged is the list that you want list1 and list2 to be
sorted into.
Returns: A list that represents the Word objects sorted in descending
order based on their counts and in alphabetical order if they have
the same count value."""
if list1 == [] or list2 == []:
return merged + list1 + list2
else:
if list1[0].count() > list2[0].count():
merged.append(list1[0])
return merge_word(list1[1:], list2, merged)
elif list1[0].count() < list2[0].count():
merged.append(list2[0])
return merge_word(list1, list2[1:], merged)
else:
if list1[0].word() < list2[0].word():
merged.append(list1[0])
return merge_word(list1[1:], list2, merged)
else:
merged.append(list2[0])
return merge_word(list1, list2[1:], merged)
def merge_sort_list(alist):
"""Takes a list of Word objects and continuously breaks it down until
there is either no elements left or only 1 and calls merge_word each
time to sort the broken down lists.
Parameters: alist is a list of Word objects.
Returns: A new list that is alist but sorted in descending order based
on each Word object's count attribute, and if two objects share
the same count, then sorted in alphabetical order."""
if alist == [] or len(alist) == 1:
return alist
else:
x = len(alist) // 2
first_half = alist[:x]
second_half = alist[x:]
sort_first_half = merge_sort_list(first_half)
sort_second_half = merge_sort_list(second_half)
return merge_word(sort_first_half, sort_second_half, [])
def process_punctuation(line):
"""Removes any punctuation in a string.
Parameters: line is a string.
Returns: A string that is the original string, but without
any punctuation."""
astring = ""
for letter in line[4]:
if letter not in string.punctuation:
astring += letter
else:
astring += " "
return astring
def process_whitespace(line):
"""Removes any whitespace in a string.
Parameters: line is a string.
Returns: A string that is the original string, but without
any whitespace."""
astring = ""
for letter in line:
if letter not in string.whitespace:
astring += letter
else:
astring += " "
return astring
def get_rid_of_small_words(line):
"""Takes a list and removes any elements that have a length of 2 or less.
Parameters: line is a list of strings.
Returns: A new list that is the old list but without any elements
that have a length of two or less."""
i = 0
while i != len(line):
if len(line[i]) <= 2:
del(line[i])
else:
i += 1
return line
def create_list_of_words(alist, line):
"""Takes an empty list to be appended to and a list of strings. Creates
a Word object for each word in the line and appends that object to the
empty list. If an object that represents the word already exists in
the empty list, then the count attribute of the object is incremented
instead.
Parameters: alist is a list that will have Word objects appeded to it.
line is a list of strings.
Returns: None."""
for word in line:
found = False
for element in alist:
if element._word == word.lower():
element.incr()
found = True
if found == False:
alist.append(Word(word.lower()))
def print_out_words(alist, k):
"""Takes a list of Word objects and recursively searches through it for
any objects that have a count equal to or greater than k and prints
their words out.
Parameters: alist is a list of Word objects.
k is an integer.
Returns: None."""
if alist == []:
return
else:
if alist[0]._count >= k:
print("{} : {:d}".format(alist[0].word(), alist[0].count()))
return print_out_words(alist[1:], k)
def main():
afile = csv.reader(open(input("File: "), "r"))
alist = []
for line in afile:
if "#" not in line[0]:
line = process_punctuation(line)
line = process_whitespace(line)
line = line.split()
line = get_rid_of_small_words(line)
create_list_of_words(alist, line)
merged = merge_sort_list(alist)
n = input("N: ")
k = merged[int(n)].count()
print_out_words(merged, k)
sys.setrecursionlimit(4000)
main()