Движки e‑repa.ru

Часть 1. dub: аудиодиктант

Английский я преподаю с 1989 года. С 1995 по 2005 год работал старшим преподавателем в Институте иностранных языков Уральского государственного педагогического университета, а с 2001 по 2005 год был там же заведующим отделением перевода и переводоведения. С 2004 по 2006 год был председателем приёмной комиссии Института иностранных языков и составлял экзаменационные материалы для поступающих. С 2005 по 2009 год был старшим преподавателем Института лингвистики Российского государственного профессионально‑педагогического университета. В 2006 году там же получил второе образование по специальности «Компьютерные технологии в образовании».

Чтобы сделать учебный процесс удобным и максимально эффективным, у меня возникла идея создать сайт для учеников и коллег — так и появился сайт e‑repa.ru. На нём методические решения оформлены тестами, упражнениями, дриллами по грамматике, лексике, аудированию, речевым моделям и так далее. Всё построено на js‑движках. Каждый движок решает одну конкретную учебно‑методическую задачу или одновременно несколько. Сначала выясняю, в чём конкретная трудность ученика, когда ему необходимо выполнить некое целевое методическое действие, но вместо этого ученик ищет обходной путь — угадывание, калькирование или механическое списывание, повтор ранее успешного решения и тому подобное — и только после этого строю задание так, чтобы выполнить его можно было только целевым методическим действием, а не обходным способом. Под такую задачу код собственно и пишется.

Как это устроено на практике, покажу на примере задания на аудирование, построенного на движке dub.

Почему ученик не узнаёт на слух знакомые слова

Известно, что если слова звучат изолированно, ученик воспринимает их на слух без ошибок. Но в живой речи слова соединяются в синтагмы, и привычный звуковой образ слов перестаёт совпадать с их звучанием. Например, слова side of the road в синтагме стягиваются в sideoftheroad. Для ученика это новый, незнакомый звуковой облик, и ему кажется, что перед ним какое‑то новое, незнакомое слово.

В родном русском языке синтагмы раскладываются на составляющие их слова автоматически: «онаидёт» + «вшколу» → «она + идёт + в + школу». Носитель русского языка членит речь на слова настолько эффективно, что почти никогда не осознаёт этой операции. Отчасти это достигается за счёт накопленного знания структуры родного языка. При говорении происходит такая же операция — членение речи на синтагмы. Никто не скажет «Она пошлав школу»: звукосочетание «пошлав» не может попасть в речь ни при каких обстоятельствах.

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

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

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

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

Отсюда и методическая ценность js‑движка: он переводит структуру синтагмы из слухового канала в визуальный, что полностью согласуется с концепцией Л. С. Выготского о зоне ближайшего развития.

Упражнение на примере Unit 1 «A Driving Test»

Как это выглядит на экране, покажу на примере первого урока серии Intensive Listening 2 — Unit 1 «A Driving Test», короткого рассказа об экзаменаторе, который принимает экзамен по вождению. Запись рассказа разрезана на восемь фрагментов, по одному предложению в каждом, и ученик проходит их по очереди.

Над упражнением дан список опорных слов: первым в нём стоит имя героя, Harry Marsh, а за ним слова, которые ученику могут быть незнакомы (examiner, licence, faultlessly и другие), с транскрипцией и переводом. Ниже находится аудиоплеер, а под ним строка задания. Текста в этой строке нет: каждое слово записи заменено пустым полем, все пустые поля одинаковой ширины, а между ними стоят только знаки препинания из текста рассказа. Первый фрагмент выглядит так:

1. ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁ ▁▁-▁▁.

Это и есть визуальная структура синтагмы: ещё до того, как ученик начнёт слушать, он видит, из скольких слов состоит фрагмент и где проходят его границы.

