вторник, 2 мая 2017 г.

Kids Learn Programming: Working as a Team

This week Ivan and I decided to show the kids of IT specialists what their parents do at work. The process of software development had been explained at the previous lesson, but the kids wanted to participate in it, write the code and feel as they are a part of the process. Here is how we did it.

A letter was sent to our group by a young businessman who wanted us to write him a game and present a demo version in the end of the lesson. The idea of the game had to be something like a flappy bird: a bird which flies by pressing the space key and has to avoid the obstacles. Here is our example. The customer wanted something different instead of the bird, and the obstacles to be more interesting than regular pipes. He wanted the game to have several levels and be distinctive. He also brought a (generous and loving) dog to watch how his task is moving. The dog stayed with us till the end of the lesson.

Kids got involved in the task, tried to guess who was the customer, started telling their ideas how to implement the stuff. Some of them told that we could make a nyan cat instead of a bird, and make him handle the comets. It was hard to come to a common denominator about the rest and in order to have enough time to do the job so we decided to split. Three kids with one tutor stayed making the cat, and other 4 kids went to come up with ideas about the logic of game levels, environment, and such, plus implement some.
Many of us in order to achieve certain goal act as they feel like. In the end, some really get what they wanted but others fail and agree not to have what they initially planned. That’s not how it’s done in development where the result has to be predictable. So after we collected the ideas and before doing anything, we wrote business stories. They looked like:

Given: as a player
When: I press “Start” button
Then: cat flies straight.
We planned how much time we’ll spend for which story, thought of acceptance criteria and made a table where tasks were assigned to the certain kids. Truth is, in the process when some felt they can do better and the author of the story agreed, the keyboard was taken by the more willing kid. Unfortunately, the timeframes weren’t kept and it took us longer than we planned, but that's the reality.
Brainstorming is a nice and helpful technique. I tried to get an idea from each kid so that we all develop general logic of the game and make something really nice. It worked out better with 4 kids rather than 7. Some were too shy and didn’t want to speak unless they have to. Finally, while all were making the first level, one guy designed and draw the elements for the next levels, eating which affected the cat in different ways. However, that was too much for half an hour that we were supposed to work in separate teams. During this time, at least one level had to be implemented in full. The ones who drew nicely or knew where to get the sprites (the boys) did the drawing. The shy ones (the girls) wrote the code for the level. We did it all using one computer and one projector. In the end, everyone participated in every task.
When both teams were done with the elementary stuff, we came together for the merge. Everyone was excited about how it’s gonna work out together. The teacher did the merge because no one knew how to do it. But when we checked what it looked like, it turned out that there is no code for when the cat bumps into the comets. This we fixed together.
This all was interesting and important. But what we are typically afraid of most is what will others say about our work, thoughts, and ideas. Will they like and share them? So the customer came to look at what he’s gonna earn money with. (The customer was a friend of teachers’ who the kids didn’t know.) He thoroughly examined the functionality, read the stories, and checked if they worked as expected. The most enjoyable comments of his were:
“This looks like a cookie, I didn’t realize this is the comet I’ve got to omit rather than eat!”
“Why does the cat say “Meow” when it bumps? Does it like to?”
When criticizing something, try to do it in a kind and even funny way, still so that the kid understands that his work has to be improved but he won’t get afraid of punishment or being disliked.
To sum up, the kids learnt to put the task in a form of a story (Given, When, Then), learnt to track the tasks and to work together on a common project.

среда, 12 апреля 2017 г.

Lesson with Kids: Handling the Failure


Imagine (or remember) the situation, where you are the teacher and have to deal with kids.

What Can Go Wrong During the Lesson?

  1. Teacher isn’t able to explain the material. Result: kids lose interest in the subject and may even stop listening to the teacher altogether.
  2. Teacher runs out of time. Not everything he wanted to explained reaches kids’ ears. Result: all the planning for the following lessons is messed up.
  3. Teacher explains the lesson too fast. In the end, he doesn’t know what to do with the time left.

Who to Blame?

  1. Kids who come late. Some kids showed up late, so the teacher was disturbed while presenting the material, or even started later because of waiting.
  2. Kids who behave badly. Some of them just cannot sit calmly and do whatever the teacher wants them to. They do their own stuff, talk to each other, play with their pens or toys.
  3. Plan of the lesson. If the material is too easy, it’s boring. On the other hand, if the material is too hard, the kids might not be prepared well enough to do the job. Therefore, some of them skip the lessons, others don’t do their homework, yet others are just not smart enough to get the formulas etc.
  4. Teacher who didn’t prepare well enough. Teachers also want their spare time, they can’t always produce new amazing ideas for each lesson to keep kids interested, and they also have their mindset that doesn’t allow for quick adapting to new situations.

