Автоматизируем новости

И другие нелинейные процессы принятия решений.

Автоматизируем новости, image #1

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

Предыстория

У нас есть рубрика «Новости» — там наши коллеги каждый день публикуют заметки о технологических и научных новинках.

Раньше процесс был устроен так:

  1. Каждый автор «пылесосит» свои источники.
  2. Авторы делают подборки событий и изобретений, о которых можно написать.
  3. Авторы присылают подборки дежурному редактору рубрики. Тот принимает решение, какие новости стоит взять в «Код», а какие — нет.
  4. Авторы пишут новости.
  5. Дежурный редактор проверяет и доделывает новости.

Основной затык с п. 3 — если редактор затупил или долго не отвечает, редакционный процесс может встать.

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

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

Автоматизируем новости, image #2

Что будем делать

Самый простой способ решить эту задачу — сделать веб-страницу с вариантами ответов. Вы выбираете нужные и получаете ответ: стоит эту новость брать или нет.

В чек-листе у нас есть значки: ✅ и ❌. Пусть галочка обозначает плюс 1 балл, а крестик — минус 1 балл. За каждый ответ мы прибавляем или отнимаем нужное количество баллов и смотрим на результат.

Чтобы понять, брать новость или нет, сделаем такую градацию:

  • если новость набирает отрицательное количество баллов, то точно не берём;
  • если сумма баллов равна нулю — переспросить шефа;
  • если новость набрала один балл, то всё решают картинки или видео — если они есть, то новость тоже есть;
  • если у новости в сумме 2 балла и выше — однозначно берём в работу.

Выбираем варианты ответов

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

Автоматизируем новости, image #3

Синяя точка означает, что мы выбрали первый вариант. Если выберем второй, то на первом она автоматически снимется:

Автоматизируем новости, image #4

За такой переключатель в HTML отвечает элемент <input> со свойством type="radio". Чтобы поставить его на страницу, пишут так:

<input name="result" type="radio" value="2">

Последнее свойство value отвечает за результат — какой ответ мы получим, если выберем этот вариант. Двойка у нас получилась от того, что в чек-листе напротив этого ответа стояло две галочки. Если бы было два крестика, мы бы написали value="-2".

Теперь у нас есть всё, чтобы оформить первый вопрос в виде кода на HTML:

<!-- Заголовок вопроса -->
<p><b>
Это результат или мысли?
</b></p>
<!-- Абзац, который состоит из переключателя и текста -->
<!-- У каждого ответа есть свой рейтинг, он записан в значение value -->
<p><input name="result" type="radio" value="2">
Что-то изобрели, получили результаты исследования, ключевое слово — результаты
</p>
<!-- Дальше всё то же самое -->
<p><inputname="result"type="radio"value="-1">
Только думают, планируют, размышляют
</p>
<p><input name="result" type="radio" value="-2">
Статья-обзор, как кто-то фантазирует о будущем
</p>
<br>

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

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

<p><b>
Это прорыв для человека?

</b></p>

<p><input name="mega" type="radio" value="-2">

Что-то существующее немного улучшат с помощью технологий

</p>

<p><input name="mega" type="radio" value="1"> 

Что-то существующее выведут на новый уровень с помощью технологий

</p>

<p><input name="mega" type="radio" value="2">

Речь о чём-то, что резко повышает качество жизни человека

</p>

<p><input name="mega" type="radio" value="-2">

Речь о чём-то, что в первую очередь поможет учёным или исследователям

</p>

<br>

<p><b>

Это на хайпе? 

</b></p>

<p><input name="hype" type="radio" value="1">

Новость про публичную фигуру: Маска, Безоса и т. д.

</p>

<p><input name="hype" type="radio" value="2"> 

Это касается сервисов или продуктов, доступных в России

</p>

<p><input name="hype" type="radio" value="2">

Это сделано или будет использоваться в России

</p>

<p><input name="hype" type="radio" value="-3">

Это касается продуктов или сервисов, которых нет в России? Алекса, например 

</p>

<br>

<p><b>

Можно посмотреть?

</b></p>

<p><input name="see" type="radio" value="3">

Есть красивая картинка или видео, где демонстрируются результаты работы

</p>

<p><input name="see" type="radio" value="-1"> 

У учёных есть идея, но пока нет картинок. Или есть картинка, но это скорее график

</p>

<p><input name="see" type="radio" value="1">

Эта картинка демонстрирует конкретно то, что изобрели?

</p>

<p><input name="see" type="radio" value="-1">

То, что изобрели, невозможно продемонстрировать как таковое, например, это скрытый алгоритм

</p>

<br>
Даже без дизайна и стилей страница выглядит как рабочий продукт
Даже без дизайна и стилей страница выглядит как рабочий продукт

Добавляем кнопку подсчёта баллов

Добавим на страницу кнопку, по нажатию на которую запустится скрипт подсчёта баллов:

<button onclick="count()"> Оценить </button>

