Рубрики
Без рубрики

Как я автоматизировал свои обязанности по оценке

Первоначально опубликовано в Renegade Coder 11 марта 2019 года с тех пор, как я начал чай … Tagged с помощью обучения, Java, тестирования, Python.

Первоначально опубликовано в Renegade Doder 11 марта 2019 года

С тех пор, как я начал преподавать, я пытался найти способы автоматизировать свои обязанности по оценке. В конце концов, это очень трудоемкое, и я не считаю, что это очень полезно для студентов. Каждую минуту, которую я экономлю из -за автоматизации, восходит к обеспечению качественной обратной связи, сосредоточению на моем обучении и улучшении моего психического здоровья. Кто мог бы сказать «нет»?

Ответственность за оценку

Я упоминал свои обязанности по оценке несколько раз в этой серии, но я подумал, что не повредит их снова.

В дополнение к преподаванию, я отвечаю за 12 проектов, 14 домашних заданий, 14 лабораторий и 3 экзамена за семестр. Умножьте все эти цифры на 40, и это общее количество заданий в течение семестра. Как вы, наверное, можете себе представить, это огромное время за пределами класса.

Чтобы ускорить ситуацию, я попытался найти способы автоматизировать оценку. Возможно, самая большая возможность сэкономить время – это проекты, которые могут занимать около 6 часов в неделю. К сожалению, эта длительная продолжительность связана с горсткой проблем:

  • Проекты стоят наибольшего количества очков, поэтому они требуют наибольшей обратной связи.
  • Проекты должны быть проверены, которые могут занять некоторое время в зависимости от сложности программы.
  • Проекты организованы в пакетах, поэтому их необходимо переносить в архивных форматах, таких как Zip.
  • Проекты написаны студентами, поэтому стиль сильно варьируется, что затрудняет чтение кода.

Как вы можете видеть, существует много строгих требований для проектов, которые могут сделать оценку очень трудоемкой задачи. Чтобы добавить оскорбление к травмам, учащиеся имеют тенденцию не следовать указаниям, поэтому файлы иногда должны быть отредактированы, прежде чем их можно будет выполнить. Худший сценарий: я должен связаться с студентами, потому что они не представляли все.

Оценка автоматизация

Как человек, который всегда пытается доить каждую небольшую эффективность из повседневных задач, я быстро взял на себя возможность автоматизировать оценку проекта. Честно говоря, я просто не мог себе представить, чтобы завершить следующую процедуру для 40 учеников, не сойдя без ума:

  1. Скачать студенческое решение.
  2. Распространение студенческого решения.
  3. Загрузите файл (ы) в IDE.
  4. Запустите файл (ы) (повторите для различных тестовых случаев).
  5. Калибровочный стиль.
  6. Оценить решение на основе тестирования и стиля.
  7. Дать обратную связь.

Посмотрев на этот список, я чувствую, что сделал правильный выбор для автоматизации моей оценки, но что именно влечет за собой автоматизация? Давайте взглянем.

Представляем Junit

В течение моего первого семестра лучшим вариантом, который у меня был в то время для автоматизации, был Тестирование JUNIT Анкет На любой неделе мне потребуется около 90 минут, чтобы написать решение для проекта JUNIT и еще 2 часа, чтобы завершить оценку. Другими словами, мне удалось сократить 6 -часовой процесс вплоть до 4 часов. Я возьму это в любой день!

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

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

private static ArrayList getTestClasses(int project) {
    ArrayList toTest = new ArrayList();
    toTest.add("osu.cse1223.Project%1$s");
    toTest.add("osu.cse1223.Project%1$sa");
    toTest.add("osu.cse1223.CSEProject%1$s");
    toTest.add("cse1223.Project%1$sa");
    toTest.add("cse1223.Project%1$s");
    toTest.add("project%1$s.Project%1$s");
    toTest.add("Project%1$s");
    toTest.add("Project%1$sA");
    toTest.add("osu.cse1223.DragonsGame");
    toTest.add("Project04.DragonTrainers");
    toTest.add("Main");
    String projectNumberWhole = Integer.toString(project);
    String projectNumberPad = "0" + projectNumberWhole;
    int originalSize = toTest.size();
    for (int i = 0; i < originalSize; i++) {
        String test = toTest.get(i);
        toTest.set(i, String.format(test, projectNumberPad));
        toTest.add(String.format(test, projectNumberWhole));
        toTest.add(String.format(test, projectNumberPad).toLowerCase());
        toTest.add(String.format(test, projectNumberWhole).toLowerCase());
    }
    return toTest;
}

Кроме того, поскольку многие из проектов используют основной метод и форматирование текста, я потратил много времени на то, чтобы захватить стандартный выход и записать в стандартный ввод. Проверьте мои методы настройки и разрыва:

