2020-02-11_teaching-programming-2019.md 17KB

4 роки тому
4 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. Title: Teaching folks to program 2019, a.k.a. in the search of an ideal program: Sequence
  2. Date: 2020-02-12 00:00
  3. Category: News
  4. Slug: teaching-to-program-2019
  5. Lang: en
  6. ![MUROM][screenshot]
  7. In this article Michael shares his thoughts on teaching folks to program in 2019.
  8. **Preface**
  9. Autumn 2019 was the third time I participated as one of the teachers in the course to teach 10-15-year-old folks to program. The course took place from mid. September to mid. December. Each Saturday, we were studying from 10 AM to 12 PM. More details about the structure of each class and the game itself can be found in [the 2018 article][article-2018].
  10. I have the following goals for conducting such courses:
  11. * create a convenient tool to allow the creation of simple games, the tool interested folks of 10 years old or older can master;
  12. * create a program to teach programming, the program interested folks of 10 years old or older can use themselves to create simple games.
  13. **Game**
  14. ![Game][screenshot-game]
  15. Memory is a simple game we create during the course. The goal of Memory is to find matching items on a playing field. More details, including game mechanics, can be found in [the 2018 article][article-2018]. You can play the created game in a web browser by clicking [this link][game].
  16. **Tool**
  17. ![IDE][screenshot-ide]
  18. When I was creating the tool, my guiding principle was **unpretentiousness** that manifests itself in the following:
  19. 1. work under any operating system
  20. * development can be conducted under Linux, macOS, or Windows
  21. * one can play the game on a PC, a tablet, or a smartphone
  22. 1. no need to configure anything: just open the link in a web browser and start working
  23. 1. no need for the Internet: work locally if you want, there's no back-end
  24. 1. the game is available to everyone
  25. * if you place a file on GitHub Pages, just share the link
  26. * if you send the file over Skype, just open the file locally
  27. The tool is an integrated development environment (IDE) that is technically a single HTML file. This single file contains both IDE and a project under development (Memory game in our case). The tool looks pretty standard:
  28. 1. left area depicts the code of a selected module;
  29. 1. middle area contains buttons to restart, save the project and manage modules;
  30. 1. top right area contains result;
  31. 1. bottom right area lists modules belonging to both IDE and the project.
  32. Since we only have a single HTML file, we should be able to run it in two modes:
  33. 1. replay
  34. * default mode;
  35. * just open the file;
  36. 1. editing
  37. * append `?0` symbols in the address bar.
  38. Web browser cache (IndexedDB) is used to keep changes temporarily. To save changes permanently, one has to download the file with the changes by clicking the corresponding button in the middle area.
  39. **The first classes**
  40. I prepared [80 lines of JavaScript code][80-sloc] for the first class and printed the code on paper. Each student received the paper and had to type the code into the tool. The typing exercise had the following goals:
  41. 1. find out the typing speed of students;
  42. 1. demonstrate API of the tool.
  43. The typing speed turned out to be extremely low: ranging from 14 symbols per minute (a student managed to type only half of the code) to 39 symbols per minute. Since I used to type the code with the speed of 213 symbols per minute, I was shocked by the results and started to doubt we would be able to write the game in an hour by the end of the course.
  44. We spent the second class to find typos in the code. I met typos that I have never seen in my life. I was shocked again: students had a hard time finding the typos even with the correct code on the paper in front of them. It's hard to imagine what would happen to the students' psyche if we were to pass a [brutal UX/UI test][cant-unsee] with questions like this:
  45. ![Can't unsee][screenshot-cant-unsee]
  46. Later I tried to decrease the code down to 10 lines, offered partially completed code so that students could find and fix errors. Nothing helped: students just couldn't comprehend anything as if they saw hieroglyphs instead of familiar letters.
  47. **Successful seventh class**
  48. The half of the course was over, and I haven't moved an inch. In another attempt to find a way to explain the code I rewrote the game one more time. Now with a module of an intriguing title `последовательность` (`sequence` in Russian).
  49. To my surprise, the class had a stunning success: we got everything done before "the bell rang", and the students were burning with enthusiasm. The burning was so strong that we finished the class with a spontaneous brainstorm session where we came up with functionality to make the newly appeared game even better:
  50. ![Brainstorm][screenshot-brainstorm]
  51. The lines in Russian read:
  52. * timer;
  53. * tutorial;
  54. * sounds;
  55. * the camera should be farther;
  56. * randomize;
  57. * hearts (meaning lives);
  58. * randomize after a failed matching attempt;
  59. * exploding spheres;
  60. * levels with different number of spheres;
  61. * background.
  62. Let's look closer into the class.
  63. **Board**
  64. Previous classes were using "teachers work with each student individually" approach. After six classes we (two teachers) realized that diving into each student's specific typos/errors takes more time than teaching anything new.
  65. Starting with the seventh class, we decided to hook everyone to the board, i.e., the board became a central place where all of us were working, a place for everyone to stand up, approach the board and write there. PCs became secondary, a place for students to copy the board contents to. This practice clearly indicated school boards exist for many reasons:
  66. * every student is accustomed to receiving information from the board; students know what to observe;
  67. * teacher's environment is at the board; it's now possible to explain single new item to everyone without diving into individual errors;
  68. * fixing individual errors becomes faster because most of them stem from negligence, i.e., typos made while copying the board contents.
  69. I'd like to highlight the fact that teachers work at the board together with students: a teacher sets direction; however, students stand up and come to the board themselves, write answers to the teacher's questions themselves. The benefits of such an approach are the following:
  70. * students write with their own hands, i.e., they come up with a solution and implement it themselves, a teacher does not write for them;
  71. * students stand up and come to the board, i.e., they move, which is good for health and drains unbridled energy that usually hampers discipline;
  72. * students have to remember the code to copy it to the board;
  73. * teachers have an opportunity to evaluate students' observation skills by seeing how easy (or hard) it is for them to remember and write the code on the board.
  74. **Sequence**
  75. `последовательность` module of the game looks like this:
  76. ![Sequence][screenshot-sequence]
  77. The sequence allows to write an algorithm in the form of events and reactions:
  78. * events (`начало` (`start`), `выбор` (`selection`), etc.) are lines without indentation;
  79. * reactions (`настроить ThreeJS` (`configure ThreeJS`), `показать заставку` (`show splash screen`), etc.) are lines with indentation to signify their relation to events.
  80. Thus, when starting the game (`начало` event) we configure ThreeJS (`настроить ThreeJS` reaction), show splash screen (`показать заставку` reaction), and so on.
  81. The class had almost an empty `последовательность` module in the beginning; only events were present:
  82. ![Events][screenshot-events]
  83. I have duplicated these same events onto the board, leaving free space to add reactions later during the class (I used GIMP to depict free space in the following image):
  84. ![Board events][screenshot-board-events]
  85. We were searching for reactions in `память.реакции` module (`memory.reactions`):
  86. ![Reactions][screenshot-reactions]
  87. Each reaction of `последовательность` module is represented in `память.реакции` module by [constructor functions][constructor-function]. For example, `проверить окончание` reaction (`check for ending`) has a uniquely corresponding `ПроверитьОкончание` function (`CheckForEnding`):
  88. ```javascript
  89. function ПроверитьОкончание(мир) // 1.
  90. {
  91. мир.состояние["скрыто сфер"] = 0; // 2.
  92. this.исполнить = function() // 3.
  93. {
  94. мир.состояние["скрыто сфер"] += 2; // 4.
  95. var скрыто = мир.состояние["скрыто сфер"]; // 5.
  96. var сфер = мир.состояние["сферы"].length; // 6.
  97. if (сфер == скрыто) // 7.
  98. {
  99. мир.события["конец"].уведомить(); // 8.
  100. }
  101. };
  102. }
  103. ```
  104. The same code in English would look like this:
  105. ```js
  106. function CheckForEnding(world) // 1.
  107. {
  108. world.state["spheres hidden"] = 0; // 2.
  109. this.run = function() // 3.
  110. {
  111. world.state["spheres hidden"] += 2; // 4.
  112. var hidden = world.state["spheres hidden"]; // 5.
  113. var spheres = world.state["spheres"].length; // 6.
  114. if (spheres == hidden) // 7.
  115. {
  116. world.events["ending"].report(); // 8.
  117. }
  118. };
  119. }
  120. ```
  121. Let's look closer:
  122. 1. The function accepts `world` (dictionary) that is used by functions to communicate with each other. `world` consists of three regions (dictionary keys):
  123. * `state` contains variable data used for communication;
  124. * `settings` contain constants to configure functions;
  125. * `events` contain [publishers][pub-sub] to be able to subscribe functions to events.
  126. 1. An instance of this constructor function is created with `new` operator while parsing `последовательность` module. Practically, everything outside of `run` method is considered to be part of the constructor body. In our case, we create `spheres hidden` variable to count hidden spheres.
  127. 1. `run` method is executed each time an event is reported.
  128. 1. Since `check for ending` reaction is executed each time a user hides a pair of spheres, we increase `spheres hidden` counter by `2`.
  129. 1. Just a shorter alias for `spheres hidden` counter.
  130. 1. Count the number of spheres at the playing field.
  131. 1. Compare the number of spheres at the playing field with the number of hidden spheres.
  132. 1. Report `ending` event if they are equal, i.e., if all spheres were hidden.
  133. Students took turns searching for functions in `память.реакции` module:
  134. * a student looks for a function in the module (to simplify the process, I've split the functions with `// // // //` symbols);
  135. * once a function is located, the student speaks the name of the function out loud and comes to the board;
  136. * the student writes the name down on the board to the list of found functions (students may use any means to remember the names except teacher's hints).
  137. Such an exercise also highlights who's actively tracking the functions and who's unable to find the next function when it's their turn.
  138. Once the names of all functions have been written on the board, we were mapping reactions (functions) to events in a similar fashion:
  139. * a teacher asks, for example, which of the listed functions is suitable for event `начало`
  140. * if a student answers correctly, the student
  141. * comes to the board
  142. * writes the reaction under the related event
  143. * crosses corresponding function out of the listed functions
  144. Once we have a more-or-less working set of reactions for an event it's time to transfer them from the board to student PCs. That way we managed to fill the board with reactions both on the board:
  145. ![Board sequence][screenshot-board-sequence]
  146. ![Board functions][screenshot-board-functions]
  147. and in the tool:
  148. ![Sequence][screenshot-sequence]
  149. **The following classes**
  150. During the following classes, we were trying to create a new reaction and a corresponding constructor function. First, I tried to put a solution into heads quickly (providing complete lines of code); however, that didn't work. That's why we ended up with learning the following code, which took us several classes:
  151. ```js
  152. var кот = "9";
  153. console.log(кот);
  154. ```
  155. Unfortunately, these two lines of code were hard to explain: students were confused with the concept of variables and their values. This wasn't the only problem: the new function required the use of an array, which I failed to explain at all. There's a long road ahead of me before I'm able to explain variables and arrays to students.
  156. Of course, by the end of the course we managed to complete the new function, however, I haven't seen understanding and subsequent faith in themselves, which usually manifests itself with a burning enthusiasm we saw in the seventh class.
  157. **The last class**
  158. The last class was not using the famous greeting circle at the beginning. Instead, I asked everyone (including myself) to tell what was good (+) and what was bad (-) during the course. Here's the table I got:
  159. ![Retro][screenshot-retro]
  160. The same table in English would look like this:
  161. | № | + | - |
  162. |---|---|---|
  163. | 1 | Personalized ending screen | Touchpad? |
  164. | 2 | Working on PC | Writing on the board |
  165. | 3 | Explanation | Discipline |
  166. | 4 | Flexible learning program | Sometimes unclear and uninteresting |
  167. | 5 | There's a finished game | Learning program is too big |
  168. | 6 | A detailed explanation of algorithms | Doing the same thing each time |
  169. | 7 | Teamwork | Students of disparate skill level |
  170. | 8 | Interesting / Difficult | Too early |
  171. | 9 | Sequence | Half of the course |
  172. Surprisingly enough, the folks didn't like to write on the board even though it greatly increased the efficiency of teaching. On the one hand, the "learning program was too big", on the other hand, we were "doing the same thing each time", i.e. repeating what we have learned before.
  173. We were saving the game to GitHub from time to time. This was difficult, too: we were spending half an hour while students were authenticating. As always, nobody remembered their passwords (each time), others had to verify it's really them accessing GitHub account on a new device, which required access to e-mail, which sometimes belonged to parents (the folks had to call their parents).
  174. Nonetheless, each student had its own version of the game by the end of the course with personalized beginning and ending screens:
  175. ![Addr][screenshot-addr]
  176. **Conclusion**
  177. On the one hand, we had significant success:
  178. * the tool worked as unpretentiously as expected;
  179. * the concept of sequences was easily understood.
  180. On the other hand, we had an evident failure:
  181. * the tool wasn't friendly to students without JavaScript knowledge, i.e., everyone;
  182. * the teaching program has been stuck most of the time.
  183. That's why I'll try to answer the following questions when teaching in 2020:
  184. 1. Will another language (Python, Lua) be simpler to explain and work with?
  185. 1. Is it possible to hide Git inside the tool so that one could save the game to [Git without leaving the tool][isomorphic-git]?
  186. 1. Is it possible to create API as declarative as [SwiftUI][swiftui]?
  187. 1. How to explain variables and arrays?
  188. I'll share answers to these and other questions next year ;)
  189. ![Group][screenshot-group]
  190. [screenshot]: ../../images/2020-02-11_teaching-to-program-2019_screenshot.png
  191. [article-2018]: teaching-kids-to-program.html
  192. [screenshot-game]: ../../images/2020-02-11_teaching-to-program-2019_game.png
  193. [game]: http://kornerr.ru/ekids2019
  194. [screenshot-ide]: ../../images/2020-02-11_teaching-to-program-2019_ide.png
  195. [80-sloc]: http://kornerr.ru/ekids19?техника
  196. [cant-unsee]: https://cantunsee.space/
  197. [screenshot-cant-unsee]: ../../images/2020-02-11_teaching-to-program-2019_cant-unsee.jpg
  198. [screenshot-brainstorm]: ../../images/2020-02-11_teaching-to-program-2019_brainstorm.jpg
  199. [screenshot-sequence]: ../../images/2020-02-11_teaching-to-program-2019_sequence.png
  200. [screenshot-events]: ../../images/2020-02-11_teaching-to-program-2019_events.png
  201. [screenshot-board-events]: ../../images/2020-02-11_teaching-to-program-2019_board-events.jpg
  202. [screenshot-reactions]: ../../images/2020-02-11_teaching-to-program-2019_reactions.png
  203. [constructor-function]: https://javascript.info/constructor-new
  204. [screenshot-board-sequence]: ../../images/2020-02-11_teaching-to-program-2019_board-sequence.jpg
  205. [screenshot-board-functions]: ../../images/2020-02-11_teaching-to-program-2019_board-functions.jpg
  206. [screenshot-retro]: ../../images/2020-02-11_teaching-to-program-2019_retro.jpg
  207. [screenshot-addr]: ../../images/2020-02-11_teaching-to-program-2019_addr.jpg
  208. [screenshot-group]: ../../images/2020-02-11_teaching-to-program-2019_group.jpg
  209. [isomorphic-git]: https://isomorphic-git.org/
  210. [swiftui]: https://www.hackingwithswift.com/quick-start/swiftui/what-is-swiftui
  211. [pub-sub]: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern