kattis-cli 1.0.2__py3-none-any.whl → 1.0.4__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.
- kattis_cli/download.py +0 -2
- kattis_cli/kattis.py +2 -2
- kattis_cli/main.py +19 -9
- kattis_cli/test_solution.py +6 -25
- kattis_cli/utils/config.py +1 -1
- kattis_cli/utils/languages.py +332 -0
- kattis_cli/utils/utility.py +22 -322
- {kattis_cli-1.0.2.dist-info → kattis_cli-1.0.4.dist-info}/METADATA +25 -9
- kattis_cli-1.0.4.dist-info/RECORD +19 -0
- {kattis_cli-1.0.2.dist-info → kattis_cli-1.0.4.dist-info}/WHEEL +1 -1
- kattis_cli-1.0.2.dist-info/RECORD +0 -18
- {kattis_cli-1.0.2.dist-info → kattis_cli-1.0.4.dist-info}/LICENSE +0 -0
- {kattis_cli-1.0.2.dist-info → kattis_cli-1.0.4.dist-info}/entry_points.txt +0 -0
kattis_cli/download.py
CHANGED
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
and save them to data folders.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
# import sys
|
|
6
5
|
import shutil
|
|
7
6
|
from typing import Any, Dict
|
|
8
7
|
from pathlib import Path
|
|
9
8
|
import requests
|
|
10
9
|
import yaml
|
|
11
10
|
from bs4 import BeautifulSoup
|
|
12
|
-
|
|
13
11
|
from .utils import config, utility
|
|
14
12
|
from . import settings
|
|
15
13
|
|
kattis_cli/kattis.py
CHANGED
|
@@ -20,7 +20,7 @@ from rich.align import Align
|
|
|
20
20
|
from rich.live import Live
|
|
21
21
|
from rich.prompt import Confirm
|
|
22
22
|
|
|
23
|
-
from kattis_cli.utils import
|
|
23
|
+
from kattis_cli.utils import languages
|
|
24
24
|
from kattis_cli.utils import config
|
|
25
25
|
from kattis_cli import ui
|
|
26
26
|
|
|
@@ -182,7 +182,7 @@ def confirm_or_die(problem: str, language: str,
|
|
|
182
182
|
console.print('Language:', language)
|
|
183
183
|
console.print('Files:', ', '.join(files))
|
|
184
184
|
if mainclass:
|
|
185
|
-
if language in
|
|
185
|
+
if language in languages.GUESS_MAINFILE:
|
|
186
186
|
console.print('Main file:', mainclass)
|
|
187
187
|
else:
|
|
188
188
|
console.print('Mainclass:', mainclass)
|
kattis_cli/main.py
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
""" Main module for the kattis_cli package.
|
|
2
|
-
|
|
1
|
+
""" Main module for the kattis_cli package.
|
|
2
|
+
This is the main.py file for the kattis_cli package.
|
|
3
|
+
|
|
4
|
+
Change the contents here instead of main.py.
|
|
5
|
+
build.sh script copies the contents of this file to main.py.
|
|
6
|
+
|
|
7
|
+
Change the __version__ to match in pyproject.toml
|
|
8
|
+
Has to be higher than the pypi version.
|
|
9
|
+
"""
|
|
10
|
+
__version__ = '1.0.4'
|
|
3
11
|
|
|
4
12
|
from math import inf
|
|
5
13
|
from typing import Tuple
|
|
@@ -10,15 +18,17 @@ import kattis_cli.download as download
|
|
|
10
18
|
import kattis_cli.ui as ui
|
|
11
19
|
import kattis_cli.test_solution as test_solution
|
|
12
20
|
import kattis_cli.kattis as kattis
|
|
13
|
-
import kattis_cli.utils.
|
|
21
|
+
import kattis_cli.utils.languages as languages
|
|
14
22
|
import kattis_cli.kattis_setup as kattis_setup
|
|
15
23
|
|
|
16
24
|
|
|
17
25
|
@click.group()
|
|
26
|
+
@click.version_option(version=__version__, prog_name='kattis-cli')
|
|
18
27
|
def main() -> None:
|
|
19
28
|
"""
|
|
20
29
|
CLI for downloading, testing and submitting Kattis problems.
|
|
21
30
|
"""
|
|
31
|
+
pass
|
|
22
32
|
|
|
23
33
|
|
|
24
34
|
@main.command(help='Download sample data & metadata.')
|
|
@@ -34,7 +44,7 @@ def get(problemid: str) -> None:
|
|
|
34
44
|
except requests.exceptions.InvalidURL:
|
|
35
45
|
console.print(
|
|
36
46
|
f"""Sample data for Problem ID: [bold blue]
|
|
37
|
-
{problemid}[/bold blue] not found.")
|
|
47
|
+
{problemid}[/bold blue] not found.")
|
|
38
48
|
""")
|
|
39
49
|
console.print(
|
|
40
50
|
f"Downloading metadata: [bold blue]{problemid}[/bold blue]")
|
|
@@ -65,11 +75,11 @@ def test(
|
|
|
65
75
|
"""Test solution with sample files.
|
|
66
76
|
"""
|
|
67
77
|
problemid, loc_language, mainclass, _files, root_folder, lang_config = \
|
|
68
|
-
|
|
78
|
+
languages.update_args(problemid, language, mainclass, list(files))
|
|
69
79
|
# print('After - ', f'{problemid=} {language=} {mainclass=} {_files=}')
|
|
70
80
|
# lang_config = config.parse_config(language)
|
|
71
81
|
if not mainclass:
|
|
72
|
-
mainclass =
|
|
82
|
+
mainclass = languages.guess_mainfile(
|
|
73
83
|
language, _files, problemid, lang_config)
|
|
74
84
|
|
|
75
85
|
test_solution.test_samples(
|
|
@@ -101,14 +111,14 @@ def submit(problemid: str, language: str,
|
|
|
101
111
|
"""Submit a solution to Kattis.
|
|
102
112
|
"""
|
|
103
113
|
problemid, language, mainclass, _files, _, lang_config = \
|
|
104
|
-
|
|
114
|
+
languages.update_args(
|
|
105
115
|
problemid, language, mainclass, list(files))
|
|
106
116
|
# Finally, submit the solution
|
|
107
117
|
# print(f'{problemid=} {language=} {mainclass=} {tag=} {force=} {_files=}')
|
|
108
118
|
if not mainclass:
|
|
109
|
-
mainclass =
|
|
119
|
+
mainclass = languages.guess_mainfile(
|
|
110
120
|
language, _files, problemid, lang_config)
|
|
111
|
-
kat_lang =
|
|
121
|
+
kat_lang = languages.LOCAL_TO_KATTIS[language]
|
|
112
122
|
kattis.submit_solution(_files, problemid,
|
|
113
123
|
kat_lang, mainclass,
|
|
114
124
|
tag, force)
|
kattis_cli/test_solution.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Tester module for Kattis.
|
|
2
2
|
"""
|
|
3
3
|
|
|
4
|
-
from math import inf
|
|
5
4
|
from typing import Any, List, Dict
|
|
6
5
|
import glob
|
|
7
6
|
import time
|
|
@@ -17,26 +16,7 @@ from rich.prompt import Confirm
|
|
|
17
16
|
from rich.markup import escape
|
|
18
17
|
|
|
19
18
|
from kattis_cli import kattis
|
|
20
|
-
from kattis_cli.utils import run_program, utility
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def compare_floats(expected: str, ans: str, places: float) -> bool:
|
|
24
|
-
"""Compare two floating point numbers with given accuracy.
|
|
25
|
-
|
|
26
|
-
Args:
|
|
27
|
-
expected (str): expected result
|
|
28
|
-
ans (str): actual result
|
|
29
|
-
places (float): decimal places for approximation
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
bool: True if the two numbers are equal within the given accuracy
|
|
33
|
-
"""
|
|
34
|
-
try:
|
|
35
|
-
flt_expected = float(expected)
|
|
36
|
-
flt_ans = float(ans)
|
|
37
|
-
return abs(flt_expected - flt_ans) <= 10**(-places)
|
|
38
|
-
except ValueError:
|
|
39
|
-
return False
|
|
19
|
+
from kattis_cli.utils import languages, run_program, utility
|
|
40
20
|
|
|
41
21
|
|
|
42
22
|
def test_samples(
|
|
@@ -46,7 +26,7 @@ def test_samples(
|
|
|
46
26
|
problem_root_folder: str,
|
|
47
27
|
files: List[str],
|
|
48
28
|
lang_config: Dict[Any, Any],
|
|
49
|
-
accuracy: float =
|
|
29
|
+
accuracy: float = 0
|
|
50
30
|
) -> None:
|
|
51
31
|
"""Tests a problem by running all the .in files in
|
|
52
32
|
the problem folder and comparing the output to the .ans files.
|
|
@@ -147,14 +127,15 @@ def test_samples(
|
|
|
147
127
|
if code != 0:
|
|
148
128
|
ans = error
|
|
149
129
|
# console.print(f"{ans=} {error=}")
|
|
150
|
-
if accuracy ==
|
|
130
|
+
if accuracy == 0: # string comparison
|
|
151
131
|
if expected == ans.encode('utf-8').strip():
|
|
152
132
|
result = "[bold green]✅[/bold green]"
|
|
153
133
|
count += 1
|
|
154
134
|
else:
|
|
155
135
|
result = "[bold red]❌[/bold red]"
|
|
156
136
|
else: # floating point comparison
|
|
157
|
-
if compare_floats(expected.decode('utf-8'),
|
|
137
|
+
if utility.compare_floats(expected.decode('utf-8'),
|
|
138
|
+
ans, accuracy):
|
|
158
139
|
result = "[bold green]✅[/bold green]"
|
|
159
140
|
count += 1
|
|
160
141
|
else:
|
|
@@ -188,7 +169,7 @@ def test_samples(
|
|
|
188
169
|
"Awesome... Time to submit it to :cat: Kattis! :cat:",
|
|
189
170
|
style="bold green")
|
|
190
171
|
if Confirm.ask("Submit to Kattis?", default=True):
|
|
191
|
-
kat_language =
|
|
172
|
+
kat_language = languages.LOCAL_TO_KATTIS.get(loc_language, '')
|
|
192
173
|
kattis.submit_solution(files, problemid,
|
|
193
174
|
kat_language, mainclass,
|
|
194
175
|
tag="", force=True)
|
kattis_cli/utils/config.py
CHANGED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"""Module for language utilities.
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
from typing import List, Dict, Any
|
|
5
|
+
import sys
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from kattis_cli.utils import config
|
|
11
|
+
from kattis_cli.utils.utility import find_problem_root_folder
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
LANGUAGE_GUESS = {
|
|
15
|
+
'.c': 'c',
|
|
16
|
+
'.c++': 'cpp',
|
|
17
|
+
'.cc': 'cpp',
|
|
18
|
+
'.c#': 'csharp',
|
|
19
|
+
'.cpp': 'cpp',
|
|
20
|
+
'.cs': 'csharp',
|
|
21
|
+
'.cxx': 'cpp',
|
|
22
|
+
'.cbl': 'cobol',
|
|
23
|
+
'.cob': 'cobol',
|
|
24
|
+
'.cpy': 'cobol',
|
|
25
|
+
'.fs': 'fsharp',
|
|
26
|
+
'.go': 'go',
|
|
27
|
+
'.hs': 'haskell',
|
|
28
|
+
'.java': 'java',
|
|
29
|
+
'.js': 'nodejs',
|
|
30
|
+
'.ts': 'typescript',
|
|
31
|
+
'.kt': 'kotlin',
|
|
32
|
+
'.lisp': 'lisp',
|
|
33
|
+
'.cl': 'lisp',
|
|
34
|
+
'.m': 'objective-c',
|
|
35
|
+
'.ml': 'ocaml',
|
|
36
|
+
'.pas': 'pascal',
|
|
37
|
+
'.php': 'php',
|
|
38
|
+
'.pl': 'prolog',
|
|
39
|
+
'.py': 'python3',
|
|
40
|
+
'.rb': 'ruby',
|
|
41
|
+
'.rs': 'rust',
|
|
42
|
+
'.scala': 'scala',
|
|
43
|
+
'.f90': 'fortran',
|
|
44
|
+
'.f': 'fortran',
|
|
45
|
+
'.for': 'fortran',
|
|
46
|
+
'.sh': 'bash',
|
|
47
|
+
'.apl': 'apl',
|
|
48
|
+
'.ss': 'gerbil',
|
|
49
|
+
'.jl': 'julia',
|
|
50
|
+
'.vb': 'vb',
|
|
51
|
+
'.dart': 'dart',
|
|
52
|
+
'.zig': 'zig',
|
|
53
|
+
'.swift': 'swift',
|
|
54
|
+
'.nim': 'nim',
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
GUESS_MAINCLASS = {'Java', 'Kotlin', 'Scala'}
|
|
58
|
+
|
|
59
|
+
GUESS_MAINFILE = {
|
|
60
|
+
'APL',
|
|
61
|
+
'Bash',
|
|
62
|
+
'Dart',
|
|
63
|
+
'Gerbil',
|
|
64
|
+
'JavaScript (Node.js)',
|
|
65
|
+
'Julia',
|
|
66
|
+
'Common Lisp',
|
|
67
|
+
'Pascal',
|
|
68
|
+
'PHP',
|
|
69
|
+
'Python 3',
|
|
70
|
+
'Ruby',
|
|
71
|
+
'Rust',
|
|
72
|
+
'TypeScript',
|
|
73
|
+
'Zig'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# mapping is used for .kattis-cli.toml file configuration
|
|
77
|
+
LOCAL_TO_KATTIS = {
|
|
78
|
+
'python3': 'Python 3',
|
|
79
|
+
'java': 'Java',
|
|
80
|
+
'cpp': 'C++',
|
|
81
|
+
'c++': 'C++',
|
|
82
|
+
'nodejs': 'JavaScript (Node.js)',
|
|
83
|
+
'typescript': 'TypeScript',
|
|
84
|
+
'csharp': 'C#',
|
|
85
|
+
'kotlin': 'Kotlin',
|
|
86
|
+
'scala': 'Scala',
|
|
87
|
+
'rust': 'Rust',
|
|
88
|
+
'pascal': 'Pascal',
|
|
89
|
+
'go': 'Go',
|
|
90
|
+
'haskell': 'Haskell',
|
|
91
|
+
'ruby': 'Ruby',
|
|
92
|
+
'php': 'PHP',
|
|
93
|
+
'lisp': 'Common Lisp',
|
|
94
|
+
'fortran': 'Fortran',
|
|
95
|
+
'bash': 'Bash',
|
|
96
|
+
'apl': 'APL',
|
|
97
|
+
'gerbil': 'Gerbil',
|
|
98
|
+
'julia': 'Julia',
|
|
99
|
+
'vb': 'Visual Basic',
|
|
100
|
+
'dart': 'Dart',
|
|
101
|
+
'zig': 'Zig',
|
|
102
|
+
'swift': 'Swift',
|
|
103
|
+
'nim': 'Nim',
|
|
104
|
+
'ocaml': 'OCaml',
|
|
105
|
+
'fsharp': 'F#',
|
|
106
|
+
'cobol': 'COBOL',
|
|
107
|
+
'prolog': 'Prolog',
|
|
108
|
+
'objective-c': 'Objective-C',
|
|
109
|
+
'c': 'C',
|
|
110
|
+
'c#': 'C#'
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def guess_language(ext: str, files: List[str]) -> str:
|
|
115
|
+
"""Guess the language.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
ext (str): File extension.
|
|
119
|
+
files (List[str]): Tuple of files.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
str: guessed language
|
|
123
|
+
"""
|
|
124
|
+
if ext == ".C":
|
|
125
|
+
return "cpp"
|
|
126
|
+
ext = ext.lower()
|
|
127
|
+
if ext == ".h":
|
|
128
|
+
if any(f.endswith(".c") for f in files):
|
|
129
|
+
return "c"
|
|
130
|
+
else:
|
|
131
|
+
return "cpp"
|
|
132
|
+
if ext == ".py":
|
|
133
|
+
return "python3"
|
|
134
|
+
return LANGUAGE_GUESS.get(ext, '')
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# flake8: noqa: C901
|
|
138
|
+
def guess_mainfile(
|
|
139
|
+
kat_language: str,
|
|
140
|
+
files: List[str],
|
|
141
|
+
problemid: str,
|
|
142
|
+
lang_config: Dict[Any, Any]) -> Any:
|
|
143
|
+
"""Guess the main file.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
kat_language (str): programming language name used by Kattis
|
|
147
|
+
files (List[str]): Tuple of files
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
str: main file
|
|
151
|
+
"""
|
|
152
|
+
if len(files) == 1:
|
|
153
|
+
return files[0]
|
|
154
|
+
# check .kattis-cli.toml file
|
|
155
|
+
if 'mainfile' in lang_config:
|
|
156
|
+
return lang_config['mainfile'].replace(('{problemid}'), problemid)
|
|
157
|
+
for filename in files:
|
|
158
|
+
if os.path.splitext(os.path.basename(filename))[0] in ['main', 'Main']:
|
|
159
|
+
return filename
|
|
160
|
+
if problemid and os.path.splitext(
|
|
161
|
+
os.path.basename(filename))[0] == problemid:
|
|
162
|
+
return filename
|
|
163
|
+
for filename in files:
|
|
164
|
+
try:
|
|
165
|
+
with open(filename, 'r', encoding='utf-8') as f:
|
|
166
|
+
conts = f.read()
|
|
167
|
+
if kat_language in [
|
|
168
|
+
'Java', 'Rust', 'Scala', 'Kotlin'] and re.search(
|
|
169
|
+
r' main\s*\(', conts):
|
|
170
|
+
return filename
|
|
171
|
+
if kat_language == 'Pascal' and re.match(
|
|
172
|
+
r'^\s*[Pp]rogram\b', conts):
|
|
173
|
+
return filename
|
|
174
|
+
except IOError:
|
|
175
|
+
pass
|
|
176
|
+
# main file is the one with problemid
|
|
177
|
+
return files[0]
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def guess_mainclass(
|
|
181
|
+
problemid: str,
|
|
182
|
+
kat_language: str,
|
|
183
|
+
files: List[str],
|
|
184
|
+
lang_config: Any) -> Any:
|
|
185
|
+
"""Guess the main class.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
kat_language (str): programming language name used by Kattis
|
|
189
|
+
files (List[str]): List of files to guess mainclass from
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
str: mainclass name or empty string
|
|
193
|
+
"""
|
|
194
|
+
if kat_language in GUESS_MAINFILE and len(files) > 1:
|
|
195
|
+
return os.path.basename(
|
|
196
|
+
guess_mainfile(
|
|
197
|
+
kat_language,
|
|
198
|
+
files,
|
|
199
|
+
problemid,
|
|
200
|
+
lang_config))
|
|
201
|
+
if kat_language in GUESS_MAINCLASS:
|
|
202
|
+
mainfile = os.path.basename(
|
|
203
|
+
guess_mainfile(
|
|
204
|
+
kat_language,
|
|
205
|
+
files,
|
|
206
|
+
problemid,
|
|
207
|
+
lang_config))
|
|
208
|
+
name = os.path.splitext(mainfile)[0]
|
|
209
|
+
if kat_language == 'Kotlin':
|
|
210
|
+
return name[0].upper() + name[1:] + 'Kt'
|
|
211
|
+
return name
|
|
212
|
+
return ''
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def validate_language(loc_language: str) -> bool:
|
|
216
|
+
"""Check if valid language.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
loc_language (str): programming language provided by user
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
bool: True if valid language, exit otherwise.
|
|
223
|
+
"""
|
|
224
|
+
if loc_language in LOCAL_TO_KATTIS:
|
|
225
|
+
return True
|
|
226
|
+
console = Console()
|
|
227
|
+
console.print(f'Invalid language: "{loc_language}"', style='bold red')
|
|
228
|
+
console.print('Valid languages are:', style='bold green')
|
|
229
|
+
for lang in sorted(LOCAL_TO_KATTIS.keys()):
|
|
230
|
+
console.print(f'\t\t - {lang}')
|
|
231
|
+
exit(1)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def valid_extension(file: str) -> bool:
|
|
235
|
+
"""Check if valid extension.
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
file (str): File name.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
bool: True if valid extension, False otherwise.
|
|
242
|
+
"""
|
|
243
|
+
if os.path.isfile(file):
|
|
244
|
+
ext = os.path.splitext(file)
|
|
245
|
+
if len(ext) != 2:
|
|
246
|
+
return False
|
|
247
|
+
return ext[1] in LANGUAGE_GUESS
|
|
248
|
+
return False
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
# flake8: noqa: C901
|
|
252
|
+
def update_args(problemid: str,
|
|
253
|
+
loc_language: str,
|
|
254
|
+
mainclass: str,
|
|
255
|
+
files: List[str]) -> Any:
|
|
256
|
+
"""Check if problemid, language, mainclass, and program files are valid.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
problemid (str): problemid
|
|
260
|
+
loc_language (str): programming language provided by user
|
|
261
|
+
mainclass (str): main class
|
|
262
|
+
files (List[str]): List of files
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
Tuple[str]: Update problemid, kattis_language, mainclass, and files
|
|
266
|
+
"""
|
|
267
|
+
|
|
268
|
+
console = Console()
|
|
269
|
+
if not files:
|
|
270
|
+
files = get_coding_files()
|
|
271
|
+
# check if problemid is given
|
|
272
|
+
# if not problemid:
|
|
273
|
+
cur_folder = Path.cwd()
|
|
274
|
+
root_folder = Path.cwd()
|
|
275
|
+
if not problemid:
|
|
276
|
+
for f in files:
|
|
277
|
+
try:
|
|
278
|
+
root_folder = find_problem_root_folder(
|
|
279
|
+
cur_folder, f.lower())
|
|
280
|
+
# if not problemid:
|
|
281
|
+
problemid = root_folder.name
|
|
282
|
+
break
|
|
283
|
+
except FileNotFoundError:
|
|
284
|
+
# print(ex)
|
|
285
|
+
pass
|
|
286
|
+
if not problemid:
|
|
287
|
+
try:
|
|
288
|
+
root_folder = find_problem_root_folder(
|
|
289
|
+
cur_folder, '*.yaml')
|
|
290
|
+
problemid = root_folder.name
|
|
291
|
+
except FileNotFoundError:
|
|
292
|
+
console.print(f'''No problemid specified and I failed to guess
|
|
293
|
+
problemid and root problem folder from filename(s) and cwd: {cur_folder}.''',
|
|
294
|
+
style='bold red')
|
|
295
|
+
sys.exit(1)
|
|
296
|
+
# check if language
|
|
297
|
+
if not loc_language:
|
|
298
|
+
_, ext = os.path.splitext(os.path.basename(files[0]))
|
|
299
|
+
# Guess language from files
|
|
300
|
+
loc_language = guess_language(ext, files)
|
|
301
|
+
if not loc_language:
|
|
302
|
+
console.print(f'''\
|
|
303
|
+
No language specified, and I failed to guess language from
|
|
304
|
+
filename extension "{ext}"''')
|
|
305
|
+
sys.exit(1)
|
|
306
|
+
# check if valid language
|
|
307
|
+
validate_language(loc_language)
|
|
308
|
+
lang_config = config.parse_config(loc_language)
|
|
309
|
+
kat_language = LOCAL_TO_KATTIS[loc_language]
|
|
310
|
+
if not mainclass:
|
|
311
|
+
mainclass = guess_mainclass(
|
|
312
|
+
problemid, kat_language, files, lang_config)
|
|
313
|
+
# print(f'Returning...{problemid=} {language=} {mainclass=} {files=}')
|
|
314
|
+
return problemid, loc_language, mainclass, files, root_folder, lang_config
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def get_coding_files() -> List[str]:
|
|
318
|
+
"""Get coding files from current directory.
|
|
319
|
+
|
|
320
|
+
Returns:
|
|
321
|
+
List[str]: List of coding files.
|
|
322
|
+
"""
|
|
323
|
+
cur_folder = str(Path.cwd())
|
|
324
|
+
console = Console()
|
|
325
|
+
files = [
|
|
326
|
+
f for f in os.listdir(cur_folder) if valid_extension(f)]
|
|
327
|
+
if not files:
|
|
328
|
+
console.print(
|
|
329
|
+
'No source file(s) found in the current folder!',
|
|
330
|
+
style='bold red')
|
|
331
|
+
exit(1)
|
|
332
|
+
return files
|
kattis_cli/utils/utility.py
CHANGED
|
@@ -1,251 +1,9 @@
|
|
|
1
|
-
"""
|
|
2
|
-
"""
|
|
1
|
+
""" Utility functions. """
|
|
3
2
|
|
|
4
|
-
from typing import List, Union, Any, Dict
|
|
5
|
-
import sys
|
|
6
|
-
import os
|
|
7
|
-
import re
|
|
8
3
|
from pathlib import Path
|
|
4
|
+
import os
|
|
5
|
+
from typing import Union
|
|
9
6
|
import yaml
|
|
10
|
-
from rich.console import Console
|
|
11
|
-
from kattis_cli.utils import config
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
LANGUAGE_GUESS = {
|
|
15
|
-
'.c': 'c',
|
|
16
|
-
'.c++': 'cpp',
|
|
17
|
-
'.cc': 'cpp',
|
|
18
|
-
'.c#': 'csharp',
|
|
19
|
-
'.cpp': 'cpp',
|
|
20
|
-
'.cs': 'csharp',
|
|
21
|
-
'.cxx': 'cpp',
|
|
22
|
-
'.cbl': 'cobol',
|
|
23
|
-
'.cob': 'cobol',
|
|
24
|
-
'.cpy': 'cobol',
|
|
25
|
-
'.fs': 'fsharp',
|
|
26
|
-
'.go': 'go',
|
|
27
|
-
'.hs': 'haskell',
|
|
28
|
-
'.java': 'java',
|
|
29
|
-
'.js': 'nodejs',
|
|
30
|
-
'.ts': 'typescript',
|
|
31
|
-
'.kt': 'kotlin',
|
|
32
|
-
'.lisp': 'lisp',
|
|
33
|
-
'.cl': 'lisp',
|
|
34
|
-
'.m': 'objective-c',
|
|
35
|
-
'.ml': 'ocaml',
|
|
36
|
-
'.pas': 'pascal',
|
|
37
|
-
'.php': 'php',
|
|
38
|
-
'.pl': 'prolog',
|
|
39
|
-
'.py': 'python3',
|
|
40
|
-
'.rb': 'ruby',
|
|
41
|
-
'.rs': 'rust',
|
|
42
|
-
'.scala': 'scala',
|
|
43
|
-
'.f90': 'fortran',
|
|
44
|
-
'.f': 'fortran',
|
|
45
|
-
'.for': 'fortran',
|
|
46
|
-
'.sh': 'bash',
|
|
47
|
-
'.apl': 'apl',
|
|
48
|
-
'.ss': 'gerbil',
|
|
49
|
-
'.jl': 'julia',
|
|
50
|
-
'.vb': 'vb',
|
|
51
|
-
'.dart': 'dart',
|
|
52
|
-
'.zig': 'zig',
|
|
53
|
-
'.swift': 'swift',
|
|
54
|
-
'.nim': 'nim',
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
GUESS_MAINCLASS = {'Java', 'Kotlin', 'Scala'}
|
|
58
|
-
|
|
59
|
-
GUESS_MAINFILE = {
|
|
60
|
-
'APL',
|
|
61
|
-
'Bash',
|
|
62
|
-
'Dart',
|
|
63
|
-
'Gerbil',
|
|
64
|
-
'JavaScript (Node.js)',
|
|
65
|
-
'Julia',
|
|
66
|
-
'Common Lisp',
|
|
67
|
-
'Pascal',
|
|
68
|
-
'PHP',
|
|
69
|
-
'Python 3',
|
|
70
|
-
'Ruby',
|
|
71
|
-
'Rust',
|
|
72
|
-
'TypeScript',
|
|
73
|
-
'Zig'
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
# mapping is used for .kattis-cli.toml file configuration
|
|
77
|
-
LOCAL_TO_KATTIS = {
|
|
78
|
-
'python3': 'Python 3',
|
|
79
|
-
'java': 'Java',
|
|
80
|
-
'cpp': 'C++',
|
|
81
|
-
'c++': 'C++',
|
|
82
|
-
'nodejs': 'JavaScript (Node.js)',
|
|
83
|
-
'typescript': 'TypeScript',
|
|
84
|
-
'csharp': 'C#',
|
|
85
|
-
'kotlin': 'Kotlin',
|
|
86
|
-
'scala': 'Scala',
|
|
87
|
-
'rust': 'Rust',
|
|
88
|
-
'pascal': 'Pascal',
|
|
89
|
-
'go': 'Go',
|
|
90
|
-
'haskell': 'Haskell',
|
|
91
|
-
'ruby': 'Ruby',
|
|
92
|
-
'php': 'PHP',
|
|
93
|
-
'lisp': 'Common Lisp',
|
|
94
|
-
'fortran': 'Fortran',
|
|
95
|
-
'bash': 'Bash',
|
|
96
|
-
'apl': 'APL',
|
|
97
|
-
'gerbil': 'Gerbil',
|
|
98
|
-
'julia': 'Julia',
|
|
99
|
-
'vb': 'Visual Basic',
|
|
100
|
-
'dart': 'Dart',
|
|
101
|
-
'zig': 'Zig',
|
|
102
|
-
'swift': 'Swift',
|
|
103
|
-
'nim': 'Nim',
|
|
104
|
-
'ocaml': 'OCaml',
|
|
105
|
-
'fsharp': 'F#',
|
|
106
|
-
'cobol': 'COBOL',
|
|
107
|
-
'prolog': 'Prolog',
|
|
108
|
-
'objective-c': 'Objective-C',
|
|
109
|
-
'c': 'C',
|
|
110
|
-
'c#': 'C#'
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def guess_language(ext: str, files: List[str]) -> str:
|
|
115
|
-
"""Guess the language.
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
ext (str): File extension.
|
|
119
|
-
files (List[str]): Tuple of files.
|
|
120
|
-
|
|
121
|
-
Returns:
|
|
122
|
-
str: guessed language
|
|
123
|
-
"""
|
|
124
|
-
if ext == ".C":
|
|
125
|
-
return "cpp"
|
|
126
|
-
ext = ext.lower()
|
|
127
|
-
if ext == ".h":
|
|
128
|
-
if any(f.endswith(".c") for f in files):
|
|
129
|
-
return "c"
|
|
130
|
-
else:
|
|
131
|
-
return "cpp"
|
|
132
|
-
if ext == ".py":
|
|
133
|
-
return "python3"
|
|
134
|
-
return LANGUAGE_GUESS.get(ext, '')
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
# flake8: noqa: C901
|
|
138
|
-
def guess_mainfile(
|
|
139
|
-
kat_language: str,
|
|
140
|
-
files: List[str],
|
|
141
|
-
problemid: str,
|
|
142
|
-
lang_config: Dict[Any, Any]) -> Any:
|
|
143
|
-
"""Guess the main file.
|
|
144
|
-
|
|
145
|
-
Args:
|
|
146
|
-
kat_language (str): programming language name used by Kattis
|
|
147
|
-
files (List[str]): Tuple of files
|
|
148
|
-
|
|
149
|
-
Returns:
|
|
150
|
-
str: main file
|
|
151
|
-
"""
|
|
152
|
-
if len(files) == 1:
|
|
153
|
-
return files[0]
|
|
154
|
-
# check .kattis-cli.toml file
|
|
155
|
-
if 'mainfile' in lang_config:
|
|
156
|
-
return lang_config['mainfile'].replace(('{problemid}'), problemid)
|
|
157
|
-
for filename in files:
|
|
158
|
-
if os.path.splitext(os.path.basename(filename))[0] in ['main', 'Main']:
|
|
159
|
-
return filename
|
|
160
|
-
if problemid and os.path.splitext(
|
|
161
|
-
os.path.basename(filename))[0] == problemid:
|
|
162
|
-
return filename
|
|
163
|
-
for filename in files:
|
|
164
|
-
try:
|
|
165
|
-
with open(filename, 'r', encoding='utf-8') as f:
|
|
166
|
-
conts = f.read()
|
|
167
|
-
if kat_language in [
|
|
168
|
-
'Java', 'Rust', 'Scala', 'Kotlin'] and re.search(
|
|
169
|
-
r' main\s*\(', conts):
|
|
170
|
-
return filename
|
|
171
|
-
if kat_language == 'Pascal' and re.match(
|
|
172
|
-
r'^\s*[Pp]rogram\b', conts):
|
|
173
|
-
return filename
|
|
174
|
-
except IOError:
|
|
175
|
-
pass
|
|
176
|
-
# main file is the one with problemid
|
|
177
|
-
return files[0]
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
def guess_mainclass(
|
|
181
|
-
problemid: str,
|
|
182
|
-
kat_language: str,
|
|
183
|
-
files: List[str],
|
|
184
|
-
lang_config: Any) -> Any:
|
|
185
|
-
"""Guess the main class.
|
|
186
|
-
|
|
187
|
-
Args:
|
|
188
|
-
kat_language (str): programming language name used by Kattis
|
|
189
|
-
files (List[str]): List of files to guess mainclass from
|
|
190
|
-
|
|
191
|
-
Returns:
|
|
192
|
-
str: mainclass name or empty string
|
|
193
|
-
"""
|
|
194
|
-
if kat_language in GUESS_MAINFILE and len(files) > 1:
|
|
195
|
-
return os.path.basename(
|
|
196
|
-
guess_mainfile(
|
|
197
|
-
kat_language,
|
|
198
|
-
files,
|
|
199
|
-
problemid,
|
|
200
|
-
lang_config))
|
|
201
|
-
if kat_language in GUESS_MAINCLASS:
|
|
202
|
-
mainfile = os.path.basename(
|
|
203
|
-
guess_mainfile(
|
|
204
|
-
kat_language,
|
|
205
|
-
files,
|
|
206
|
-
problemid,
|
|
207
|
-
lang_config))
|
|
208
|
-
name = os.path.splitext(mainfile)[0]
|
|
209
|
-
if kat_language == 'Kotlin':
|
|
210
|
-
return name[0].upper() + name[1:] + 'Kt'
|
|
211
|
-
return name
|
|
212
|
-
return ''
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
def validate_language(loc_language: str) -> bool:
|
|
216
|
-
"""Check if valid language.
|
|
217
|
-
|
|
218
|
-
Args:
|
|
219
|
-
loc_language (str): programming language provided by user
|
|
220
|
-
|
|
221
|
-
Returns:
|
|
222
|
-
bool: True if valid language, exit otherwise.
|
|
223
|
-
"""
|
|
224
|
-
if loc_language in LOCAL_TO_KATTIS:
|
|
225
|
-
return True
|
|
226
|
-
console = Console()
|
|
227
|
-
console.print(f'Invalid language: "{loc_language}"', style='bold red')
|
|
228
|
-
console.print('Valid languages are:', style='bold green')
|
|
229
|
-
for lang in sorted(LOCAL_TO_KATTIS.keys()):
|
|
230
|
-
console.print(f'\t\t - {lang}')
|
|
231
|
-
exit(1)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
def valid_extension(file: str) -> bool:
|
|
235
|
-
"""Check if valid extension.
|
|
236
|
-
|
|
237
|
-
Args:
|
|
238
|
-
file (str): File name.
|
|
239
|
-
|
|
240
|
-
Returns:
|
|
241
|
-
bool: True if valid extension, False otherwise.
|
|
242
|
-
"""
|
|
243
|
-
if os.path.isfile(file):
|
|
244
|
-
ext = os.path.splitext(file)
|
|
245
|
-
if len(ext) != 2:
|
|
246
|
-
return False
|
|
247
|
-
return ext[1] in LANGUAGE_GUESS
|
|
248
|
-
return False
|
|
249
7
|
|
|
250
8
|
|
|
251
9
|
def find_problem_root_folder(
|
|
@@ -302,85 +60,27 @@ def find_problem_root_folder(
|
|
|
302
60
|
raise FileNotFoundError("Error: Problem root folder not found.")
|
|
303
61
|
|
|
304
62
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
loc_language: str,
|
|
308
|
-
mainclass: str,
|
|
309
|
-
files: List[str]) -> Any:
|
|
310
|
-
"""Check if problemid, language, mainclass, and program files are valid.
|
|
63
|
+
def compare_floats(expected: str, ans: str, places: float) -> bool:
|
|
64
|
+
"""Compare two floating point numbers with given accuracy.
|
|
311
65
|
|
|
312
66
|
Args:
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
files (List[str]): List of files
|
|
67
|
+
expected (str): expected result
|
|
68
|
+
ans (str): actual result
|
|
69
|
+
places (float): decimal places for approximation
|
|
317
70
|
|
|
318
71
|
Returns:
|
|
319
|
-
|
|
72
|
+
bool: True if the two numbers are equal within the given accuracy
|
|
320
73
|
"""
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
# if not problemid:
|
|
335
|
-
problemid = root_folder.name
|
|
336
|
-
break
|
|
337
|
-
except FileNotFoundError:
|
|
338
|
-
# print(ex)
|
|
339
|
-
pass
|
|
340
|
-
if not problemid:
|
|
341
|
-
try:
|
|
342
|
-
root_folder = find_problem_root_folder(
|
|
343
|
-
cur_folder, '*.yaml')
|
|
344
|
-
problemid = root_folder.name
|
|
345
|
-
except FileNotFoundError:
|
|
346
|
-
console.print(f'''No problemid specified and I failed to guess
|
|
347
|
-
problemid and root problem folder from filename(s) and cwd: {cur_folder}.''',
|
|
348
|
-
style='bold red')
|
|
349
|
-
sys.exit(1)
|
|
350
|
-
# check if language
|
|
351
|
-
if not loc_language:
|
|
352
|
-
_, ext = os.path.splitext(os.path.basename(files[0]))
|
|
353
|
-
# Guess language from files
|
|
354
|
-
loc_language = guess_language(ext, files)
|
|
355
|
-
if not loc_language:
|
|
356
|
-
console.print(f'''\
|
|
357
|
-
No language specified, and I failed to guess language from
|
|
358
|
-
filename extension "{ext}"''')
|
|
359
|
-
sys.exit(1)
|
|
360
|
-
# check if valid language
|
|
361
|
-
validate_language(loc_language)
|
|
362
|
-
lang_config = config.parse_config(loc_language)
|
|
363
|
-
kat_language = LOCAL_TO_KATTIS[loc_language]
|
|
364
|
-
if not mainclass:
|
|
365
|
-
mainclass = guess_mainclass(
|
|
366
|
-
problemid, kat_language, files, lang_config)
|
|
367
|
-
# print(f'Returning...{problemid=} {language=} {mainclass=} {files=}')
|
|
368
|
-
return problemid, loc_language, mainclass, files, root_folder, lang_config
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
def get_coding_files() -> List[str]:
|
|
372
|
-
"""Get coding files from current directory.
|
|
373
|
-
|
|
374
|
-
Returns:
|
|
375
|
-
List[str]: List of coding files.
|
|
376
|
-
"""
|
|
377
|
-
cur_folder = str(Path.cwd())
|
|
378
|
-
console = Console()
|
|
379
|
-
files = [
|
|
380
|
-
f for f in os.listdir(cur_folder) if valid_extension(f)]
|
|
381
|
-
if not files:
|
|
382
|
-
console.print(
|
|
383
|
-
'No source file(s) found in the current folder!',
|
|
384
|
-
style='bold red')
|
|
385
|
-
exit(1)
|
|
386
|
-
return files
|
|
74
|
+
expect_ans = expected.strip().split('\n')
|
|
75
|
+
actual_ans = ans.strip().split('\n')
|
|
76
|
+
if len(expect_ans) != len(actual_ans):
|
|
77
|
+
return False
|
|
78
|
+
try:
|
|
79
|
+
for i, ex_ans in enumerate(expect_ans):
|
|
80
|
+
flt_expected = float(ex_ans)
|
|
81
|
+
flt_ans = float(actual_ans[i])
|
|
82
|
+
if abs(flt_expected - flt_ans) > 10**(-places):
|
|
83
|
+
return False
|
|
84
|
+
return True
|
|
85
|
+
except ValueError:
|
|
86
|
+
return False
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: kattis-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: A command-line tool for Kattis
|
|
5
5
|
Home-page: https://github.com/rambasnet/kattis-cli
|
|
6
6
|
Author: Ram Basnet
|
|
7
|
-
Author-email:
|
|
7
|
+
Author-email: rbasnet@coloradomesa.edu
|
|
8
8
|
Requires-Python: >=3.8,<4.0
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
@@ -75,21 +75,25 @@ If you've Python version 3.8 or higher, you can skip creating virtual environmen
|
|
|
75
75
|
```bash
|
|
76
76
|
pip install kattis-cli
|
|
77
77
|
python -m pip install kattis-cli
|
|
78
|
+
kattis --version
|
|
78
79
|
```
|
|
79
80
|
|
|
80
81
|
- on Windows add the path shown in the output of the above command to your PATH environment variable
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
## Update Kattis-CLI
|
|
83
|
+
## Update/Upgrade Kattis-CLI
|
|
84
84
|
|
|
85
85
|
- remove or rename **.kattis-cli.toml** file in your home directory
|
|
86
86
|
- activate virtual environment if you've created one for kattis-cli
|
|
87
87
|
|
|
88
88
|
```bash
|
|
89
|
+
kattis --version
|
|
89
90
|
pip install kattis-cli --upgrade
|
|
90
91
|
python -m pip install kattis-cli --upgrade
|
|
91
92
|
```
|
|
92
93
|
|
|
94
|
+
- on Windows add the path shown in the output of the above command to your PATH environment variable
|
|
95
|
+
|
|
96
|
+
|
|
93
97
|
## Kattis configuration
|
|
94
98
|
|
|
95
99
|
- run the following command and enter your Kattis credentials
|
|
@@ -113,13 +117,13 @@ kattis --help
|
|
|
113
117
|
- problem id can be found in the last part of the URL of the problem
|
|
114
118
|
- example: [https://open.kattis.com/problems/cold](https://open.kattis.com/problems/cold) => problem id: **cold**
|
|
115
119
|
|
|
116
|
-

|
|
120
|
+

|
|
117
121
|
|
|
118
122
|
```bash
|
|
119
123
|
kattis get <problem_id>
|
|
120
124
|
```
|
|
121
125
|
|
|
122
|
-

|
|
126
|
+

|
|
123
127
|
|
|
124
128
|
### Display problem metadata
|
|
125
129
|
|
|
@@ -128,10 +132,12 @@ cd <problem_id>
|
|
|
128
132
|
kattis info
|
|
129
133
|
```
|
|
130
134
|
|
|
131
|
-

|
|
135
|
+

|
|
132
136
|
|
|
133
137
|
### Test a solution locally
|
|
134
138
|
|
|
139
|
+

|
|
140
|
+
|
|
135
141
|
- currently the following languages have been tested: Python 3, C++, NodeJS, C, Java
|
|
136
142
|
- make sure CLI compilers are in your PATH
|
|
137
143
|
- make sure python3 files have first line shebang: !/usr/bin/env python3
|
|
@@ -141,10 +147,20 @@ kattis info
|
|
|
141
147
|
|
|
142
148
|
```bash
|
|
143
149
|
cd <problem_id>
|
|
144
|
-
kattis test
|
|
150
|
+
kattis test # for exact comparion of answers (string and int)
|
|
151
|
+
kattis test -a 6 # Answer accepted upto 6 decimal places of accuracy
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Testing floating point results
|
|
155
|
+
|
|
156
|
+
- for floating point ouput, problem provides the tolerance or accuracy upto certain decimal points
|
|
157
|
+
- one can use `-a <N>` switch after kattis test command to provide the decimal places of accuracy
|
|
158
|
+
- e.g., the following command checks for accuracy upto 6 decimal points or absolute error upto $10^-6$
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
kattis test -a 6
|
|
145
162
|
```
|
|
146
163
|
|
|
147
|
-

|
|
148
164
|
|
|
149
165
|
### Submit a problem
|
|
150
166
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
kattis_cli/.kattis-cli.toml,sha256=kGh0gmpFAnivyUC9hR8Y1ZqYJeTBWNyBQ9zOg4AInZ0,898
|
|
2
|
+
kattis_cli/__init__.py,sha256=afN92pog2fGyicY6KNBofYbCBYbYj4Fpi_INUSpsc-E,402
|
|
3
|
+
kattis_cli/download.py,sha256=kvUJdqRW3_ETvTd4XMruEs87RWPVHp_3a4VUhcYZEz8,5863
|
|
4
|
+
kattis_cli/kattis.py,sha256=uZct7vjbEW2HA5FJr1ItSZ-b07P9JQHv5SccV4Pqjo8,13771
|
|
5
|
+
kattis_cli/kattis_setup.py,sha256=rq_-Fz8oafxFJ8MOcxJqHQT8-bezgVHZXY2hm4EQF3U,4357
|
|
6
|
+
kattis_cli/main.py,sha256=aI9EWMqAr-QawCzDUPJSpxwoIsEHSi2ed-23-KOeiAQ,4475
|
|
7
|
+
kattis_cli/settings.py,sha256=d5q4dYj9VqDSqPalleh2oZWtND-1bPB0T2IwdajFrBg,591
|
|
8
|
+
kattis_cli/test_solution.py,sha256=g8LwVKx7Z1bSsXWs_JExCagBrrpKs7vL5PfaAoJHGKA,6114
|
|
9
|
+
kattis_cli/ui.py,sha256=dI06yncjm8sdLQkupPxGRODvQ6Gbawwuqn-67FrWg6I,2682
|
|
10
|
+
kattis_cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
kattis_cli/utils/config.py,sha256=6SIuiXA9sFADo8RZUj8A6rXb3uqmrWrmmArfZrqNQdw,2293
|
|
12
|
+
kattis_cli/utils/languages.py,sha256=wlhl1Zng0gQAtsWW6FLxdkdzqeeY_qQ94wqa3NLypEU,8758
|
|
13
|
+
kattis_cli/utils/run_program.py,sha256=NWQ6vtTeWgkaW75r91FIHGXR5cAbeu8yMb5hwzpYFsg,2613
|
|
14
|
+
kattis_cli/utils/utility.py,sha256=XqiL7nVWCXs8DsoF6BqbkL0O9-348W-GKN1ScAzQdZ4,2732
|
|
15
|
+
kattis_cli-1.0.4.dist-info/LICENSE,sha256=JmBa4SEKBCDWEgiOZcISU4tUCpli6xSpVlSYgkBXSNQ,1067
|
|
16
|
+
kattis_cli-1.0.4.dist-info/METADATA,sha256=fs7fFZhce3ZgAMKeRSlMAYU2i_rVbyYN1LFDtAiUSek,6603
|
|
17
|
+
kattis_cli-1.0.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
18
|
+
kattis_cli-1.0.4.dist-info/entry_points.txt,sha256=kyzGN20VqUPR_H0J_jJUKT-10-cAMFLVegQ6C7tbHss,47
|
|
19
|
+
kattis_cli-1.0.4.dist-info/RECORD,,
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
kattis_cli/.kattis-cli.toml,sha256=kGh0gmpFAnivyUC9hR8Y1ZqYJeTBWNyBQ9zOg4AInZ0,898
|
|
2
|
-
kattis_cli/__init__.py,sha256=afN92pog2fGyicY6KNBofYbCBYbYj4Fpi_INUSpsc-E,402
|
|
3
|
-
kattis_cli/download.py,sha256=aa0hBg_6Ou8SGrufgkNUjfWEHdmiu7U-W4d-yWHZNOA,5877
|
|
4
|
-
kattis_cli/kattis.py,sha256=t5fog-tx1f1GeM-D3aa2YhuhxTnai_kV-x7miZbs6SI,13767
|
|
5
|
-
kattis_cli/kattis_setup.py,sha256=rq_-Fz8oafxFJ8MOcxJqHQT8-bezgVHZXY2hm4EQF3U,4357
|
|
6
|
-
kattis_cli/main.py,sha256=LDUUdG0eqiKL_zJX9V05OaqUIXKrOOwVAWOgN4TWWQQ,4121
|
|
7
|
-
kattis_cli/settings.py,sha256=d5q4dYj9VqDSqPalleh2oZWtND-1bPB0T2IwdajFrBg,591
|
|
8
|
-
kattis_cli/test_solution.py,sha256=KKYedt3ISQYLIoahLPgPizpApLQnOrBhmkew5aHW9BM,6627
|
|
9
|
-
kattis_cli/ui.py,sha256=dI06yncjm8sdLQkupPxGRODvQ6Gbawwuqn-67FrWg6I,2682
|
|
10
|
-
kattis_cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
kattis_cli/utils/config.py,sha256=cr5ssEVWolDbqP8krts0YSK5vSLatKTveeHBRNsLRC8,2277
|
|
12
|
-
kattis_cli/utils/run_program.py,sha256=NWQ6vtTeWgkaW75r91FIHGXR5cAbeu8yMb5hwzpYFsg,2613
|
|
13
|
-
kattis_cli/utils/utility.py,sha256=JkypTfPOlDSxmZsh7KKcAVG2BC58t66corMBtcdvU7E,10532
|
|
14
|
-
kattis_cli-1.0.2.dist-info/LICENSE,sha256=JmBa4SEKBCDWEgiOZcISU4tUCpli6xSpVlSYgkBXSNQ,1067
|
|
15
|
-
kattis_cli-1.0.2.dist-info/METADATA,sha256=TImOazyOs7tJWBf_E-NP9x3-_InVey2bnqBxhjJMGOs,5961
|
|
16
|
-
kattis_cli-1.0.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
17
|
-
kattis_cli-1.0.2.dist-info/entry_points.txt,sha256=kyzGN20VqUPR_H0J_jJUKT-10-cAMFLVegQ6C7tbHss,47
|
|
18
|
-
kattis_cli-1.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|