@Before
public void setUp() {
    System.setOut(new PrintStream(outContent));
    System.setErr(new PrintStream(errContent));
}

@After
public void tearDown() {
    System.setIn(System.in);
    System.setOut(System.out);
}

В целом, решение JUNIT довольно неуклюже, но оно выполнило работу.

Скрипт беззазарного раза

В то время как Джунит сэкономил мне много времени, все еще были способы сократить время. В частности, я обнаружил, что трачу много времени вручную, рассеяв папки.

Чтобы немного поставить вещи в перспективу, мы используем Canvas для загрузки решений, которые делают немного имени файла. В результате отдельные заявки на Java заканчиваются разрушенными именами файлов. Чтобы бороться с этой проблемой, мы просим студентов экспортировать свои решения из Eclipse в качестве файлов zip. Это помогает двумя способами:

  1. Он защищает базовые имена файлов Java.
  2. Он сохраняет структуру упаковки, когда это необходимо.

К сожалению, я застрял, рассеяв 41 файл каждую неделю. Конечно, я ускорил ситуацию с 7-Zip, но мне все еще приходилось делать это вручную.

В конце концов, я решил автоматизировать этот процесс распаковки с помощью Python и библиотеки Zipfile:

def extract_main_zip() -> str:
    """
    Extracts an archive given by the user.
    :return: the path to the unzipped archive
    """
    archive_name = filedialog.askopenfilename(
        title="Select Zip File",
        filetypes=(("zip files", "*.zip"), ("all files", "*.*"))
    )
    archive = zipfile.ZipFile(archive_name)
    archive_path = os.path.join(os.path.dirname(archive_name), ARCHIVE)
    archive.extractall(archive_path)
    archive.close()
    return archive_path

В этой функции я использую TK Чтобы открыть графический интерфейс выбора файла. Оттуда я распаковываю выбранный zip -файл и возвращаю путь к сайту извлечения.

Поскольку zip -файл содержит zip -файлы, я также решил автоматизировать этот процесс распаковки:

def extract_solutions() -> str:
    """
    Extracts user folders.
    :return: the path to the extraction site
    """
    unzipped_archive = extract_main_zip()
    dump = os.path.join(os.path.dirname(unzipped_archive), DUMP)
    pathlib.Path(dump).mkdir(parents=True, exist_ok=True)
    for file in os.listdir(unzipped_archive):
        file_name = os.fsdecode(file)
        file_path = os.path.join(unzipped_archive, file_name)
        file_path_plus_name = os.path.join(dump, file_name.split("_")[0])
        if file_name.endswith(".zip"):
            zip_file = zipfile.ZipFile(file_path, "r")
            zip_file.extractall(file_path_plus_name)
            zip_file.close()
        else:
            name = file_name.split("_")[0]
            project = file_name.split("_")[-1]
            pathlib.Path(os.path.join(dump, name)).mkdir(parents=True, exist_ok=True)
            new_file_path = os.path.join(dump, name, project)
            os.rename(file_path, new_file_path)
    return dump

Как мы видим, эта функция вызывает предыдущую функцию и сохраняет путь к сайту извлечения. Оттуда функция генерирует новый сайт извлечения, называемый Damp.

После этого мы повторяем все файлы ZIP, извлекаем их и размещаем их в новую папку с именем студентов в качестве имени каталога. Если мы столкнемся с файлом, который не является ZIP -файлом, мы попытаемся решить проблему «Манглинг», прежде чем поместить файл в папку вместе со всеми извлеченными файлами ZIP.

Когда мы закончим, мы возвращаем путь к новому сайту извлечения. Всего у нас будет две новые папки. Тот, который содержит все файлы ZIP (архивы), и тот, который содержит все незамеченные файлы (дамп). На этом этапе каталог архивов бесполезен, поэтому мы могли бы удалить его.

Тестирование автоматизации

С автоматизированным процессом извлечения я, вероятно, сохранил себя около 30 секунд файла, который составляет около 20 минут. Конечно, я бы взял это в любой день.

Тем не менее, я чувствовал, что еще предстоит сделать еще что -то еще. В частности, я обнаружил, что это действительно требует времени, чтобы сделать следующее:

  1. Скачать все студенческие материалы.
  2. Запустите сценарий извлечения Python.
  3. Загрузите доктор Ява.
  4. Перетащите тестовый файл в IDE.
  5. Отправка студентов (повторить 40 раз).
    1. Получите подчинение студента и бросьте в IDE.
    2. Хит тест.
    3. Проанализируйте результаты теста.
    4. Оценить стиль отправки.
    5. Дать обратную связь.

