Skip to content

andrew--r/yandex-second

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Задание 2

Описание

Предметная область

Студенты в Школе разработки интерфейсов делятся на команды. В процессе обучения студенты выполняют задания. Оценки за них ставятся либо конкретному студенту, либо всей команде студентов. В конце Школы перед менторами стоит задача распределения студентов. Каждый ментор составляет приоритезированный список студентов, в которых он заинтересован. Каждый из студентов также составляет приоритезированный список менторов, к которым он бы хотел пойти.

Задача

Создайте библиотеку, которая реализует такой программный интерфейс:

  • добавление студентов-участников и объединение их в команды;
  • создание командных и индивидуальных заданий;
  • выставление оценок за задание;
  • создание приоритезированных списков менторов и студентов;
  • решение задачи распределения студентов среди менторов в соответствии с приоритезированными списками.

Выполнение одной или нескольких дополнительных задач будет плюсом:

  • организуйте процесс сериализации/десериализации в разных форматах данных;
  • создайте тесты к библиотеке;
  • реализуйте веб-интерфейс или интерфейс командной строки для своей библиотеки.

Мои комментарии

Ход мыслей

Определяю, какие данные необходимо будет хранить. Выделяю четыре сущности:

  • Задания;
  • Студенты;
  • Команды студентов;
  • Менторы.

Решаю начать с наиболее независимой сущности. Описываю задание:

{
	id: 1,
	type: 'individual' || 'command',
	name: '',
	description: '',
}

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

{
	id: ++lastTaskId,
}

Пишу методы для добавления и получения заданий.

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

Описываю команду студентов:

{
	name: '', // уникальное поле
	members: [], // содержит идентификаторы участников
	tasks: [], // содержит данные о заданиях и прогрессе выполнения
}

Как должны выглядеть данные о заданиях и прогрессе выполения у команд и студентов? Минимальный набор необходимых данных:

{
	tasks: [
		{
			id: 1,
			completed: false,
			score: null,
		},
		{
			id: 1,
			completed: true,
			score: 10, // десятибалльная шкала
		}
	],
}

На основе представленных выше данных реализую интерфейс для добавленя и удаления команд, студентов и менторов.

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

Студента описал следующим образом:

{
	id: 1,
	fullname: 'John Doe',
	tasks: [],
	mentor: null,
	team: null,
	preferredMentors: [],
}

Поле team позволяет проверить, принадлежит ли студент к какой-либо команде. При удалении команды это поле автоматически сбросится на null у всех бывших участников удалённой команды.

Самая сложная часть задания — создание приоритезированных списков студентов и менторов, а также их распределение в соответствии с приоритетами.

Для начала нужно просто решить, в каком виде будут храниться приоритеты. Они должны быть довольно простые, то есть грубо говоря от наиболее предпочтительного к наименее предпочтительному, без дополнительных шкал. Поэтому можно просто хранить список идентификаторов в массиве, где элемент с индексом 0 — наиболее предпочтительный, а элемент с индексом length - 1 — наименее предпочтительный:

// Приоритезированный список менторов у студента
{
	mentors: [1, 3, 7, 4, ...],
}

// Приоритезированный список студентов у ментора
{
	students: [9, 26, 2, 5, ...],
}

Задача с распределением студентов и менторов по приоритетам для меня довольно нетривиальна. Во время размышлений над способом распределения решил каждому приоритету поставить в соответствие определённый «вес» — чем выше приоритет, тем больше вес. Затем сравнивать каждую пару «студент — ментор» и в соответствии с поставленными ими приоритетами считать её вес. Например, если они оба будут стоять друг у друга в наивысшем приоритете, вес у из пары получится тоже наивысший. После подсчёта веса каждой пары останется только распределить пары по весу, от наибольшего к наименьшему. Кроме того, при распределении нужно будет ограничить максимальное количество студентов у одного ментора, чтобы добиться равномерности.

В самом простом случае у каждого студента должен быть составлен приоритезированный список всех наставников, а у каждого наставника — приоритезированный список всех студентов. Однако мы живём не в идеальном мире, и, скорее всего, каждый наставник/студент занесут в список лишь несколько человек, в которых они заинтересованы больше всего. Будем считать, что те, кто не был занесён в список, имеют наименьший приоритет (и, соответственно, вес).

Таблица с весом каждой пары «студент/ментор» будет иметь такой вид:

[
	{
		studentId: 1,
		mentorId: 1,
		value: 20,
	},
	{
		studentId: 3,
		mentorId: 5,
		value: 4,
	}
]

После распределения у каждого студента в поле mentor будет лежать идентификатор наставника, а у каждого наставника в поле students будет лежать список идентификаторов его студентов.

About

Тестовое задание для поступления в ШРИ Яндекса

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published