Monday, April 14, 2014

Reeborg knows multiple programming languages

I wish I were in Montreal to visit my daughter, eat some delicious Saint-Sauveur bagels for breakfast, a good La Banquise poutine and some Montreal Smoked Meat for lunch... and, of course, attend Pycon.  Alas....

In the meantime, a quick update: Reeborg now knows Python, Javascript and CoffeeScript.  The old tutorials are gone as Reeborg's World has seen too many changes.  I now am in the process of writing the following tutorials, all using Reeborg's world as the test environment

  1. A quick introduction to Python (for people that know programming in another language)
  2. A quick introduction to Javascript (same as above)
  3. A quick introduction to CoffeeScript (same as above)
  4. An introduction to programming using Python, for absolute beginners
  5. An introduction to programming using Javascript, for absolute beginners
  6. An introduction to Object-Oriented Programming concepts using Python
  7. An introduction to Object-Oriented Programming concepts using Javascript
Note that I have two "versions" of Javascript, one that uses JSHint to enforce good programming practices (and runs the code with "use strict"; option) and one that is the normal permissive Javascript.

If anyone knows of any other transpilers written in Javascript that can convert code client-side from language X into Javascript (like Brython does for Python, or CoffeeScript does naturally), I would be interested in adding them as additional options.

Thursday, March 13, 2014

Reeborg news