К кнопке привязан обработчик событий onclick — он следит за нажатиями и запускает нужный скрипт. Скрипта у нас ещё нет, поэтому им и займёмся.

Логика будет такая:

  1. Обнуляем количество отмеченных вопросов и набранных баллов.
  2. Находим все переключатели на странице.
  3. Считаем, сколько из них отмечено. Если меньше четырёх (у нас 4 вопроса), то выводим сообщение, что не всё отмечено.
  4. Для каждого отмеченного считаем, сколько он даёт нам баллов, положительных или отрицательных, и складываем баллы вместе.
  5. Если у нас есть 4 ответа, то в зависимости от набранных баллов выводим результат.

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

Добавим абзац в самый конец страницы:

<!-- В самом низу сделаем пустой абзац, куда будем выводить результаты -->

<p class = "itogo"></p>

Пишем скрипт

В скрипте мы будем использовать три команды, которые нам ещё не встречались, но они довольно простые.

Чтобы не подключать jQuery и при этом находить нужные элементы на странице, используем функцию document.getElementsByClassName("itogo"). Она найдёт все элементы на странице с указанным классом (itogo) и вернёт массив из найденных элементов. Так как на странице у нас только один такой элемент с таким классом, то это сразу всё упрощает.

Вторая команда — функция document.getElementsByTagName('input'). Она находит все тэги input и делает из них массив с объектами. Дальше с ними можно уже работать как с обычными элементами — проверять их свойства и значения.

Третье — свойство getAttribute(). С его помощью мы выясним, переключатель перед нами или нет. Если свойство getAttribute('type') совпадает с 'radio', значит это переключатель.

// Функция, которая делает всю работу и срабатывает после нажатия «Оценить»
function count() {

	// общее количество баллов
  let score = 0;

    // Сколько вопросов отмечено 
	let set = 0;

	// Находим элемент на странице, куда будем выводить результат
	let el = document.getElementsByClassName("itogo");

	// А сюда получаем все элементы ввода, в том числе и переключатели
	let inputs = document.getElementsByTagName('input');

	// Перебираем все элементы ввода по порядку и смотрим
	for(var i=0; i<inputs.length; i++){

	  // Если перед нами — переключатель и он отмечен, то…
	  if ((inputs[i].getAttribute('type')=='radio') && (inputs[i].checked == true)) {
	  	// Увеличиваем общее количество отмеченных переключателей 
		set += 1;
		// Обновляем рейтинг для новости: берём значение, переводим его в число и складываем
		score = score + Number(inputs[i].getAttribute('value'));
	  }
	}

	// Если есть ответы на все 4 вопроса
	if (set == 4) {
		// то смотрим на рейтинг и выводим итоговый вердикт, а в скобках — сколько баллов набрала новость
		if (score < 0) {el[0].innerHTML = 'Не берём (' + score + ')'};
		if (score == 0) {el[0].innerHTML = 'Ни туда, ни сюда  (' + score + ')'};
		if (score == 1 ) {el[0].innerHTML = 'Если есть картинки — берём (' + score + ')'};
		if (score > 1) {el[0].innerHTML = 'Точно берём (' + score + ')'};

		} 
		// А если какой-то вопрос пропустили, то так и пишем
		else {
			el[0].innerHTML = 'Отмечены не все вопросы';
		}
}

Сбрасываем ответы

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

<button onclick="clear()"> Сбросить </button>

Для функции clear() мы возьмём код из предыдущей функции и немного его поправим:

// Сброс ответов
function clearall() {

	// Получаем все элементы ввода, в том числе и переключатели
	let inputs = document.getElementsByTagName('input');

	// Перебираем все элементы ввода по порядку и смотрим
	for(var i=0; i<inputs.length; i++){

	  // Если перед нами — переключатель, то…
	  if (inputs[i].getAttribute('type')=='radio') {
	  	// …сбрасываем его
		inputs[i].checked = false;
	  }
	}

	// Находим элемент на странице, куда будем выводить результат
	let el = document.getElementsByClassName("itogo");
	
	// Очищаем абзац с результатами
	el[0].innerHTML = '';

}
Сразу видно, что с такими ответами новость можно брать в работу
Сразу видно, что с такими ответами новость можно брать в работу

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

Что дальше

Кажется, что проблема решена, но на самом деле нет, смотрите:

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

Всё это сделаем в следующий раз. Не переключайтесь.

<html>

<!-- служебная часть -->
<head>
  <!-- заголовок страницы -->
  <title>Отбор новостей</title>

  <!-- настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">

<!-- закрываем служебную часть страницы -->
</head>

