nanom commited on
Commit
e5fc5ba
1 Parent(s): ba8ecf7

Remodularization. Added style.css

Browse files
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Hernán J. Maina
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
app.py CHANGED
@@ -1,13 +1,13 @@
1
  import gradio as gr
2
  from modules.m_connector import Connector
3
 
4
- iface = gr.Blocks(css="container {max-width: 78%; margin: auto;}")
5
  conn = Connector()
6
 
7
  with iface:
8
- gr.Markdown("<center><h5>Active to Passive Voice (Beta)</h5></center>")
9
  with gr.Row():
10
- with gr.Column(scale=2):
11
  in_sentence = gr.Textbox(
12
  label = "Active sentence",
13
  max_lines=2,
@@ -19,7 +19,6 @@ with iface:
19
  )
20
  out = gr.HTML(
21
  label = "Out. Pasive sentences:",
22
- elem_id=".btn-group"
23
  )
24
 
25
  with gr.Column(variant='panel'):
@@ -31,9 +30,10 @@ with iface:
31
  "Mchael Jackson sings Billy Jean",
32
  "They are painting the house" ,
33
  "My mom has prepared the dinner",
34
- "The man has not found the farm"
 
35
  ],
36
- examples_per_page=5
37
  )
38
 
39
  btn_act2pas.click(
 
1
  import gradio as gr
2
  from modules.m_connector import Connector
3
 
4
+ iface = gr.Blocks(css="css/style.css")
5
  conn = Connector()
6
 
7
  with iface:
8
+ gr.HTML("<center><h5>Active to Passive Voice (Beta)</h5></center>")
9
  with gr.Row():
10
+ with gr.Column():
11
  in_sentence = gr.Textbox(
12
  label = "Active sentence",
13
  max_lines=2,
 
19
  )
20
  out = gr.HTML(
21
  label = "Out. Pasive sentences:",
 
22
  )
23
 
24
  with gr.Column(variant='panel'):
 
30
  "Mchael Jackson sings Billy Jean",
31
  "They are painting the house" ,
32
  "My mom has prepared the dinner",
33
+ "The man has not found the farm",
34
+ "He closes the doors"
35
  ],
36
+ examples_per_page=10
37
  )
38
 
