Example #1
0
    def _act(self) -> None:

        pypi_info = requests.get(_PYPI_PACKAGE_INFO)
        releases = list(pypi_info.json()['releases'])
        if len(releases) == 0:
            log_red('Hmm seems like there is currently no pypi releases :-?')
            return
        current_latest_version = releases[-1]
        if current_latest_version != version:
            subprocess.check_call([
                sys.executable, "-m", "pip", "install", "--upgrade",
                "--no-cache-dir", f"kttool=={current_latest_version}"
            ])
            log(f'Installed version {color_green(current_latest_version)} successfully!'
                )
        else:
            log(f'You already have the {color_green("latest")} version!')
Example #2
0
    def remove_template(self) -> None:
        ''' Remove a template from ktconfig file'''
        existed_templates = self.load_kt_config()

        log(f'Which template would you like to {color_red("delete")} ? For eg cpp, cc, ...'
            )
        for k in existed_templates.keys():
            log(k)
        res = input()

        assert res in existed_templates, f'Invalid template chosen. Template {res} is not in ur config file'

        move_default = existed_templates[res]['default']
        existed_templates.pop(res, None)
        if existed_templates and move_default:  # move default to the first key of template
            existed_templates[next(iter(existed_templates))] = True
        with open(self.kt_config, 'w') as kt_config:
            json.dump(existed_templates, kt_config, indent=2)
Example #3
0
    def update_default(self) -> None:
        default_key = ''
        existed_templates = self.load_kt_config()

        log(f'Which template would you like to gen as {color_cyan("default")} ? For eg cpp, cc, ...'
            )

        for k, v in existed_templates.items():
            log(f'{k} {color_green("(default)") if v["default"] else ""}')
            if v["default"]:
                default_key = k
        res = input()

        assert res in existed_templates, f'Invalid template chosen. Template {res} is not in ur config file'
        existed_templates[default_key]["default"] = False
        existed_templates[res]["default"] = True
        with open(self.kt_config, 'w') as kt_config:
            json.dump(existed_templates, kt_config, indent=2)
        log_green('Yosh, your configuration has been saved')
Example #4
0
File: test.py Project: heiseish/kt
    def _act(self) -> None:
        """ Run the executable file against sample input and output files present in the folder
        The sample files will only be recognized if the conditions hold:
        - Naming style should be in{idx}.txt and ans{txt}.txt
        - for in{idx}.txt, there must exist a ans{idx}.txt with the same `idx`
        """
        self.detect_file_name()

        # Get sample files that match the condition
        usable_samples = self._gather_samples()
        # run test
        log(f'Problem ID : {color_cyan(self.get_problem_id())}')
        log(f'Lanuage    : {self.lang}')
        if self.pre_script:
            log_cyan(f'running {self.pre_script}')
            subprocess.check_call(shlex.split(self.pre_script))

        self._compare_samples(usable_samples)

        if self.post_script:
            log_cyan(f'running {self.post_script}')
            subprocess.check_call(shlex.split(self.post_script))
Example #5
0
 def _act(self) -> None:
     log(f'Current version: {color_cyan(version)}')
Example #6
0
    def add_template(self) -> None:
        question = 'Which template would you like to add:\n'
        selectable_lang = {}
        idx = 1
        existed_templates = {}
        options = {}

        log_green('Adapted from xalanq\'s cf tool')
        log('''
Template will run 3 scripts in sequence when you run "kt test":
    - before_script   (execute once)
    - script          (execute the number of samples times)
    - after_script    (execute once)
You could set "before_script" or "after_script" to empty string, meaning not executing.
You have to run your program in "script" with standard input/output (no need to redirect).

You can insert some placeholders in your scripts. When execute a script,
cf will replace all placeholders by following rules:

$%path%$   Path to source file (Excluding $%full%$, e.g. "/home/user/")
$%full%$   Full name of source file (e.g. "a.cpp")
$%file%$   Name of source file (Excluding suffix, e.g. "a")
$%rand%$   Random string with 8 character (including "a-z" "0-9")
        ''')

        existed_templates = self.load_kt_config()

        for template_type, lang in MAP_TEMPLATE_TO_PLANG.items():
            if template_type not in existed_templates:
                temp = f'{idx} ({lang.extension}): {lang.full_name}\n'
                question += temp
                selectable_lang[idx] = (template_type, lang)
                idx += 1

        res = input(question)
        ret = int(res)
        assert 1 <= ret < idx, 'Invalid input'

        selected_lang = selectable_lang[ret][1]

        import readline, glob

        def complete(text, state):
            return (glob.glob(os.path.expanduser(text) + '*') + [None])[state]

        readline.set_completer_delims(' \t\n;')
        readline.parse_and_bind("tab: complete")
        readline.set_completer(complete)
        options['path'] = os.path.expanduser(input('Path to template file: '))
        options['pre_script'] = ask_with_default('Pre-script',
                                                 selected_lang.pre_script)
        options['script'] = ask_with_default('Script', selected_lang.script)
        options['post_script'] = ask_with_default('Post-script',
                                                  selected_lang.post_script)
        options['default'] = False if existed_templates else True

        existed_templates[selected_lang.alias] = options
        with open(self.kt_config, 'w') as kt_config:
            json.dump(existed_templates, kt_config, indent=2)
        log_green(
            f'Yosh, your configuration has been saved to {self.kt_config}')
