Научная статья на тему 'Интегрированная среда для обучения программированию'

Интегрированная среда для обучения программированию Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
375
97
i Надоели баннеры? Вы всегда можете отключить рекламу.
i Надоели баннеры? Вы всегда можете отключить рекламу.
iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Текст научной работы на тему «Интегрированная среда для обучения программированию»

корневым для валидационных правил, проверяющих диапазон вводимых значений. Реализованный наследник RangeDateTimeAttributesValidationRule позволяет проверить диапазон введенной даты. Класс RangeIntAttributesValidationRule служит для проверки диапазона целочисленных атрибутов, а RangeDecimalAttributesValidationRule используется для атрибутов дробного значения. Класс RangeTimeAttributesValidationRule предназначен для описания правил, накладываемых на атрибуты, принимающие временные значения.

После описания всех классов рассмотрим соответствие данной иерархии выделенным ранее критериям оптимальности. Система соответствует КО1, т.к. выделен базовый корневой абстрактный класс AttributesValidationRule, позволяющий разработать механизм валидации значения каждого отдельного атрибута класса, представляющего сущность реального мира. При этом унаследованные классы позволяют реализовать требуемое поведение.

Базовый класс ClassCheckingValidationRule представляет возможность валидации на уровне классов и реализовать проверку комбинации атрибутов класса с помощью логического условия, что выполнено в конкретном классе CriteriaCheckingValidationRule. Следовательно, требования КО2 выполнено.

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

Требования КО4 выполнены, т.к. при разработке данной иерархии классов представления валидационных правил используется унифицированная метамодель объектной системы, описанная в работе [2] и предполагающая встроенную возможность наследования. Т.к. требования всех критериев выполнены, то можно утверждать, что разработанная система является оптимальной.

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

Литература

1. Грэхем И., Объектно-ориентированные методы. Принципы и практика. 3-е издание.: Пер. с англ. - М.: Издательский дом «Вильямс», 2004. - 880 с.: ил. - Парал. тит. англ.

2. Олейник П.П. Иерархия классов метамодели объектной системы // Объектные системы -2012: материалы VI Международной научно-практической конференции (Ростов-на-Дону, 1012 мая 2012 г.) / Под общ. ред. П.П. Олейника. - Ростов-на-Дону: ШИ ЮРГТУ (НПИ), 2012. -С. 37-40

3. Новиков Ф.А., Иванов Д.Ю. Моделирование на UML. Теория, практика, видеокурс. - СПб.: Профессиональная литература, Наука и Техника, 2010. - 640 с.

УДК 004.4’232 +004.588

ИНТЕГРИРОВАННАЯ СРЕДА ДЛЯ ОБУЧЕНИЯ ПРОГРАММИРОВАНИЮ1

Лаптев Валерий Викторович, к.т.н., доцент, Астраханский государственный технический университет, Россия, Астрахань, [email protected] Грачев Дмитрий Александрович, магистрант, Астраханский государственный технический университет, Россия, Астрахань, [email protected]

1 Лауреат номинации "Лучший доклад о методах преподавания объектных технологий в ВУЗе". Автор доклада награждается правом бесплатной публикации одного доклада по данной тематике на следующей конференции

17

Введение

В работе [1] описан учебный язык программирования Semantic Language и его интерпретатор. Разработка программ на учебном языке должна поддерживаться средой программирования (Integrated Development Environment, IDE), минимальные сведения о которой приведены в той же работе. С одной стороны, эта среда является частью обучающей системы (как указано в работе [2]) и должна поддерживать процесс обучения (например, среда должна обеспечивать преподавателю возможности подготовки обучающих материалов). С другой стороны, интегрированная среда должна быть похожа на современную интегрированную среду для профессиональной разработки программ. Это необходимо, чтобы у обучаемых формировались навыки работы в подобных средах. Поэтому рассмотрим некоторые свойства, присущие современным интегрированным средам.

