среда, 31 июля 2013 г.

ПМО ИУС — Rapid Application Development

Включение изучения среды RAD было обусловлено рядом причин: другой (GUI) интерфейс, второй тип проекта в курсе (не только консоль, т.е. два проекта используют одну библиотеку для понимания подключения разрабатываемых библиотек), мультяшность (эмоциональность другой среды, т.к. изначально консоль это тривиально и скучно), другая парадигма в построении приложения (консоль это одна стартовая нить, здесь же одна нить, которая выполняется на разных методах в случае наступления событий). Кроме того, среда RAD ранее в Delphi и сейчас в Builder'e имеет низкий порог вхождения, что позволяет её внедрять в массы.

В рамках данной темы две работы — одна на базовый интерфейс и компоненты VCL вообще, а вторая на понимание событий в RAD (чтобы можно было делать динамичное, например захватывать мышой и тягать объект по экрану).

RAD также хотелось запускать как можно раньше, сразу же после завершения тем ООП. Это обсуловлено было тем, что во-первых, эта тема эмоциональная и контрастная, во-вторых, существенно разбавляет консоль и в-третьих, делает переключение на второй проект (не консольный, а GUI-шный, который в дальнейшем развивается). Кроме того, после прохождения RAD тема по исключениям делается немногим более насыщенной, так как подхватываются не только пользовательские и стандартные исключения, но и исключения VCL.

Результат выполнения работы получался зачастую веселым и занимательным. В зависимости от задания требовалось изобразить графически в помощью методов Canvas (рисование простейших элементов — линии, эллипсы, прямоугольники, …) состояния разрабатываемого объекта класса,и далее этот объект становится в следующей работе динамическим. Это были и обезьяны, ползающие по пальмам за орехами, и змей горыныч в пару десятков голов с глазами следящими за мышкой, и спутник взлетающий на орбиту по параболе и др..

Удержание фокуса

Использование классов библиотек как есть, без изменений.

Продвинутые студенты использовали полиморфизм, работая через указатели. Т.е. объект в зависимости от типа подстановки вел себя различным образом.

Выделение отдельных функций для рисования-стирания объекта.

Подробности

Слайды.

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

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

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

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

Базовые классы — AnsiString он же String, свой внутренний велосипед стрингов внутри VCL и на нем построены все стринги, которые используются в VCL.

Различные типы свойств — простые типы, выбор из нескольких, множества, сложные со своими редакторами, массивы свойств, вложенные свойства. Их всех можно найти в Object Inspector'e.

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

Примеры базовых методов Canvas для рисования элементов на нем. Есть несколько компонентов, которые имеют Canvas, и рисовать можно на каждом из них, делая это практически одинаковым образом.

Представление цвета в Canvas. RGB. Canvas как большой двумерный массив пикселов.

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

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


вторник, 30 июля 2013 г.

ПМО ИУС — ООП — Наследование и полиморфизм

Наследование уже изучалось после прохождения 3-й работы и усваивания Google Test Framework. Таким образом, первые основные три темы, которые должны были введены быть в курс как можно быстрее для того, чтобы в каждой из работ потом повторятся — проведены.

Вместе с наследованием изучалась перегрузка операторов. Полиморфизм без наследования изучать сложно, а перегрузка операторов потом пригождается при изучении STL.

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

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

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

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

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

Все это проверяется в Google Test. Как и следовало ожидать, так как функция переносится в наследник, то все тесты ломаются, так как базовый класс уже создать нельзя в силу его абстрактности. В связи с этим чинятся тесты (что полезно — что-то изменилось, нужно привести в порядок тесты). И далее тестируется в том числе и новая функция.

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

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

Подробности

Слайды, слайды.

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

Наследование может быть в несколько уровней. Кроме того, оно может быть множественное и очень разное.

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

Как это делается в С++. Демонстрация повторного использования кода и данных.

Изменение доступа при наследовании в C++. По умолчанию делаем public.

Размещение данных в памяти и как может произойти срезка.

Синтаксис конструирования объектов иерархии. Порядок вызова конструкторов и деструкторов.

Доступ к одноименным функциям в рамках одной иеррархии наследования.

Множественное наследование (как так получается, контроль одного базового класса компилятором С++).

Перегрузка функций в С++. Одно имя, разный интерфейс. Выбор интерфейса исходя из контекста. Преимущества такого подхода по сравнению с зоопарком разноименных функций.

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


понедельник, 29 июля 2013 г.

ПМО ИУС — ООП — Инкапсуляция и модульность

Инкапсуляция хорошо по интуитивному смыслу дружит с модульностью, поэтому благоразумно давать их вместе — первое как контроль состояния объекта и защита от внешних воздействий, и модульность как уменьшение сложности методом распиливания на независимые части. В рамках первой — это перевод всех данных под private раз и навсегда до конца курса, в рамках второй — разделение класса на пару файлов hpp/cpp и вынесение их в отдельное место, отличное от главной программы, которая уже подключает их через include.

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

С точки зрения работы функционал практически не добавляется — только с точки зрения поведения классов необходимо добавить действия по сохранению объекта в корректном состоянии (чтобы Дюймовочка не плыла участки в минус 5 метров, иначе поведение объекта или его состояние может стать некорректным) — это делается как раз вместе с инкапсуляцией. Кроме того, идет разделение и вынос hpp/cpp, что тоже не меняет функционал.

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

Разбиение hpp/cpp является подготовительным шагом к следующей работе, где классы выносятся как отдельная библиотека и там тестируются. Т.е. сначала сплошной cpp с классом и main(), далее main() + файлы hpp/cpp, и далее уже main подключает через svn:externals hpp/cpp. Малые шаги лучше чем все сразу.

Фокус на обязательности инкапсуляции и обязательности всех правил оформления кода.

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

Сразу прописывыаем защиту от повторной компиляции — чтобы она стояла везде.

Подробности

Слайды.

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

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

Как это делается в C++. Что это дает (защита, разделение).

