Saturday, April 29, 2017

nonstandard module and PEP 542


PEP 542 proposes a shortcut notation when defining functions that would be added to a class. A discussion of this idea can be found here.   Personally, I am not too fond of the idea ... but it's a good test case to see if I my nonstandard module, which I have mentioned before on this blog, could allow the proposed syntax to be used right now.

$$ type pep542_testfile.py
from __nonstandard__ import pep542

def test_pep542():
    class MyClass:
        pass

    def MyClass.square(self, x):
        return x**2

    a = MyClass()

    def a.out():
        return 42

    assert a.out() == 42
    assert a.square(3) == 9
$$ python test_pep542.py
Successfully tested function test_pep542


The answer seems to be yes ...



Monday, April 24, 2017

Easily modifiable Python

You want to try out some new syntactic construction in Python but do NOT want to have to go through the trouble of

1. modifying Python's grammar file
2. modifying Python's lexer
3. modifying Python's parser
4. modifying Python's compiler
5. re-compile all the sources  so as to create a new Python interpreter?

(These steps are described in these two blog  posts.)

It can be done much more easily using any existing Python interpreter! ;-)


More details soon...

Monday, December 12, 2016

Reeborg's answer to pip

If you are not familiar with Reeborg's World, then this post is likely not of interest to you and I apologize for the title.

As Python programmers know, pip is extremely convenient to install Python modules.  However, when creating a website like Reeborg's World which does not store any user code on the server and run everything in the client (browser), the idea of installing a Python module may seem to be totally nonsensical: how can one install a Python module in a web browser?

Yet, since Reeborg's World aims to teach not only basic Python programming but also Python's concepts like creating and using a library and third-party modules, it only made to me that I should attempt to reproduce the basic idea of installing third-party modules.  After all, it already allow users to write their own functions in a library and import them; so why not finding a way to "install" third party modules from the web.

Before I explain how to do so, let me recap what can be done with Reeborg's World (just in case you are not familiar with it and did not get put off by the opening sentence of this blog post).

The user (student) enters Python code [1] in the editor and runs it, making Reeborg accomplish various tasks.



The student can also enter functions in the library and import them as usual. Reeborg's World uses Brython as its Python interpreter.


World creators (educators) can create their own worlds, making use potentially of six different editors:

  • The Python code editor: one can save some program (e.g. a stub) together with a world as a starting point for the students.
  • The library - which can be prepopulated by the educator
  • The pre- and post- editors. When a program is run, the code found in the "pre-" editor is concatenated with the code found in the main editor followed by the code found in the "post-" editor.  This allow the world creator to set up some particular condition, going beyond what is possible to do with the graphical world editor.
  • The "description" editor. The world creator can add information about the world using html; this can include images.  Some information (position of robot, final position to reach, etc., is extracted automatically from the world file content and added to the information.
  • The "onload" editor: this allow the world creator to add some (Javascript) code that will be automatically executed once when the world is loaded. One can use this to load new images to use for the robot, define new objects types (with pictures) that can be used, etc.  The images can be loaded from anywhere on the web.
In theory, an educator could design worlds that would include either in the "post-" editor or in the library some code to be used by the students.  However, this would have to be done every time a world is created, which can be quite tedious.  With the new functionality, one can load a script from anywhere on the web and have it made available as the content of a module named "extra".




Instead of calling the new function "install_extra()", I was toying with the idea of calling it "pip_install()" ... but I thought this might be 1) too cheeky and 2) potentially confusing for beginners when they moved to a "real" Python environment and had to use pip from the command line, and not from within an editor.  However, I am  not totally convinced that "extra" is the best name for this library nor that "install_extra()" is the best name for the new function.  If you have any suggestion or comments, feel free to do so.

For those that are curious and would like to try it, click on this link http://reeborg.ca/reeborg2.html?lang=en&mode=python&url=http://pastebin.com/raw/t9Vvj7nG&name=Install%20extra and then make sure to click on the button to have the content of the editor replace by that included with this sample world.
Note that this link is for a development version and may not work in the future.