Remedy

Some time ago, I learnt that the original sin was not the disobedient behaviour towards God, but rather making someone else the reason of your own fault: Adam blamed Eve and she blamed the serpent. So I’d like to propose not to look for the bad guy here but rather to see what can be done.

Let’s start with the last point. You may think you prepared the lesson nicely, but sooner of all, you’re not the one to evaluate it. Those who listen to you are to judge. If, however, the kids are the troublemakers indeed, it doesn’t matter if they are too active, too passive, come late, or skip the lessons. There are 2 things that can help:


1) It’s about the redundant energy that searches the way out. What the teacher needs to do is to show the right direction for the energy to eject by giving out active tasks, communication tasks, and other activities that involve kids as life models. The more shy ones should participate as well but act from passive positions.


2) Much depends on being able to tell the material in an interesting way. When the teacher does just that, typically, even those who have problems with managing themselves start listening. The teacher needs to make every child feel like they are participants of the lesson, propose to make the decisions, say their ideas out loud and describe the opinion. Students should not realise themselves passive bystanders watching the boring theatre of one actor. And believe me, it might take even fewer resources of yours to prepare such a lesson where you’ll rely on the help from the auditorium.


What we haven’t tackled yet is the plan issue. The teacher can either change the plan altogether or adapt it to the needs of the kids. When both options are impossible, possibly he should change the job is still left.

An Example from Real Life

Andrii Savchuk, Ivan Godzynskyi and me were to teach together. We wrote a detailed schedule of the lesson and planned who does what.

At first, while discussing the homework*, each child would mention the most interesting and the hardest moments they’d experienced. After one of the trainers would show the new material, then the “cookies break,” a game to show how the events work in real life, and another piece of theory about events in Scratch. Then we planned to discuss the future projects for the kids. Sounds good enough for 1.5 hours, isn’t it?



The first issue we faced was that kids were talking too quietly, and only nearby people could hear them. When we were presenting the new material, something went wrong, and then something else didn’t work as expected. The new material part started taking too much time, and the goal to do all planned was at risk.


The reason for all this was bad preparation. Happened once, was obvious, will be fixed next time. But, the lesson is not about the teacher, and even not about the material. Its main goal is to inspire to create, act, and try out the subject under discussion.


In the end, we had to get rid of some part of the lesson. Which one to drop? Maybe not the theoretical material because it’s most important and kids will probably understand it without the game**? Still, we decided to do with the game. At least the little ones left the classroom feeling happy, and we were kind of sure that they would want to come back to find out more, even though the first part of the lesson was not good enough.

* Some hunting projects kids started in class, continued at home and had to make more advanced in the lesson again



** The game we played: there was a labyrinth put (drawn, made with strings or paper) on the floor. One kid would have his eyes closed with cloth so that he sees nothing. Others are the "listeners". They wait for the occasion to tell where the child with closed eyes needs to move. But one kid can say only one type of move: straight, turn left, bind, etc. As a result, one behaves as a computer and others are directions from the programmer.

Have fun with your kids and be wise :)

воскресенье, 2 апреля 2017 г.

Первый урок с детьми

Я уже не раз как учитель пробовала проводить урок и для детей и для взрослых. В этот раз надо было скооперироваться с двумя другими парнями: Андреем Савчуком и Иваном Годжинским, которые тоже имели желание передать свои знания в интересной форме детям 10-12 лет и показать им, что такое программирование.


Когда мы боимся, скорей всего это не что-то конкретное, а незнание, чего ждать, ведь кабы знал, где упасть, соломки бы подослал. Исходными данными было то, что дети придут на курсы впервые. Из этого можно было бы сделать вывод, что они не знакомы со Scratch (язык программирования, использующий блоки как операции над объектами-спрайтами, на котором пишутся в первую очередь простые видеоигры). При более подробном изучении вопроса о знаниях детей, оказалось, что кто-то в школе уже на программировании учился “играть” в скреч, а кто-то не впервые на курсы пришел. Таким образом непонятно, какой глубины знания у ребят и что им будет интересно.


Страшно не угадать, но начинать с чего-то надо было. Мы решили, что каждый урок должен стартовать увлекательно, какого бы уровня знания у ребенка не были. Когда настроение приподнятое, то и скучная работа не такая горькая. Развеселить детей решили небольшим квестом, частью которого было поедание печенек. Удивительно, но дети оказались скромными и ни один не взял печенье во время прохождения заданий, заявив, что там написано “в случае, если ты голодный”, а голодным никто не оказался.


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