People reading this blog may be familiar with rur-ple (https://code.google.com/p/rur-ple/), a Karel-the-robot clone using Python that I wrote.  The robot's name in my version is Reeborg, hence the title of this post.

Since the last version was produced in 2009, rur-ple had been downloaded more than 11,000 times.  Since people that download it do not need to contact me to do so, it is only through serependity that I find out where it is used.  By doing some searches on the web, including videos on youtube, I found out that it has been used by elementary school children in Austria, high school children in the U.S. and by university students in the U.S. and Latin America as a tool to introduce Python.

Recently, Samsung contacted me and asked my permission (!) to produce a book based on rur-ple. They distributed free copies of this book yesterday to approximately 1000 Korean students.  

So what you say?....

I am happy to announce that a test-version of "Reeborg's world" is now available online as a tool to learn Python.  Like the desktop version (rur-ple) I wrote, it is free to use and does not require registration.

The first version of Reeborg's world was produced to teach Javascript; it is the default version available from http://reeborg.ca.    It includes some 98 lessons (available in both English and French); the English version can be found directly at http://reeborg.ca/learn_js.html

I'm working on an "improved" version which can be found at http://reeborg.ca/learn_js_dev.html 
Following some comments by early adopters, the UI of this version is improved slightly and more changes are planned, including a graphical world builder, new images for the robot, the option to import from file and save to file  programs and worlds, etc.  I am also thinking of adding a collaborative option using https://togetherjs.com/.

This time, I will probably include a page on the site where I will ask teachers that use it to communicate with me to let me know in what context they use it, and keep track of it on a "wall of fame".

The proof-of-concept Python version, which is probably of greater interest for readers of this blog, can be found at http://reeborg.ca/learn_py_test.html It is based on the "improved" version and uses Brython  to translate the Python code into Javascript, which can then be executed using eval(), like the Javascript version does.  I do not plan to do more work on it (including adapting the lessons to teach Python instead of Javascript) until I have nailed down the "improved" Javascript version.

If you want to quickly try the Python version to see what it can do, after dismissing the "contents window", I suggest you select (from the drop down menu showing "Alone" by default) the world "Tokens 1" and run the following program:

move()
take()
move()
put()
move()

I welcome any comments & suggestions about Reeborg's world; please feel free to email me directly. 


Thursday, February 13, 2014

Importing modules in RUR-PLE

When I first started working on RUR-PLE some 10 years ago, I wanted to create a "safe" environment so that beginners using it could not be "tricked" by others into running malicious programs.  So, before running a user program, I would parse it and prevent the use of keywords such as "chr", "exec", "eval", "input" and "import".  However, I still wanted to teach the idea of "importing a module", so I created a "fake" module allowed the user to have the line

import useful

or

from useful import turn_right

into their program, and this would import various "useful" definitions so that they would not have to retype them.  I added a note to teachers  at the bottom of the relevant lesson, telling them that they could get in touch with me if they wanted to remove the "import" restriction, and I would tell them how to modify the code.

Somewhere along the way, prompted by a discussion with a user, discussion whose details I have long forgotten, I removed the so-called useful module and enabled the import statement to be used. However, the lesson about the "import useful" module remained (and has been translated into other languages) as I just noticed, much to my embarassment.

Today, five years after I last modified the code, I was contacted by a teacher had read what I wrote and who wanted their students to be able to save their own functions and import them.  Here's a way to do it. Note however it involves a bit of "magic" (at least from the point of view of the student).

First, just to demonstrate that import works, one can type the following:

import sys
print sys.path   # python 2 syntax
turn_off()

Here is the output from the window below the robot world (I used the version installed by the .exe file)

['C:\\Program Files (x86)\\RUR-PLE', 'C:\\Program Files (x86)\\RUR-PLE\\library.zip']

I used a usb key (recognized as drive d: on my computer) to save the file my_def.py and containing the following:

from rur_py.cpu import rur_program
robot = rur_program()

def turn_around():
robot.turn_left()
robot.turn_left()

The first two lines contained the required "magic" so that our user-defined module can use all the same robot instruction that a "normal" program can.  However, these instructions, such as turn_left(), must be preceded by "robot."  [or any other name given to rur_program()].   

Note that I could have used just about any name instead of "my_def".

Once we have saved this module, we can now use it.  First, we need to make rur-ple aware of where our definitions exist.  To this end, we first run the following program once within RUR-PLE:

import sys
sys.path.append("D:\\")
turn_off()

Next, if we want to use our definitions found in module my_def.py, we do as follows:

import my_def
my_def.turn_around()
turn_off()

Of course, one could use the  "from my_def import turn_around" syntax instead so as not to have to write
"my_def." in front of every instruction I define.

Note that, if my_def is modified, RUR-PLE will have to be restarted and the entire procedure above will have to be repeated. 

===
Note added after the original post.  I wrote RUR-PLE when I was just relearning computer programming and I did not really understand a lot of things very well.  rur_program() referred to above is not a function, but a class (I was learning!...).  And, having learned a bit of Java some years before and having come accross some sample code about singletons in Python, I wrote rur_program() to be a singleton, thinking I was never going to need more than one user program at a time.  I don't think most Python programmers would have done that.  Yet, through sheer luck, this is needed for the above to work, otherwise "turn_left" in the imported module, defined as a method of rur_program, would have referred to a different instance than that used in the user's program, and it would not have been possible to import user definitions as done above. 
===
Edit #2 
I know that some teachers that use rur-ple are not familiar with advanced Python features; so here's another equivalent way (sent to me by a reader) to import and use modules with rur-ple; the path uses the syntax one may have on a Mac.  (For people familiar with Python, I do realize that both ways will look essentially the same - but they do not for beginners.)

from rur_py.cpu import rur_program
robot = rur_program()

def left():
    robot.turn_left()

def turn_around():
    left()
    left()

def right():
    turn_around()
    left()


======== and within rur-ple

import sys
my_py_dir = "/Users/andre/rurple_files"
if my_py_dir no in sys.path:
     sys.path.append(my_py_dir)       

from my_module import *

# main program

right()
turn_off()

Friday, March 01, 2013

Correction: Javascript NOT more dynamic than Python

EDITED: Adam showed me that I had missed a way to do something similar in Python as I added below.
====


After a very long hiatus, I'm finally back and working on a web version of rur-ple, my "Karel the Robot in Python" program.  Since it's going to be on the web, I have decided to have both a Javascript version and a Python version (using Brython).  As I was exploring javascript prototype-based "inheritance" pattern, I found  what I think is a neat way to illustrate how dynamic the method lookup can be in Javascript, in a way that has (to my knowledge) no parallel in Python.

As in rur-ple, I have a robot "class" called UsedRobot which is broken (i.e. like the original Karel it can only turn left, etc.).  For completely separate reasons, I had decided that I would actually implement a PrivateRobot "class" within the RUR  namespace, which would not be directly exposed to the user, and have UsedRobot "inherit" from it.

Here's what one can can do


var r = new UsedRobot();      // does not have a turn() method
RUR.PrivateRobot.prototype.turn = RUR.PrivateRobot.prototype.turn_left;   // give such a method to the "parent"
r.turn();  // turns left using the new parent's method.
UsedRobot.prototype.turn = RUR.PrivateRobot.prototype.__turn_right;  //give different method to "child"
r.turn();  //  turns right - look up stops at "child"
delete UsedRobot.prototype.turn;
r.turn(); // turns left again  - look up goes up to parent since method no longer exists in child.

I still prefer Python to Javascript ... but I find that one can do neat things in Javascript which (to my knowledge) can not be done in Python.   Caveat: the fact that something like the above can be done in Javascript does not mean that it should be done.

===
Adam, in the comments, pointed out that something similar can be done with Python, using instance.__class__ to modify the behaviour of a class.  For example:


class A:
    pass

class B(A):
    def turn(self):
        print("turn left")

def right(self):
    print("turn right")

b1 = B()
b2 = B()
a1 = A()
b1.turn()  # prints turn left
a1.__class__.turn = right
a1.turn() # prints turn right
b1.turn() # prints turn left
del b1.__class__.turn
b1.turn()  # prints turn right



Friday, February 08, 2013

Is there any merit to stepping back through the code?

After a long hiatus, I have gone back to work on a new version of my very first project - essentially a clone of Karel the Robot - this time delivered entirely via the web (not yet available though).  Like rur-ple, and Guido van Robot, and many others I am sure, the user will have the option of executing all the code without interruptions, or stepping through, one instruction at a time.  Since Javascript does not have  a "sleep()" function, the way I implemented the program was to create a series of frames (like a movie) which can be then played back at a given frame rate, or stepped through one frame at a time, etc.  This makes is easy to include the possibility of stepping back from a given frame instead of being restricted to only moving forward.  However, since I use the browser to evaluate the code (rather than creating my own interpreter), I do not have the information regarding the code line whose execution corresponds to a given frame.

I know that Greg WilsonBrad Miller,  and many others I am sure, have expressed opinions about this being a desirable feature in a teaching environment.  However, I don't want to implement things that are not needed (and will needlessly complicate the user interface) and, given the non-availability of the line of code which corresponds to a given frame, I am not sure that a really good case can be made for the possibility of going backwards.  (Note that I have implemented a "pause" instruction which would enable a user to effectively set a breakpoint and, knowing where they inserted this instruction in the code, be able to follow step-by-step
the result.)  The fact that *I* do not have a good use case for it right now does not mean that such a good use case exist.  So, dear reader, can you think of a situation where such a feature would be useful?  (in this type of programming environment.)