Промышленная интегрированная среда традиционно объединяет в единую систему множество системных программ: компилятор (и/или интерпретатор), отладчик, мейкер, компоновщик, профайлер и другие. Современная среда в обязательном порядке обеспечивает работу с многомодульными проектами. Однако наиболее важной частью любой интегрированной среды является редактор кода, который и обеспечивает взаимодействие пользователя-программиста со средой.

Как правило, редактор кода представляет собой обычный текстовый редактор, в котором основные операции выполняются с символами, строками и блоками текста. Однако современные промышленные среды обеспечивают некоторую поддержку языка разработки, например: осуществляется цветовая подсветка синтаксиса, которая обычно настраивается в самом редакторе; блоки кода (классы, модули, условные операторы и операторы цикла, определения подпрограмм, и т.п.) разрешается сворачивать и разворачивать. Для ускорения набора кода современные редакторы предоставляют набор так называемых сниппетов (snippets). Сниппет - это короткая комбинация клавиш, с помощью которой в код вставляется конструкция языка программирования; сниппеты, как правило, разрешается настраивать в редакторе.

В последние годы в некоторых средах выполняется интеллектуальный анализ (технология IntelliSense) кода при его создании (до компиляции). Например, при наборе вызова метода некоторого библиотечного класса предоставляется подсказка, позволяющая не набирать конструкцию полностью вручную, а выбрать нужную из списка. Ошибочные конструкции помечаются в окне редактора в момент набора (без компиляции), и в отдельном окне выводятся сообщения о возможных ошибках. Обеспечивается интеллектуальная навигация по коду, например, переход от вызова метода к его определению и обратно. В наиболее развитых средах реализованы некоторые операции рефакторинга [3,4].

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

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

18

Б. Страуструп в своей книге [5] отмечал, что главным препятствием на пути развития языка С++ являются символьно-ориентированные инструменты (в частности, текстовый редактор кода). Наиболее перспективный и интересный подход - отказаться от традиционного текстового представления и реализовать инструментарий на основе семантических понятий языка программирования. В этом случае синтаксис языка представляет собой интерфейс между языком программирования и пользователем (программистом). И, как всякий интерфейс, его можно заменять, не изменяя базовой семантики языка.

В соответствии этим подходом и с учетом анализа свойств современных сред авторами был сформулирован ряд концепций реализации обучающей интегрированной среды Semantic IDE, которая поддерживает разработку программ на учебном языке программирования [1].

1. Интегрированная среда Semantic IDE и семантический редактор кода

Внешний вид среды Semantic IDE показан на рисунке 1. Центральное окно - это окно редактора кода. В нем пользователь набирает код программ и пишет текст документов. Для каждого документа создается отдельная вкладка. Над центральным окном расположены главное меню и лента выбранного пункта главного меню.

Рис. 1 - Общий вид Semantic IDE

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

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

19

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

1.1. Проекты

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

Любой файл, созданный в редакторе кода, может содержать программный модуль на учебном языке. Но в общем случае это не обязательно - файл может содержать только неисполняемую информацию. Таким образом, в редакторе кода можно создавать как программные, так и информационные проекты. Примером информационных проектов в Semantic IDE являются проект Справка и проект Задачник, содержащий набор лабораторных работ по программированию.

Программные проекты могут быть исполняемыми и неисполняемыми. Примером неисполняемого проекта в среде является проект Framework, в котором собраны модули стандартной библиотеки. Если же программный проект требуется выполнять, то один из модулей проекта назначается стартовым: выполнение программы начнется с секции инициализации этого модуля. Остальные модули загружаются и связываются по мере необходимости. Примером исполняемого проекта, предоставляемого в составе Semantic IDE, является проект Example, который содержит множество примеров программ на учебном языке (см. рис. 1).

Для хранения проектов на диске был разработан специальный xml-формат. Например, текущая версия проекта Задачник выглядит следующим образом:

<?xml version="1.0" encoding="utf-16"?>

<Project Name="Задачник" StartupModule="#notset">

<Files>

<Module Path="Лабораторная 1.sl" />

<Module Path="Лабораторная 2.sl" />

<Module Path="Лабораторная 10.sl" />

