Критика, идеи и бессмыслица из окопов индустрии

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

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

Если ваш ребенок интересуется робототехникой, вы можете получить Кибо:

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

Правильно, этот умный продукт стоит всего 200 долларов и использует любовь вашего ребенка к робототехнике и программированию и готовит его к будущей карьере в розничной торговле!

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

В том же ключе существует программа Fisher-Price Think & Learn Code-a-Pillar (50 долларов США):

Разработанный для детей в возрасте от двух лет, ваш ребенок будет часами веселиться, нажимая кнопку питания и разбрасывая сегменты по комнате! Он умело вводит программирование, соблазняя родителей (под принуждением к тому, что они потратили на это 50 долларов), чтобы они сами поиграли с игрушкой в ​​предполагаемой манере, в то же время отчаянно объясняя программирование и робототехнику своему плачущему малышу, который просто хочет вернуть чертову гусеницу.

Не буду врать, думаю, с гусеницей мне весело, чем с малышами.

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

  • Вперед
  • Левый
  • Верно
  • Вращаться

И если ваш ребенок все еще не заинтересован, не вся надежда потеряна. Вы также можете научить их электротехнике! Купите им LittleBits (от 100 долларов и выше… намного дороже):

Всем известно, что цепи начинаются с батареи на одном конце и продолжаются от батареи по прямой!

Я сам испытал на себе обучающую мощь LittleBits, когда запускал демонстрацию электротехники, отличную от LittleBits (реальная история):

Я: «Итак, в этом упражнении мы собираемся подключить батарею к светодиоду, чтобы он загорелся».
Мать ребенка: «О , он хорош в этом. У нас дома куча LittleBits, и он все время с ними играет! »
Ребенок: * Хватает батарею и светодиод и сплавляет все провода одновременно *
Свет: * Не горит *
Цепь: * Короткое замыкание *
Я: «Хорошо, круто».

Если вы все еще не уверены, вот вдохновляющий доклад на TEDx об обучении молодых программистов с помощью творческого самовыражения (и игрушечных роботов за 200 долларов, которые она также продает):

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

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

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

Настоящая беседа ниже, в которой я останавливаюсь на (большинстве) Снарке

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

«Если будет хорошая погода, мы пойдем в парк».

if weather == 'nice':
    goToPark()

«Оставайся в своей комнате, пока я не скажу тебе выходить».

while !toldToComeOut:
    stayInRoom()
comeOut()

Примечание. Знак "!" в первой строке указывает «нет» или противоположное значение. Например, «Пока вас не просят выйти…» Программисты называют этот оператор «взрывом», а не «восклицательным знаком». Итак, вы можете прочитать этот код вслух как «Бан сказал, чтобы он выходил», что забавнее сказать.

«Мы можем прочитать любую книгу, которую вы хотите, но после этого вам придется лечь спать».

readBook(bookIWant)
sleep()

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

Не покупая им гусениц по 50 долларов.

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

И я бы сказал, что эти игрушки вообще этому не учат. Фактически, они часто изо всех сил стараются не преподавать эти концепции, и это нормально. Я обучал Scratch (вводный язык программирования с перетаскиванием) 12-летних, которые так же быстро понимали упрощенный синтаксис, как и я. Самым сложным было просто заставить блоки выстроиться так, как вы хотите!

Когда я впервые начал программировать (13 лет - до этого я, условно говоря, почти не пользовался компьютерами), не было момента, когда я подумал: «В чем смысл этого оператора if ? ” Я просто увидел это, это имело смысл, и ввел его в свой интерфейс TI-BASIC, потому что хотел сгенерировать несколько приятных, приятных простых чисел.

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

Итак, дети, как люди, взаимодействующие с миром, уже имеют довольно хорошее чувство логики, порядка и структуры. А если нет, не волнуйтесь, они это поймут (но, вероятно, не через программирование).

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

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

  • Дизайнеры обслуживают родителей и преподавателей, которые мало разбираются в информатике или программировании и придерживаются стереотипа «программирование как рецепт / набор инструкций».
  • Они используют игрушки как способ заставить детей не бояться программирования в более позднем возрасте, а не «учат» их чему-либо. Подобно тем кухонным гарнитурам для малышей, которые «привыкают», а не «учат готовить».
  • Сами взрослые боятся программировать и проецировать этот страх на детей.

Но разобрать вещи легко. Если я так ненавижу все, что существует, какова альтернатива?

Чтобы было ясно: я не ненавижу все. Например, я люблю LittleBits (даже если он иногда сбивает детей с толку относительно того, как работает электричество). Но я считаю, что преподавателям программирования необходимо сделать глубокий вдох и сделать шаг назад. Затем мы должны посмотреть, чему мы учим на самом деле и почему мы это учим. Из всего мира возможностей нам следует подумать о том, чему лучше всего учить.

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

