22import os
33import re
44import sys
5+ import typing
56
67from .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