Типичная сборка проекта в C++ с точки зрения файлов (пары hpp/cpp, которые независимы и подключаемы при необходимости).

Защита от повторного подключения в С++ (как выглядит и зачем).

Доступ к полям класса (public/private/protected). Что такое наследование пока что не знаем, просто помечаем на будущее. Как это выглядит в C++.

Getter'ы и Setter'ы.

Пример изменения реализации — изменяем private и логику функций, однако интерфейс не изменяется.


воскресенье, 28 июля 2013 г.

ПМО ИУС — ООП — Абстрагирование и типизация

Изначально мне и нам преподносили ООП с теоретическом стиле Буча — программные системы становятся все сложнее, понятие сложности, с этим надо что-то делать, … К этому всему эволюция программных парадигм (формулы, алгоритмы, подпрограммы, модули, …). Как показывала практика, понимание и усвоение с такой подачи шло очень слабо. По моему мнению, это происходило из-за ряда причин: приличный кусок теории, не связанной с практикой (просто большой объем такой информации воспринять и переварить сложно); отсутствие у студентов опыта написания и понимания сложных систем; новизна большого числа понятий, которые появлялись на практически пустом месте.

Такой подход по моему мнению, конечно классический, но через данный барьер проходили не многие (мало кто в конце 2003-2004 года мог толком сказать чем класс отличается от объекта), а ещё хорошо помню с какими потерями в свое время мне пришлось изучать ООП самому. Хотелось чтобы это не оставалась как система выживания (типа кто хочет, тот научится), а минимизировать порог вхождения для понимания основных сущностей в ООП.

Для решения данных проблем было предпринято ряд действий. Во-первых, все ООП было аккуратно распилено на 6 разных частей (абстрагирование, типизация, модульность, наследование, иерархия, полиморфизм). Каждая часть — это отдельный пункт, с которым надо отдельно разобраться, а разбор проходил в виде отдельной лекционной части, не залезая в другие. Аналогичное деление происходило в лабораторных — когда в каждой из них акцент ставился на определенные моменты. Во-вторых, вся история появления ООП была выброшена из потенциальных конспектов и преподнесение делалось как есть (как создать класс, что такое объект, как можно эти оперировать, какие преимущества и недостатки). В-третьих, психологически практически полностью выброшен пугающий подтекст (сложность, большие системы, …), т.е. да, ООП может показаться и оказаться сложным, но ничего сложного в нем нет. В-четвертых, в материале были выброшены все малые детали, а акцент был только на больших сущностях, которые прокручивались по нескольку раз на разных лекциях (важно первое приближение, а детали уже в случае частных вопросов). В-пятых, материал не только как есть, но вокруг него ряд вопросов-ответов (почему так; зачем; что это дает; как это сделать; вот аналогичный в жизни пример, но не на языке С++; когда применять а когда воздержаться;…).

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

Абстрагирование и типизация

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