Несколько концепций для рассмотрения

Столкнувшись с яркой, блестящей новой связкой tabula rasa, возникает соблазн сразу же засунуть им в голову весь мир знаний. Но это смущает детей.

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

Я использовал для этого три критерия:

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

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

Состояние и ценность: фундаментальная теория программирования

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

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

Большинство этих программных игрушек просто изменяют состояние объекта в виде серии линейных шагов. Робот переходит из одного состояния в другое, пробираясь по полу.

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

while noWallInFrontOfRobot:
    moveForward()

turnRight()

В этом случае используется значение, находится ли стена перед роботом. Робот будет двигаться вперед, пока не появится стена. На этом этапе программа перейдет из состояния «счастливо продвигаюсь вперед» к состоянию «лучше повернуть, потому что есть стена!» штат.

Значение меняет состояние.

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

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

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

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

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

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

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

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

Структура программирования

Посмотрите, как ребенок играет с Лего. Уложены ли они линейно друг на друга по схеме: красный, желтый, синий, красный, желтый, синий, красный, желтый, синий…

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

Может быть, ребенок понимает, что ему нужно несколько деревьев Lego, поэтому он указывает другому ребенку начать делать деревья с определенной спецификацией (повторно используя один и тот же набор шагов для каждого дерева), чтобы ландшафт свойства Lego.

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

Фактически, в профессиональном программировании очень не рекомендуется работать самостоятельно и писать свою программу только как набор линейных шагов. Я и принимал, и давал инструкции вроде: «Ого, это мерзко. Разбейте это на части, разбейте это, вы делаете одно и то же несколько раз - сделайте его отдельным блоком ... Кто-то уже написал это, просто используйте его ... "

Когда в образовательных инструментах действительно есть концепция функций (например, Scratch), их часто преподают как продвинутую технику только для самых крупных и сложных фрагментов кода. Это посылает сообщение о том, что код в основном «линейный», но ладно, если он вам действительно, действительно нужен, вот эта странная «функция».

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

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

Я не поддерживаю этот подход как способ обучения программированию. Если хотите, начните с линий! Но я думаю, что время от времени важно развивать этот образ мышления. Это ближе к сути того, что такое программирование, как оно используется и почему оно такое мощное. Ведь за кадром каждая строчка Scratch действительно выполняет свою функцию. Функция в Scratch - это функция функций (а эти функции, в свою очередь, вызывают другие функции - это функции полностью вниз!)

Но никогда нельзя преподавать функции как странный побочный продукт чрезмерно сложного кода. Функции небольшие и несложные. Они могут состоять из пары строк или даже одной строки!

function turnRight():
    right(90)
function rightForward():
    turnRight()
    forward()

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

forward

Попытайтесь объяснить происходящее:

purpleRobot.forward

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

function slowToStop(robot):
    robot.speed = 10
    loop 5 times:
        robot.forward
        robot.speed = robot.speed - 2
slowToStop(purpleRobot)

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

  • Может ли ребенок сделать второго робота и передвигать обоих по одной программе?
  • Могут ли роботы взаимодействовать друг с другом или влиять друг на друга в коде?
  • Может ли один робот быть быстрым роботом со специальными функциями и способностями, а другой - медленным роботом, который мало что делает?
  • Что произойдет, если я сделаю это:
purpleRobot.forward = slowToStop
  • Для детей постарше: в чем разница между «вперед» (функция) и «скорость» (значение)?

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

Это не значит, что мы все «усложняем».

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

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

Сложно писать одни и те же инструкции и числа снова и снова.

Сложно не сказать, что команда должна делать или на чем она действует, в зависимости от того, как она написана.

Структуры красивы, просты и являются фундаментальным ключом к программированию. Они делают это легко, а не сложно!

Изучите информатику, прежде чем программировать

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

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

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

  • Наивный подход: выберите журнал из стопки «на полку» и положите его в нужное место.
  • Или я мог бы сначала отсортировать стопку «на полку», помня о дате выхода журнала наверху стопки, просматривая большую полку слева направо, вставляя по ходу.
  • Если бы нужно было разложить много журналов, не лучше ли было бы отсортировать их только по годам, а затем вставлять их, сортируя по месяцам, по годам?

Многие посетители также взяли на себя ответственность переделать свою собственную National Geographics, которая оставила большую полку в неупорядоченном состоянии. Как лучше это решить? Было ли лучше сначала изменить полку, а потом внести исправления или сначала внести исправления, а затем заново? Если бы полки были немного неупорядочены, я мог бы исправить это, сделав несколько переключателей здесь и там. Или я мог бы полностью удалить неупорядоченные и вернуться к технике «вставки из неупорядоченного стека».