Example #7
0
File: test.py Project: heiseish/kt
    def _compare_samples(self, samples: List[Sample]) -> None:
        rusage_denom = 1 << 20
        actual = []
        expected = []
        diff = []

        for sample in samples:
            is_ac = True
            actual.clear()
            expected.clear()
            diff.clear()
            try:
                with open(sample.output_file, 'r') as f:
                    expected = [l.strip(" \n") for l in f.readlines()]
                with open(sample.input_file, 'rb') as f:
                    raw_input = f.read()
                # log_cyan(f'running {self.script}')
                p = subprocess.Popen(shlex.split(f'{self.script} -'),
                                     stdin=subprocess.PIPE,
                                     stdout=subprocess.PIPE,
                                     shell=False,
                                     preexec_fn=os.setsid)
                register_subprocess(p)
                proc = psutil.Process(p.pid)
                mem_used = proc.memory_info().rss / rusage_denom
                start_time = time.perf_counter()
                raw_output = p.communicate(raw_input)[0].decode()
                p.wait()
                taken = time.perf_counter() - start_time
                actual = [z.strip(" \n") for z in raw_output.split('\n')]
                make_list_equal(actual, expected)

                for i in range(len(expected)):
                    ''' 
                    Compare the values line by line
                    For each line, compare the values from left to right. 
                    '''
                    ith_line_exp = [z for z in expected[i].split(' ')]
                    ith_line_actual = [z for z in actual[i].split(' ')]

                    make_list_equal(ith_line_exp, ith_line_actual)
                    current_diff = ''
                    for j in range(len(ith_line_exp)):
                        lhs = ith_line_exp[j]
                        rhs = ith_line_actual[j]
                        is_good, now_diff = compare_entity(rhs, lhs)
                        is_ac &= is_good
                        current_diff += now_diff

                    diff.append(current_diff)
                if is_ac:
                    log(
                        color_green(
                            f'Test Case #{sample.index}: {"Accepted".ljust(13, " ")} ... {taken:.3f} s   {mem_used:.2f} M'
                        ))
                else:
                    log(
                        color_red(
                            f'Test Case #{sample.index}: {"Wrong Answer".ljust(13, " ")} ... {taken:.3f} s   {mem_used:.2f} M'
                        ))
                    log(color_cyan('--- Input ---'))
                    log(raw_input.decode())
                    log(color_cyan('--- Diff ---'))
                    for i in range(len(diff)):
                        log(diff[i])

            except subprocess.CalledProcessError as e:
                log(
                    color_red(
                        f'Test case #{sample.index}: Runtime Error {e!r}'))
            except Exception as e:
                import traceback
                tmp_file = get_temp_log_file()
                with open(tmp_file, 'w+') as f:
                    f.write(traceback.format_exc())
                log(
                    color_red(
                        f'Test case #{sample.index}: Internal Error {e!r}. More info at {tmp_file}'
                    ))
Example #8
0
 def _act(self) -> None:
     log(f'Openning {self.get_problem_url()}')
     webbrowser.open(self.get_problem_url())
Example #9
0
 def _act(self) -> None:
     log(f'Problem is {self.problem_id}')
     problem_dir = self.cwd / self.problem_id
     problem_dir.mkdir(parents=True, exist_ok=True)
     self._gen_samples()