<Module Path="Лабораторная 11.sl" />

</Files>

</Project>

Файл проекта сохраняется в папке проекта в виде xml-файла с расширением «prj», а файлы, созданные в редакторе и включенные в проект, имеют расширение «sl». В данном случае отсутствует стартовый модуль, поскольку проект не является исполняемым.

1.2. Редактирование кода

Редактор кода - это не традиционный текстовый редактор. В Semantic IDE реализован семантический редактор. Как было описано в работе [1], семантический редактор оперирует не символами, а операторами учебного языка и объектами программы. Во-первых, оператор всегда вставляется в код в синтаксически правильном виде. Во-вторых, редактор сам следит за отступами вложенных операторов и не позволяет нарушать структурный вид программы. В-третьих, изменение ключевых слов запрещено, что полностью исключает многие синтаксические ошибки, возникающие из-за ошибок набора ключевых слов. Редактор разрешает символьный ввод только в строго определенных позициях оператора. Например, в операторе вызова разрешено вводить посимвольно имя вызываемой процедуры.

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

20

устанавливается на конкретном операторе.

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

Редактор следит за действиями программиста и сообщает об ошибках в момент набора программы. Пока ввод оператора не завершен, в окне ошибок «вывешены» все сообщения об ошибках, которые возникают по мере ввода составных частей оператора. Например, при ошибке в написании имени переменной во время ввода оператора мгновенно появляется сообщение о том, что данная переменная не была определена. Отметим, что в кодовом окне нумеруются операторы программы, а не строки текста (см. рис. 1).

Аналогично выполняется удаление - удаляется вся конструкция целиком. Если же оператор не удаляется, то разрешается замена элементов оператора. При замене тоже работает контекстный подсказчик. Например, в операторе объявления переменной можно заменить тип переменной, выбрав его из списка предложенных типов. Точно так же предлагается список видимых в данной точке имен переменных, если программисту потребовалось заменить имя переменной.

Заметим, что программа при вводе/удалении операторов всегда является синтаксически правильной - синтаксические ошибки отсутствуют. Даже при наборе арифметических или логических выражений всегда вставляется (и удаляется) синтаксически правильная часть выражения. Все возникающие ошибки являются исключительно лексическими (например, неверно набранная числовая константа) или семантическими (например, в операторе присваивания требуется недопустимое преобразование типа). Таким образом, набор кода программы требует минимального количества действий от программиста, и при этом существенно сокращается количество ошибок.

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

2. Синтаксис как интерфейс

Как сказано в работе [1], редактор кода в соответствии с действиями программиста строит внутреннее представление программы. Один модуль - это дерево с вершинами сложной структуры, которое мы назвали семантическим. Каждая вершина (узел) дерева представляет отдельный оператор программы, в котором сохраняется полная информация о семантике оператора. Например, для оператора присваивания хранится информация о вычисляемом выражении и о переменной, которой присваивается значение выражения.

В каждом узле имеется ссылка на следующий узел-оператор. Таким образом, последовательность операторов представляет собой последовательный список узлов семантического дерева. В узлах, соответствующих блочным операторам учебного языка [1], имеется еще одна ссылка - на первый вложенный оператор тела.

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

С другой стороны, представление программы в виде семантического дерева позволяет реализовать идею Б. Страуструпа о том, что синтаксис языка программирования является интерфейсом [5], который можно менять, выбирая наиболее подходящий для обучения. В Semantic IDE, помимо синтаксиса учебного языка Semantic Language, реализованы Си-

21

подобный и Pascal-подобный синтаксисы. Си-подобный синтаксис разработан на основе языка Java [7], а за образец Pascal-подобного принят синтаксис языка Component Pascal [6], реализованного в системе BlackBox Component Builder. Каждое из представлений может быть показано и в русской лексике, и в английской.

Представление программы вычисления факториала на языке Semantic Language в английской и русской лексике показано на рис. 2.

module Факториал start

variable integer i := 1; variable real current := 1; constant integer N = 15; while i < N do

let current := current * let i := i + 1; output '\n'; output current; end of while; end Факториал.