Желание решить задачу у одних людей возникает после того, как им в голову вложить новые знания, которые они еще не применяли. Другим же лучше сначала показать задачу, которую они не представляют, как решить, и только в том случае они в голову будут записывать новые знания, касающиеся задачи. Поскольку все мы разные, способы лучше чередовать даже в пределах одной темы. Так я и делала. Первым делом предложила всем знакомый из мультика “Том и Джери” сюжет, который надо было написать на скрече. Бабуля, хозяйка Тома, чем-то занята, и тут появляется мышь. Старушка кричит, залазит на стул и зовет на помощь своего питомца. Тот бросается на охоту. Вот несколько картинок из моей программы, которую я для тренировки написала дома.




Когда наблюдаешь за “мозговым штурмом”, который в группе детей часто сам образуется, кажется, что дети - это вьющаяся речка, которая иногда разливается и даже меняет русло. У них свое представление о мире и склонности, идеи, которые брызжут наружу и мотивации. Я старалась создать запланированный красивый законченный продукт, показав для кого-то первую историю успеха в программировании. Но мои мысли и идеи могут не совпадать с детскими. А ведь то, что я (мы) делаем, должно быть близко в первую очередь детям. Поэтому очень важно не держаться за свою идею, а дать детям зерно, показать, что надо делать, чтоб оно выросло, а там уже только отслеживать, что они движутся в правильном направлении. Поэтому именно дети выбирали персонажей, комнату и думали со мной вместе, что где надо написать, чтоб персонажи работали по задумке, которых становилось все больше и больше в процессе обсуждения. Те, кто уже был знаком со скречем, предлагали, куда нажимать и что делать; им было интересно показать свои знания новым людям. Для тех, кто впервые видел программу, мы разбирали основные блоки, которые могли бы пригодиться. Таким образом и новички и опытные были вовлечены.
Вот картинки того, что у нас вышло. Суть осталась та же, но вместо бабули мы предпочли девочку-рок фанатку, которая зеленеет от разного рода неблаговидной живности, а мышка превратилась в жука, ведь они тоже страшные, сказала одна девочка. Так что если у вас в программе заведутся баги - вы знаете, кого на них натравить ;)


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


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


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

Задание:
Это предложл сделать тренер

Вот, что вышло:
Котик охотится на голубя
Альтернативный лев доганяет лошадку

Мистика в черном лесу


Квест "Спасти девочку (современную принцессу)"


Да, кто-то таки делал, что говорил тренер

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

вторник, 29 ноября 2016 г.

Учусь программировать робота для хакатона

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

Организаторы курсов предложили учителям провести детский хакатон, основная задача которого - собрать и запрограммировать робота. За основу взяли конструктор Lego Mindstorm EV3 45544 и бесплатную программу LEGO® MINDSTORMS® Education EV3 Teacher Edition для программирования на нем.


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

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

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

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


Робот может находиться в четырех основных состояниях:
0: Движение прямо;
1: Поворот направо;
2: Поворот налево;
3: Разворот назад.

После пунктов 1-3 подразумевается движение прямо в случае отсутствия близкой преграды. Движение прямо выполняется, пока преграда не окажется на расстоянии менее 20 см. После каждого поворота в коде стоит switch, основанный на расстоянии до преграды. В нем переменная заполняется значением цифры, которая станет управляющей на следующей итерации.

Вы спросите, зачем же делать проверку при развороте назад? Программирование для робота сильно отличается от написания обычной программы, которая не будет обитать в случайно меняющейся среде и у которой есть физический облик. Случается, что перед роботом неожиданно вырастает преграда в виде маминой ноги или папиной руки, и роботу недостаточно места для разворота. В таких случаях ему лучше отъехать назад на расстояние, которого ему хватит для маневра. У меня это - один оборот колеса. Данное действие в случае необходимости выполняется перед входом в switch выбора направления движения и его реализации. Другая причина - робот разворачивается не одинаково точно в зависимости от поверхности, на которой он ездит: ковер и паркет дают разные результаты. Также на градусы поворота влияет мощность поворота и калибровка робота. Мне одолжили такой экземпляр, которому для поворота на 90° на мощности 50 из 100  пришлось прописать 400°.



Вроде бы, все основное рассказала. Смотрите саму программу.



На этом видео можно увидеть робота в действии.


Если смотреть внимательно, то видно, что робот ни разу не входит в состояние “3”. Посмотрите внимательно на картинку программы, и вы поймете причину. Предпоследний блок ссылается на “3”, если расстояние слишком мало, и на “0”, если места достаточно. Последний блок называется “4”, а блока “3” не существует. :) А в таком случае он по умолчанию идет в “0” (на switch рядом с нулем отмечена соответствующая радио-кнопка). Тут корректная работа алгоритма

