Coder Social home page Coder Social logo

kks's People

Contributors

antyats avatar darkkeks avatar dubr0vin avatar m0r0zk01 avatar maximkm avatar namorniradnug avatar objatiegroba avatar senchopens avatar technothecow avatar tmlev avatar vvd170501 avatar yuki0iq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

kks's Issues

Частичная синхронизация портит список контестов

При синхронизации с фильтром (kks sync sm01) в файл .kks-contests/.index (список существующих контестов) записываются только синхронизированные в последний раз контестов. Из-за этого команды kks (un)hide могут не работать

Падает kks submit

  • Проблема: kks крашится при submit
  • Версия питона: 3.8
  • Трейс ошибки:
Traceback (most recent call last):
  File "/home/alex/.local/bin/kks", line 8, in <module>
    sys.exit(cli())
  File "/home/alex/.local/lib/python3.8/site-packages/click/core.py", line 829, in call
    return self.main(*args, **kwargs)
  File "/home/alex/.local/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/alex/.local/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/alex/.local/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/alex/.local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/alex/.local/lib/python3.8/site-packages/kks/cmd/submit.py", line 21, in submit
    rootdir = find_problem_rootdir()
  File "/home/alex/.local/lib/python3.8/site-packages/kks/cmd/submit.py", line 54, in find_problem_rootdir
    if cwd.is_relative_to(hidden):
AttributeError: 'PosixPath' object has no attribute 'is_relative_to'
  • Причина: is_relative_to была добавлена в версии питона 3.9 вроде

Неоптимальный парсинг страниц

Парсинг страниц, получаемых от ejudge, работает неоптимально.
Например, в функции parse_rows в ejudge_standings в каждой строке таблицы теги ищутся по 3 раза

В vvd170501/kks@0fffb16 реализован альтернативный вариант - все теги <td> находятся за один вызов find, а потом, в зависимости от класса, содержимое тегов сохраняется в нужные переменные.

Время работы функции parse_rows (на момент запуска команды в таблице 32 строки, 73 столбца):

  • Ubuntu 20.04, x86_64: старый вариант - 45-50 мс, новый - 8-10 мс
  • Android 11, aarch64: старый вариант - 240 мс, новый - 46 мс

Возможно, парсинг в классе Statement можно оптимизировать похожим образом Для Statement очевидных оптимизаций нет, и при синхронизации в любом случае запросы к ejudge занимают намного больше времени, чем парсинг страниц

Разделение опций сборки и запуска решений

В версии 1.7.0 (0958b08) класс kks.util.testing.RunOptions используется как при запуске, так и при компиляции решения (опция asan). Этот же класс используется при запуске генератора тестов (см kks.cmd.gen), хотя в этом случае в нём используется только опция ignore_exit_code (и неявно используется asan в случае, если генератор написан на C++)

Стоит создать отдельный класс для опций компиляции (туда же можно добавить аргумент verbose, который передаётся из kks run и kks test). Также, возможно, есть смысл создать отдельный класс для опций запуска генератора (как вариант - использовать наследование от какого-нибуть базового класса)