Каким бы раздражающим был этот новый процесс, это было невероятное улучшение по сравнению с оценкой вручную. В любую неделю я мог бы потратить только 2-3 часа, оценивая проекты. Было бы глупо сказать, что вся автоматизация до этого момента не стоила того.

Тем не менее, в процессе выше еще много ручных шагов, поэтому я взял на себя обязательство снова уменьшить шаги:

  1. Скачать все студенческие материалы.
  2. Запустите сценарий извлечения и тестирования Python.
  3. Оценить стиль отправки (повторить 40 раз)
  4. Дайте обратную связь (повторить 40 раз)

Для этого я расширил свой сценарий Python, чтобы поддержать тестирование JUNIT. На высоком уровне каждое решение оценивается следующим образом:

def grade_file(classes: str, build_file: str, test_class: str, results):
    """
    Grades a file.
    :param classes: a directory contain files under test
    :param build_file: a file to test
    :param test_class: the path to the test file
    :param results: the results file
    :return: None
    """
    classpath = "C:\\Program Files\\JUnit\\junit-4.13-beta-2.jar;C:\\Program Files\\JUnit\\hamcrest-all-1.3.jar;"
    compile_junit(classes, classpath, build_file)
    compilation_results = compile_junit(classes, classpath, test_class)
    execution_results = test_junit(classes, classpath, get_test_name(test_class))
    write_to_file(results, compilation_results, execution_results, build_file)

Помимо жестко -кодированной класса, это решение автоматически собирает решение для учащихся и мой тестовый код JUNIT, выполнить тест и распечатать результаты в файл. В этот момент все, что мне нужно сделать, это сканировать файл для имен студентов и их отчет о тестировании, прежде чем я смогу оценить оценку.

Будущие расширения

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

С другой стороны, было бы неплохо создать отчет о тестировании, который просто рассказывает мне оценки, поэтому я не принимаю какую -либо когнитивную нагрузку, чтобы перевести тестовые примеры в оценки. Если это возможно, вероятно, можно также автоматизировать загрузку класса.

С конца до конца у нас будет система, которая полностью автоматизирует оценки студентов. Мне не нужно было бы уделять время оценке оценок. Вместо этого я мог бы сосредоточиться на том, что меня волнует, что является отзывом студентов. В конце концов, оценки являются своего рода произвольными показателями. Обратная связь – это то, что помогает студентам расти.

Кроме того, без когнитивной нагрузки от оценки, я бы, вероятно, смог бы создать лучшие лекционные материалы, удерживать лучшие рабочие часы и лучше поддержать электронную почту. Это была бы мечта!

Недостатки

Недавно я рассказывал другу о том, что я сделал для автоматизации моей оценки, и у них был отличный вопрос для меня:

Если вы автоматизируете все, как вы собираетесь обнаружить плагиат?

  • Амиго, 2019

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

Но может быть интересно расширить текущее решение для обнаружения плагиата на местном уровне. Другими словами, я мог бы сохранить все решения и отличать их друг против друга, как иду. Это может быть весело!

Тем не менее, я никогда не был обжедением для наказания. Мои основные ценности основаны на доверии, поэтому я склонен предлагать студентам те же ценности. Если я не подозреваю никакого мошенничества, я не собираюсь охотиться за этим. Мое доверие – это проиграть.

Сила автоматизации

Время от времени я вижу мем, высмеивая разработчиков, которые предпочитают, чтобы написать сценарий, чтобы автоматизировать задачу, чем потратить пять минут, выполняя эту задачу, и я очень виноват в этом. Тем не менее, я не думаю, что мои поиски автоматизации – это плохо. В конце концов, я всегда делюсь своими решениями для общественности.

Например, вы можете проверить Весь тестовый код JUNIT, который я использую для автоматизации оценки для моего курса CSE 1223 Анкет Например, папка Projects содержит все сценарии тестирования JUNIT. Между тем, Недавно я перенес сценарий Python в собственную репо Анкет Не стесняйтесь оглядываться и одолжить часть моей работы в вашей собственной выгоде. Вот почему я делаю то, что делаю!

Кроме того, я должен упомянуть, что сценарий оценки Python прошел много изменений с тех пор, как я написал эту статью. Например, теперь он сбрасывает все оценки в файл JSON, который позволяет мне гнездясь о частях файла в IDE, поэтому его проще сканировать. С улучшением JSON, я могу получить представление о высоком уровне о том, кто преуспел, а кто этого не сделал, чтобы оценить аналогичные оценки подряд.

Если вы знаете каких -либо учителей, которые могут быть заинтересованы в автоматической оценке, почему бы не отправить им эту статью. Я уверен, что они это признали! Во всяком случае, спасибо за то, что нашли время прочитать эту статью.

Оригинал: “https://dev.to/renegadecoder94/how-i-automated-my-grading-responsibilities-42g3”