automateaching -- part 2: proof of concept

1 direct reply — Read more / Contribute by Discipulus

on Sep 30, 2020 at 04:45 Only Perl can teach Perl

Discipulus Introduction This is the follow up of Perl Automateaching -- part 1: brainstorming so read it first to have an idea of my intentions even if the pseudocode presented there is not what I currently plan. I have choosen the name for this project and it will be Perl::Teacher as it is clear and explicative. This post is a mere proof of concept about Perl teaching and, yes! it can be done! I'd like to be billionaire to hire super skilled perl geeks to develop my idea... but let's say they are all busy at the moment :) so the pupil (discipulus in Latin) will squeeze his brain and will dress teacher dresses. Contributors are welcome! In the final form Perl::Teacher will be document oriented, ie: it will analyze perl programs wrote by the pupil in physical files. But in the current proof of concepts various student's attempts are hardcoded into the below program contained in scalars from $work_01 to $work_n and with a $solution_code Also the final form of Perl::Teacher will be a bit interactive presenting and reviewing assignements and telling small lessons, but for the moment nothing of this is done. So running the below program you will see a serie of attempts to satisfy the assignemnt and results of tests applied to provided code fragments. Modify the $debug variable to 1 or 2 to see much more messages. Proof of concept Here my efforts up now ( Ignore the warning you'll receive: Having more than one /x regexp modifier is deprecated at .../perl5.24-64b/perl/site/lib/Perl/Critic/Policy/ValuesAndExpressions/RequireInterpolationOfMetachars.pm line 110. beacuse it is a problem of Perl::Critic itself: see resolved issue on github ) Read more... (22 kB) Implementation (current) As you can see there is a lot PPI stuff but not exclusively. Tests are execuded in order from 001 to 00n and if a test fails the current mini program is rejected. Each test can contain different steps, the first one being the optional run that simply sends the current code to a sub: this preliminary, optional test passes if the sub returns 1 and fails otherwise. Here it is used only to check if the program compiles ( see below for future ideas ). The second step of a test is select_child_of and it expects a PPI class name and a serie of subtests. Each PPI element of the specified PPI class, for example PPI::Statement::Variable (a variable declaration) will be processed to see if they contains PPI elemnts which satisfy all subtests. The first PPI element passing all subtests is returned by select_child_of and becomes a candidate for further inspections. Infact if evaluate_to is also specified, the current PPI element is, take a deep breath, keep calm, string evaluated to see if it holds the wanted value. And hic sunt leones or here are dragons because eval only returns the last statement value. Search the code above for the string dirty trick to see my workaround. For me it is a genial solution, but wait, I'm the guy who string eval'ed entire CPAN.. :) so improvements are warmly welcome. This form of testing is a proof of concepts: is not the final form of the testing framework needed by Perl::Teacher When a miniprogram passes all tests it is evaluated by Perl::Critic to give more hints to the student. Eventual policy violations will not make the program to be marked as wrong, but are just presented as suggestions. A note about flexibilty: looking carefully at the assignement you will notice that @letters and $result are constraints. Not the same for the intermediate scalars containing the first element and the last one. Implementation (future) module design The main Perl::Teacher module will provide only a framework to produce courses. The $teacher will load or create a configuration will have methods to deal with the student's input and to emit messages, but the main activity will be to load and follow courses plugins of the class Perl::Teacher::Course In my idea the course creator will publish Perl::Teacher::Course::EN::BasicVariables or Perl::Teacher::Course::IT::RegexIntroduzione all being child of the main Perl::Teacher::Course class. These courses have to be pluggable to the $teacher object ( Module::Pluggable probably but I have to investigate it further) Each course will contain a serie of lessons published a sub modules, as in Perl::Teacher::Course::EN::BasicVariables::01_strings , ..::02_lists etc. Yes I know: very long names.. but this will ensure a clarity of intent and of usage, in my opinion. lessons Each lesson will contain an ordered serie of optional elements: zero one or more assignement , multiple test elements possibly interleaved by one or more discourse and direct question . So a possible flow can be: Read more... (688 Bytes) Suggestions on module design are warmly welcome, but i want to keep it as simple as possible, not spawning objects for everything. tests Tests presented in the above code are too semplicistics to cover each teaching activity. I need beside positive tests also negative ones for example to prevent the use of modules, or all modules but one, to prevent external program execution and so on. Theese tests will be quite on success and will emit messages only on failure: "dont do this!". I can use Test::Script to add tests about correct overall syntax check, behaviour of STDOUT and STDERR given different arguments and so on. Then Perl::Teacher will provide its own tests like ones presented above: evaluate_to ( evaluate_at is probably a better name as it eval the code at a certain line), is dirty but it seems to me a viable option not so risky given the super small and controlled environment. I also plan a method named evaluate_subs which will grab al subs to test them. I have to mix all this features in a clean and easy to use interface. Suggetions are welcome. student interaction During a lesson the student must have the possibility to review the current assignement, to receive hints and be pointed to relevant documentation. Part of this is roughly done in the presented code using hints and docs embedded in tests. Can be and must be improved. I like to add a TIMTOWTDI discourse at the end of each lesson showing more ways to accomplish, even if not in the very same way, the assignement. Every output, comprensive of examined code, errors and hints, emitted during 03_array_manipulation must be saved into a 03_array_manipulation.history file so that the student can review the whole lesson including errors commited and pitfalls and the solution alongside different approaches to the same problem. Passing the time this becomes a good source of knoweledge. further ideas Testing standalone scripts is an idea haunting me since years. Modulino is an approach. I can be mad enough to take the original PDOM of a given program, then save all subs and use PPI method prune to delete them from the PDOM, then wrap the rest into a new main_original_program sub, add it to a new PDOM along with all previously saved subs. Then I could do the obtained file and test it nicely. A lot of cut 'n paste and probably error prone, but can be a path to explore. I'd like also my Perl::Teacher to be as much possible input/output agnostic: implement a way to interact with the console leaving open the possibility to be used by a web interface too: how to do this? I'd like to ear your opinions about this project, sugesstions on module design and implementation of its parts, comments to the above proof concepts and everything you want to share. L* There are no rules, there are no thumbs..

Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.