<script type="text/javascript">

  // Функция, которая делает всю работу и срабатывает после нажатия «Оценить»
  function count() {

		// общее количество баллов
	  let score = 0;

	    // Сколько вопросов отмечено 
		let set = 0;

		// Находим элемент на странице, куда будем выводить результат
		let el = document.getElementsByClassName("itogo");

		// А сюда получаем все элементы ввода, в том числе и переключатели
		let inputs = document.getElementsByTagName('input');

		// Перебираем все элементы ввода по порядку и смотрим
		for(var i=0; i<inputs.length; i++){

		  // Если перед нами — переключатель, и он отмечен, то…
		  if ((inputs[i].getAttribute('type')=='radio') && (inputs[i].checked == true)) {
		  	// Увеличиваем общее количество отмеченных переключателей 
			set += 1;
			// Обновляем рейтинг для новости: берём значение, переводим его в число и складываем
			score = score + Number(inputs[i].getAttribute('value'));
		  }
		}

		// Если есть ответы на все 4 вопроса
		if (set == 4) {
			// то смотрим на рейтинг и выводим итоговый вердикт, а в скобках — сколько баллов набрала новость
			if (score < 0) {el[0].innerHTML = 'Не берём (' + score + ')'};
			if (score == 0) {el[0].innerHTML = 'Ни туда, ни сюда  (' + score + ')'};
			if (score == 1 ) {el[0].innerHTML = 'Если есть картинки — берём (' + score + ')'};
			if (score > 1) {el[0].innerHTML = 'Точно берём (' + score + ')'};

			} 
			// А если какой-то вопрос пропустили, то так и пишем
			else {
				el[0].innerHTML = 'Отмечены не все вопросы';
			}
	}

	// Сброс ответов
	function clearall() {

		// Получаем все элементы ввода, в том числе и переключатели
		let inputs = document.getElementsByTagName('input');

		// Перебираем все элементы ввода по порядку и смотрим
		for(var i=0; i<inputs.length; i++){

		  // Если перед нами — переключатель, то…
		  if (inputs[i].getAttribute('type')=='radio') {
		  	// …сбрасываем его
				inputs[i].checked = false;
		  }
		}

		// Находим элемент на странице, куда будем выводить результат
		let el = document.getElementsByClassName("itogo");
		
		// Очищаем абзац с результатами
		el[0].innerHTML = '';

	}
</script>

<!-- началось содержимое страницы -->
 <body>

	<!-- Заголовок вопроса -->
	<p><b>
	Это результат или мысли?
	</b></p>
	<!-- Абзац, который состоит из переключателя и текста -->
	<!-- У каждого ответа есть свой рейтинг, он записан в значение value -->
	<p><input name="result" type="radio" value="2">
	Что-то изобрели, получили результаты исследования, ключевое слово — результаты  
	</p>
	<!-- Дальше всё то же самое -->
	<p><input name="result" type="radio" value="-1"> 
	Только думают, планируют, размышляют 
	</p>
	<p><input name="result" type="radio" value="-2">
	Статья-обзор, как кто-то фантазирует о будущем 
	</p>
	<br>		

	<p><b>
	Это прорыв для человека?
	</b></p>
	<p><input name="mega" type="radio" value="-2">
	Что-то существующее немного улучшат с помощью технологий
	</p>
	<p><input name="mega" type="radio" value="1"> 
	Что-то существующее выведут на новый уровень с помощью технологий
	</p>
	<p><input name="mega" type="radio" value="2">
	Речь о чём-то, что резко повышает качество жизни человека
	</p>
	<p><input name="mega" type="radio" value="-2">
	Речь о чем-то, что в первую очередь поможет учёным или исследователям
	</p>
	<br>		

	<p><b>
	Это на хайпе? 
	</b></p>
	<p><input name="hype" type="radio" value="1">
	Новость про публичную фигуру: Маска, Безоса и т. д.
	</p>
	<p><input name="hype" type="radio" value="2"> 
	Это касается сервисов или продуктов, доступных в России
	</p>
	<p><input name="hype" type="radio" value="2">
	Это сделано или будет использоваться в России
	</p>
	<p><input name="hype" type="radio" value="-3">
	Это касается продуктов или сервисов, которых нет в России? Алекса, например 
	</p>
	<br>	

	<p><b>
	Можно посмотреть?
	</b></p>
	<p><input name="see" type="radio" value="3">
	Есть красивая картинка или видео, где демонстрируются результаты работы
	</p>
	<p><input name="see" type="radio" value="-1"> 
	У учёных есть идея, но пока нет картинок. Или есть картинка, но это скорее график
	</p>
	<p><input name="see" type="radio" value="1">
	Эта картинка демонстрирует конкретно то, что изобрели?
	</p>
	<p><input name="see" type="radio" value="-1">
	То, что изобрели, невозможно продемонстрировать как таковое, например, это скрытый алгоритм
	</p>
	<br>	
	<!-- Рисуем кнопку, по нажатию на которую запустится подсчёт рейтинга для новости -->
	<button onclick="count()"> Оценить </button>

	<!-- Кнопка, которая сбрасывает все ответы -->
	<button onclick="clearall()"> Сбросить </button>

	<!-- Делаем отступ -->
	<br>	
	
	<!-- В самом низу сделаем пустой абзац, куда будем выводить результаты -->
	<p class = "itogo"></p>
 </body>
</html> 
1274 views·12 shares