Spaces:
Sleeping
Sleeping
nanom
commited on
Commit
•
703bf01
0
Parent(s):
First commit
Browse files- .gitignore +1 -0
- LICENSE +21 -0
- app.py +51 -0
- css/style.css +167 -0
- modules/m_parser.py +100 -0
- requirements.txt +2 -0
.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
__pycache__
|
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
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from modules.m_parser import Parser
|
3 |
+
|
4 |
+
execute = Parser()
|
5 |
+
iface = gr.Blocks(css='css/style.css')
|
6 |
+
|
7 |
+
with iface:
|
8 |
+
gr.HTML("<center><h5>🇺🇸 🇬🇧 Verb Tense Converter</h5></center>")
|
9 |
+
with gr.Row():
|
10 |
+
input_verb = gr.Textbox(
|
11 |
+
label = "1. Enter a verb",
|
12 |
+
max_lines=1,
|
13 |
+
placeholder = "Enter here a single verb in any tense...",
|
14 |
+
)
|
15 |
+
btn_get = gr.Button(
|
16 |
+
value = "2. Click here to convert!"
|
17 |
+
)
|
18 |
+
|
19 |
+
with gr.Row():
|
20 |
+
error = gr.HTML()
|
21 |
+
|
22 |
+
with gr.Row(variant='panel'):
|
23 |
+
with gr.Column(variant='panel'):
|
24 |
+
out_infinitive = gr.Textbox(
|
25 |
+
label="Infinitive",
|
26 |
+
max_lines=1,
|
27 |
+
placeholder="The verb in the 'infinitive' will be shown here..."
|
28 |
+
)
|
29 |
+
with gr.Column(variant='panel'):
|
30 |
+
out_simple_past = gr.Textbox(
|
31 |
+
label="Simple Past",
|
32 |
+
max_lines=1,
|
33 |
+
placeholder="The verb in the 'past' will be shown here..."
|
34 |
+
)
|
35 |
+
with gr.Column(variant='panel'):
|
36 |
+
out_past_participle = gr.Textbox(
|
37 |
+
label="Past Participle",
|
38 |
+
max_lines=1,
|
39 |
+
placeholder="The verb in the 'participle' will be shown here..."
|
40 |
+
)
|
41 |
+
|
42 |
+
btn_get.click(
|
43 |
+
fn = execute.get_verbs,
|
44 |
+
inputs = input_verb,
|
45 |
+
outputs = [error, out_infinitive, out_simple_past, out_past_participle],
|
46 |
+
api_name="get"
|
47 |
+
)
|
48 |
+
|
49 |
+
iface.launch(
|
50 |
+
server_name = "0.0.0.0"
|
51 |
+
)
|
css/style.css
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.container {
|
2 |
+
max-width: 80%;
|
3 |
+
margin: auto;
|
4 |
+
}
|
5 |
+
|
6 |
+
h1, h2, h3, h4, h5, h6 {
|
7 |
+
margin-top: 0;
|
8 |
+
margin-bottom: 0.5rem;
|
9 |
+
}
|
10 |
+
|
11 |
+
h1, h2, h3, h4, h5, h6,
|
12 |
+
.h1, .h2, .h3, .h4, .h5, .h6 {
|
13 |
+
margin-bottom: 0.5rem;
|
14 |
+
font-weight: 500;
|
15 |
+
line-height: 1.2;
|
16 |
+
}
|
17 |
+
|
18 |
+
h1, .h1 {
|
19 |
+
font-size: 2.5rem;
|
20 |
+
}
|
21 |
+
|
22 |
+
h2, .h2 {
|
23 |
+
font-size: 2rem;
|
24 |
+
}
|
25 |
+
|
26 |
+
h3, .h3 {
|
27 |
+
font-size: 1.75rem;
|
28 |
+
}
|
29 |
+
|
30 |
+
h4, .h4 {
|
31 |
+
font-size: 1.5rem;
|
32 |
+
}
|
33 |
+
|
34 |
+
h5, .h5 {
|
35 |
+
font-size: 1.25rem;
|
36 |
+
}
|
37 |
+
|
38 |
+
h6, .h6 {
|
39 |
+
font-size: 1rem;
|
40 |
+
}
|
41 |
+
|
42 |
+
.no-outline {
|
43 |
+
border: 0px none;
|
44 |
+
}
|
45 |
+
|
46 |
+
.alert {
|
47 |
+
position: relative;
|
48 |
+
padding: 0.75rem 1.25rem;
|
49 |
+
margin-bottom: 1rem;
|
50 |
+
border: 1px solid transparent;
|
51 |
+
border-radius: 0.25rem;
|
52 |
+
}
|
53 |
+
|
54 |
+
.alert-primary {
|
55 |
+
color: #004085;
|
56 |
+
background-color: #cce5ff;
|
57 |
+
border-color: #b8daff;
|
58 |
+
}
|
59 |
+
|
60 |
+
.alert-secondary {
|
61 |
+
color: #383d41;
|
62 |
+
background-color: #e2e3e5;
|
63 |
+
border-color: #d6d8db;
|
64 |
+
}
|
65 |
+
|
66 |
+
.alert-success {
|
67 |
+
color: #155724;
|
68 |
+
background-color: #d4edda;
|
69 |
+
border-color: #c3e6cb;
|
70 |
+
}
|
71 |
+
|
72 |
+
.alert-info {
|
73 |
+
color: #0c5460;
|
74 |
+
background-color: #d1ecf1;
|
75 |
+
border-color: #bee5eb;
|
76 |
+
}
|
77 |
+
|
78 |
+
.alert-warning {
|
79 |
+
color: #856404;
|
80 |
+
background-color: #fff3cd;
|
81 |
+
border-color: #ffeeba;
|
82 |
+
}
|
83 |
+
|
84 |
+
.alert-danger {
|
85 |
+
color: #721c24;
|
86 |
+
background-color: #f8d7da;
|
87 |
+
border-color: #f5c6cb;
|
88 |
+
}
|
89 |
+
|
90 |
+
.alert-light {
|
91 |
+
color: #818182;
|
92 |
+
background-color: #fefefe;
|
93 |
+
border-color: #fdfdfe;
|
94 |
+
}
|
95 |
+
|
96 |
+
.alert-dark {
|
97 |
+
color: #1b1e21;
|
98 |
+
background-color: #d6d8d9;
|
99 |
+
border-color: #c6c8ca;
|
100 |
+
}
|
101 |
+
|
102 |
+
.btn {
|
103 |
+
display: inline-block;
|
104 |
+
font-weight: 400;
|
105 |
+
color: #212529;
|
106 |
+
text-align: center;
|
107 |
+
vertical-align: middle;
|
108 |
+
-webkit-user-select: none;
|
109 |
+
-moz-user-select: none;
|
110 |
+
-ms-user-select: none;
|
111 |
+
user-select: none;
|
112 |
+
background-color: transparent;
|
113 |
+
border: 1px solid transparent;
|
114 |
+
padding: 0.375rem 0.75rem;
|
115 |
+
font-size: 1rem;
|
116 |
+
line-height: 1.5;
|
117 |
+
border-radius: 0.25rem;
|
118 |
+
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;
|
119 |
+
}
|
120 |
+
|
121 |
+
.btn-primary {
|
122 |
+
color: #fff;
|
123 |
+
background-color: #007bff;
|
124 |
+
border-color: #007bff;
|
125 |
+
}
|
126 |
+
|
127 |
+
.btn-secondary {
|
128 |
+
color: #fff;
|
129 |
+
background-color: #6c757d;
|
130 |
+
border-color: #6c757d;
|
131 |
+
}
|
132 |
+
|
133 |
+
.btn-success {
|
134 |
+
color: #fff;
|
135 |
+
background-color: #28a745;
|
136 |
+
border-color: #28a745;
|
137 |
+
}
|
138 |
+
|
139 |
+
.btn-info {
|
140 |
+
color: #fff;
|
141 |
+
background-color: #17a2b8;
|
142 |
+
border-color: #17a2b8;
|
143 |
+
}
|
144 |
+
|
145 |
+
.btn-warning {
|
146 |
+
color: #212529;
|
147 |
+
background-color: #ffc107;
|
148 |
+
border-color: #ffc107;
|
149 |
+
}
|
150 |
+
|
151 |
+
.btn-danger {
|
152 |
+
color: #fff;
|
153 |
+
background-color: #dc3545;
|
154 |
+
border-color: #dc3545;
|
155 |
+
}
|
156 |
+
|
157 |
+
.btn-light {
|
158 |
+
color: #212529;
|
159 |
+
background-color: #f8f9fa;
|
160 |
+
border-color: #f8f9fa;
|
161 |
+
}
|
162 |
+
|
163 |
+
.btn-dark {
|
164 |
+
color: #fff;
|
165 |
+
background-color: #343a40;
|
166 |
+
border-color: #343a40;
|
167 |
+
}
|
modules/m_parser.py
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import subprocess
|
2 |
+
import spacy
|
3 |
+
import pyinflect
|
4 |
+
from typing import Tuple, Union
|
5 |
+
|
6 |
+
class Parser:
|
7 |
+
def __init__(
|
8 |
+
self
|
9 |
+
) -> None:
|
10 |
+
|
11 |
+
self.parser = self.__init_parser("en_core_web_md")
|
12 |
+
|
13 |
+
def __init_parser(
|
14 |
+
self,
|
15 |
+
model: str
|
16 |
+
) -> spacy.language:
|
17 |
+
|
18 |
+
parser = None
|
19 |
+
try:
|
20 |
+
parser = spacy.load(model)
|
21 |
+
except:
|
22 |
+
print(f"* Downloading {model} model...")
|
23 |
+
_ = subprocess.Popen(
|
24 |
+
f"python -m spacy download {model}",
|
25 |
+
stdout=subprocess.PIPE,
|
26 |
+
shell=True
|
27 |
+
).communicate()
|
28 |
+
|
29 |
+
parser = spacy.load(model)
|
30 |
+
|
31 |
+
return parser
|
32 |
+
|
33 |
+
def __v2participle(
|
34 |
+
self,
|
35 |
+
tk_verb: spacy.tokens.token.Token
|
36 |
+
) -> Union[str, None]:
|
37 |
+
|
38 |
+
return tk_verb._.inflect('VBN')
|
39 |
+
|
40 |
+
def __v2past(
|
41 |
+
self,
|
42 |
+
tk_verb: spacy.tokens.token.Token
|
43 |
+
) -> Union[str, None]:
|
44 |
+
|
45 |
+
return tk_verb._.inflect('VBD')
|
46 |
+
|
47 |
+
def __v2infinitive(
|
48 |
+
self,
|
49 |
+
tk_verb: spacy.tokens.token.Token
|
50 |
+
) -> Union[str, None]:
|
51 |
+
|
52 |
+
return tk_verb._.inflect('VB')
|
53 |
+
|
54 |
+
def __tokenizer(
|
55 |
+
self,
|
56 |
+
verb: str
|
57 |
+
) -> spacy.tokens.token.Token:
|
58 |
+
|
59 |
+
return self.parser(verb)[0]
|
60 |
+
|
61 |
+
def ___format_error(
|
62 |
+
self,
|
63 |
+
error: str
|
64 |
+
) -> str:
|
65 |
+
|
66 |
+
template = """
|
67 |
+
<center>
|
68 |
+
<div class="alert alert-warning" role="alert">
|
69 |
+
<h6><b>{}</b></h6>
|
70 |
+
</div>
|
71 |
+
</center>
|
72 |
+
"""
|
73 |
+
return template.format(error)
|
74 |
+
|
75 |
+
def get_verbs(
|
76 |
+
self,
|
77 |
+
verb: str
|
78 |
+
) -> Tuple[str,str,str]:
|
79 |
+
|
80 |
+
verb = verb.strip().lower()
|
81 |
+
error, infinitive, past, participle = "", "", "", ""
|
82 |
+
|
83 |
+
if verb == "":
|
84 |
+
error = self.___format_error(
|
85 |
+
f"Error: The Verb field can not be empty!"
|
86 |
+
)
|
87 |
+
return error, infinitive, past, participle
|
88 |
+
|
89 |
+
tk_verb = self.__tokenizer(verb)
|
90 |
+
infinitive = self.__v2infinitive(tk_verb)
|
91 |
+
past = self.__v2past(tk_verb)
|
92 |
+
participle = self.__v2participle(tk_verb)
|
93 |
+
|
94 |
+
if infinitive is None or past is None or participle is None:
|
95 |
+
error = self.___format_error(
|
96 |
+
f"Error: The verb '<b>{verb}</b>' has not been found or not spelled correctly!"
|
97 |
+
)
|
98 |
+
return error, infinitive, past, participle
|
99 |
+
|
100 |
+
return error, infinitive, past, participle
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
pyinflect
|
2 |
+
spacy
|