-
Notifications
You must be signed in to change notification settings - Fork 0
/
rules.py
87 lines (75 loc) · 2.92 KB
/
rules.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
# -*- coding: utf-8 -*-
from utils import run_file
from os.path import join as join_path
def init(rule_dict, pwd=join_path('.', 'data', 'rules')):
'''Initialize rules from file.'''
for elem in run_file(join_path(pwd, 'rules_list.csv')):
rule_dict[elem] = Rule(elem)
rules_list = ['nominal', 'verbal']
for rule_name in rules_list:
for elem in run_file(join_path(pwd, rule_name+'.csv')):
name, par, subs = elem.split(',')
rule_dict[name].insert(par, subs)
PERSON_NUMBER_POS = {
'1s': 0, '2s': 1, '3s': 2, '1p': 3, '2p': 4, '3p': 5,
}
class Rule:
'''
Defines how to decline/conjugate words based on roots/lists.
'''
def __init__(self, name):
'''Attributes:
- self.name: the rule's name/identifier;
- self.subs: the substitution rule's dict;
- self.kind: defines the rule's kind among verbal, nominal1
and nominal2.
'''
self.name = name
self.subs = {}
self.kind = None
def insert(self, par, subs):
if subs[0] == '@':
self.kind = 'verbal'
for i in range(6):
self.subs[(par, i)] = subs.split('/')[0] + '/' + \
subs[1:].split('/')[1].split(':')[i]
elif subs[0] == '%':
self.kind = 'nominal1'
self.subs[tuple(par.split('/'))] = subs[1:]
else:
self.kind = 'nominal2'
self.subs[tuple(par.split('/'))] = subs.split('/')
def apply(self, txt, par, person_number=None):
aux = txt
if self.kind == 'nominal1':
for k in self.subs:
if not filter(lambda x: x,
map(lambda y: k[y] != par[y] and k[y] != '*',
range(len(k)))):
return txt.split('/')[int(self.subs[k])-1]
return txt
elif self.kind == 'nominal2':
for k in self.subs:
if not filter(lambda x: x,
map(lambda y: k[y] != par[y] and k[y] != '*',
range(len(k)))):
for j in self.subs[k]:
sub = j.split(':')
if sub[0][-1] == '$':
aux = (aux + '$').replace(sub[0], sub[1])
if aux[-1] == '$':
aux = aux[:-1]
else:
aux = aux.replace(sub[0], sub[1])
return aux
return txt
elif self.kind == 'verbal':
sub = self.subs[(par, PERSON_NUMBER_POS[person_number])].split('/')
if sub[0][-1] == '$':
return (aux + '$').replace(sub[0][1:], sub[1])
if aux[-1] == '$':
aux = aux[:-1]
else:
return aux.replace(sub[0][1:], sub[1])
else:
raise 'Rule kind not defined', self.name