-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.py
153 lines (128 loc) · 4.69 KB
/
util.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
class IdMap:
"""
Ingat kembali di kuliah, bahwa secara praktis, sebuah dokumen dan
sebuah term akan direpresentasikan sebagai sebuah integer. Oleh
karena itu, kita perlu maintain mapping antara string term (atau
dokumen) ke integer yang bersesuaian, dan sebaliknya. Kelas IdMap ini
akan melakukan hal tersebut.
"""
def __init__(self):
"""
Mapping dari string (term atau nama dokumen) ke id disimpan dalam
python's dictionary; cukup efisien. Mapping sebaliknya disimpan dalam
python's list.
contoh:
str_to_id["halo"] ---> 8
str_to_id["/collection/dir0/gamma.txt"] ---> 54
id_to_str[8] ---> "halo"
id_to_str[54] ---> "/collection/dir0/gamma.txt"
"""
self.str_to_id = {}
self.id_to_str = []
def __len__(self):
"""Mengembalikan banyaknya term (atau dokumen) yang disimpan di IdMap."""
# TODO
return len(self.str_to_id)
def __get_id(self, s):
"""
Mengembalikan integer id i yang berkorespondensi dengan sebuah string s.
Jika s tidak ada pada IdMap, lalu assign sebuah integer id baru dan kembalikan
integer id baru tersebut.
"""
# TODO
tmp = self.str_to_id.get(s)
if tmp:
return tmp
self.str_to_id[s] = len(self.str_to_id)
self.id_to_str.append(s)
return self.str_to_id[s]
def __get_str(self, i):
"""Mengembalikan string yang terasosiasi dengan index i."""
# TODO
return self.id_to_str[i]
def __getitem__(self, key):
"""
__getitem__(...) adalah special method di Python, yang mengizinkan sebuah
collection class (seperti IdMap ini) mempunyai mekanisme akses atau
modifikasi elemen dengan syntax [..] seperti pada list dan dictionary di Python.
Silakan search informasi ini di Web search engine favorit Anda. Saya mendapatkan
link berikut:
https://stackoverflow.com/questions/43627405/understanding-getitem-method
Jika key adalah integer, gunakan __get_str;
jika key adalah string, gunakan __get_id
"""
# TODO
return self.__get_id(key) if isinstance(key, str) else self.__get_str(key)
def __contains__(self, key):
return (
key in self.str_to_id.keys()
if isinstance(key, str)
else key in self.id_to_str
)
def merge_and_sort_posts_and_tfs(posts_tfs1, posts_tfs2):
"""
Menggabung (merge) dua lists of tuples (doc id, tf) dan mengembalikan
hasil penggabungan keduanya (TF perlu diakumulasikan untuk semua tuple
dengn doc id yang sama), dengan aturan berikut:
contoh: posts_tfs1 = [(1, 34), (3, 2), (4, 23)]
posts_tfs2 = [(1, 11), (2, 4), (4, 3 ), (6, 13)]
return [(1, 34+11), (2, 4), (3, 2), (4, 23+3), (6, 13)]
= [(1, 45), (2, 4), (3, 2), (4, 26), (6, 13)]
Parameters
----------
list1: List[(Comparable, int)]
list2: List[(Comparable, int]
Dua buah sorted list of tuples yang akan di-merge.
Returns
-------
List[(Comparable, int)]
Penggabungan yang sudah terurut
"""
# TODO
res = []
i = j = 0
while i < len(posts_tfs1) and j < len(posts_tfs2):
doc_id1, tf1 = posts_tfs1[i]
doc_id2, tf2 = posts_tfs2[j]
if doc_id1 == doc_id2:
res.append((doc_id1, tf1 + tf2))
i += 1
j += 1
elif doc_id1 < doc_id2:
res.append((doc_id1, tf1))
i += 1
else:
res.append((doc_id2, tf2))
j += 1
# append remaining elements
while i < len(posts_tfs1):
res.append(posts_tfs1[i])
i += 1
while j < len(posts_tfs2):
res.append(posts_tfs2[j])
j += 1
return res
if __name__ == "__main__":
doc = ["halo", "semua", "selamat", "pagi", "semua"]
term_id_map = IdMap()
assert [term_id_map[term] for term in doc] == [0, 1, 2, 3, 1], "term_id salah"
assert term_id_map[1] == "semua", "term_id salah"
assert term_id_map[0] == "halo", "term_id salah"
assert term_id_map["selamat"] == 2, "term_id salah"
assert term_id_map["pagi"] == 3, "term_id salah"
docs = [
"/collection/0/data0.txt",
"/collection/0/data10.txt",
"/collection/1/data53.txt",
]
doc_id_map = IdMap()
assert [doc_id_map[docname] for docname in docs] == [0, 1, 2], "docs_id salah"
assert merge_and_sort_posts_and_tfs(
[(1, 34), (3, 2), (4, 23)], [(1, 11), (2, 4), (4, 3), (6, 13)]
) == [
(1, 45),
(2, 4),
(3, 2),
(4, 26),
(6, 13),
], "merge_and_sort_posts_and_tfs salah"