Алгоритм вышел действенный и простой, но у него есть недостаток. Что случится, если отверстие, в которое нужно попасть, находится в середине стены? Например, робот идет по шляпке буквы Т, а выход - в ноге. Этот алгоритм ждет преграды, и в отверстие в стене сбоку без случайности не попадет. Иными словами, алгоритм хорош для прогулок по квартире или офису. А что, если имеем настоящий лабиринт?

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

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


  
К сожалению, робота мне пришлось отдать, и настоящий лабиринт для тестирования времени построить не хватило. Но с помощью метода “внезапного препятствия” можно увидеть, как работает робот.

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

Другие задания, которые были на хакатоне:

  1. Собрать роборуку и ею поднимать бумажный стаканчик.
  2. Собрать и написать логику для принтера (двигать машинку так, чтоб она ездила по особой осмысленной траектории и рисовала прикрепленным к ней фломастером).
  3. Борьба роботов: 2 команды собирают по роботу и встраивают в них датчик касания, так что при нажатии на него робот “умирает”. Один робот должен атаковать другого и попасть в то самое место :)

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

Если у кого-нибудь есть соответствующий опыт или полезные советы, буду рада прочитать.

воскресенье, 16 октября 2016 г.

What to Do When Parallel Threads Modify the Same DB Row

During several days I was trying to solve an issue with rowlock on Oracle and MariaDB (MySQL). There were concurrent requests entering into @Transactional* method which changed data in the DB.





HOW TO DEBUG


When solving such issues, it might be hard to reproduce the situation because of the concurrency. One solution is to use logging or simple output. It’ll give understanding at least how many streams have passed a particular point in the code. Using static variables can also help. Iterating them might give an estimate of the number of times something happens.

It’s possible to send two concurrent threads using, for example, sleep() for a thread. Placing it before the problematic area will provide enough time to send as many threads as needed. However, you might need to use static counter in order to let every second thread without falling asleep.



HOW TO FIX

Lock


In the case of reading-writing the data, the safest fix is to put a trigger, which tells if the area contains consistent information or it’s better to wait till the previous thread finishes changing the resource. To find out more about this mechanism, read about Semaphores and, particularly, about one of its implementations, Mutex. What was especially strange with this approach in my case was that in MariaDB all worked fine but not in Oracle. The problem was that with the find request I used the following annotation: @Lock(PESSIMISTIC_WRITE). Its parameter is LockModeType enum value. Somehow it seems not to work proper with Oracle 12 or Hibernate 5.0.2.Final. What helped was to use entityManager.lock(Entity, LockModeType) method. You can also make a lock on the session: entityManager.unwrap(Session.class).lock(Entity, LockMode). Here you can get more general info about locking. For more information why the annotation didn't work and how to fix it check the following StackOverflow question of mine. One of the Hibernate authors was very kind to reply.


Exchange Uncommitted Info (Scarry)


There are different ways to fix the problem, but they heavily depend on the code. For example, you can enable information exchange between transactions-sessions. As soon as the data are changed in terms of one session, the other one will become aware of it and will read the already updated data. This feature can be enabled using READ_UNCOMMITED in the DB. Note that it’s a possible isolation level in MariaDB (MySql) which you can happily use when debugging but it’s not applicable in serious Oracle.
It’s also possible to use Hibernate’s second level cache.

Problems may occur, however. If the transaction that changed the data and gave it to the next parallel transaction rollbacks, the data, with which the second transaction operates, might become erroneous. Besides, it’s always better to have guarantees that 2 parallel transactions won’t read the data being changed, which they use to write new information. The first transaction still could want to continue updating the data, when the second one had already read it to change.


Try Until You Make it or Fast fix


Badly written locks can produce deadlocks. Two threads will constantly attempt to access the same resource. Each will wait until the other one releases the DB. If this happens very rarely, you might be interested in using Ostrich algorithm. The better solution might be to get rid of possible deadlocks and wait till the exception of writing to the DB happens. When it does, just try again and hope that this time, no other thread will want to disturb the same data. This solution might be applied when the problem happens really rarely, and when putting a lock will cause serious downshift in performance. For example, I knew that the erroneous insert to the DB was always followed by update, and I couldn’t have 2 bad consecutive inserts. So the just described fix worked for my problem.

I wish you good luck! Have fun with your problem. Hope the fix comes soon. :)

* This article is inspired by experienced problems in Java + Spring + Hibernate + SpringData + DB (Oracle and MariaDB)