Skip to content

Commit 94a3896

Browse files
committed
add import typing clause
1 parent 8a79105 commit 94a3896

File tree

1 file changed

+51
-23
lines changed

1 file changed

+51
-23
lines changed

jupyterlab_leetcode/utils/notebook_generator.py

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import re
44
import sys
5+
import typing
56

67
from .utils import first
78

@@ -17,10 +18,18 @@ def __init__(self):
1718
os.path.dirname(os.path.realpath(__file__)),
1819
"notebook.template.json",
1920
)
20-
2121
with open(template_path, "rt") as f:
2222
self.template = json.load(f)
2323

24+
self.typing_regex = re.compile(
25+
"|".join(
26+
# '|' is matched by order
27+
sorted(
28+
filter(lambda t: t[0].isupper(), dir(typing)), key=len, reverse=True
29+
)
30+
)
31+
)
32+
2433
def __populate_metadata(self, q):
2534
self.template["metadata"]["language_info"]["version"] = "{}.{}.{}".format(
2635
*sys.version_info[:3]
@@ -84,7 +93,13 @@ def __populate_test(self, q):
8493
if not test_cell:
8594
return
8695

96+
# TODO: parse test case
8797
test_cell["source"] = ["#### Sample Test Case\n", q["sampleTestCase"]]
98+
test_cell["metadata"]["exampleTestcaseList"] = q["exampleTestcaseList"]
99+
100+
def __extract_type(self, code) -> list[str]:
101+
_, args = self.__parse_code(code)
102+
return self.typing_regex.findall(args)
88103

89104
def __populate_code(self, q):
90105
code_cell = first(
@@ -99,43 +114,56 @@ def __populate_code(self, q):
99114

100115
snippet = code_snippet["code"]
101116
pre_solution_index = snippet.find("class Solution:")
102-
pre_solution = None
103-
if pre_solution_index > 0:
104-
pre_solution = snippet[:pre_solution_index]
105-
snippet = snippet[pre_solution_index:]
117+
pre_solution = snippet[:pre_solution_index]
118+
snippet = snippet[pre_solution_index:]
106119
code_cell["source"] = [snippet + "pass"]
107120
code_cell["metadata"]["isSolutionCode"] = True
108121

109-
if pre_solution:
110-
code_cell_index = first(
111-
enumerate(self.template["cells"]),
112-
lambda ic: ic[1]["metadata"]["id"] == "code",
122+
types = self.__extract_type(snippet)
123+
typing_import = f"from typing import {' '.join(set(types))}" if types else None
124+
source = list(filter(None, [typing_import, pre_solution.strip(" \n")]))
125+
if source:
126+
pre_code_cell = first(
127+
self.template["cells"], lambda c: c["metadata"]["id"] == "pre_code"
113128
)
114-
if code_cell_index is not None:
115-
self.template["cells"].insert(
116-
code_cell_index[0],
117-
{
118-
"cell_type": "code",
119-
"execution_count": None,
120-
"metadata": {"id": "pre_code"},
121-
"outputs": [],
122-
"source": [pre_solution.strip(" \n")],
123-
},
129+
if pre_code_cell:
130+
pre_code_cell["source"] = source
131+
else:
132+
code_cell_index = first(
133+
enumerate(self.template["cells"]),
134+
lambda ic: ic[1]["metadata"]["id"] == "code",
124135
)
136+
if code_cell_index is not None:
137+
self.template["cells"].insert(
138+
code_cell_index[0],
139+
{
140+
"cell_type": "code",
141+
"execution_count": None,
142+
"metadata": {"id": "pre_code"},
143+
"outputs": [],
144+
"source": source,
145+
},
146+
)
125147

126148
return snippet
127149

150+
def __parse_code(self, code) -> tuple[str, str]:
151+
match = re.search(r"class Solution:\s+def (.*?)\(self,(.*)", code)
152+
if not match:
153+
return ("", "")
154+
return (match[1], match[2])
155+
128156
def __populate_run(self, snippet):
129157
run_cell = first(self.template["cells"], lambda c: c["metadata"]["id"] == "run")
130158
if not run_cell:
131159
return
132160

133-
func_match = re.search(r"class Solution:\s+def (.*?)\(self,", snippet)
134-
if not func_match:
161+
# TODO: fill in test case
162+
func_name, _ = self.__parse_code(snippet)
163+
if not func_name:
135164
return
136-
137-
func_name = func_match[1]
138165
run_cell["source"] = [f"Solution().{func_name}()"]
166+
# TODO: multiple test case run
139167

140168
def __dump(self, q):
141169
qid = q["questionFrontendId"]

0 commit comments

Comments
 (0)