kattis-cli 1.0.3__tar.gz → 1.0.5__tar.gz

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.
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kattis-cli
3
- Version: 1.0.3
3
+ Version: 1.0.5
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: rambasnet@gmail.com
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
@@ -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
 
@@ -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 utility
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 utility.GUESS_MAINFILE:
185
+ if language in languages.GUESS_MAINFILE:
186
186
  console.print('Main file:', mainclass)
187
187
  else:
188
188
  console.print('Mainclass:', mainclass)
@@ -7,7 +7,7 @@ build.sh script copies the contents of this file to main.py.
7
7
  Change the __version__ to match in pyproject.toml
8
8
  Has to be higher than the pypi version.
9
9
  """
10
- __version__ = '1.0.3'
10
+ __version__ = '1.0.5'
11
11
 
12
12
  from math import inf
13
13
  from typing import Tuple
@@ -18,7 +18,7 @@ import kattis_cli.download as download
18
18
  import kattis_cli.ui as ui
19
19
  import kattis_cli.test_solution as test_solution
20
20
  import kattis_cli.kattis as kattis
21
- import kattis_cli.utils.utility as utility
21
+ import kattis_cli.utils.languages as languages
22
22
  import kattis_cli.kattis_setup as kattis_setup
23
23
 
24
24
 
@@ -75,11 +75,11 @@ def test(
75
75
  """Test solution with sample files.
76
76
  """
77
77
  problemid, loc_language, mainclass, _files, root_folder, lang_config = \
78
- utility.update_args(problemid, language, mainclass, list(files))
78
+ languages.update_args(problemid, language, mainclass, list(files))
79
79
  # print('After - ', f'{problemid=} {language=} {mainclass=} {_files=}')
80
80
  # lang_config = config.parse_config(language)
81
81
  if not mainclass:
82
- mainclass = utility.guess_mainfile(
82
+ mainclass = languages.guess_mainfile(
83
83
  language, _files, problemid, lang_config)
84
84
 
85
85
  test_solution.test_samples(
@@ -111,14 +111,14 @@ def submit(problemid: str, language: str,
111
111
  """Submit a solution to Kattis.
112
112
  """
113
113
  problemid, language, mainclass, _files, _, lang_config = \
114
- utility.update_args(
114
+ languages.update_args(
115
115
  problemid, language, mainclass, list(files))
116
116
  # Finally, submit the solution
117
117
  # print(f'{problemid=} {language=} {mainclass=} {tag=} {force=} {_files=}')
118
118
  if not mainclass:
119
- mainclass = utility.guess_mainfile(
119
+ mainclass = languages.guess_mainfile(
120
120
  language, _files, problemid, lang_config)
121
- kat_lang = utility.LOCAL_TO_KATTIS[language]
121
+ kat_lang = languages.LOCAL_TO_KATTIS[language]
122
122
  kattis.submit_solution(_files, problemid,
123
123
  kat_lang, mainclass,
124
124
  tag, force)
@@ -1,8 +1,8 @@
1
1
  """Tester module for Kattis.