39
  btn_act2pas.click(
css/style.css ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ h1, h2, h3, h4, h5, h6 {
2
+ margin-top: 0;
3
+ margin-bottom: 0.5rem;
4
+ }
5
+
6
+ h1, h2, h3, h4, h5, h6,
7
+ .h1, .h2, .h3, .h4, .h5, .h6 {
8
+ margin-bottom: 0.5rem;
9
+ font-weight: 500;
10
+ line-height: 1.2;
11
+ }
12
+
13
+ h1, .h1 {
14
+ font-size: 2.5rem;
15
+ }
16
+
17
+ h2, .h2 {
18
+ font-size: 2rem;
19
+ }
20
+
21
+ h3, .h3 {
22
+ font-size: 1.75rem;
23
+ }
24
+
25
+ h4, .h4 {
26
+ font-size: 1.5rem;
27
+ }
28
+
29
+ h5, .h5 {
30
+ font-size: 1.25rem;
31
+ }
32
+
33
+ h6, .h6 {
34
+ font-size: 1rem;
35
+ }
36
+
37
+ .badge {
38
+ display: inline-block;
39
+ padding: 0.25em 0.4em;
40
+ font-size: 75%;
41
+ font-weight: 700;
42
+ line-height: 1;
43
+ text-align: center;
44
+ white-space: nowrap;
45
+ vertical-align: baseline;
46
+ border-radius: 0.25rem;
47
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
48
+ }
49
+
50
+ .badge-pill {
51
+ padding-right: 0.6em;
52
+ padding-left: 0.6em;
53
+ border-radius: 10rem;
54
+ }
55
+
56
+ .badge-primary {
57
+ color: #fff;
58
+ background-color: #007bff;
59
+ }
60
+
61
+ .badge-secondary {
62
+ color: #fff;
63
+ background-color: #6c757d;
64
+ }
65
+
66
+ .badge-success {
67
+ color: #fff;
68
+ background-color: #28a745;
69
+ }
70
+
71
+ .badge-info {
72
+ color: #fff;
73
+ background-color: #17a2b8;
74
+ }
75
+
76
+ .badge-warning {
77
+ color: #212529;
78
+ background-color: #ffc107;
79
+ }
80
+
81
+ .badge-danger {
82
+ color: #fff;
83
+ background-color: #dc3545;
84
+ }
85
+
86
+ .badge-light {
87
+ color: #212529;
88
+ background-color: #f8f9fa;
89
+ }
90
+
91
+ .badge-dark {
92
+ color: #fff;
93
+ background-color: #343a40;
94
+ }
95
+
96
+ .alert {
97
+ position: relative;
98
+ padding: 0.75rem 1.25rem;
99
+ margin-bottom: 1rem;
100
+ border: 1px solid transparent;
101
+ border-radius: 0.25rem;
102
+ }
103
+
104
+ .alert-primary {
105
+ color: #004085;
106
+ background-color: #cce5ff;
107
+ border-color: #b8daff;
108
+ }
109
+
110
+ .alert-secondary {
111
+ color: #383d41;
112
+ background-color: #e2e3e5;
113
+ border-color: #d6d8db;
114
+ }
115
+
116
+ .alert-success {
117
+ color: #155724;
118
+ background-color: #d4edda;
119
+ border-color: #c3e6cb;
120
+ }
121
+
122
+ .alert-info {
123
+ color: #0c5460;
124
+ background-color: #d1ecf1;
125
+ border-color: #bee5eb;
126
+ }
127
+
128
+ .alert-warning {
129
+ color: #856404;
130
+ background-color: #fff3cd;
131
+ border-color: #ffeeba;
132
+ }
133
+
134
+ .alert-danger {
135
+ color: #721c24;
136
+ background-color: #f8d7da;
137
+ border-color: #f5c6cb;
138
+ }
139
+
140
+ .alert-light {
141
+ color: #818182;
142
+ background-color: #fefefe;
143
+ border-color: #fdfdfe;
144
+ }
145
+
146
+ .alert-dark {
147
+ color: #1b1e21;
148
+ background-color: #d6d8d9;
149
+ border-color: #c6c8ca;
150
+ }
151
+
152
+ .btn {
153
+ display: inline-block;
154
+ font-weight: 400;
155
+ color: #212529;
156
+ text-align: center;
157
+ vertical-align: middle;
158
+ -webkit-user-select: none;
159
+ -moz-user-select: none;
160
+ -ms-user-select: none;
161
+ user-select: none;
162
+ background-color: transparent;
163
+ border: 1px solid transparent;
164
+ padding: 0.375rem 0.75rem;
165
+ font-size: 1rem;
166
+ line-height: 1.5;
167
+ border-radius: 0.25rem;
168
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
169
+ }
170
+
171
+ .btn-primary {
172
+ color: #fff;
173
+ background-color: #007bff;
174
+ border-color: #007bff;
175
+ }
176
+
177
+ .btn-secondary {
178
+ color: #fff;
179
+ background-color: #6c757d;
180
+ border-color: #6c757d;
181
+ }
182
+
183
+ .btn-success {
184
+ color: #fff;
185
+ background-color: #28a745;
186
+ border-color: #28a745;
187
+ }
188
+
189
+ .btn-info {
190
+ color: #fff;
191
+ background-color: #17a2b8;
192
+ border-color: #17a2b8;
193
+ }
194
+
195
+ .btn-warning {
196
+ color: #212529;
197
+ background-color: #ffc107;
198
+ border-color: #ffc107;
199
+ }
200
+
201
+ .btn-danger {
202
+ color: #fff;
203
+ background-color: #dc3545;
204
+ border-color: #dc3545;
205
+ }
206
+
207
+ .btn-light {
208
+ color: #212529;
209
+ background-color: #f8f9fa;
210
+ border-color: #f8f9fa;
211
+ }
212
+
213
+ .btn-dark {
214
+ color: #fff;
215
+ background-color: #343a40;
216
+ border-color: #343a40;
217
+ }
modules/{m_apvoice.py → m_active_voice.py} RENAMED
@@ -1,127 +1,115 @@
1
- import enum
2
- import subprocess
3
- import spacy
4
- import pyinflect
5
  from difflib import ndiff
6
- from typing import List, Union, Tuple, Dict
7
-
8
- # BES auxiliary “be” Let it **be**.
9
- # HVS forms of “have” I**’ve** seen the Queen
10
- # MD verb, modal auxiliary VerbType=mod This **could** work.
11
- # VB verb, base form VerbForm=inf I want to **go**.
12
- # VBD verb, past tense VerbForm=fin Tense=past This **was** a sentence.
13
- # VBG verb, gerund or present participle VerbForm=part Tense=pres Aspect=prog I am **going**.
14
- # VBN verb, past participle VerbForm=part Tense=past Aspect=perf The treasure was **lost**.
15
- # VBP verb, non-3rd person singular present VerbForm=fin Tense=pres I **want** to go.
16
- # VBZ verb, 3rd person singular present VerbForm=fin Tense=pres Number=sing Person=3 He **wants** to go.
17
-
18
- class APVoice:
19
- class Tense(enum.Enum):
20
- simple_present = {
21
- 'aux':[None,'VBZ'],
22
- 'main':['VBZ','VBP', 'VB'],
23
- 'tobe':{'NN':'is{}','NNS':'are{}'}
24
- }
25
- simple_past = {
26
- 'aux':[None, 'VBD'],
27
- 'main':['VBD', 'VB'],
28
- 'tobe':{'NN':'was{}','NNS':'were{}'}
29
- }
30
- future_simple = {
31
- 'aux':['MD'],
32
- 'main':['VB'],
33
- 'tobe':{'NN':'will{} be','NNS':'will{} be'}
34
- }
35
- present_cont = {
36
- 'aux':['VBP','VBZ'],
37
- 'main':['VBG'],
38
- 'tobe':{'NN':'is{} being','NNS':'are{} being'}
39
- }
40
- past_cont = {
41
- 'aux':['VBD'],
42
- 'main':['VBG'],
43
- 'tobe':{'NN':'was{} being','NNS':'were{} being'}
44
- }
45
- present_perfect = {
46
- 'aux':['VBP','VBZ'],
47
- 'main':['VBN'],
48
- 'tobe':{'NN':'has{} been','NNS':'have{} been'}
49
- }
50
 
 
51
  def __init__(
52
  self
53
  ) -> None:
54
 
55
- self.parser = None
56
- self.__init_parser(model="en_core_web_sm")
57
 
58
- def __init_parser(
59
  self,
60
- model: str
61
- ) -> None:
 
62
 
63
- self.parser = None
64
- try:
65
- self.parser = spacy.load(model)
66
- except:
67
- print(f"* Downloading {model} model...")
68
- _ = subprocess.Popen(
69
- f"python -m spacy download {model}",
70
- stdout=subprocess.PIPE,
71
- shell=True).communicate()
72
 
73
- self.parser = spacy.load(model)
 
 
 
 
 
74
 
75
- def verb2participle(
76
- self,
77
- verb: str
78
- ) -> str:
 
 
 
 
 
 
 
 
 
79
 
80
- tk = self.parser(verb)[0]
81
- return tk._.inflect('VBN')
82
-
83
- def subjp2objp(
 
 
 
 
 
 
 
84
  self,
85
- pronoun: str
86
  ) -> str:
87
- """
88
- Convert Subject pronouns to Object pronouns.
89
- """
90
- mapping = {"i":"me","you":"you","we":"us","they":"them","he":"him","she":"her", "it":"it"}
91
- return mapping.get(pronoun.lower(), None)
92
 
93
- def get_gramatical_number(
 
 
94
  self,
95
- dobj_data: List[List[Tuple[str,str,str]]]
96
- ) -> Union[str, None]:
 
 
 
 
 
 
 
 
 
 
97
 
98
- result = [tag for _,dep,tag in dobj_data if dep == 'dobj']
99
- if len(result) == 0:
100
- result = None
101
- else:
102
- result = result[0].replace('NNP', 'NN')
103
 
104
- return result
105
-
106
- def get_verbal_tense(
107
- self,
108
- verb_data: List[List[Tuple[str,str,str,int]]]
109
- ) -> Union[str, None]:
 
 
110
 
111
- aux, neg, root = verb_data
 
 
112
 
113
- root = root[0][2] if len(root) > 0 else None
114
- aux = aux[0][2] if len(aux) > 0 else None
115
 
116
- tense_name = None
117
- for tense in self.Tense:
118
- if aux in tense.value['aux'] and root in tense.value['main']:
119
- tense_name = tense.name
120
- break
 
 
 
 
 
 
 
121
 
122
- return tense_name
123
 
124
- def get_subj(
125
  self,
126
  sentence: str,
127
  ) -> Tuple[ List[Tuple[str,str,str]], str]:
@@ -135,7 +123,7 @@ class APVoice:
135
  out_str = ' '.join([t.text for t,_,_ in out_data])
136
  return out_data, out_str
137
 
138
- def get_verb(
139
  self,
140
  sentence: str,
141
  ) -> Tuple[ List[List[Tuple[str,str,str,int]]], str]:
@@ -157,7 +145,7 @@ class APVoice:
157
  out_str = ' '.join([t.text for t,_,_,_ in out_str])
158
  return out_data, out_str
159
 
160
- def get_dobj(
161
  self,
162
  sentence: str,
163
  ) -> Tuple[ List[Tuple[str,str,str]], str]:
@@ -171,7 +159,7 @@ class APVoice:
171
  out_str = ' '.join([t.text for t,_,_ in out_data])
172
  return out_data, out_str
173
 
174
- def get_complement(
175
  self,
176
  subj: str,
177
  verb: str,
@@ -188,71 +176,37 @@ class APVoice:
188
 
189
  return diff.strip()
190
 
191
- def active2passive(
192
  self,
193
- active_sentence: str,
194
  debug: bool=False
195
  ) -> Dict[str, str]:
196
 
197
- active_sentence = active_sentence.strip()
198
- if active_sentence == "":
199
- raise RuntimeError(
200
- f"Error: The sentence cannot be empty!"
201
- )
202
-
203
- subj_data, subj_str = self.get_subj(active_sentence)
204
- if debug: print(subj_data)
205
- if subj_str == "":
206
- raise RuntimeError(
207
- f"Error: The sentence's subject has not been found or the sentence does not be the correct format!"
208
- )
209
-
210
- verb_data, verb_str = self.get_verb(active_sentence)
211
- if debug: print(verb_data)
212
- if verb_str == "":
213
- raise RuntimeError(
214
- f"Error: The sentence's verb has not been found or the sentence does not be the correct format!"
215
- )
216
 
217
- dobj_data, dobj_str = self.get_dobj(active_sentence)
218
- if debug: print(dobj_data)
219
- if dobj_str == "":
220
- raise RuntimeError(
221
- f"Error: The sentence's direct object has not been found or the sentence does not be the correct format!"
222
- )
223
-
224
- complement = self.get_complement(subj_str, verb_str, dobj_str, active_sentence)
225
-
226
- # Get pasive subject
227
- p_subj = dobj_str
228
-
229
- # Get tense + participle verb
230
- verbal_tense = self.get_verbal_tense(verb_data)
231
- if debug: print(verbal_tense)
232
- if verbal_tense is None:
233
- raise RuntimeError(
234
- f"Error: The sentence does not be the correct format or the verbal tense has not been implemented yet!"
235
- )
236
-
237
- _, neg_data, main_data = verb_data
238
- neg = " not" if len(neg_data) > 0 else ""
239
- gramatical_number = self.get_gramatical_number(dobj_data)
240
- if debug: print(gramatical_number)
241
- p_tobe = self.Tense[verbal_tense].value['tobe'][gramatical_number].format(neg)
242
- p_verb = self.verb2participle(main_data[0][0].text)
243
-
244
- # Convert active_object to pasive_agent
245
- p_agent = ""
246
- for tk,_,tag in subj_data:
247
- word = tk.text
248
- if tag == 'PRP':
249
- word = self.subjp2objp(word)
250
- p_agent += word + " "
251
 
252
  return {
253
- 'subject': p_subj.capitalize(),
254
  'tobe':p_tobe,
255
- 'participle': p_verb,
256
  'agent': 'by '+ p_agent[0].lower() + p_agent[1:].strip(),
257
- 'complement':complement
258
  }
 
1
+ from modules.m_parser import Parser, Tense
 
 
 
2
  from difflib import ndiff
3
+ from typing import List, Tuple, Dict
4
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
+ class ActiveVoice(Parser):
7
  def __init__(
8
  self
9
  ) -> None:
10
 
11
+ Parser.__init__(self)
 
12
 
13
+ def __check_errors(
14
  self,
15
+ sentence: str,
16
+ debug: bool = False
17
+ ) -> Dict:
18
 
19
+ sentence = sentence.strip()
20
+ if sentence == "":
21
+ raise RuntimeError(
22
+ f"Error: The sentence can not be empty!"
23
+ )
 
 
 
 
24
 
25
+ subj_data, subj_str = self.get_a_subj(sentence)
26
+ if debug: print(subj_data)
27
+ if subj_str == "":
28
+ raise RuntimeError(
29
+ f"Error: The subject of the sentence was not found or the sentence is not in the correct format!"
30
+ )
31
 
32
+ verb_data, verb_str = self.get_a_verb(sentence)
33
+ if debug: print(verb_data)
34
+ if verb_str == "":
35
+ raise RuntimeError(
36
+ f"Error: The verbs of the sentence were not found or the sentence is not in the correct format!"
37
+ )
38
+
39
+ dobj_data, dobj_str = self.get_a_dobj(sentence)
40
+ if debug: print(dobj_data)
41
+ if dobj_str == "":
42
+ raise RuntimeError(
43
+ f"Error: The direct object of the sentence was not found or the sentence is not in the correct format!"
44
+ )
45
 
46
+ compl_str = self.get_a_compl(subj_str, verb_str, dobj_str, sentence)
47
+ if debug: print(compl_str)
48
+
49
+ return {
50
+ 'subj': [subj_data, subj_str],
51
+ 'verb': [verb_data, verb_str],
52
+ 'dobj': [dobj_data, dobj_str],
53
+ 'compl': compl_str,
54
+ }
55
+
56
+ def __create_p_subj(
57
  self,
58
+ a_dobj: str
59
  ) -> str:
 
 
 
 
 
60
 
61
+ return a_dobj
62
+
63
+ def __create_p_verb(
64
  self,
65
+ a_verb_data: List[Tuple[str,str,str,int]],
66
+ a_dobj_data: List[Tuple[str,str,str]],
67
+ debug: bool = False
68
+ ) -> Tuple[str, str]:
69
+
70
+ # know verbal tense
71
+ verbal_tense = self.get_verbal_tense(a_verb_data)
72
+ if debug: print(verbal_tense)
73
+ if verbal_tense is None:
74
+ raise RuntimeError(
75
+ f"Error: The sentence is not in the correct format or the verbal tense has not been implemented yet!"
76
+ )
77
 
78
+ # Know if sentence is in afirmative or negative
79
+ _, neg_data, main_data = a_verb_data
80
+ neg = " not" if len(neg_data) > 0 else ""
 
 
81
 
82
+ # know if noun is plural or singular
83
+ gramatical_number = self.get_gramatical_number(a_dobj_data)
84
+ if debug: print(gramatical_number)
85
+
86
+ # Form to be verb
87
+ tobe = Tense[verbal_tense].value['tobe'][gramatical_number]
88
+ tobe = tobe.format(neg)
89
+ if debug: print(tobe)
90
 
91
+ # Know participle
92
+ participle = self.verb2participle(main_data[0][0].text)
93
+ if debug: print(participle)
94
 
95
+ return tobe, participle
 
96
 
97
+ def __create_p_agent(
98
+ self,
99
+ a_subj_data: List[Tuple[str,str,str]],
100
+ debug: bool = False
101
+ ) -> str:
102
+
103
+ agent = []
104
+ for tk,_,tag in a_subj_data:
105
+ word = tk.text
106
+ if tag == 'PRP':
107
+ word = self.subj2obj(word)
108
+ agent.append(word)
109
 
110
+ return ' '.join(agent).strip()
111
 
112
+ def get_a_subj(
113
  self,
114
  sentence: str,
115
  ) -> Tuple[ List[Tuple[str,str,str]], str]:
 
123
  out_str = ' '.join([t.text for t,_,_ in out_data])
124
  return out_data, out_str
125
 
126
+ def get_a_verb(
127
  self,
128
  sentence: str,
129
  ) -> Tuple[ List[List[Tuple[str,str,str,int]]], str]:
 
145
  out_str = ' '.join([t.text for t,_,_,_ in out_str])
146
  return out_data, out_str
147
 
148
+ def get_a_dobj(
149
  self,
150
  sentence: str,
151
  ) -> Tuple[ List[Tuple[str,str,str]], str]:
 
159
  out_str = ' '.join([t.text for t,_,_ in out_data])
160
  return out_data, out_str
161
 
162
+ def get_a_compl(
163
  self,
164
  subj: str,
165
  verb: str,
 
176
 
177
  return diff.strip()
178
 
179
+ def to_pasive(
180
  self,
181
+ sentence: str,
182
  debug: bool=False
183
  ) -> Dict[str, str]:
184
 
185
+ outputs = self.__check_errors(sentence, debug)
186
+ subj_data, subj_str = outputs['subj']
187
+ verb_data, verb_str = outputs['verb']
188
+ dobj_data, dobj_str = outputs['dobj']
189
+ p_compl = outputs['compl']
190
+
191
+ # Create passive subject
192
+ p_subj = self.__create_p_subj(
193
+ dobj_str
194
+ )
195
+
196
+ # Create passive verb
197
+ p_tobe, p_participle = self.__create_p_verb(
198
+ verb_data, dobj_data, debug
199
+ )
 
 
 
 
200
 
201
+ # Create passive agent
202
+ p_agent = self.__create_p_agent(
203
+ subj_data, debug
204
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
 
206
  return {
207
+ 'subj': p_subj.capitalize(),
208
  'tobe':p_tobe,
209
+ 'participle': p_participle,
210
  'agent': 'by '+ p_agent[0].lower() + p_agent[1:].strip(),
211
+ 'compl': p_compl
212
  }
modules/m_connector.py CHANGED
@@ -1,52 +1,29 @@
1
  from typing import Tuple
2
- from modules.m_apvoice import APVoice
3
-
 
4
  class Connector:
5
  def __init__(
6
  self
7
  ) -> None:
8
 
9
- self.apvoice = APVoice()
10
-
11
- self.__out_template = """
12
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
13
- <center>{}</center>
14
- """
15
- self.__error_template = "<center><h2><b>{}</b></h2></center>"
16
-
17
- def create_category(
18
- self,
19
- text: str,
20
- category: str,
21
- color: str
22
- ) -> str:
23
-
24
- html = f"""
25
- <div type="button" title="{category}" class="btn btn-{color} btn-sm p-2">
26
- <b>{text}</b><br>
27
- <span class="badge text-bg-light">{category}</span>
28
- </div>
29
- """
30
- return html if text != "" else ""
31
 
32
  def active2passive(
33
  self,
34
  sentence: str
35
  ) -> Tuple[str,str]:
36
 
37
- out = ""
38
  try:
39
- out = self.apvoice.active2passive(sentence)
40
- out = f"""
41
- {self.create_category(out['subject'], 'subject','primary')}
42
- {self.create_category(out['tobe'],'to be','warning')}
43
- {self.create_category(out['participle'],'participle','danger')}
44
- {self.create_category(out['agent'],'agent','info')}
45
- {self.create_category(out['complement'],'compl.','dark')}
46
- """
47
- out = self.__out_template.format(out)
48
-
49
  except Exception as e:
50
- out = self.__error_template.format(str(e))
51
 
52
- return out
 
 
 
 
 
 
 
1
  from typing import Tuple
2
+ from modules.m_active_voice import ActiveVoice
3
+ from modules.m_htmlrender import HtmlRender
4
+
5
  class Connector:
6
  def __init__(
7
  self
8
  ) -> None:
9
 
10
+ self.avoice = ActiveVoice()
11
+ self.html = HtmlRender()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
  def active2passive(
14
  self,
15
  sentence: str
16
  ) -> Tuple[str,str]:
17
 
 
18
  try:
19
+ data = self.avoice.to_pasive(sentence)
 
 
 
 
 
 
 
 
 
20
  except Exception as e:
21
+ return self.html.error(str(e))
22
 
23
+ subj = self.html.budget(data['subj'], 'subject', 'primary')
24
+ tobe = self.html.budget(data['tobe'],'to be','warning')
25
+ participle = self.html.budget(data['participle'],'participle','danger')
26
+ agent = self.html.budget(data['agent'],'agent','success')
27
+ compl = self.html.budget(data['compl'],'compl.','dark')
28
+
29
+ return self.html.output(f"{subj} {tobe} {participle} {agent} {compl}")
modules/m_htmlrender.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class HtmlRender:
2
+ def __init__(
3
+ self
4
+ ) -> None:
5
+ pass
6
+
7
+ def output(
8
+ self,
9
+ html: str
10
+ ) -> str:
11
+
12
+ template = "<center>{}</center>"
13
+ return template.format(html)
14
+
15
+ def error(
16
+ self,
17
+ html: str
18
+ ) -> str:
19
+
20
+ template = """
21
+ <center>
22
+ <div class="alert alert-warning" role="alert">
23
+ <h6><b>{}</b></h6>
24
+ </div>
25
+ </center>
26
+ """
27
+ return template.format(html)
28
+
29
+ def budget(
30
+ self,
31
+ text: str,
32
+ category: str,
33
+ color: str
34
+ ) -> str:
35
+
36
+ html = f"""
37
+ <span type="button" title="{category}" class="btn btn-{color}">
38
+ <b>{text}</b><br>
39
+ <span class="badge badge-pill badge-light">{category}</span>
40
+ </span>
41
+ """
42
+ return html if text != "" else ""
modules/m_parser.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import enum
2
+ import subprocess
3
+ import spacy
4
+ import pyinflect
5
+ from typing import List, Union, Tuple
6
+
7
+ # BES auxiliary “be” Let it **be**.
8
+ # HVS forms of “have” I**’ve** seen the Queen
9
+ # MD verb, modal auxiliary VerbType=mod This **could** work.
10
+ # VB verb, base form VerbForm=inf I want to **go**.
11
+ # VBD verb, past tense VerbForm=fin Tense=past This **was** a sentence.
12
+ # VBG verb, gerund or present participle VerbForm=part Tense=pres Aspect=prog I am **going**.
13
+ # VBN verb, past participle VerbForm=part Tense=past Aspect=perf The treasure was **lost**.
14
+ # VBP verb, non-3rd person singular present VerbForm=fin Tense=pres I **want** to go.
15
+ # VBZ verb, 3rd person singular present VerbForm=fin Tense=pres Number=sing Person=3 He **wants** to go.
16
+
17
+ class Tense(enum.Enum):
18
+ simple_present = {
19
+ 'aux':[None,'VBZ'],
20
+ 'main':['VBZ','VBP', 'VB'],
21
+ 'tobe':{'NN':'is{}','NNS':'are{}'}
22
+ }
23
+ simple_past = {
24
+ 'aux':[None, 'VBD'],
25
+ 'main':['VBD', 'VB'],
26
+ 'tobe':{'NN':'was{}','NNS':'were{}'}
27
+ }
28
+ future_simple = {
29
+ 'aux':['MD'],
30
+ 'main':['VB'],
31
+ 'tobe':{'NN':'will{} be','NNS':'will{} be'}
32
+ }
33
+ present_cont = {
34
+ 'aux':['VBP','VBZ'],
35
+ 'main':['VBG'],
36
+ 'tobe':{'NN':'is{} being','NNS':'are{} being'}
37
+ }
38
+ past_cont = {
39
+ 'aux':['VBD'],
40
+ 'main':['VBG'],
41
+ 'tobe':{'NN':'was{} being','NNS':'were{} being'}
42
+ }
43
+ present_perfect = {
44
+ 'aux':['VBP','VBZ'],
45
+ 'main':['VBN'],
46
+ 'tobe':{'NN':'has{} been','NNS':'have{} been'}
47
+ }
48
+
49
+ class Parser:
50
+ def __init__(
51
+ self
52
+ ) -> None:
53
+
54
+ self.parser = None
55
+ self.__init_parser(model="en_core_web_sm")
56
+
57
+ def __init_parser(
58
+ self,
59
+ model: str
60
+ ) -> None:
61
+
62
+ self.parser = None
63
+ try:
64
+ self.parser = spacy.load(model)
65
+ except:
66
+ print(f"* Downloading {model} model...")
67
+ _ = subprocess.Popen(
68
+ f"python -m spacy download {model}",
69
+ stdout=subprocess.PIPE,
70
+ shell=True).communicate()
71
+
72
+ self.parser = spacy.load(model)
73
+
74
+ def verb2participle(
75
+ self,
76
+ verb: str
77
+ ) -> str:
78
+
79
+ tk = self.parser(verb)[0]
80
+ return tk._.inflect('VBN')
81
+
82
+ def subj2obj(
83
+ self,
84
+ pronoun: str
85
+ ) -> str:
86
+ """
87
+ Convert Subject pronouns to Object pronouns.
88
+ """
89
+ mapping = {"i":"me","you":"you","we":"us","they":"them","he":"him","she":"her", "it":"it"}
90
+ return mapping.get(pronoun.lower(), None)
91
+
92
+ def get_gramatical_number(
93
+ self,
94
+ dobj_data: List[List[Tuple[str,str,str]]]
95
+ ) -> Union[str, None]:
96
+
97
+ result = [tag for _,dep,tag in dobj_data if dep == 'dobj']
98
+ if len(result) == 0:
99
+ result = None
100
+ else:
101
+ result = result[0].replace('NNP', 'NN')
102
+
103
+ return result
104
+
105
+ def get_verbal_tense(
106
+ self,
107
+ verb_data: List[List[Tuple[str,str,str,int]]]
108
+ ) -> Union[str, None]:
109
+
110
+ aux, neg, root = verb_data
111
+
112
+ root = root[0][2] if len(root) > 0 else None
113
+ aux = aux[0][2] if len(aux) > 0 else None
114
+
115
+ tense_name = None
116
+ for tense in Tense:
117
+ if aux in tense.value['aux'] and root in tense.value['main']:
118
+ tense_name = tense.name
119
+ break
120
+
121
+ return tense_name