При этом длину слов строка не выдаёт: короткое a занимает столько же места, сколько длинное examiner, поэтому какое слово стоит в поле, ученику приходится расслышать самому. Набирает он прямо в поля, и каждая буква окрашивается в момент набора: зелёным, если она совпала с ключом, и красным, если не совпала. Если же в слове не хватает буквы, под полем появляется отметка. Так ученик видит не только то, что ошибся, но и в каком слове и в каком месте этого слова, и переслушивает именно это место записи.

Чтобы переслушать трудное место, у ученика в плеере есть три средства. В режиме «Кольцо» фрагмент повторяется сам, без повторного нажатия на play. Кнопками «◄ 1 с» и «1 с ►» ученик возвращается к трудному месту, не прослушивая предложение с начала. Если темп речи для него слишком высок, запись можно замедлить до 0,75 или 0,5 от обычной скорости, и высота голоса при этом не меняется, так что звучание слов не искажается. Слитность синтагмы при замедлении тоже сохраняется: sideoftheroad звучит медленнее, но по‑прежнему без границ между словами, поэтому декомпилировать синтагму ученику всё равно предстоит самому.

Когда очередное слово наконец набрано верно, подчёркивание под полем исчезает, и курсор сам переходит в следующее незаполненное поле. Перейти к нему можно и вручную — пробелом, Enter или Tab, — поэтому трудное слово ученик может оставить и вернуться к нему позже.

Фрагмент засчитывается только тогда, когда верны все слова: пропущенное слово остаётся пустым полем, и, пока оно пустое, фрагмент не засчитан. Засчитанный фрагмент появляется в списке ответов под заданием, и открывается следующий. Если фрагмент не получается, ученик нажимает Skip: фрагмент откладывается до следующего круга, а в списке ответов остаётся то, что ученик успел набрать, с той же раскраской букв. Ключа ученик не видит ни в строке задания, ни в списке ответов, поэтому пройти тест, не записав верно все восемь фрагментов, нельзя.

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

Как это устроено в коде

Всё, что ученик видит на экране и делает в упражнении, реализовано в движке dub. Упражнение состоит из трёх частей: HTML‑страницы, XML‑файла с заданиями и самого движка. Движок — это один JS‑файл, dub‑script.js, и один CSS‑файл, dub‑styles.css. Оба файла общие для всех упражнений этого типа, а сам движок написан с использованием jQuery. Запись одна на всё упражнение, и каждый фрагмент задан в ней интервалом, так что аудиофайл на части не режется.

Задание автор пишет в XML обычным текстом и указывает начало и конец фрагмента в миллисекундах:

<![CDATA[1. Harry Marsh was a driving examiner who had to test people who wanted to get a driving-licence.]]>

Текст внутри ученик видит как есть, а всё остальное движок при загрузке превращает в поля сам. Поэтому размечать пропуски автору не нужно: он вписывает текст записи, и поле на каждое слово появляется автоматически.

Поле на каждое слово

Визуальную структуру синтагмы, то есть поле на каждое слово, строит функция insertInputs(). Она проходит по тексту задания и оборачивает в каждую последовательность латинских букв, допуская один апостроф внутри слова:

f = it.match(new RegExp('^[a-z]+'{0,1}[a-z]*', 'i'));

Под это правило попадают только слова, поэтому цифры, знаки препинания и HTML‑теги вместе с их содержимым остаются в строке как есть. Так между пустыми полями оказываются знаки препинания оригинала. Для слов с апострофом движок добавляет в ключ варианты с ’ и `, и засчитывается любое из трёх начертаний: из‑за того, какой апостроф стоит на клавиатуре ученика, верно расслышанное слово не должно считаться ошибкой.»

Побуквенная проверка

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

for (i = l1 - 1; i >= 0; i--){for (j = l2 - 1; j >= 0; j--){if (tl1[i] == tl2[j]){nop[i][j] = 1 + nop[i + 1][j + 1];}else{nop[i][j] = Math.max(nop[i + 1][j], nop[i][j + 1]);}}}

По этой таблице движок восстанавливает, как буквы ответа соотносятся с буквами ключа. Совпавшие буквы он окрашивает зелёным, лишние — красным, а там, где буквы не хватает, ставит отметку под полем. Такое сравнение отличает недописанное слово от ошибочного: если ученик набрал examin, все шесть букв будут зелёными, потому что ошибки в них нет, и ученик просто продолжает набирать. Регистр при сравнении не учитывается. Если для слова в ключе есть несколько вариантов написания, движок сравнивает ответ с каждым и выбирает тот, где у ученика меньше всего лишних букв.

Фрагмент засчитывается только целиком

Чтобы фрагмент нельзя было сдать с пропущенным словом, функция regenSpan() всякий раз, когда очередное слово набрано верно, проверяет все поля фрагмента:

i = 1;var r = true;while(items[cur]['check'+i]!=undefined && r){r = r && items[cur]['check'+i];i++;}if(r){items[cur]['status'] = 'right';clickReply();}

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

Skip и круги

Чтобы через Skip нельзя было пройти тест, не записав трудный фрагмент, функция nextCur() после каждого фрагмента ищет следующий несданный, а дойдя до конца списка, начинает поиск сначала:

function nextCur(){var i;var n = -1;for(i = cur+1; i<items.length; i++){if(items[i]['status']!=='right') { n = i; break; }}if(n==-1){for(i = 0; i<=cur; i++){if(items[i]['status']!=='right') { n = i; break; }}}return n;}

Отложенный фрагмент возвращается к ученику в следующем круге, и так до тех пор, пока он не будет записан верно. Тест заканчивается, только когда nextCur() возвращает −1, то есть когда несданных фрагментов не осталось.

Плеер

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

if(t>=this.positionMax){if(optLoop){t = this.positionMin;this.video.currentTime = t;}else{this.toStart();return;}}

Замедлять запись имеет смысл, только если звучание слов при этом не искажается. Поэтому движок включает сохранение высоты голоса и в стандартном свойстве, и в вариантах с префиксами moz и webkit, а скорость задаёт сразу в двух свойствах. Второе свойство нужно потому, что load() при смене фрагмента сбрасывает playbackRate к значению defaultPlaybackRate, и без него выбранное замедление пропадало бы на следующем фрагменте:

if(this.video.preservesPitch!==undefined) this.video.preservesPitch = true;if(this.video.mozPreservesPitch!==undefined) this.video.mozPreservesPitch = true;if(this.video.webkitPreservesPitch!==undefined) this.video.webkitPreservesPitch = true;this.video.defaultPlaybackRate = r;this.video.playbackRate = r;

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

if(this.shiftBase===null) this.shiftBase = this.video.currentTime;this.shiftSum += sec;var t = Math.min(this.positionMax, Math.max(this.positionMin, this.shiftBase + this.shiftSum));

Серия обрывается, если между нажатиями прошло больше 800 мс. После перемотки звук включается с паузой 333 мс: за это время браузер успевает перейти на новую позицию, и ученик слышит запись уже с нового места.

Сохранение

Над трудным фрагментом ученик может просидеть долго, и перезагрузка страницы не должна стирать эту работу. Поэтому прогресс хранится в localStorage под ключом, равным пути страницы, и сохраняются не только засчитанные фрагменты, но и незаконченный, со всем, что ученик успел в нём набрать. Во время набора движок сохраняет его с задержкой 400 мс, а при уходе со страницы (pagehide, visibilitychange) — сразу. Открыв страницу снова, ученик выбирает, продолжить с того места, где остановился, или начать заново. Настройки плеера — кольцо, автозапуск и темп — хранятся отдельно, под общими ключами без пути страницы, поэтому заново выставлять их на каждом упражнении не нужно.

Зона ближайшего развития

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

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

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

Источник: habr.com

0 0 голоса
Рейтинг новости
1
0
Подписаться
Уведомить о
0 комментариев