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.
"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.)
===
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()
did you tried out asteval? http://newville.github.io/asteval/
ReplyDeleteI did not try asteval. I use exec to run the user code, not eval. I wrote rur-ple in 2004, with the last code change in 2009 and I would be very surprised if asteval existed back then.
ReplyDelete