Мы с раннего детства умеем абстрагировать, но не знаем, что это так называется (; Если у нас есть корзинка фруктов и мы хотим узнать сколько там яблок, то для этого нам нужно провести абстрагирование. У нас есть задача (посчитать количество яблок), мы представляем что такое яблоко (можем его отличить от другого предмета в корзинке), умеем считать (ответ — число). Мы выбираем только те сущности и свойства реального мира, которые важны в нашей задаче. Нам важны только яблоки, и только их число. Нас не интересуют груши и грибы, нам не интересны спелые ли яблоки или червивые, нам важны только яблоки и только их число. Выделение нужных свойств из всего разнообразия — есть готовое абстрагирование.

Первая из лабораторных ориентирована в самом начале (после первых шагов в SVN) на абстрагирование. Раньше такой ориентации не было. Если посмотреть на примеры выполнения первых ООП-работ 2003-2005 гг. (которые пришли мне в наследство), то можно заметить, что процесса ООП-абстрагирования нет вообще, а в мыслях об ООП рождается впечатление, что это такой хитрый способ сборки функций в одном месте и рядом лежащих данных, а с таким высказываемым студентами впечатлением на л.р. я сталкивался постоянно. Когда сейчас смотрю на эти примеры, то понимаю, что это выглядит как будто ООП (классы, объекты), но это не ООП, а процедурное программирование, обернутое в классы и объекты.

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

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

    Во двор каждый день прилетают новые воробьи, и кот Васька знает, сколько каждый день прилетит новых. Старые же воробьи из двора не улетают.

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

  2. Дюймовочка плывёт на кувшинке и спасается от жабы. Согласно первоисточнику, течение было очень сильным (M м/с) и поэтому жаба отставала и не смогла догнать. Согласно законам физики, течение действует одинаково как на Дюймовочку, так и на жабу. Но, о чём умалчивает первоисточник, жабу слишком жёстко заносило на поворотах. Поэтому Дюймовочка двигалась с постоянной скоростью M м/с, а жаба ускорялась с ускорением X м/с^2 и на поворотах её скорость падала до нуля. Подлинной истории неизвестно, догнала жаба Дюймовочку или нет, но известны длины участков реки, а также то, что жаба стартовала со скоростью 0 м/с.

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

  3. Когда варкается, хливкие шорьки превращаются в мюмзиков. При чём за один такой день - одно превращение. Если не варкается, то количество мюмзиков увеличивается на 2. В зависимости от погоды каждый день варкается или нет.

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

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

Первые шаги в работе — проведение абстрагирования. Необходимо исходя из задания выделить необходимые для решения сущности (данные и код, поля и методы). Этот процесс происходит не у всех и не сразу, что тоже вполне естественно,и также естественно то, что большинству студентов требуется помощь — что и имеет место, когда мы начинаем лично разбирать задачу — что происходит, какие объекты, в каких они могут быть состояниях, что для нас важно а что не важно и т.д. (это вполне естественно потому, что способность к проведению абстрагирования с точки зрения ООП приобретается только с опытом, а у студентов пока что опыта нет). Таким образом в результате абстрагирования собирается класс, позволяющий решить задачу. Из одного и того же задания класс не всегда получается одинаковый (может быть даже пара классов, типы полей студент выбирает сам исходя из своих соображений, …).

Следующие шаги — каркас уже готов (поля и интерфейсы методов), собирается функциональность и проверяется её работа. В этой работе нет никакой инкапсуляции (все в public), обязательна демонстрация доступа к полям и методам класса напрямую (чтение, запись, вызов). Кроме того, необходима сборка конструктора по умолчанию и конструктора с параметрами, задающего полное начальное состояние объекта, и, соответственно, проверка их работы. Все в одном cpp-файле, ничего лишнего (так как ещё тут есть SVN, консольная среда Builder считается новой).

Таким образом, акцент идет на абстрагировании и типизации (создание своего типа, первые шаги; другие элементы типизации позже), а фокус держится прежде всего на базовыя понятиях класса/объекта, объединения кода и данных, а также их применения.

Подробности

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

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

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

Объект — это код (действия) плюс данные (поля). Если мы возьмем абстрагированную лампочку, то она будет иметь какое-то нам важное состояние (поля) и над ней можно будет делать какие-то нам важные действия (код).

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

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

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

Синтаксис в С++ для типов/переменных и классов/объектов аналогичен. Также можно создавать указатели определенного класса на объекты, массивы объектов определенного класса, присваивать один другому и др..

Само определение ООП звучит так (база объекты, объект является экземпляром какого-то класса, есть иерархия).

Этапы ООП — абстрагирование (изучили), проектирование (сборка классов-объектов и взаимоотношений между ними) и программирование.

Пример иерархии классов и каков в ней смысл (общее объединяется и выносится наверх; это общее может быть как код, так и данные).

Примеры того, как это может быть в С++ (лучше в Real-Time с нуля) — просто пустой класс, добавление 1-2 полей, запись-чтение, добавление функций (методов), вызов функции, работа в контексте класса, две формы записи тела метода (внутри класса и вне), функции-помощники класса (объекты можно передавать как параметры).

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

Специальная функция перед уничтожением объекта — деструктор.


суббота, 27 июля 2013 г.

ПМО ИУС — Разработка через тестирование

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

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

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

Причинами появления именно Google Test являлись: наличие зоопарка фреймворков для юнит-тестинга (о чем жаловались сами гуглеры — каждая собака желает иметь свой велосипед) и выбор межплатформенного и документированного из них; изучение ещё одного инструмента; точное попадание в С++ и лаконичность инструмента; потенциал развития и поддержки фреймворка, а также его совместимость с основной IDE (Buidler). Google Test стал совместимым только с XE2, поэтому Google Test появился в курсе только в 2012 году.

Следует отметить, что изучение новых и различных инструментов являлось одним и больших фокусов всего курса. Т.е. важным пониманием является то, что многое сделано до нас, и что этим многим надо уметь пользоваться, понимать что есть много полезных вещей и не только самим языком программирования жив инженер. В частности, од этот фокус попадали Doxygen и SVN. На заре ещё думали прикрутить JIRA'у, но руки не дошли.

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

Удержание фокуса

Тестирование проводится для всех функций, конструкторов и методов классов. Покрывается белый ящик по всем веткам поведения.

Обязательно сначала идет разработка класса и его тестирование, и только потом переключение из другого проекта (консоль или GUI) на новый собранный тег (которое через externals).

Сам Google Test подключается тоже как externals, в проекте достаточно было прописать пути и за-include-ть фреймворк.

Подробности

Слайды.

Старт и приближение к TDD начинался с рассмотрения моделей разработки ПО. Водопад — сам каскад водопада, необходимость этапов и правила отката, область применения (детерминированные с точки зрения технического задания системы). Если правила меняются, то использовать водопад сложно.

Диаметрально противоположная модель — спираль. Пример использования спирали (первый цикл, прототип, тест, обратная связь с заказчиком, уточнение требований, проектирование, разработка, … цикл). Каждый виток спирали — малый водопад. Итерации быстрые, ориентированные на изменяющиеся требования. Необходимость выхода на первый прототип. Условия применения спиральной модели — изменяющиеся требования, быстрое развитие ПО, необходимость экспериментирования, …

Между ними — V-образная модель. Как делается гибрид, в чем он выигрывает (соответствие каждой цикловой V отдельному процессу), преимущества и недостатки.

Только сейчас идет переход к TDD. Общая постановка TDD, как по алгоритму он применяется (классика TDD).

Следующий шаг — Google Test. Как инструмент, облегчающий автоматизацию процессов, происходящих в TDD. Да, можно сделать все вручную, но уже есть готовое помогающее решение и мы его будем изучать.

Получение Google Test и его подключение к проекту, рассказ на пальцах.

Простейший тест консольного приложения. Одиночный тест, EXPECT, ASSERT, EQ/NE/…, TRUE/FALSE, ….

Группы в Google Test. Зачем и что это такое. Порядок запуска тестов (или беспорядок (; ).

Выполнение теста как функции — любые дополнительные действия на С++.

Fixture-tests. Инициализация и завершение. Использование методов в служебных целях (контроль времени теста например).

Использование готовых Fixture.


пятница, 26 июля 2013 г.

ПМО ИУС — Оформление кода

Оформление кода начал внедрять ещё Андрей Логвиненко, но с этого времени прошел ряд изменений.

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

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

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

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

Doxygen, также как и оформление, был обязателен со второй л.р..

Первая лабораторная была о SVN и первые шаги ООП (абстрагирование и понятие классов и объектов). Такой выбор потому, что больше двух тем на одну работу нанизывать не рекомендуется (исходя из практики). SVN потому что все лучше сразу делать как проект с нуля и под его контролем. Вторая лабораторная уже фокусируется на инкапсуляции в ООП как логический шаг и продолжение первой, а инкапсуляция отлично сочетается с оформлением кода — уже есть пример неоформленного кода, который нужно оформить, появляется несколько файлов и структура функций и данных для оформления и документирования, а также для автоматической документации Doxygen. Оформление кода также желательно ставить как можно раньше, но ранее SVN его не поставишь, потому только вторая.

Удержание фокуса

Необходимость приведения оформления при каждой сдаче л.р.. Большинство постепенно при таком контроле привыкало делать сразу так, как надо. Данные исправления были волнами — сначала заметили одно (например форматирование) — исправляем. Закончили — идем дальше (нижний регистр, пробелы, предел по длине, …).

Необходимость комментариев каждой сущности (класс, объект, поле класса, функция, возвращаемые и передаваемые параметры, броски исключений). Обязательность сборки Doxygen, все необходимые комментарии должны быть были подхвачены.

Студенты вне графика (в обе стороны) — рафинирование комментариев (удаление бесполезных, акцент на задаче, пред-условиях и пост-условиях, а не на конкретной реализации, указание информации для внешнего пользователя, а не про себя, лаконичность, …).

Подробности

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

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

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

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

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

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

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

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

Сравнение c Lower Case. В последней отсутствует тип (облегчение работы с кодом), все буквы в нижнем регистре (облегчение восприятия и отсутствие неоднозначностей и ошибок при двух регистрах).

Использование префиксов и постфиксов в Lower Case по широкополосным служебным целям. Например указание типа «_t» ускоряет принятие решения при создании переменной по умолчанию, а также отличает принципиальное качество тип и переменная.

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

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

Систем автоматического генерирования документации много, Doxygen одна из них.


четверг, 25 июля 2013 г.

ПМО ИУС — Системы контроля версий

Исторически все развивалось так, что системы контроля версий были добавлены в курс ~ в 2008-м году, когда ещё не было Git'ов, Mercurial'ов и пр., а SVN занимал 90% рынка новых стартующих проектов. Subversion уже длительное время использовался в «Интервэйле» (как минимум с 2004 года) и этот опыт напрямую переносился. Кроме того, система организации каталогов проектов и подключения библиотек была взята в определяющем так, как это было организовано в компании.

По теме была запланирована одна лекция, которая обычно длилась 1-1.5 пары. Это была первая тема, так как все, что делалось в дальнейшем, делалось под контролем SVN.

SVN-сервер находился на кафедральном сервере и студенты имели доступ к нему из любой точки ВУЗа. Каждый из учащихся получал свой репозиторий, с которым он работал в течение семестра. На лабораторных в подавляющем числе случаев использовался интерфейс TortoiseSVN.

Удержание фокуса

Каждая лабораторная должна быть в конце зафиксирована в репозитории в виде тега и это проверялось при сдаче. Приучаем к отработке всего цикла — checkout, правки одной малой задачи, commit с описанием что было сделано. Для многих действий нужно было делать все в первых работ step-by-step, что, зачем, как.

checkout на локальные машины, а не на внешние сервера. Много копий (локальных и в репозитории) это плохо — то что закоммичено, того не вырубишь топором — переход на новую идеологию хранения исходников.

Установка под контроль сразу же после появления исходных файлов. За контроль EXE/OBJ/… давать по рукам и заставлять снимать из под контроля.

Подробности

Слайды.

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

Сначала рассмотрение понятия проекта — нечто с определенной целью в виде некоторой активности в течение времени. Подготовка к вечеринке, выполнение курсового, поход на рыбалку, регулярная уборка в доме — все это проекты (будущий проект в svn).

Каждый проект с чего-то начинается и имеет последовательность действий. Каждое малое действие может быть выделено и описано отдельно (будущие ревизии и их описание в svn).

Если рассмотреть проект во времени, то его состояние постоянно изменяется по мере выполнения каких-либо действий. Таким образом проект не просто набор чего-то, а что-то, что существует и изменяется во времени (будущий контроль проекта svn во времени).

С точки зрения контроля проекта во времени у нас могут возникать вопросы: в каком состоянии был проект в момент X? кто сделал действие Y? что изменялось в проекте за месяц Z? что надо сделать, чтобы отменить изменения за позапрошлую неделю? Данные проблемы надо как-то решать, и решение зависит от организации контроля проекта во времени (будущие типичные задачи при работе в svn).

Как мы можем контролировать проект во времени? Завести блокнот, создать ряд каталогов на диске, держать в голове, … у каждого способа есть свои достоинства и недостатки (блокнот копировать сложно но он надежный, компьютер доступен не всегда, но он быстр, в голове можно и забыть, но это всегда под рукой).

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

С точки зрения автоматизации уже имеются всем знакомые системы контроля версий, которые помогают нам в этом. Undo/Redo в где угодно (хоть в MS Word), страница в википедии (показываем в онлайне историю правок с датами, комментариями, возможностями сравнения и отката, …). Таких ресурсов много — история изменений одного файла в Dropbox, изменения страниц в pbworks.

И только теперь на сцену выходит Subversion и начинаются слайды.

Понятие архитектуры клиент-сервер. Хранилище одно, оно надежное и доступное отовсюду. Клиентов много, они общаются с хранилищем и сами себе буратины.

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

Понятие ревизий в Subverison. Ревизии атомарные, инкрементируются только при успешном commit'e. Каждая ревизия — в идеале одна отдельная задача.

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

Фиксация изменений (commit). Инициирует клиент, дает описание изменений. Все хорошо — фиксируется, плохо — не фиксируется (требуется ручное вмешательство при слиянии, проблемы подключения, …). Описание изменений ассоциируется с ревизией и потом может быть использовано.

Обновление (update). Использование когда возможны внешние правки (например работа в команде).

Откат локальных изменений (revert). Команда отрабатывает локально, без подключения к серверу. Локально всегда хранится копия с последнего checkout'a или update'a, чтобы система знала, что было исправлено локально, и чтобы можно было таким образом откатить изменения.

Понятие контроля файлов в WC. SVN должен знать, что ему контролировать, т.е. каждый файл на диске находится под контролем SVN или нет. Если мы сами создаем файл, то SVN о нем ничего не знает, и при необходимости мы должны ему сказать. Под контроль ставятся только исходные, но не производные (EXE, OBJ, …) файлы. Команды установки код контроль и снятия из-под контроля. Копирование и перемещение в SVN — не создает нагрузку на сервер.

Структура хранилища с точки зрения классики SVN — trunk, tags, branches. Что такое trunk, зачем нужны теги (фиксация стабильной версии, передача конкретной версии заказчику, выделение версии для конкретных работ, …). Понятие branches — выделение отельных веток и слияние (один программист пилит новую функциональность, второй правит баги, и оба друг другу не мешают; отдельные ветки для подпроектов и подзадач, когда требуется дальнейшее развитие).

Описание полного типичного рабочего цикла (checkout, updaten commit).

Свойства в SVN, на примере svn:externals. Подключение внешних ресурсов через externals (иначе не получится), экономия места, переключение externals на другую версию.

По обстоятельствам — демонстрация создания svn-сервера и типичных действий над hello world.


среда, 24 июля 2013 г.

ПМО ИУС — Содержание курса


Планирую сделать некоторое описание содержания курса на последний из семестров с выкладками того, почему было сделано так и какие имели место особенности. Букв получается много, поэтому распилено на несколько сообщений. Сначала — общее содержание.
Системы контроля версий
Изучение систем контроля версий в общем, практическое изучение Subversion на всем протяжении курса.
Оформление программного кода, системы автоматической генерации документации.
Общие вопросы оформления (зачем, когда, как), практическое изучение на всех лабораторных кроме одной, + также все под Doxygen.
Разработка через тестирование (Test Driven Development)
Спектр от водопада до спирали, использование Google Test с полным функциональным тестированием на всех лабораторных, кроме 2-х.
Объектно-ориентированное программирование
Последовательно, теоретически и практически, с периодическим повторением — абстрагирование, типизация, модульность, инкапсуляция, наследование, полиморфизм.
Rapid Application Development
GUI интерфейс на практической основе C++ Builder, изучение базовой событийной системы в Builder (который выглядит как однопоточный Reactor).
Исключения
Традиционные способы обработки исключительных ситуаций (игнор, останов, общая функция, возврат кода ошибки), исключения как инструмент, создание своих классов исключений и исключения сторонних библиотек на примере std::exception и исключениях среды C++ Builder.
Структуры данных
Разбор понятия структур данных. Линейные структуры данных: массив, стек, очередь, списки (разные). Деревья, бинарные, балансировка деревьев, способы обхода. Куча (heap). Динамическая и статическая реализация (линейных, деревьев, кучи). Хэш. Пример экзотической структуры данных — Sparse Array с инициализацией элементов только по требованию. (здесь без лабораторных)
STL
Основные понятия библиотеки: контейнеры, итераторы, алгоритмы (только). Разбор vector, list, stack, queue, priority_queue, deque, map, multimap, set, multiset, heap. Несколько алгоритмов.
Потоки ввода-вывода
Общие понятия потоков, иерархия потоковых классов std::, буферизация, функции потоков и манипуляторы, ошибки потоков и файловые потоки.

Развитие проекта под Subversion в лабораторных (кликабельно):


суббота, 20 июля 2013 г.

ПМО ИУС — Автоматизация и разработка IT-инфраструктуры

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

Начальные условия

Прежде всего следует напомнить о том, какой мир был в то время. Так, в 2003-2005-м году Интернет не был таким доступным как сейчас — только dial-up за по нынешним меркам бешеные деньги со скоростью 2кб/с и постоянными обрывами связи. Возможности использования готовой SQL-БД резко ограничены как в силу отсутствия подходящих пакетов, так и потенциальной необходимостью переездов между серверами с соответствующим бюрократическим сопротивлением. HTML был максимум XHTML'ом, набирающим обороты. JavaScript максимум что делал, это проверял поля формы на правильность количества букв полей с диагностикой только через alert. Из web-языков царствовал PHP, его планомерно покусывал Perl, Java существовала в виде экзотических апплетов.

Что касается организационной части, то в этом плане картина для нас уже выглядела древней. Абсолютное большинство операций по выдаче заданий, контролю выполнения, предоставления информации в удобном виде, какой-либо автоматической обработки — не существовало. Преподаватели давали нам лабораторные в методичках, а индивидуальные задания в отдельных бумажных листочках. Многообразие вариантов представлялось собой максимум вариант номер N, иногда один из 2-4-х прямым текстом, иногда таблица, в которой студент номер N выбирает набор параметров в N-й строчке таблицы. Кроме этого, было много бумажной работы — мы многие отчеты либо писали вручную, либо печатали на одном на всю группу принтере, потом эти тонны бумаги куда-то надо было сдавать. Если обратить внимание, то на все это уходила уйма времени.

В течение последних лет в группах до сих пор постоянно на первых занятиях были студенты, которые приносили тетрадки для лабораторных работ (чтобы туда писать), и ещё много кто переписывал задания себе куда-то. Очень часто приходилось объяснять, что сервер доступен из любой точки БелГУТа, задания никуда не пропадут, можно быстро будет собрать отчет и вся бюрократия в электронном виде. На основании этого делаю вывод, что скорее всего со степенью автоматизации в ВУЗе все так же плохо, а студенты во время учебы зачастую занимаются переписыванием и перепечатыванием.

Когда информация о процессе выполнения работ собирается в одном месте, то появляются возможности делать над ней что-либо. Например, если мы смотрим в бумажный журнал, то можем посмотреть, сколько отличников а сколько двоешников в этой или этой группе, сколько было пропусков, сколько народу выполнило курс, провести какие-либо сравнения и т.д.. С точки зрения такой коллекции информации максимум что было, это преподавательский журнал. Единственный пример который мы видели другого плана — у Харлапа С.Н. в курсе ПМО МПС вся информация собиралась в Excel-табличке, которую потом можно было через FTP в R/O посмотреть. Но даже в таком варианте чувствовались плюсы — файл по сети можно забрать и посмотреть из сети, данные самые последние, можно смотреть всем и подумать над происходящим всем (преподавателю, студенту, декану, …).

Первый сезон

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

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

Было понятно, что если что-то делать в качестве предоставления информации, то нужно это делать на вебе. В то время веб эволюционировал быстро (что сейчас происходит не знаю), — браузеры и платформы были разными и жили каждый своей жизнью, кроме того, какие из новых фич станут стандартными было не понятно. Ко всему прочему война браузеров была и у нас в Университете — на ВЦ на старых машинах жил IE, на новых жестко прописанная админами Opera непредсказуемой версии, в аудиториях нашей кафедры была демократия и возможность выбора, а в оставшейся части ВУЗа — самый настоящий заповедник гоблинов. Поэтому те вещи, которые делались в первый год были пилотно-экспериментальными и мы быстро пришли к идеям пуленепробиваемого веб-дизайна (минималистичность самых стабильных фич, работающих везде независимо от всего).

Программный инструментарий также был не ясен (ввиду малого опыта в вебе). И на начальном этапе, например, эта табличка генерировалась с помощью EXE-программы на Pascal'e, данные для генерации вводили преподаватели (как набор флагов сдал-не сдал) методом редактирования файла удаленно с доступом по FTP. Кроме того, форма подачи несколько раз изменялась.

Приблизительно в это время я создаю сайт Гомельского Айкидо (все полностью, клиент-сервер, частично дизайн, форма подачи материала, … согласуя только содержимое и дизайн с руководителем объединения; до настоящего времени сайт функционирует на этой системе). Сайт несколько раз переписывался, начиная от набора страниц и заканчивая внутренним движком с файловой БД, полным разделением «данные→форма представления→оформление на устройстве» (на языке веб-разработки можно описать как «только полезная информация→HTML→HTML+CSS», наверно есть какой-то известный паттерн по этому поводу (; ), со своими внутренними велосипедами (свои счетчики, лента новостей, под-движки для фото-галерей, функциональности для статей, подсистема для создания меню и др..). В какой-то момент времени я взял то, что было сделано для сайта и фактически сделал форк на отдельную ветку.

Сейчас смотрю на сохраненные данные и исторически вижу, что уже во втором сезоне работы со студентами у нас было сделано многое для сервера ПМО ИУС и автоматизации процесса — переход всего на веб клиент-сервер нашего интРАнета.

Технические подробности

Основные функциональные вещи обеспечивала серверная часть, собранная на Perl'е. Выбор обусловился тем, что совсем рядом существовало две системы, написанные Максимом Кузьмичем тоже на Perl'e (система для автоматизации проведения олимпиад по программированию и система автоматизации тестирования студентов).

В качестве самого нижнего уровня для сайта и системы сервера ПМО ИУС использовалась мною написанная файловая БД. Такой выбор был сделан потому, что файловая БД менее независима от хостинга, не требует дополнительных ресурсов, легко перемещаема и редактируема с ориентиром на то, что будет справляться со своими задачами при небольших нагрузках. Не знаю как сейчас, но в то время с SQL-серверами были проблемы (на том же хостинге они стоили приличных денег).

Файловая БД позволяла создавать сущности в виде реляционных таблиц, в которых все данные представлялись в виде строк (потому что на Perl'ах все есть строка и типизация приводилась в конечном счете к ней). При этом имелась обязательное наличие PK (2NF) и было собрано ряд функций (такие как поиск поля, замена поля, получение содержимого таблицы в скрипт, сохранение изменений, кэширование таблиц находящихся в работе, работа в R/O не требующая синхронизации одновременно запущенных скриптов). Запускаемые скрипты при этом уже работали с непробиваемым слоем, под которым находились данные на диске.

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

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

Архитектура и развитие

Глядя сейчас на историю могу сказать, что с точки зрения архитектуры сложилось все удачно. Угадалось то, что архитектура как таковая была очень минималистичной, т.е. не было жестких функциональных правил, а базовые сущности (что в БД, что в веб-движке) были простыми и легко поддающимися под любые запросы. Особенность последующих лет заключалась в том, что все, что над таблицами данных (интерфейс пользователя, веб-представление, формы генераторов, системы обработки запросов от студентов и преподавателей и др.), несколько раз переписывалось по причине того, что «No project manager plan survives contact with the development». Как только мы внедряли какой-либо вариант системы, то через месяц становилось понятно, что в ней есть существенные недостатки, которые выявлялись только после внедрения, когда конечные пользователи пробовали с этим что-то делать, а мы за этим наблюдали.

Если для типичных действий получается так, что делается 5 кликов по разным точкам, и понимаешь, что это можно-лучше сделать за 1-2, то это лучше исправлять. Если 5 из 10 человек регулярно не находят что-то, то с этим надо что-то делать. Если при каком-либо действии делаются ошибки, то надо организовать действие так, чтобы пользователь их делал намного реже, а лучше чтобы это контролировала автоматика.

Примечание к предыдущему абзацу — как организовывать этот процесс, важность конечного пользователя и зачем все это надо (я встречал всего пару человек, которые действительно как-то это понимают, и это — не программисты вообще) лучше всего видел в курсе Human Computer Interaction, рекомендую, достаточно посмотреть видео-лекции).

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

Финализация

Общий эволюционный процесс вышеописанного фактически остановился где-то в 2007-2008. Пилить систему было куда и зачем — фиксация удобной архитектуры, создание системы не только для себя но и для других (это отдельный большой кусок работы), куча фич вида отослать новые задания студентов на e-mail. Но в это время состав программистов курса на кафедре сокращается втрое, соответственно падает сила обратной связи и разнообразие опыта. Кроме того я сам перехожу на full-time в «Интервэйл» и ресурсы остаются только на поддержание системы.

К слову говоря, в свое время сайтовый фреймворк был переведен с Perl+FileBD на Java+SQL, но опять же, развитие потеряло свое поступательное движение.


воскресенье, 14 июля 2013 г.

ПМО ИУС — Развитие и общая тематика

О последующем периоде до настоящего времени писать проще, так как ведение курса и ответственность за него перешла на меня.

2005-2007

В это время Сергей Зобов переходит на другую дисциплину, а к ПМО ИУС официально подключается Максим Кузьмич, так как он в это время был в магистратуре. Где-то в течение этого времени периода плюс минус год всем курсом занимаемся мы втроем — я, Максим и Андрей Логвиненко. Отличительной особенностью этого времени является то, что все мы уже являлись программистами со значимым опытом, и при этом стиль работы каждого из нас определялась индивидуально — мы только обменивались идеями, согласовывали материалы лекций и темы лабораторных, а форма организации, индивидуальные задания и многое другое уже решалось каждым по-своему. И хочу сказать, она была существенно разной.

2008-2013

Не затрагивая изменения внутренностей курса, в первом году (плюс минус) покидают кафедру Максим Кузьмич и Андрей Логвиненко. Как результат из программистов остаюсь только я, и вести в таком ключе становится сложнее, так как такого рода курс требует серьезной подготовки. Система отношений в преподавательском составе дисциплины меняется из тройки независимых к чему-то более похожему на маленькую иерархию. Нагрузку на весь поток я взять не в состоянии, как результат за мной остаются лекции и 1-2 подгруппы микропроцессорщиков (это треть факультета, более ориентированного на микроэлектронику), остальными занимаются те, на кого удобнее на кафедре распределить нагрузку. Олимпиадное движение в это время затухает и расстворяется за отсутствием кого-либо, этим занимающегося. Над курсом я проводил ещё эксперименты и попытки улучшения, а также изменения содержимого для движения в ногу со временем, но стало понятно, что ресурсы уже не те.

Тематические изменения

В первом же году (2005) стали очевидными несколько проблем, которые стали понятны только к концу семестра. Первая из них — оставшийся материал и лабораторные по алгоритмам, которые коррелировали с тем, что мы знали и изучали на олимпиадном программировании. Так 3-я л.р. представляла собой работу с рекурсией, и как показала практика, для большинства студентов это оказалось слишком серьезным барьером. Без посторонней помощи его не преодолевал фактически никто, а для совместного решения необходима была кропотливая индивидуальная работа. Такая же история с графами, до которых дошли единицы. Поэтому их прохождение шло с существенными временными и моральными потерями, так как осваивание абстрактных вещей давалась с трудом. В связи с этим после первого же года были исключены все лабораторные работы с алгоритмами в пользу облегчения курса и большего уклона к ООП. Параллельно у нас был неофициальный кружок (в то время его организацией, автоматизацией, сервером, заданиями и прочим занимался Максим Кузьмич), который как раз посещали те, кто готовился к олимпиадам, и соответственно те способные студенты, которые потенциально хорошо могли освоить алгоритмизацию, при желании делали это там.

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

Существенным изменением, повлиявшим на весь курс, явился принцип общего проекта, который я различными способами старался усилить все время. Смысл его заключался в том, что цепочка лабораторных работ представляла собой единое целое, как проект, который постоянно нужно дорабатывать. Только первая лабораторная работа делалась с нуля, остальные — это изменения из предыдущей. Такой принцип работал сразу в нескольких положительных моментах. Во-первых, многие действия можно было вынести как повторяющие, и это усиливало закрепление материала. Например, со второй лабораторной все работы должны были быть оформлены строго по правилам оформления и собрана документация Doxygen. На каждой сдаче это строго контролировалось, поэтому студенту приходилось в случае лени переформатировать всю работу, писать комментарии и пересобирать Doxygen, и часто это приводило к пониманию того, что лучше оформлять правильно все сразу. После внедрения Subversion каждая лабораторная — отдельный commit, выделение тега, что тоже приводило к закреплению навыка. После внедрения Google Test — каждый раз написать тесты для новой функциональности, проверить, и только потом пускать класс в рабочую среду.

Следующее изменение — объединение нескольких тем в одну лабораторную работу. Л.р. становилась больше по объему, но при этом уменьшалось само количество лабораторных работ. Это раза в 2 снизило издержки по сдаче-приему-бюрократизации процесса (интересно, но эта идея была впервые озвучена деканом в процессе разбора полетов).

В один момент времени студент не мог работать больше, чем над двумя лабораторными работами, и это контролировалось автоматической системой выдачи заданий. Сначала были открыты только 1 и 2 работа, 3-я закрыта. Если студент сдавал полностью 1ю или 2ю, то открывалась 3я. И т.д. (идея взята с курса коллеги по кафедре Бориса Френкеля). Правило было жестким, и, таким образом, если студент ничего не сдавал весь семестр, то он не мог попытаться принести и сдать сразу все л.р.. Это все понимали, и оно давало ощутимый эффект.

В общем случае предыдущее нововведение являлось частью принципа, который когда-то нам озвучил Сергей Харлап, заключавшийся в максимальном переносе работы студента конца семестра (сессии, зачетной недели) в основное время. Смысл этого был в том, что невозможно чему-либо существенному научиться в короткие сроки. Что-то сделать (именно что-то, на что-то отдаленно напоминающее), списать, выучить на день, но не научиться. Элементы данного принципа внедрялись на всех уровнях. Например хорошим примером являлся Иван Матылицкий, который сдал все работы где-то за 1-1.5 месяца и был освобожден от посещения занятий. Остальная группа смотрит на это и понимает, что это возможно, и что это принципиально отличается от того, чтобы просиживать занятия.

По темам добавились абстрагирование, полиморфизм, инкапсуляция, среда RAD (построение GUI интерфейса), STL (алгоритмы и структуры данных), вернулись исключения. Первые 3-4 года существовал XML+HTML+CSS (общие принципы на 1.5 лекции и 1 л.р., разбор понятий validation, well-formed; XML; CSS; DTD). Была попытка внедрения л.р. по шаблонам (templates в C++), но оказалась неудачной в силу неусваивоемости и тотальной списываемости. Весь курс был обернут под SVN, Doxygen, Google Test, а также переведен на несколько проектов (несколько branches/tags с подключением через externals, об этом подробнее позже).

Изначально как основную среду мы использовали C++ Buidler. Основная причина — низкий порог вхождения для неподготовленных людей. Жестко недекларировалось (хотите приносите в VS, хотите хоть в Qt), но за все время все, кто хотел принести в чем-то другом, так этого и не сделали. Стартовали мы с C++ Builder 6.0, потом был 2007, 2009, и последний переход на XE2 — это был первый из билдеров, на котором скомпилировался Google Test, так как эмбакадеровцы меньше стали заниматься самодеятельностью и приблизились вплотную к VC.


суббота, 13 июля 2013 г.

ПМО ИУС — Становление

Начальное состояние

В то время, когда я учился в БелГУТе, то проходил этот курс (2000 год) и тогда он включал в себя ~ следующее содержание:

Базовая графика в C++
Нарисовать фигуру на экране с помощью графики CGI.
Интерфейсы управления мышь и клавиатура
Нарисованной фигурой управлять с помощью клавиатуры (по стрелкам) и мыши.
Базовые вопросы ООП: классы и объекты
Создать класс и объект, среда — Borland C++ 3.11.
Наследование
Создать два класса с наследованием друг от друга и продемонстировать результат.
Перегрузка операторов
Для существующего класса осуществить перегрузку операторов.
Полиморфизм
Только теоретически.

Дисциплину длительное время вел Семенюта А. Н.. В какой-то момент у него произошел конфликт с кем-то в университете и он ушел в другой ВУЗ (МИТСО).

В этот момент курс оказался в подвешенном состоянии, и его взял вести с условием только на один год Харлап С.Н.. Только после этого он был передан Андрею Логвиненко (потому что аспирантам первого года обучения не пристало вести лекции).

2003-2004

Лекции и содержание курса взял на себя Андрей Логвиненко. К ведению лабораторных подключился я и Сергей Зобов. По инициативе заведующей нашей кафедры Рязанцевой Н.В. одна из дисциплин на потоке была ликвидирована и по часам передана в ПМО ИУС, что расширяло общий объем где-то в 1.5 раза.

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

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

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

К содержимому лабораторных добавились потоки (iostream), блочная работа с файлами (fstream, чтение-запись блоками), конструкторы-деструкторы, перегрузка операторов, ассоциативные контейнеры, исключения, изучение одного и того же на C++ и Java для сравнения, HTML 4.0.

По большому счету темы л.р. не были каким-либо образом систематезированы — на тот момент фактически брались известные из практики вещи и внедрялись в качестве тем и работ. При чем без понимания возможностей студентов, потому половину работ в срок выполняли единицы, а весь курс не выполнил никто (состояние потока за 1-2 недели до зачётов — запасная ссылка). До тем Java, исключений, HTML никто не добрался.

2004-2005

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

С результативностью получилось уже лучше (резервная ссылка).

Такие результаты обусловлены многими причинами. Нами начались использоваться инструменты автоматизации — мною была разработана веб-система выдачи заданий, предоставления студентам информации курса и автоматического генерирования результатов (которая эволюционировала до настоящего времени), а Максим Кузьмич разработал систему тестирования (вопрос-ответ-результат для проверки знаний по л.р. или курсу) — она в ПМО ИУС использовалась где-то 2-3 года, а на другой дисциплине (ПМО МПС) используется до сих пор.

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

Самой главной причиной улучшений в этом и последующих годах являлся человеческий фактор и накопление педагогического опыта. Это большое число различных моментов, о которых сложно узнать или понять, ни разу с этим не столкнувшись. Абстракции — для опытных и профессионалов, само обучение начинается с конкретики. Первое приближение самое важное, а в нём детали совершенно не нужны, важна только ключевые идеи. Люди разные, и объяснять одно и то же одинаковым образом нельзя. Чтобы научиться чему-то принципиально важному, его нужно повторять и повторение внедрять в курс. Если сказать, что л.р. можно сдавать до зачета в любое неважно-какое-время, то они и будут сдаваться в самый последний момент. Заставить и продавить — можно, но может получиться так, что факел у этого человека уже никогда не зажжется и программирование останется страшным кошмаром. …

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


пятница, 12 июля 2013 г.

Кафедра — все

Где-то на этой или следующей неделе заканчивается мой трудовой договор на кафедре «МТ и ИУС» БелГУТ'а, и в моем сознании он последний. Может быть будет что-то частичное, вида прочитать отдельную лекцию, вести кружок или отдельная роль дипломного руководителя.

Преподаванием начал заниматься с 2003-го года, во время обучения в магистратуре. С этого времени на кафедре занимался только одним предметом (ПМО ИУС — это С++/ООП, или просто продвинутое программирование) — подробнее позже.

Первые два года это были только ведение лабораторных, но с 2005-го года мне был передан весь курс, и при этом расширен по предоставляемому объему по часам (поток более 100 студентов, 1 семестр, 36 часов лекций, 52 часа лабораторных). До настоящего года через меня прошло 10 потоков (в один из был перевод дисциплины с 3-го на 2-й курс, соответственно 2 раза за год) и ~ 10 дипломников.

Преподавания на полную ставку у меня за все это время не было, нагрузка была где-то немногим более 0.5 ст. в начале и в дальнейшем плавно уменьшалась до 0.25. Получалось так, что сначала мы занимались разработкой «i-Пути» + аспирантура, а с 2006-2007 года я начал работать в «Интервэйл». Тот опыт, который получался, автоматически влиял и транслировался на сам курс.

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

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

Хочу сказать и говорю отдельное спасибо потоку, являющемуся выпуском 2009-го года. Без вас мое преподавание закончилось бы на лет 7 раньше.


понедельник, 1 июля 2013 г.

MyZeo is «out of business»

Судя по всему, компания MyZeo (о которой было от меня пара сообщений) где-томесяц назад прекратила свое существование и вышла из бизнеса.

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

Для меня основную функцию Myzeo выполнил, но сам факт удручает.

В общем же случае на свете уже есть и другие системы, позволяющие делать что-то подобное. При чем как более сложные (с видеокамерами, снятием ЭЭГ, …), так и попроще (небольшой датчик движения).