2
2
  """
3
3
 
4
- from math import inf
5
4
  from typing import Any, List, Dict
5
+ from math import inf
6
6
  import glob
7
7
  import time
8
8
  import os
@@ -17,26 +17,7 @@ from rich.prompt import Confirm
17
17
  from rich.markup import escape
18
18
 
19
19
  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
20
+ from kattis_cli.utils import languages, run_program, utility
40
21
 
41
22
 
42
23
  def test_samples(
@@ -138,27 +119,31 @@ def test_samples(
138
119
  input_content = f.read()
139
120
  input_content.replace(b'\r\n', b'\n') # Windows fix
140
121
  out_file = in_file.replace('.in', '.ans')
141
- with open(out_file, 'rb') as f:
142
- expected = f.read()
143
- expected.replace(b'\r\n', b'\n')
122
+ try:
123
+ with open(out_file, 'rb') as f:
124
+ expected = f.read()
125
+ expected.replace(b'\r\n', b'\n')
126
+ except FileNotFoundError:
127
+ try:
128
+ out_file = in_file.replace('.in', '.out')
129
+ with open(out_file, 'rb') as f:
130
+ expected = f.read()
131
+ expected.replace(b'\r\n', b'\n')
132
+ except FileNotFoundError:
133
+ expected = b"No .ans or .out file found!"
144
134
  # Run the program
145
135
  code, ans, error = run_program.run(lang_config, mainclass, in_file)
146
- expected = expected.strip()
147
136
  if code != 0:
148
137
  ans = error
149
138
  # console.print(f"{ans=} {error=}")
150
- if accuracy == inf: # string comparison
151
- if expected == ans.encode('utf-8').strip():
152
- result = "[bold green]✅[/bold green]"
153
- count += 1
154
- else:
155
- result = "[bold red]❌[/bold red]"
156
- else: # floating point comparison
157
- if compare_floats(expected.decode('utf-8'), ans, accuracy):
158
- result = "[bold green]✅[/bold green]"
159
- count += 1
160
- else:
161
- result = "[bold red]❌[/bold red]"
139
+
140
+ # floating point comparison
141
+ if utility.check_answer(expected.decode('utf-8'),
142
+ ans, accuracy):
143
+ result = "[bold green]✅[/bold green]"
144
+ count += 1
145
+ else:
146
+ result = "[bold red]❌[/bold red]"
162
147
 
163
148
  # UI Table Row ---
164
149
  in_filename = Path(in_file).parts[-1]
@@ -188,7 +173,7 @@ def test_samples(
188
173
  "Awesome... Time to submit it to :cat: Kattis! :cat:",
189
174
  style="bold green")
190
175
  if Confirm.ask("Submit to Kattis?", default=True):
191
- kat_language = utility.LOCAL_TO_KATTIS.get(loc_language, '')
176
+ kat_language = languages.LOCAL_TO_KATTIS.get(loc_language, '')
192
177
  kattis.submit_solution(files, problemid,
193
178
  kat_language, mainclass,
194
179
  tag="", force=True)
@@ -9,7 +9,7 @@ import configparser
9
9
  from tomlkit import load
10
10
  import yaml
11
11
 
12
- from .utility import find_problem_root_folder
12
+ from kattis_cli.utils.utility import find_problem_root_folder
13
13
 
14
14
  _DEFAULT_CONFIG = Path.home().joinpath('.kattisrc')
15
15
 
@@ -1,14 +1,14 @@
1
1
  """Module for language utilities.