i;

модуль Факториал начало

переменная целое i := 1; переменная вещ current := 1; константа целое N = 15; пока i < N повторять

присвоить current := current присвоить i := i + 1; вывести '\n'; вывести current; конец цикла; конец Факториал.

i;

Рис. 2 - Представление программы на языке Semantic Language

Та же программа в Си-подобном и Pascal-подобном виде представлена на рис. 3.

package Факториал; function Main() { var int i = 1; var double current = 1; const int N = 15; while (i < N) {

let current = current * i; let i = i + 1; Console.Write('\n'); Console.Write(current);

} // конец Main } // конец Факториал

MODULE Факториал;

BEGIN

VAR i: INTEGER := 1;

VAR current: REAL := 1;

CONST N: INTEGER = 15;

WHILE i < N DO

LET current := current * LET i := i + 1; Log.Out('\n'); Log.Out(current);

END

END Факториал.

Рис. 3 - Представление программы вычисления факториала а) Си-подобный синтаксис б) Pascal-подобный синтаксис

i;

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

Каждый синтаксис определяется собственной грамматикой представления, в которой каждому оператору соответствует правило представления, задаваемое в формате РБНФ. Правила представлены в русской лексике - механизм переключения лексики ключевых слов реализован независимо от грамматики. Например, оператор присваивания в грамматике представления Semantic Language, задан таким правилом:

<Assign> ::= "присвоить" <expression> ":=" <expression>";"

Нетерминал в левой части правила - это семантическая единица языка (оператор), которая в семантическом дереве представлена соответствующим узлом. В правой части правила - синтаксис представления этого оператора в окне редактора. Последовательности символов, заключенные в кавычки, выводятся буквально в окно редактора - это ключевые слова языка. Нетерминалы в правой части правил - это параметры данной семантической единицы, о них «знает» интерпретатор. В данном случае узел имеет два параметра: слева параметр-выражение, представляющий объект, которому присваивается значение правого параметра-выражения.

То же правило в грамматике Pascal-подобного представления выглядит так:

<Assign> ::= "%ПРИСВОИТЬ""% "<expression> ":=" <expression>";"

22

В грамматике Си-подобного представления это правило выглядит следующим образом:

<Assign> ::=

'<expression> "=" <expression>";

Знак процента «%» в начале слова означает, что это слово не входит в состав слов, синтаксис которого определяет грамматика. В данном случае это правило говорит о том, что в Си-подобных и Pascal-подобных языках в операторе присваивания отсутствует ключевое слово «присвоить» (английское «let»). Слово-исключение показано в коде подчеркнутым.

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

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

3. Поддержка разработки обучающих материалов