Thursday, March 15, 2012

Python for iOS: first look

Jonathan Hosmer has put together a nice app Python for iOS, bundling a Python interpreter, a basic editor with output window, the documentation for Python 2.7 and links to a discussion forum.  While it is a bit limited, due to some Apple policies regarding importing/exporting files, it is a nice tool to have on an iPad when a laptop is not available and one wants to play with Python - even in the absence of connectivity.  At $3, it is quite affordable.  He has even bundled sympy with it and, I believe, plan on including numpy as well.  If you have an iPad, and would like to be able to fire up a Python interpreter anywhere, I recommend it highly.

Friday, December 09, 2011

Porting to Python 3: What are you waiting for?

Lately, there seems to be a lot of posts trying to encourage people to port their apps/libraries/modules to Python 3.  I'd like to add my voice and perhaps, use as a reminder this old post: more than 2 years ago, Crunchy was made compatible with Python 2.4, 2.5, 2.6 ... and 3.1.  At the time, we made the decision to not follow what seem to be the official recommendation, namely to have one code base based on 2.x and use the 2to3 tool to do the automatic translation.  Instead, we decided to have a single code base, which seems the way people are doing it these days.  There were of course some challenges, especially as we kept compatibility all the way back to Python 2.4: since Crunchy puts a Python interpreter inside your browser and manipulates what's there, regardless of the encoding, it has to be able to do a lot of string (and bytes for 3.x) manipulations, as well as dealing with incompatible syntax for handling exceptions, etc.  when running the code that is fed to it.  This was done when there was very little known about best practices for porting from 2.x to 3.  Partly as a result, Crunchy's code is not the best example to look at when it comes to doing such a port ... but it certainly demonstrated that it was possible to port a non-trivial program with a tiny team.  Now, the situation is quite different, and many more projects have been ported, and you can benefit from their experience.

So, what are you waiting for?