2
2
  """
3
3
 
4
- from typing import List, Union, Any, Dict
4
+ from typing import List, Dict, Any
5
5
  import sys
6
6
  import os
7
7
  import re
8
8
  from pathlib import Path
9
- import yaml
10
9
  from rich.console import Console
11
10
  from kattis_cli.utils import config
11
+ from kattis_cli.utils.utility import find_problem_root_folder
12
12
 
13
13
 
14
14
  LANGUAGE_GUESS = {
@@ -248,60 +248,6 @@ def valid_extension(file: str) -> bool:
248
248
  return False
249
249
 
250
250
 
251
- def find_problem_root_folder(
252
- cur_dir_path: Union[str, Path],
253
- filename: str
254
- ) -> Path:
255
- """Find the root problem folder given a directory path and filename.
256
-
257
- Args:
258
- cur_dir_path (Union[str, Path]): String or Path
259
- object of directory path
260
- filename (str): filename to search for
261
- including wildcard pattern
262
-
263
- Returns:
264
- Path: Path object of the root problem folder
265
- """
266
-
267
- def _check_file_match_folder(path: Path, filename: str) -> bool:
268
- """ Check folder is same name as the filename given
269
- filename including wildcard.
270
-
271
- Args:
272
- path (Path): Path object of directory path
273
- filename (str): filename to search for
274
- including wildcard pattern
275
- Returns:
276
- bool: True if path exists, False otherwise
277
- """
278
- for file in path.glob(filename):
279
- name, ext = os.path.splitext(file.name)
280
- folder_name = path.parts[-1]
281
- # print(f'{name} {folder_name=} {name=} {ext=}')
282
- if name == folder_name:
283
- return True
284
- # read yaml file
285
- if ext == '.yaml':
286
- with open(file, 'r', encoding='utf-8') as f:
287
- data = yaml.safe_load(f)
288
- if 'problemid' in data:
289
- return True
290
- return False
291
-
292
- # print(f'{cur_dir_path=} {filename=}')
293
- if not filename:
294
- filename = '.yaml'
295
- cur_path = Path(cur_dir_path)
296
- if _check_file_match_folder(cur_path, filename):
297
- return cur_path
298
- for parent in cur_path.parents:
299
- # print('parent', parent, file=sys.stderr)
300
- if _check_file_match_folder(parent, filename):
301
- return parent
302
- raise FileNotFoundError("Error: Problem root folder not found.")
303
-
304
-
305
251
  # flake8: noqa: C901
306
252
  def update_args(problemid: str,
307
253
  loc_language: str,
@@ -0,0 +1,94 @@
1
+ """ Utility functions. """
2
+
3
+ from pathlib import Path
4
+ import os
5
+ from math import inf
6
+ from typing import Union
7
+ import yaml
8
+
9
+
10
+ def find_problem_root_folder(
11
+ cur_dir_path: Union[str, Path],
12
+ filename: str
13
+ ) -> Path:
14
+ """Find the root problem folder given a directory path and filename.
15
+
16
+ Args:
17
+ cur_dir_path (Union[str, Path]): String or Path
18
+ object of directory path
19
+ filename (str): filename to search for
20
+ including wildcard pattern
21
+
22
+ Returns:
23
+ Path: Path object of the root problem folder
24
+ """
25
+
26
+ def _check_file_match_folder(path: Path, filename: str) -> bool:
27
+ """ Check folder is same name as the filename given
28
+ filename including wildcard.
29
+
30
+ Args:
31
+ path (Path): Path object of directory path
32
+ filename (str): filename to search for
33
+ including wildcard pattern
34
+ Returns:
35
+ bool: True if path exists, False otherwise
36
+ """
37
+ for file in path.glob(filename):
38
+ name, ext = os.path.splitext(file.name)
39
+ folder_name = path.parts[-1]
40
+ # print(f'{name} {folder_name=} {name=} {ext=}')
41
+ if name == folder_name:
42
+ return True
43
+ # read yaml file
44
+ if ext == '.yaml':
45
+ with open(file, 'r', encoding='utf-8') as f:
46
+ data = yaml.safe_load(f)
47
+ if 'problemid' in data:
48
+ return True
49
+ return False
50
+
51
+ # print(f'{cur_dir_path=} {filename=}')
52
+ if not filename:
53
+ filename = '.yaml'
54
+ cur_path = Path(cur_dir_path)
55
+ if _check_file_match_folder(cur_path, filename):
56
+ return cur_path
57
+ for parent in cur_path.parents:
58
+ # print('parent', parent, file=sys.stderr)
59
+ if _check_file_match_folder(parent, filename):
60
+ return parent
61
+ raise FileNotFoundError("Error: Problem root folder not found.")
62
+
63
+
64
+ def check_answer(expected: str, ans: str, places: float = inf) -> bool:
65
+ """Compare two numeric strings with given precision.
66
+
67
+ Args:
68
+ expected (str): expected result
69
+ ans (str): actual result
70
+ places (float): decimal places for approximation;
71
+ default inf for string comparison
72
+
73
+ Returns:
74
+ bool: True if the two values are equal, False otherwise
75
+ """
76
+ expect_ans = expected.strip().split('\n')
77
+ actual_ans = ans.strip().split('\n')
78
+ if len(expect_ans) != len(actual_ans):
79
+ return False
80
+
81
+ if places == inf:
82
+ if expect_ans == actual_ans:
83
+ return True
84
+ else:
85
+ return False
86
+ try:
87
+ for i, ex_ans in enumerate(expect_ans):
88
+ flt_expected = float(ex_ans)
89
+ flt_ans = float(actual_ans[i])
90
+ if abs(flt_expected - flt_ans) > 10**(-places):
91
+ return False
92
+ return True
93
+ except ValueError:
94
+ return False
@@ -1,7 +1,7 @@
1
1
  [tool.poetry]
2
2
  name = "kattis-cli"
3
- version = "1.0.3"
4
- authors = ["Ram Basnet <rambasnet@gmail.com>"]
3
+ version = "1.0.5"
4
+ authors = ["Ram Basnet <rbasnet@coloradomesa.edu>"]
5
5
  description = "A command-line tool for Kattis"
6
6
  readme = "README.md"
7
7
  repository = "https://github.com/rambasnet/kattis-cli"
File without changes
File without changes
File without changes