This feature has just been implemented and may very well be buggy. To load modules, I make use of cross-domain http requests and a third-party server (http://cors-anywhere.herokuapp.com). When I first attempted to write code on pastebin, and then edit it, I found that the original version was cached ... which was not very helpful as I did not realize it at first and was wondering how come the changes I made to the code were not reflected in what I saw.  Coders beware...

Suggestions and comments, as usual, are most welcome.

[1] In addition to Python, Javascript is also supported. Instead of a traditional editor, one can also use Blockly or a Python REPL to program the robot.


Monday, September 19, 2016

Backward incompatible change in handling permalinks with Reeborg coming soon

About two years ago, I implemented a permalink scheme which was intended to facilitate sharing various programming tasks in Reeborg's World. As I added new capabilities, the number of possible items to include grew tremendously. In fact, for rich enough worlds, the permalink can be too long for the browser to handle. To deal with such situations, I had to implement a clumsy way to import and interpret those permalinks after the page had been loaded. To give an idea of the potential complexity, here is a permalink (used by a teacher in Lithuania) that is still short enough to be handled by most browsers:

http://reeborg.ca/world.html?proglang=python-en&world=%7B%0A%20%20%22robots%22%3A%20%5B%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22x%22%3A%201%2C%0A%20%20%20%20%20%20%22y%22%3A%201%2C%0A%20%20%20%20%20%20%22_prev_x%22%3A%201%2C%0A%20%20%20%20%20%20%22_prev_y%22%3A%201%2C%0A%20%20%20%20%20%20%22_prev_orientation%22%3A%200%2C%0A%20%20%20%20%20%20%22start_positions%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%201%2C%0A%20%20%20%20%20%20%20%20%20%201%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%22objects%22%3A%20%7B%7D%2C%0A%20%20%20%20%20%20%22_orientation%22%3A%200%0A%20%20%20%20%7D%0A%20%20%5D%2C%0A%20%20%22walls%22%3A%20%7B%0A%20%20%20%20%2211%2C1%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%2C%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2210%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%229%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%228%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%227%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%226%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%225%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%224%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%223%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%222%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%221%2C9%22%3A%20%5B%0A%20%20%20%20%20%20%22north%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C8%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C7%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C6%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C5%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C4%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C3%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%2C%0A%20%20%20%20%2211%2C2%22%3A%20%5B%0A%20%20%20%20%20%20%22east%22%0A%20%20%20%20%5D%0A%20%20%7D%2C%0A%20%20%22goal%22%3A%20%7B%0A%20%20%20%20%22possible_positions%22%3A%20%5B%0A%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%206%2C%0A%20%20%20%20%20%20%20%206%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22position%22%3A%20%7B%0A%20%20%20%20%20%20%22x%22%3A%206%2C%0A%20%20%20%20%20%20%22y%22%3A%206%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22objects%22%3A%20%7B%0A%20%20%20%20%20%20%226%2C5%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22token%22%3A%201%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%2C%0A%20%20%22objects%22%3A%20%7B%0A%20%20%20%20%226%2C1%22%3A%20%7B%0A%20%20%20%20%20%20%22token%22%3A%201%0A%20%20%20%20%7D%0A%20%20%7D%2C%0A%20%20%22small_tiles%22%3A%20false%2C%0A%20%20%22rows%22%3A%2012%2C%0A%20%20%22cols%22%3A%2014%0A%7D&editor=%23%20jei%20ka%C5%BEkur%20stringate%2C%20vykdykite%20program%C4%85%20po%20%C5%BEingsn%C4%AF%20(%20%E2%96%BA%E2%96%8C)%0A%0A%22%22%22%20Komandos%3A%0Amove()%20%20%20%20%20%20%20%20-%20%20paeina%20langel%C4%AF%20%0Aturn_left()%20%20%20-%20pasisuka%20kair%C4%97n%20(de%C5%A1in%C4%97n%20nemoka)%0Atake()%20%20%20%20%20%20%20%20-%20paima%20objekt%C4%85%20i%C5%A1%20langelio%0Aput()%20%20%20%20%20%20%20%20%20-%20padeda%20objekt%C4%85%0A%22%22%22%0A%0A%23%20U%C5%BEduotis%3A%20%0A%23%20perne%C5%A1t%20%22kapeik%C4%85%22%20%C4%AF%20tu%C5%A1%C4%8Di%C4%85%20apskritim%C4%85%20%0A%23%20ir%20atsistoti%20%C4%AF%20fini%C5%A1o%20viet%C4%85%20(melsv%C4%85%20langel).%20%0A%0A%23%20pataisykite%2Fpabaikite%20program%C4%85%3A%0Amove()%0Aturn_left()%0Amove()&library=%23%20%27from%20my_lib%20import%20*%27%20in%20Python%20Code%20is%20required%20to%20use%0A%23%20the%20code%20in%20this%20library.%20%0A%0A

The above permalink appears to work ... but, due to a small addition to the old version of the site that handles these permalinks, the result is not quite what is desired: one must change "by hand" the programming mode (at the top) from Blockly to Editor.

The new permalinks will be much shorter and should be future proof; they can include, in any order:

  1. the programming mode/language
  2. the human language for the interface
  3. a URL pointing to a file containing the world definition
  4. an optional name to display in the world select menu instead of the URL.

The key here is the 3rd item. Instead of having to potentially deal with changing world format (to add new capabilities) AND permalinks to encode the new items, I only have to ensure that the world format remains backward compatible. Normal URL where a world can be found are usually quite short, and there is no need to worry about hitting some browser limit in terms of the number of characters.

For example, here is a URL that works on a temporary testing site, which loads a world definition I put on Pastebin (which anyone can do):

http://reeborg.ca/reeborg2.html?lang=en&mode=python&url=http://pastebin.com/raw/rGHudX7a&name=Desert

If you use Reeborg's World to teach and wish to be kept abreast of any major changes, please email me and I will add you to a mailing list that I just set up for this purpose.

Friday, September 09, 2016

Un nouveau livre au sujet de Reeborg

tl;dr: After two books published in Korean about Reeborg, a book on robotics written in French has a significant part of its content inspired by Reeborg's World.



Tel que je l'avais mentionné il y a déjà un certain temps, Samsung avait publié deux livres en Koréen basé sur un précurseur du Monde de Reeborg.  Aujourd'hui, j'ai reçu un livre sur la robotique dont environ le tiers est basé sur la robotique virtuelle du monde de Reeborg.

Vincent Maille, le co-auteur du livre sur la robotique, m'a fait plusieurs suggestions qui ont contribué à améliorer mon site.  Je n'ai pas encore eu le temps de lire ce livre (qu'on peut obtenir directement de l'éditeur ou de chez Amazon) ce que j'espère pouvoir faire très bientôt.

Saturday, March 12, 2016

Multilingual Reeborg

Instead of separate versions for different languages, (English, French and Korean so far), Reeborg's World is now available in all languages at a single location.  Mixed language modes are supported (e.g. UI in Korean with Python programs using English commands like move() ).  This previous single-language versions are still available (English, French, Korean) and will remain so until the new version has been fully tested and the documentation updated to refer to the new version.

Testing of the new version is encouraged, and new language adaptations are most definitely welcome.

Tuesday, January 19, 2016

Scratching an itch with a Chrome extension

Over the years, I have tried various "tasks organizers" and always come back eventually to using a simple text file (lately, using markdown instead of plain text).  When writing markdown documents within Atom, my new editor of choice, I can easily preview them as processed documents, which makes it for a more pleasant reading experience.  When editing a markdown document with Atom, one can use packages like markdown-folder, to hide various sections; however this does not work in the preview panel, nor does it allow to hide "sub lists".

Since I can easily export markdown documents as html, I decided to write my first Chrome extension to view such documents in a "nice" format, while allowing to hide/show various parts of the document based on the html headings (h1 to h6) or as list items containing other lists, ordered or unordered.




This extension is still very rough around the edges and could definitely be greatly improved upon.  It is definitely not in an acceptable state to be uploaded to the Chrome Web Store. For now however, it does the basics of what I wanted it to do and works on any tab for which it has been activated.