Но что, если полка была очень неупорядоченной?

Случай «очень неупорядоченный» можно также применить к моей небольшой стопке National Geographics в стопке «на полку». Использование правильного метода сортировки стало очень важным, особенно когда этот стек стал большим. И я очень быстро понял, что существует много способов отсортировать очень неупорядоченный стек!

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

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

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

Когда я был в третьем классе (* качает трость *), мы узнали о карточных каталогах. В информатике карточный каталог является примером «вторичного индекса». Ясно, что это не слишком сложная тема для восьмилетних детей в 90-х, но как дети теперь должны узнавать о вторичных индексах?

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

Я не говорю, что восьмилетние должны научиться вычислять время Big O для Heapsort (честно говоря, я почти не помню, что такое Heapsort, и у меня все в порядке). Но концепция «сортировки» и «поиска» как общих проблем, имеющих более эффективные и менее действенные решения, неоценима.

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

  • Передача данных по ненадежному соединению. Подумайте о старых рациях или письмах, где почта может потеряться. Вы хотите отправить сообщение другу, но фрагменты сообщения могут быть потеряны или искажены. Как вы проверяете, получил ли ваш друг сообщение или вам нужно отправить его повторно?
  • Использование удобной для детей версии регулярных выражений, возможно, с блоками и цветами, для извлечения шаблонов из большего набора. Это также может быть интересно и полезно для взрослых: «Как роботы автоматически собирают номера телефонов / адреса электронной почты?» Есть ли типы паттернов, которые нельзя сопоставить таким образом?
  • Поиск того, что вы ищете, в большом наборе данных. Будет ли полезно, если данные будут отсортированы по атрибуту, по которому вы ищете? Какой метод вы использовали, чтобы найти его в отсортированных данных? Что делать, если он вообще не отсортирован или не отсортирован по тому, что вы ищете? Можете ли вы добавить другую информацию (указатель), чтобы облегчить поиск?
  • Найдите данные с помощью древовидной структуры (черт возьми, если вы все еще привязаны к роботам, добавьте тот, который двигается только влево и вправо, если хотите!). Можно ли сделать разные деревья? В чем разница между деревом и сеткой?
  • Сортировка данных. Какой самый быстрый способ отсортировать пять, 10, 1000 вещей? Разве на сортировку 200 вещей уходит в два раза больше времени, чем на сортировку 100? Как мы вообще можем измерить «скорость» в некотором роде?
  • Насколько вы можете сжать сообщение? Используйте цвета, размеры блоков и / или другую «информацию» для замены букв или слов и посмотрите, насколько коротким вы сможете сделать сообщение. Меняется ли ваш алгоритм с сообщением? Как получатель узнает, какой алгоритм использовать для его декодирования?
  • Логическая логика. LittleBits имеет это как (очень дорогой) дополнительный пакет, но я потратил немало времени, фантазируя о дешевых, ярко раскрашенных блоках размером с Duplo, соединяющих вместе блоки, которые выполняют только логическую логику. Маленькие дети могут жевать их и смотреть на красивые огни, маленькие дети могут понять, почему один блок работает именно так, а дети постарше могут строить калькуляторы!
  • Хранение данных для быстрого поиска. Дети раскладывают карточки на столе в виде сетки, где каждая карточка содержит некоторый набор информации («информацией» могут быть формы, числа и цвета). Даются такие запросы, как «все карточки, содержащие красные квадраты». Цель состоит в том, чтобы иметь возможность подобрать все совпадающие карты за наименьшее количество ходов по сетке с правилами движения, похожими на то, как данные считываются и доступны в памяти компьютера. Как разные типы запросов влияют на то, как лучше всего расположить карточки на столе?

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

Что мне нужно

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

Я писал учебные книги, проводил семинары, преподавал и разрабатывал классы, а также работал волонтером в нескольких организациях в качестве преподавателя. Моя первая работа была в местном общественном колледже в качестве репетитора по математике и естественным наукам (и тому, что им было нужно) в центре доверия. Но мое формальное образование - инженерное дело, а не образование.

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

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

Я также ищу новые возможности для волонтерства в районе Бостона (вот мое резюме!). У меня есть работа на полный рабочий день (Пн-Пт, 9–5), но за пределами этого мой график широко открыт. Мне особенно интересно работать с детьми, которые испытывают трудности с математикой или естественными науками или которые иначе не смогли бы познакомиться с этими понятиями. Я понимаю, что с дневным графиком работы сложно охватить эту группу, но девушка может мечтать, верно?