(см. #45 (comment))

Слишком много предупреждений при повторной синхронизации

При запуске синхронизации выводится предупреждение для каждой ранее синхронизированной задачи. Учитывая то, что к концу года задач будет намного больше, стоит как-то изменить вывод (см. #25 (comment))

Также для скрытых контестов выводится путь до папки контеста относительно корневой директории (например, .kks-contests/sm01/1), что тоже значительно увеличивает длину вывода (см. #25 (comment))

Перевод строки в конце семплов

В некоторых задачах (по крайней мере, sm10-1), не требуется перевод строки в конце вывода.
kks sync всегда добавляет перевод строки к примерам из условия (на этой задаче корректное решение не пройдёт тестирование через kks test).
Есть ли смысл что-то с этим делать?

Синхронизация условий задач

Было бы хорошо добавить синхронизацию условий вместе с семплами.
Например, это позволит полностью взаимодействовать с ejudge чеез терминал (наверное, единственное, что нельзя будет сделать без использования браузера — отправка/получение сообщений).
Для синхронизации не потребуется дополнительных запросов к ejudge, т.к. для семпла уже запрашивается полная страница с задачей.

[feature request] Скачивание исходного кода при синхронизации с ejudge

Возможно, стоило бы добавить в команду "kks sync" скачивание исходного кода отправленных ранее решений (например, может пригодиться для использования кода из ДЗ на КР).
Альтернативный вариант - добавить для этого отдельную команду.

kks status --todo не отображает реджектнутые таски по которым прошёл дедлайн

  • Ожидаемое поведение: сделать надо бы все задачи, по которым пришёл реджект, а значит и показывать их тоже надо
  • Реальное поведение: реджектнутые задачи, по которым уже прошёл дедлайн, не показываются

Пришедший реджект:
image

Отсутствие реджекта в --todo:
image

Самое интересное что до жёсткого дедлайна ещё 3 дня (сейчас 2021.04.05, 01:48):
image

Команда «дедлайны»

Предлагаю команду deadlines, которая выводит все актуальные контесты в таком формате:
Номер контест, дата, сколько баллов осталось.
Типа
sm01 02.03.1998 -1000

Неиспользуемая опция "--ignore-exit-code" в команде "gen"

Опция --ignore-exit-code в команде kks gen используется только для объекта класса TestSource, в котором она ни на что не влияет. Если флаг добавлен к этой команде по ошибке, а не с расчетом на добавление функционала в будущем, то его стоит удалить.

Использование API для синхронизации условий

В текущей версии (1.12.7) для синхронизации условий используется парсинг страницы.
В #66 / #71 при синхронизации через ssh используются ответы от API, полученные с помощью ejudge-fuse.
Можно использовать API вместо парсинга страницы для обычной синхронизации условий.
Плюсы:

  • Условие, получаемое через API, не нужно выделять из полного кода страницы -> парсинг нужен только для получения семплов -> упрощение кода, ускорение парсинга
  • html-файл получается более читаемым - сохранены пробелы между параграфами
  • Информация о задаче доступна через API.problem_status даже при недоступном условии (хотя вряд ли есть смысл её получать без условия)

Минусы:

  • Нужно отдельно получать информацию о задаче через API.problem_status (сейчас она парсится из того же кода страницы, откуда берётся условие).
  • Два запроса вместо одного -> замедление почти в 2 раза. Вместо ~200 мс на получение условия будет тратиться 300-400 мс

Не работают аргументы с kks gen

При запуске kks gen c указанием аргументов (например kks gen 1), происходит вылет с ошибкой

File "/home/user/.local/lib/python3.9/site-packages/kks/util/testing.py", line 26, in generate_input
    args = [test] + (additional_args or [])
TypeError: can only concatenate list (not "tuple") to list

python 3.9.1

Код завершения команды "kks run"

Сейчас (версия kks 1.9.0) команда kks run всегда завершается с кодом 0.
Возможно, правильнее будет завершать работу команды с тем же кодом, который возвращает скомпилированное и запущенное решение.
Тогда будет иметь смысл (например) такой вариант запуска: kks run || echo RE

Автоопределение расширений для шаблонов при синхронизации

Можно определять расширение для шаблонного файла решения, который создаётся при синхронизации (файл вида sm12-3.c), по полному названию задачи (названия следуют шаблону "[pref]/..."). Судя по задачам прошлых лет, существующие префиксы - "c", "asm", "unix" и пустая строка.
Очевидные расширения: "c" -> "c", "asm"->"S"
Для префикса "unix" и любых других, если они появятся, можно пока оставить расширение "c" по умолчанию

"kks top -m" для КР

Во время проведения КР kks top -m выдаёт некорректные результаты.
На страницах задач не указывается полный балл, поэтому для его получения используется API. Во время проведения КР и тестирования задач его значение равно 1, поэтому в качестве максимального балла используется kks.cmd.top.MIN_SCORE, равное 20
На скриншоте - вывод команды во время проведения КР06 (опция max_kr включена)
2021-04-16 11-02-20

(Корректный) пересчёт баллов для КР в "kks top --max"

В интерфейсе ejudge после дедлайна полностью скрывается описание задачи (остаётся только дата начала и дедлайн). Из-за этого, если кеш для kks top --max был очищен, максимальный балл для таких задач становится равным 0. Поэтому для отклонённых задач пересчёт баллов перестаёт работать.
API позволяет получить максимальные баллы даже после дедлайнов
Добавлено в #109

# выставить для всех задач правильное значение макс. балла

from kks.util.ejudge import EjudgeSession
from kks.util.storage import Cache

s = EjudgeSession()
a = s.api()
problem_ids = [p['id'] for p in s.with_auth(a.contest_status)['problems']]
problems = [a.problem_status(pid)['problem'] for pid in problem_ids]
full_scores = {p['short_name']: p['full_score'] for p in problems}

with Cache('problem_info', True, 2).load() as cache:
    cache.set('full', full_scores)

Возможная проблема - для задач из КР во время проведения значение full_score равно 1 (может быть другим?), непонятно, когда появляется настоящее значение - сразу после завершения КР или только после начала тестирования решений. Поэтому, возможно, придётся добавлять дополнительную логику для таких задач

[H2T] Неправильное конвертирование тега <pre> в списках

Такая разметка:

<ol>
  <li>some text
  <pre>first_line
second_line
third_line</pre>
  </li>
</ol>

Конвертируется в

1. some text

        first_line
    second_line
    third_line

(похожая проблема возникает при конвертировании условия ku02-4).

Начиная со второй строки, у текста из <pre> не хватает отступов. Из-за этого эти строки перестают распознаваться как код.

Так происходит, потому что отступ для первой строки используется дважды (1, 2).

Пока непонятно, как это можно исправить без копирования большого количества кода (HTML2Text.o)

В списке дедлайнов как-то помечать, что контест уже сдан

Когда использую kks deadlines, непонятно, есть ли еще не сданные задачи в каком-то контесте.

Не знаю, как это сделать норм, то можно, например, поставить звездочку рядом с тем контестом, в который еще можно что-то заслать.

cc @vvd170501

Количество тестов при выполнении kks test

Сейчас при выполнении kks test выводится примерно следующее:

Compiling... Successfully compiled binary a.out
All tests passed!   

Хочется видеть еще и количество тестов, на которых запускалось решение.

Расширенное тестирование (kks test 2.0)

Идея ещё с прошлого года, но до её реализации я так и не дошёл.
Возможно, заинтересует кого-нибудь из слушателей АКОСа этого года.

Во второй половине курса было много задач, в которых использовались аргументы командной строки и/или предполагалась работа с файловой системой.
kks test умеет генерировать только входные данные для программы (в теории, с флагом -v генератор может изменять ФС, но это изначально не предполагалось).

Есть предложение расширить функционал тестирования, чтобы можно было:

  • Использовать для запуска решения аргументы командной строки
  • Настраивать внешние условия для тестов
    (например, создавать файлы/директории, с которыми должна работать программа, а после тестирования удалять их)
  • Настраивать переменные окружения для тестируемой прогаммы (в том году было было 2 или 3 задачи, в которых они использовались, но это достаточно просто реализуется)

В такой реализации gen.py может выглядеть примерно так:

import os
import sys
import random
imoort typing as t


"""
Sample problem:

1) The program receives a file name `f` in argv[1].
2) An IP is passed via `HOST` environment variable.
3) Input contains a number `n`.
The program must:
1) Read 32-bit integers from `f` (in text mode).
2) Myltiply each by `n`.
3) Send the multiplied integers to `HOST:9999` in binary form (little-endian).
4) Write to stdout the number of processed integers.
"""


def _filename(test: int) -> str:
    random.seed(test)
    return random.choice(['./a.txt', './b.txt'])


def _multiplier(test: int) -> int:
    random.seed(test)
    return random.randint(1, 100)


def _data(test: int) -> t.List[int]:
    random.seed(test)
    return [randint(1, 1000) for i in range(10)]


def gen_input(test: int) -> None:
    """Generates test input.

    Test input should be written to stdout.
    It will be passed to stdin of your program.
    """
    random.seed(test)
    print(_multiplier(test))


def args(test: int) -> t.List[str]:
    """Generates command-line arguments for the tested program.

    If this function returns ['a', 'b'],
    your program will be launched like this: `./a.out a b`. 
    """
    return [_filename(test)]


def env(test):
    """Generates test environment variables."""
    random.seed(test)
    env = os.environ.copy()
    env['HOST'] = f'127.0.0.{random.randint(1, 254)}'
    return env


def external(test):
    """Sets up and cleans external conditions for tests.

    Possible examples:
    - changing the FS (creating/modifying files),
    - changing the working directory
    - setting limits (setrlimit, cgroups?)
    - rtc.
    """
    # ========== Setup ==========
    filename = _filename(test)
    data = _data(test)
    with open(filename, 'w') as f:
        f.write(' '.join(data) + '\n')
    # ========== Testing ==========
    yield
    # program is being tested
    # checks are performed
    # ========== Cleanup ==========
    os.unlink(filename)


def check(test):
    """Checks external changes.

    If results are incorrect, should raise an error.
    Output from the program and solve.py will be compared separately.
    """
    # Assuming a server is listening at `HOST:9999`
    # and is writing received integers to `/tmp/server_log` in text form. 
    with open('/tmp/server_log', 'r') as f:
        # NOTE Not the most efficient way
        last_line = f.readlines()[-1]
    data = _data(test)
    modified_data = [int(x) for x in last_line.split()]
    multiplier = _multiplier(test)
    assert modified_data == [x * multiplier for x in data]


# Backwards compatibility
if __name__ == '__main__':
    t = int(sys.argv[1])
    gen_input(t)

Не работает header

Если написать программу с функцией для контеста, а потом подключить её в main.c через #include "name.c" для тестов, то будет ошибка:
image

Отображение символов окончания строки/табов/пробелов и т.д. в диффе при тестировании

При тестировании часто можно налететь на вот такую ситуацию: в правильном выводе в конце строки должен стоять '\n', но мы по ошибке решили вывести ' '. При этом понять, а что именно, собственно, не так, удаётся не сразу.

image

Предложение: возможно в таких случаях (ну или всегда) стоит как-то explicitly показывать, что от нас требуется перевод строки, а мы вместо него пихаем пробел?

Оптимизация импортов

Импорты requests и bs4 в сумме занимают около 100мс и выполняются даже при запуске локальных команд (например kks run)

Тестировалось на vvd170501/kks@77f5201

$time kks run --help

import requests 0.051137447357177734
import requests 2.384185791015625e-07
import bs 0.05008339881896973
import h2t 0.002858400344848633
import requests 7.152557373046875e-07
import bs 2.384185791015625e-06
Usage: kks run [OPTIONS] [RUN_ARGS]...
...
real	0m0,192s
user	0m0,164s
sys	0m0,028s

Originally posted by @vvd170501 in #45 (comment)

Можно сделать эти импорты (и/или импорты модулей kks.ejudge и kks.ejudge_submit) более локальными (как было сделано с pkg_resources в 992caf3). Это должно ускорить запуск локальных команд

Не работает kks top --global

Failed to send standings to kks api
Failed to receive global standings: HTTPSConnectionPool(host='kks.darkkeks.me', port=443): Max retries exceeded with url: /api/get?year=2021&contest_id=203&login=bpmi203-129 (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1131)')))
Standings are not available now :(

Ошибка линковки для многопоточных решений при отключенном санитайзере

При попытке компиляции многопоточного решения (команды build / run / test) с использованием опции --no-asan линковщик выдаёт ошибку (т.к. не производится линковка с libpthread).

Варианты решения проблемы:

  • Добавить флаг -pthread в дефолтный таргет. По идее, это не должно влиять на скорость компиляции, если многопоточность не используется.
  • Добавлять флаг к используемым опциям, если в названии задачи встречается /pthread/ (/thread/).
    Если будет проводиться КР на многопоточность, этот вариант для неё не сработает.
  • Добавить отдельный таргет для многопоточных решений. Минусы - придётся явно указывать таргет при компиляции / запуске решения, нужно опять переписывать (или полностью дописывать) логику компиляции C++-решений.

Неполная глобальная таблица

Новые контесты отображаются только у тех групп, которые отправляли на сервер статистику после добавления контеста.
Из-за этого некорректно работает подсчёт максимальных баллов (возможно получить разницу в 500 баллов, которой на самом деле нет).
Screenshot from 2021-02-13 17-47-20
(например, 306 и 308 строки - без опции --max у обоих пользователей 0 баллов)

Решение - добавлять новые контесты (с пустыми статусами задач) для всех групп.
Это можно реализовать как на стороне сервера, так и на стороне клиента.

Поддержка XDG Base Directory Specification

Готов сделать пул-реквест, если вы не против такого изменения.
План такой:

  • изменить поведение функции config_directory в kks/util/common.py (если существует ~/.kks, то вернуть ее, иначе вернуть ~/.config/kks`)
  • хранить PickleStorage в $XDG_DATA_HOME
  • хранить Cache(PickleStorage) в $XDG_CACHE_HOME
  • обновить README.md, kks/cmd/lint.py kks/cmd/top.py

Дедлайны в kks top --max

Некоторые задачи в ejudge могут отображаться без штрафа, но с дедлайном (баг ejudge? Задача с отклонённым старым и принятым новым решением).
Screenshot from 2021-02-11 14-20-26
При этом kks не учитывает хард-дедлайн при подсчёте максимальных баллов, из-за этого получается такое (низ глобальной таблицы):
Screenshot from 2021-02-11 14-24-19

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.