Одним из операторов, обычно размещаемых в коде, является оператор-комментарий, обозначаемый в окне редактора символом «решетка» (#). Оператор-комментарий может быть вставлен в код в любом месте, где допускается вставка оператора языка программирования, а также перед кодом и после него. Однако в семантическом редакторе разрешается создавать произвольную последовательность операторов-комментариев вообще без программного кода. Редактор вставляет в семантическое дерево отдельный узел для каждого оператора-комментария. Интерпретатор подобные узлы не обрабатывает.

В пределах комментария разрешается посимвольный ввод любого текста, и выполняются традиционные текстовые операции с символами и строками. Разрешены и обычные операции с буфером обмена - это позволяет вставлять фрагменты материалов из других программ (например, из MS Word). В операторе-комментарии можно создать таблицы, разрешается вставлять рисунки и видеоролики. Обеспечивается возможность связывания комментариев с помощью гиперссылок, в том числе и с другими файлами проекта.

Таким образом, возможности представления информации практически не уступают возможностям подготовки документа в MS Word в rtf-формате. Все это позволяет преподавателю непосредственно в редакторе готовить обучающие материалы. Проект Справка и проект Задачник подготовлены именно таким образом. Кроме того, теоретический материал можно проиллюстрировать кодом программы-примера, которую можно запустить на выполнение. Это позволяет демонстрировать образцы хорошего стиля программирования и способствует более быстрому и прочному усвоению изучаемой темы.

Заключение

Реализованная среда Semantic IDE является основой обучающей системы по программированию, которая разрабатывается на кафедре АСОИУ Астраханского государственного технического университета. В настоящее время среда используется для выполнения лабораторных работ по дисциплине «Основы алгоритмизации» и на факультативных занятиях по программированию в Астраханском колледже вычислительной техники. Опыт применения среды показывает существенное сокращение времени при создании кода программы и практически полное исчезновение ошибок набора. По отзывам преподавателей, представление программы в русской лексике облегчает усвоение базовых понятий студентам, не изучавшим основы программирования в школе, и способствует усвоению профессиональной терминологии. С другой стороны, возможность переключить программу в английскую лексику облегчает студентам переход на профессиональные англоязычные языки программирования.

В настоящий момент развитие среды продолжается. Уже разработаны Python-подобный и Basic-подобный синтаксисы представления, что повышает универсальность среды как инструмента обучения. Разрабатывается грамматика представления программы в синтаксисе C#. Исследуются возможности трансляции семантического дерева программы в код на языках, в которых среда может показывать программу. Это позволит переносить программы из Semantic IDE в профессиональные среды.

23

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

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

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

Работа поддержана грантами «У.М.Н.И.К.» в 2011 и 2012 годах, и грантом «Старт» в 2013 году. Работающую версию среды можно загрузить с сайта sem_tech.net.

Литература

1. Грачёв А.Д., Лаптев В.В. Разработка учебного языка программирования и интерпретатора для обучающей среды // Объектные системы-2012: материалы VI Международной научнопрактической конференции (Ростов-на-Дону, 10-12 мая 2012г.) / Под общ. ред. П.П. Олейника. - Ростов-на-Дону: ШИ ЮРГТУ (НПИ), 2012. - 110 с., с. 92-101.

2. Лаптев В.В. Требования к современной обучающей среде по программированию // Объектные

системы-2010 (Зимняя сессия): материалы II Международной научно-практической

конференции. Россия, Ростов-на-Дону, 10-12 ноября 2010 г. / Под общ. Ред. П.П. Олейника. -Ростов-на-Дону, 2010. - 134 с., с. 104-110.

3. Пауэрс, Л. Microsoft Visual Studio 2008 / Л. Пауэрс, М. Снелл: Пер. с англ. - СПб.: БХВ-Петербург, 2009. - 1200 с.

4. Давыдов С.В., Ефимов А.А. IntelliJ IDEA. Профессиональное программирование на Java. -СПб.: БХВ-Петербург, 2005. - 800 с.

5. Страуструп Б. Дизайн и эволюция С++. - М.: ДМК Пресс; СПб.: Питер, 2006. - 448 с.

6. Потопахин В.В. Современное программирование с нуля! - М.: ДМК Пресс, 2010. - 240 с.

7. Хорстман К.С., Корнелл Г. Java 2. Библиотека профессионала, том 1. Основы. - М.: ООО «И.Д. Вильямс», 2011. - 816 с.

8. Лаптев В.В. Метод оценивания умений и навыков при обучении программированию // Вестник Астраханского государственного технического университета. Серия: Управление, вычислительная техника и информатика. Научный журнал, № 2 / 2013. - Астрахань: Издательство АГТУ, 2013 г.- 218 с., с.194-201

УДК 004.02

МОДЕЛИРОВАНИЕ СИСТЕМЫ ФОРМИРОВАНИЯ ЗАКАЗОВ И УЧЕТА ТОВАРОВ

Шафоростова Елена Николаевна, к.п.н., доцент, Старооскольский технологический институт,

Россия, Старый Оскол, [email protected]

Ковтун Нелли Игоревна, старший преподаватель, Старооскольский технологический институт,

Россия, Старый Оскол

Михайлюк Екатерина Андреевна, старший преподаватель, Старооскольский технологический

институт, Россия, Старый Оскол

24

i Надоели баннеры? Вы всегда можете отключить рекламу.