2
2
import os
3
3
import re
4
4
import sys
5
+ import typing
5
6
6
7
from .utils import first
7
8
@@ -17,10 +18,18 @@ def __init__(self):
17
18
os .path .dirname (os .path .realpath (__file__ )),
18
19
"notebook.template.json" ,
19
20
)
20
-
21
21
with open (template_path , "rt" ) as f :
22
22
self .template = json .load (f )
23
23
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
+
24
33
def __populate_metadata (self , q ):
25
34
self .template ["metadata" ]["language_info" ]["version" ] = "{}.{}.{}" .format (
26
35
* sys .version_info [:3 ]
@@ -84,7 +93,13 @@ def __populate_test(self, q):
84
93
if not test_cell :
85
94
return
86
95
96
+ # TODO: parse test case
87
97
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 )
88
103
89
104
def __populate_code (self , q ):
90
105
code_cell = first (
@@ -99,43 +114,56 @@ def __populate_code(self, q):
99
114
100
115
snippet = code_snippet ["code" ]
101
116
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 :]
106
119
code_cell ["source" ] = [snippet + "pass" ]
107
120
code_cell ["metadata" ]["isSolutionCode" ] = True
108
121
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"
113
128
)
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" ,
124
135
)
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
+ )
125
147
126
148
return snippet
127
149
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
+
128
156
def __populate_run (self , snippet ):
129
157
run_cell = first (self .template ["cells" ], lambda c : c ["metadata" ]["id" ] == "run" )
130
158
if not run_cell :
131
159
return
132
160
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 :
135
164
return
136
-
137
- func_name = func_match [1 ]
138
165
run_cell ["source" ] = [f"Solution().{ func_name } ()" ]
166
+ # TODO: multiple test case run
139
167
140
168
def __dump (self , q ):
141
169
qid = q ["questionFrontendId" ]
0 commit comments