AtCoderStudyBooster 0.3__py3-none-any.whl → 0.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
atcdr/generate.py CHANGED
@@ -140,8 +140,8 @@ def solve_problem(file: Filename, lang: Lang) -> None:
140
140
 
141
141
  for i in range(1, 4):
142
142
  with console.status(f'{i}回目のコード生成 (by {gpt.model.value})...'):
143
- test_report = ''
144
143
  if i == 1:
144
+ test_report = ''
145
145
  reply = gpt.tell(md)
146
146
  else:
147
147
  reply = gpt.tell(f"""The following is the test report for the code you provided:
atcdr/test.py CHANGED
@@ -2,28 +2,19 @@ import os
2
2
  import subprocess
3
3
  import tempfile
4
4
  import time
5
- from dataclasses import dataclass, field
5
+ from dataclasses import dataclass
6
6
  from enum import Enum
7
- from typing import Dict, Generator, List, Tuple, Union, Optional
7
+ from typing import Callable, Dict, List, Optional, Union
8
8
 
9
9
  from bs4 import BeautifulSoup as bs
10
- from rich.console import Console, Group, RenderableType
10
+ from rich.console import Console
11
11
  from rich.markup import escape
12
12
  from rich.panel import Panel
13
- from rich.rule import Rule
14
- from rich.style import Style
15
- from rich.syntax import Syntax
16
13
  from rich.table import Table
17
14
  from rich.text import Text
18
15
 
19
16
  from atcdr.util.execute import execute_files
20
- from atcdr.util.filetype import (
21
- COMPILED_LANGUAGES,
22
- INTERPRETED_LANGUAGES,
23
- Lang,
24
- detect_language,
25
- lang2str,
26
- )
17
+ from atcdr.util.filetype import FILE_EXTENSIONS, SOURCE_LANGUAGES, Lang
27
18
 
28
19
 
29
20
  @dataclass
@@ -39,13 +30,12 @@ class LabeledTestCase:
39
30
 
40
31
 
41
32
  class ResultStatus(Enum):
42
- AC = 'Accepted'
43
- WA = 'Wrong Answer'
44
- TLE = 'Time Limit Exceeded'
33
+ CE = 'Compilation Error'
45
34
  MLE = 'Memory Limit Exceeded'
35
+ TLE = 'Time Limit Exceeded'
46
36
  RE = 'Runtime Error'
47
- CE = 'Compilation Error'
48
- WJ = 'Juding ...'
37
+ WA = 'Wrong Answer'
38
+ AC = 'Accepted'
49
39
 
50
40
 
51
41
  @dataclass
@@ -60,20 +50,10 @@ class TestCaseResult:
60
50
  class LabeledTestCaseResult:
61
51
  label: str
62
52
  testcase: TestCase
53
+ # TODO : 実はラベル自体を使わない方がいいかもしれない.ラベルという概念が削除してプリントするときに適当にTest1, Test2と適当に名前をつけてもいいかも.
63
54
  result: TestCaseResult
64
55
 
65
56
 
66
- @dataclass
67
- class TestInformation:
68
- lang: Lang
69
- sourcename: str
70
- case_number: int
71
- result_summary: ResultStatus = ResultStatus.WJ
72
- resultlist: List[LabeledTestCaseResult] = field(default_factory=list) # 修正
73
- compiler_message: str = ''
74
- compile_time : Optional[int] = None
75
-
76
-
77
57
  def create_testcases_from_html(html: str) -> List[LabeledTestCase]:
78
58
  soup = bs(html, 'html.parser')
79
59
  test_cases = []
@@ -106,312 +86,192 @@ def create_testcases_from_html(html: str) -> List[LabeledTestCase]:
106
86
 
107
87
 
108
88
  def run_code(cmd: list, case: TestCase) -> TestCaseResult:
109
- start_time = time.time()
110
89
  try:
90
+ start_time = time.time()
111
91
  proc = subprocess.run(
112
92
  cmd, input=case.input, text=True, capture_output=True, timeout=4
113
93
  )
114
- executed_time = int((time.time() - start_time) * 1000)
115
- except subprocess.TimeoutExpired as e_proc:
116
- executed_time = int((time.time() - start_time) * 1000)
117
- stdout_text = e_proc.stdout.decode('utf-8') if e_proc.stdout is not None else ''
118
- stderr_text = e_proc.stderr.decode('utf-8') if e_proc.stderr is not None else ''
119
- text = stdout_text + '\n' + stderr_text
120
- return TestCaseResult(
121
- output=text, executed_time=executed_time, passed=ResultStatus.TLE
122
- )
94
+ end_time = time.time()
123
95
 
124
- # プロセスの終了コードを確認し、異常終了ならREを返す
125
- if proc.returncode != 0:
126
- return TestCaseResult(
127
- output=proc.stdout + '\n' + proc.stderr,
128
- executed_time=executed_time,
129
- passed=ResultStatus.RE,
130
- )
96
+ execution_time = int((end_time - start_time) * 1000)
97
+
98
+ if proc.returncode != 0:
99
+ return TestCaseResult(
100
+ output=proc.stderr, executed_time=None, passed=ResultStatus.RE
101
+ )
131
102
 
132
- # 実際の出力と期待される出力を比較
133
- actual_output = proc.stdout.strip()
134
- expected_output = case.output.strip()
103
+ actual_output = proc.stdout.strip()
104
+ expected_output = case.output.strip()
105
+
106
+ if actual_output != expected_output:
107
+ return TestCaseResult(
108
+ output=actual_output,
109
+ executed_time=execution_time,
110
+ passed=ResultStatus.WA,
111
+ )
135
112
 
136
- if actual_output != expected_output:
137
113
  return TestCaseResult(
138
- output=actual_output,
139
- executed_time=executed_time,
140
- passed=ResultStatus.WA,
114
+ output=actual_output, executed_time=execution_time, passed=ResultStatus.AC
141
115
  )
142
- else:
116
+ except subprocess.TimeoutExpired:
143
117
  return TestCaseResult(
144
- output=actual_output, executed_time=executed_time, passed=ResultStatus.AC
118
+ output='Time Limit Exceeded', executed_time=None, passed=ResultStatus.TLE
145
119
  )
120
+ except Exception as e:
121
+ return TestCaseResult(output=str(e), executed_time=None, passed=ResultStatus.RE)
146
122
 
147
123
 
148
- LANGUAGE_RUN_COMMANDS: Dict[Lang, list] = {
149
- Lang.PYTHON: ['python3', '{source_path}'],
150
- Lang.JAVASCRIPT: ['node', '{source_path}'],
151
- Lang.C: ['{exec_path}'],
152
- Lang.CPP: ['{exec_path}'],
153
- Lang.RUST: ['{exec_path}'],
154
- Lang.JAVA: ['java', '{exec_path}'],
155
- }
124
+ def run_python(path: str, case: TestCase) -> TestCaseResult:
125
+ return run_code(['python3', path], case)
156
126
 
157
- LANGUAGE_COMPILE_COMMANDS: Dict[Lang, list] = {
158
- Lang.C: ['gcc', '{source_path}', '-o', '{exec_path}'],
159
- Lang.CPP: ['g++', '{source_path}', '-o', '{exec_path}'],
160
- Lang.RUST: ['rustc', '{source_path}', '-o', '{exec_path}'],
161
- Lang.JAVA: ['javac', '{source_path}'],
162
- }
127
+
128
+ def run_javascript(path: str, case: TestCase) -> TestCaseResult:
129
+ return run_code(['node', path], case)
163
130
 
164
131
 
165
- def run_compile(path: str, lang: Lang) -> Tuple[str, subprocess.CompletedProcess]:
132
+ def run_c(path: str, case: TestCase) -> TestCaseResult:
166
133
  with tempfile.NamedTemporaryFile(delete=True) as tmp:
167
134
  exec_path = tmp.name
168
- cmd = [
169
- arg.format(source_path=path, exec_path=exec_path)
170
- for arg in LANGUAGE_COMPILE_COMMANDS[lang]
171
- ]
172
- start_time = time.time()
173
- compile_result = subprocess.run(cmd, capture_output=True, text=True)
174
- compile_time = int((time.time() - start_time) * 1000)
175
-
176
- return exec_path, compile_result, compile_time
177
-
178
-
179
- def judge_code_from(
180
- lcases: List[LabeledTestCase], path: str
181
- ) -> Generator[
182
- Union[LabeledTestCaseResult, TestInformation], # type: ignore
183
- None,
184
- None,
185
- ]:
186
- lang = detect_language(path)
187
- if lang in COMPILED_LANGUAGES:
188
- exe_path, compile_result, compile_time = run_compile(path, lang)
135
+ compile_result = subprocess.run(
136
+ ['gcc', path, '-o', exec_path], capture_output=True, text=True
137
+ )
189
138
  if compile_result.returncode != 0:
190
- yield TestInformation(
191
- lang=lang,
192
- sourcename=path,
193
- case_number=len(lcases),
194
- result_summary=ResultStatus.CE,
195
- compiler_message=compile_result.stderr,
196
- )
197
- return
198
- else:
199
- yield TestInformation(
200
- lang=lang,
201
- sourcename=path,
202
- case_number=len(lcases),
203
- compiler_message=compile_result.stderr,
204
- compile_time=compile_time,
139
+ return TestCaseResult(
140
+ output=compile_result.stderr, executed_time=None, passed=ResultStatus.CE
205
141
  )
142
+ return run_code([exec_path], case)
206
143
 
207
- cmd = [
208
- arg.format(exec_path=exe_path) for arg in LANGUAGE_RUN_COMMANDS[lang]
209
- ]
210
-
211
- for lcase in lcases:
212
- yield LabeledTestCaseResult(
213
- lcase.label, lcase.case, run_code(cmd, lcase.case)
214
- )
215
-
216
- if os.path.exists(exe_path):
217
- os.remove(exe_path)
218
144
 
219
- elif lang in INTERPRETED_LANGUAGES:
220
- yield TestInformation(
221
- lang=lang,
222
- sourcename=path,
223
- case_number=len(lcases),
145
+ def run_cpp(path: str, case: TestCase) -> TestCaseResult:
146
+ with tempfile.NamedTemporaryFile(delete=True) as tmp:
147
+ exec_path = tmp.name
148
+ compile_result = subprocess.run(
149
+ ['g++', path, '-o', exec_path], capture_output=True, text=True
224
150
  )
225
- cmd = [arg.format(source_path=path) for arg in LANGUAGE_RUN_COMMANDS[lang]]
226
- for lcase in lcases:
227
- yield LabeledTestCaseResult(
228
- lcase.label, lcase.case, run_code(cmd, lcase.case)
151
+ if compile_result.returncode != 0:
152
+ return TestCaseResult(
153
+ output=compile_result.stderr, executed_time=None, passed=ResultStatus.CE
229
154
  )
230
- else:
231
- raise ValueError('適切な言語が見つかりませんでした.')
232
-
233
-
234
- COLOR_MAP = {
235
- ResultStatus.AC: 'green',
236
- ResultStatus.WA: 'red',
237
- ResultStatus.TLE: 'yellow',
238
- ResultStatus.MLE: 'yellow',
239
- ResultStatus.RE: 'yellow',
240
- ResultStatus.CE: 'yellow',
241
- ResultStatus.WJ: 'grey',
242
- }
243
-
244
- STATUS_TEXT_MAP = {
245
- ResultStatus.AC: Text.assemble(
246
- ('\u2713 ', 'green'),
247
- (
248
- f'{ResultStatus.AC.value}',
249
- Style(bgcolor=COLOR_MAP[ResultStatus.AC], bold=True),
250
- ),
251
- ),
252
- ResultStatus.WA: Text(
253
- f'\u00d7 {ResultStatus.WA.value}', style=COLOR_MAP[ResultStatus.WA]
254
- ),
255
- ResultStatus.TLE: Text(
256
- f'\u00d7 {ResultStatus.TLE.value}', style=COLOR_MAP[ResultStatus.TLE]
257
- ),
258
- ResultStatus.MLE: Text(
259
- f'\u00d7 {ResultStatus.MLE.value}', style=COLOR_MAP[ResultStatus.MLE]
260
- ),
261
- ResultStatus.RE: Text(
262
- f'\u00d7 {ResultStatus.RE.value}', style=COLOR_MAP[ResultStatus.RE]
263
- ),
264
- ResultStatus.CE: Text(
265
- f'\u00d7 {ResultStatus.CE.value}', style=COLOR_MAP[ResultStatus.CE]
266
- ),
267
- ResultStatus.WJ: Text(
268
- f'\u23f3 {ResultStatus.WJ.value}', style=COLOR_MAP[ResultStatus.WJ]
269
- ),
270
- }
271
-
272
-
273
- def create_renderable_test_info(test_info: TestInformation) -> RenderableType:
274
- components = []
155
+ return run_code([exec_path], case)
275
156
 
276
- success_count = sum(
277
- 1 for result in test_info.resultlist if result.result.passed == ResultStatus.AC
278
- )
279
- total_count = test_info.case_number
280
-
281
- # 結果に応じたスタイル付きのテキストを取得
282
- status_text = STATUS_TEXT_MAP[test_info.result_summary]
283
157
 
284
- # ヘッダーのテキストを構築
285
- header_text = Text.assemble(
286
- Text.from_markup(f'[cyan]{test_info.sourcename}[/]のテスト [\n]'),
287
- Text.from_markup(f'[gray]コンパイルにかかった時間: [italic]{test_info.compile_time} ms[/][/][\n]') if test_info.compile_time else Text(''),
288
- status_text,
289
- Text.from_markup(
290
- f' [{COLOR_MAP[test_info.result_summary]} bold]{success_count}[/] / [white bold]{total_count}[/]'
291
- ),
292
- )
293
-
294
- components.append(Panel(header_text, expand=False))
295
-
296
- if test_info.compiler_message:
297
- rule = Rule(
298
- title='コンパイラーのメッセージ',
299
- style=COLOR_MAP[ResultStatus.CE],
300
- )
301
- components.append(rule)
302
- error_message = Syntax(
303
- test_info.compiler_message, lang2str(test_info.lang), line_numbers=False
158
+ def run_rust(path: str, case: TestCase) -> TestCaseResult:
159
+ with tempfile.NamedTemporaryFile(delete=True) as tmp:
160
+ exec_path = tmp.name
161
+ compile_result = subprocess.run(
162
+ ['rustc', path, '-o', exec_path], capture_output=True, text=True
304
163
  )
305
- components.append(error_message)
306
-
307
- return Group(*components)
308
-
164
+ if compile_result.returncode != 0:
165
+ return TestCaseResult(
166
+ output=compile_result.stderr, executed_time=None, passed=ResultStatus.CE
167
+ )
168
+ return run_code([exec_path], case)
309
169
 
310
- def update_test_info(
311
- test_info: TestInformation, test_result: LabeledTestCaseResult
312
- ) -> None:
313
- test_info.resultlist.append(test_result)
314
170
 
315
- priority_order = [
316
- ResultStatus.RE,
317
- ResultStatus.WA,
318
- ResultStatus.TLE,
319
- ResultStatus.MLE,
320
- ResultStatus.WJ,
321
- ResultStatus.AC,
322
- ]
171
+ def run_java(path: str, case: TestCase) -> TestCaseResult:
172
+ compile_result = subprocess.run(['javac', path], capture_output=True, text=True)
173
+ if compile_result.returncode != 0:
174
+ return TestCaseResult(
175
+ output=compile_result.stderr, executed_time=None, passed=ResultStatus.CE
176
+ )
177
+ class_file = os.path.splitext(path)[0]
178
+ try:
179
+ return run_code(['java', class_file], case)
180
+ finally:
181
+ class_path = class_file + '.class'
182
+ if os.path.exists(class_path):
183
+ os.remove(class_path)
184
+
185
+
186
+ LANGUAGE_RUNNERS: Dict[Lang, Callable[[str, TestCase], TestCaseResult]] = {
187
+ Lang.PYTHON: run_python,
188
+ Lang.JAVASCRIPT: run_javascript,
189
+ Lang.C: run_c,
190
+ Lang.CPP: run_cpp,
191
+ Lang.RUST: run_rust,
192
+ Lang.JAVA: run_java,
193
+ }
323
194
 
324
- # 現在の結果の中で最も高い優先順位のステータスを見つける
325
- highest_priority_status = (
326
- test_info.result_summary
327
- ) # デフォルトはWJまたは現在のサマリー
328
- for result in test_info.resultlist:
329
- status = result.result.passed
330
- if priority_order.index(status) < priority_order.index(highest_priority_status):
331
- highest_priority_status = status
332
-
333
- # 特殊ケース: すべてのテストケースがACである場合(途中でも)
334
- if all(result.result.passed == ResultStatus.AC for result in test_info.resultlist):
335
- test_info.result_summary = ResultStatus.AC
336
- else:
337
- test_info.result_summary = highest_priority_status
338
-
339
-
340
- def create_renderable_test_result(
341
- i: int,
342
- test_result: LabeledTestCaseResult,
343
- ) -> RenderableType:
344
- rule = Rule(
345
- title=f'No.{i+1} {test_result.label}',
346
- style=COLOR_MAP[test_result.result.passed],
347
- )
348
195
 
349
- # 以下の部分は if-else ブロックの外に移動
350
- status_header = Text.assemble(
351
- 'ステータス ',
352
- STATUS_TEXT_MAP[test_result.result.passed], # status_text をここに追加
196
+ def choose_lang(path: str) -> Optional[Callable[[str, TestCase], TestCaseResult]]:
197
+ ext = os.path.splitext(path)[1]
198
+ lang = next(
199
+ (lang for lang, extension in FILE_EXTENSIONS.items() if extension == ext), None
353
200
  )
201
+ # lang が None でない場合のみ get を呼び出す
202
+ if lang is not None:
203
+ return LANGUAGE_RUNNERS.get(lang)
204
+ return None
354
205
 
355
- execution_time_text = None
356
- if test_result.result.executed_time is not None:
357
- execution_time_text = Text.from_markup(
358
- f'実行時間 [cyan]{test_result.result.executed_time}[/cyan] ms'
359
- )
360
206
 
361
- table = Table(show_header=True, header_style='bold')
362
- table.add_column('入力', style='cyan', min_width=10)
363
-
364
- if test_result.result.passed != ResultStatus.AC:
365
- table.add_column(
366
- '出力', style=COLOR_MAP[test_result.result.passed], min_width=10
367
- )
368
- table.add_column('正解の出力', style=COLOR_MAP[ResultStatus.AC], min_width=10)
369
- table.add_row(
370
- escape(test_result.testcase.input),
371
- escape(test_result.result.output),
372
- escape(test_result.testcase.output),
373
- )
374
- else:
375
- table.add_column(
376
- '出力', style=COLOR_MAP[test_result.result.passed], min_width=10
377
- )
378
- table.add_row(
379
- escape(test_result.testcase.input), escape(test_result.result.output)
380
- )
381
-
382
- components = [
383
- rule,
384
- status_header,
385
- execution_time_text if execution_time_text else '',
386
- table,
207
+ def judge_code_from(
208
+ lcases: List[LabeledTestCase], path: str
209
+ ) -> List[LabeledTestCaseResult]:
210
+ runner = choose_lang(path)
211
+ if runner is None:
212
+ raise ValueError(f'ランナーが見つかりませんでした。指定されたパス: {path}')
213
+
214
+ return [
215
+ LabeledTestCaseResult(lcase.label, lcase.case, runner(path, lcase.case))
216
+ for lcase in lcases
387
217
  ]
388
218
 
389
- return Group(*components)
390
219
 
220
+ class CustomFormatStyle(Enum):
221
+ SUCCESS = 'green'
222
+ FAILURE = 'red'
223
+ WARNING = 'yellow'
224
+ INFO = 'blue'
391
225
 
392
- def render_results(
393
- results: Generator[Union[LabeledTestCaseResult, TestInformation], None, None],
394
- ) -> None:
395
- console = Console()
396
226
 
397
- # 最初の結果は TestInformation として取得
398
- first_result = next(results)
399
- if not isinstance(first_result, TestInformation):
400
- raise ValueError('最初のジェネレーターの結果はTestInformationです')
401
- test_info: TestInformation = first_result
227
+ def render_results(path: str, results: List[LabeledTestCaseResult]) -> None:
228
+ console = Console()
229
+ success_count = sum(
230
+ 1 for result in results if result.result.passed == ResultStatus.AC
231
+ )
232
+ total_count = len(results)
402
233
 
403
- curernt_display_object = [test_info]
234
+ # ヘッダー
235
+ header_text = Text.assemble(
236
+ f'{path}のテスト ',
237
+ (
238
+ f'{success_count}/{total_count} ',
239
+ 'green' if success_count == total_count else 'red',
240
+ ),
241
+ )
242
+ console.print(Panel(header_text, expand=False))
404
243
 
405
- while True :
244
+ CHECK_MARK = '\u2713'
245
+ CROSS_MARK = '\u00d7'
406
246
  # 各テストケースの結果表示
407
247
  for i, result in enumerate(results):
408
- if isinstance(result, LabeledTestCaseResult):
409
- console.print(create_renderable_test_result(i, result))
410
- update_test_info(test_info, result)
411
- else:
412
- raise ValueError('テスト結果がyieldする型はLabeledTestCaseResultです')
248
+ if result.result.passed == ResultStatus.AC:
249
+ status_text = f'[green]{CHECK_MARK}[/] [white on green]{result.result.passed.value}[/]'
250
+ console.rule(title=f'No.{i+1} {result.label}', style='green')
251
+ console.print(f'[bold]ステータス:[/] {status_text}')
413
252
 
414
- console.print(create_renderable_test_info(test_info))
253
+ else:
254
+ status_text = f'[red]{CROSS_MARK} {result.result.passed.value}[/]'
255
+ console.rule(title=f'No.{i+1} {result.label}', style='red')
256
+ console.print(f'[bold]ステータス:[/] {status_text}')
257
+
258
+ if result.result.executed_time is not None:
259
+ console.print(f'[bold]実行時間:[/] {result.result.executed_time} ms')
260
+
261
+ table = Table(show_header=True, header_style='bold')
262
+ table.add_column('入力', style='cyan', min_width=10)
263
+ if result.result.passed != ResultStatus.AC:
264
+ table.add_column('出力', style='red', min_width=10)
265
+ table.add_column('正解の出力', style='green', min_width=10)
266
+ table.add_row(
267
+ escape(result.testcase.input),
268
+ escape(result.result.output),
269
+ escape(result.testcase.output),
270
+ )
271
+ else:
272
+ table.add_column('出力', style='green', min_width=10)
273
+ table.add_row(escape(result.testcase.input), escape(result.result.output))
274
+ console.print(table)
415
275
 
416
276
 
417
277
  def run_test(path_of_code: str) -> None:
@@ -427,12 +287,8 @@ def run_test(path_of_code: str) -> None:
427
287
 
428
288
  test_cases = create_testcases_from_html(html)
429
289
  test_results = judge_code_from(test_cases, path_of_code)
430
- render_results(test_results)
290
+ render_results(path_of_code, test_results)
431
291
 
432
292
 
433
293
  def test(*args: str) -> None:
434
- execute_files(
435
- *args,
436
- func=run_test,
437
- target_filetypes=INTERPRETED_LANGUAGES + COMPILED_LANGUAGES,
438
- )
294
+ execute_files(*args, func=run_test, target_filetypes=SOURCE_LANGUAGES)
atcdr/util/filetype.py CHANGED
@@ -1,6 +1,5 @@
1
- import os
2
1
  from enum import Enum
3
- from typing import Dict, List, Optional, TypeAlias
2
+ from typing import Dict, List, TypeAlias
4
3
 
5
4
  # ファイル名と拡張子の型エイリアスを定義
6
5
  Filename: TypeAlias = str
@@ -24,7 +23,7 @@ class Lang(Enum):
24
23
 
25
24
 
26
25
  # ファイル拡張子と対応する言語の辞書
27
- FILE_EXTENSIONS: Dict[Lang, str] = {
26
+ FILE_EXTENSIONS: Dict[Lang, Extension] = {
28
27
  Lang.PYTHON: '.py',
29
28
  Lang.JAVASCRIPT: '.js',
30
29
  Lang.JAVA: '.java',
@@ -40,29 +39,24 @@ FILE_EXTENSIONS: Dict[Lang, str] = {
40
39
  Lang.JSON: '.json',
41
40
  }
42
41
 
43
- # ドキュメント言語のリスト
44
42
  DOCUMENT_LANGUAGES: List[Lang] = [
45
43
  Lang.HTML,
46
44
  Lang.MARKDOWN,
47
45
  Lang.JSON,
48
46
  ]
49
47
 
50
- # コンパイル型言語のリスト
51
- COMPILED_LANGUAGES: List[Lang] = [
48
+ # ソースコードファイルと言語のリスト
49
+ SOURCE_LANGUAGES: List[Lang] = [
50
+ Lang.PYTHON,
51
+ Lang.JAVASCRIPT,
52
52
  Lang.JAVA,
53
53
  Lang.C,
54
54
  Lang.CPP,
55
55
  Lang.CSHARP,
56
- Lang.GO,
57
- Lang.RUST,
58
- ]
59
-
60
- # インタプリター型言語のリスト
61
- INTERPRETED_LANGUAGES: List[Lang] = [
62
- Lang.PYTHON,
63
- Lang.JAVASCRIPT,
64
56
  Lang.RUBY,
65
57
  Lang.PHP,
58
+ Lang.GO,
59
+ Lang.RUST,
66
60
  ]
67
61
 
68
62
 
@@ -95,11 +89,3 @@ def str2lang(lang: str) -> Lang:
95
89
 
96
90
  def lang2str(lang: Lang) -> str:
97
91
  return lang.value
98
-
99
-
100
- def detect_language(path: str) -> Optional[Lang]:
101
- ext = os.path.splitext(path)[1] # ファイルの拡張子を取得
102
- lang = next(
103
- (lang for lang, extension in FILE_EXTENSIONS.items() if extension == ext), None
104
- )
105
- return lang
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: AtCoderStudyBooster
3
- Version: 0.3
3
+ Version: 0.23
4
4
  Summary: A tool to download and manage AtCoder problems.
5
5
  Project-URL: Homepage, https://github.com/yuta6/AtCoderStudyBooster
6
6
  Author-email: yuta6 <46110512+yuta6@users.noreply.github.com>
@@ -1,17 +1,17 @@
1
1
  atcdr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  atcdr/download.py,sha256=aqJEmrLop_Mj8GNJjoWRcSzWU0z9iNc9vtZOjhWXx3U,8945
3
- atcdr/generate.py,sha256=0yWX-5PS-FR6LTaP3muHq6a7rFB2a1Oek48mF45exoA,6972
3
+ atcdr/generate.py,sha256=MKoip-0jTEkMH0hEusgJgtfQB9QCSiiZ2jlU_ccmB8E,6973
4
4
  atcdr/main.py,sha256=y2IkXwcAyKZ_1y5PgU93GpXzo5lKak9oxo0XV_9d5Fo,727
5
5
  atcdr/markdown.py,sha256=jEktnYgrDYcgIuhxRpJImAzNpFmfSPkRikAesfMxAVk,1125
6
6
  atcdr/open.py,sha256=2UlmNWdieoMrPu1xSUWf-8sBB9Y19r0t6V9zDRBSPes,924
7
- atcdr/test.py,sha256=eNHEv_y2tNBW9BbfzbGxRjUjbZB7Skxp1UVZkUJyj24,12021
7
+ atcdr/test.py,sha256=hAhttwVJiDJX8IAWcnpKj04yTTs4cmr8GQ-NsldBAGc,8468
8
8
  atcdr/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  atcdr/util/cost.py,sha256=0c9H8zLley7xZDLuYU4zJmB8m71qcO1WEIQOoEavD_4,3168
10
10
  atcdr/util/execute.py,sha256=tcYflnVo_38LdaOGDUAuqfSfcA54bTrCaTRShH7kwUw,1750
11
- atcdr/util/filetype.py,sha256=n8alyOdrItoFZzLIssDoXg7i5LamHM9DaY1legUzOD0,2007
11
+ atcdr/util/filetype.py,sha256=NyTkBbL44VbPwGXps381odbC_JEx_eYxRYPaYwRHfZ0,1647
12
12
  atcdr/util/gpt.py,sha256=Lto6SJHZGer8cC_Nq8lJVnaET2R7apFQteo6ZEFpjdM,3304
13
13
  atcdr/util/problem.py,sha256=WprmpOZm6xpyvksIS3ou1uHqFnBO1FUZWadsLziG1bY,2484
14
- atcoderstudybooster-0.3.dist-info/METADATA,sha256=xnKGPQ0_6d592dSluNqZ17xodV23Rvi1h7CGFjsIv84,4467
15
- atcoderstudybooster-0.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
16
- atcoderstudybooster-0.3.dist-info/entry_points.txt,sha256=_bhz0R7vp2VubKl_eIokDO8Wz9TdqvYA7Q59uWfy6Sk,42
17
- atcoderstudybooster-0.3.dist-info/RECORD,,
14
+ atcoderstudybooster-0.23.dist-info/METADATA,sha256=dPsYm8RVvwjgwQjXCQS_gRz8JFIZEIfK6ig_Fsvb1k0,4468
15
+ atcoderstudybooster-0.23.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
16
+ atcoderstudybooster-0.23.dist-info/entry_points.txt,sha256=_bhz0R7vp2VubKl_eIokDO8Wz9TdqvYA7Q59uWfy6Sk,42
17
+ atcoderstudybooster-0.23.dist-info/RECORD,,