[Tutor] Python vs. Ruby - and a queston on Tkinter-Canvas
Gregor Lingl
glingl at aon.at
Thu Oct 30 15:08:21 EST 2003
Andrei schrieb:
>Danny Yoo wrote on Wed, 29 Oct 2003 16:28:52 -0800 (PST):
>
>
>
>>>Python docs are a lot better too, especially the ones in the ActiveState
>>>distro; the there isn't even a "docs" entry in my Ruby program group!
>>>Another advantage is that the whole of Python is quite English-oriented,
>>>while a lot of Ruby stuff is still in Japanese only (at least I presume
>>>it's Japanese), or really broken English.
>>>
>>>
>>Hi Andrei,
>>
>>There are some good Ruby books out there. In fact, the folks who wrote
>>"The Pragmatic Programmer" have released their own Ruby book online:
>>
>> http://www.rubycentral.com/book/index.html
>>
>>
>
>Yep,
>
...
It was approx. 2 years ago, when I decided to use (and promote)
Python as a
first learning language in my classes (sharing my experiences with other
teachers here in
Vienna) and there is not a single reason why I should change to another
language, be it
Ruby or not, now. Instead many pragmatic considerations lead me to stick
with
Python for my work.
Nevertheless I'm curious, wether a look at Ruby would be rewarding and
interesting, just
to know what's going on in the world (of computer languages). So the
above link led me
to a Ruby-Tk program, which I tried, just for fun, to translate into
Python-Tkinter
Ruby-Code:
require 'tk'
class Draw
def do_press(x, y)
@start_x = x
@start_y = y
@current_line = TkcLine.new(@canvas, x, y, x, y)
end
def do_motion(x, y)
if @current_line
@current_line.coords @start_x, @start_y, x, y
end
end
def do_release(x, y)
if @current_line
@current_line.coords @start_x, @start_y, x, y
@current_line.fill 'black'
@current_line = nil
end
end
def initialize(parent)
@canvas = TkCanvas.new(parent)
@canvas.pack
@start_x = @start_y = 0
@canvas.bind("1", proc{|e| do_press(e.x, e.y)})
@canvas.bind("2", proc{ puts @canvas.postscript({}) })
@canvas.bind("ButtonRelease-1",
proc{|x, y| do_release (x, y)}, "%x %y")
end
end
root = TkRoot.new{ title 'Canvas' }
Draw.new(root)
Tk.mainloop
Translation to Python:
import Tkinter as Tk
class Draw:
def do_press(self,e):
self.start_x = e.x
self.start_y = e.y
self.current_line = self.canvas.create_line(e.x, e.y, e.x, e.y)
def do_motion(self,e):
if self.current_line:
self.canvas.coords(self.current_line,
self.start_x, self.start_y, e.x, e.y)
def do_release(self,e):
if self.current_line:
self.canvas.coords(self.current_line,
self.start_x, self.start_y, e.x, e.y)
self.canvas.itemconfig(self.current_line, fill="black")
self.current_line = None
def __init__(self, parent):
self.canvas = Tk.Canvas(parent)
self.canvas.pack()
# self.start_x = self.start_y = 0 ## is this necessary in Ruby?
self.canvas.bind("<1>",self.do_press)
self.canvas.bind("<B1-Motion>", self.do_motion)
self.canvas.bind("<ButtonRelease-1>", self.do_release)
root = Tk.Tk()
root.title("Canvas")
Draw(root)
root.mainloop()
Indeed very similar. This example can be made even more similar, when
using the Canvas module:
import Tkinter as Tk
from Canvas import Line
class Draw:
def do_press(self,e):
self.start_x = e.x
self.start_y = e.y
self.current_line = Line(self.canvas, e.x, e.y, e.x, e.y)
def do_motion(self,e):
if self.current_line:
self.current_line.coords(((self.start_x, self.start_y),
(e.x, e.y)))
def do_release(self,e):
if self.current_line:
self.current_line.coords(((self.start_x, self.start_y),
(e.x, e.y)))
self.current_line.config(fill="black")
self.current_line = None
def __init__(self, parent):
self.canvas = Tk.Canvas(parent)
self.canvas.pack()
# self.start_x = self.start_y = 0 ## is this necessary in Ruby?
self.canvas.bind("<1>",self.do_press)
self.canvas.bind("<B1-Motion>", self.do_motion)
self.canvas.bind("<ButtonRelease-1>", self.do_release)
root = Tk.Tk()
root.title("Canvas")
Draw(root)
root.mainloop()
Alas! The canvas module is declared deprecated. So we are discouraged using
canvas items as objects, contrary to Ruby-Tk users.
#### So my MAIN QUESTION, which in fact has nothing to do with Ruby:
#######
Why is the - former "experimental" - Canvas module declared deprecated now?
##################################################################
Only one remark concerning Python and Ruby:
One of the most useful, wonderfully beautiful features of Python is
(imho) how
functions as first class objects are handled. (One can observe this even
in the above
"translation". Is the back side of this coin, that Ruby doesn't need
parentheses for
function calls (at least in some cases)?) So Python enforces to "think
in function-objects"
and this is very fruitful for showing, teaching and experiencing the
power of abstraction.
And even the use of self - an often critisized feature - is from my
point of view
more an advantage than a disadvantage in the educational context. As it
makes
explicit what otherwise nevertheless is the case implicitely.
Regards, Gregor
P.S. ( ;-) ): Those who can't bear it, could make another step
(although only visually)
in direction to Ruby by writing:
import Tkinter as Tk
from Canvas import Line
class Draw:
def do_press(_,e):
_.start_x = e.x
_.start_y = e.y
_.current_line = Line(_.canvas, e.x, e.y, e.x, e.y)
def do_motion(_,e):
if _.current_line:
_.current_line.coords(((_.start_x, _.start_y), (e.x, e.y)))
def do_release(_,e):
if _.current_line:
_.current_line.coords(((_.start_x, _.start_y), (e.x, e.y)))
_.current_line.config(fill="black")
_.current_line = None
def __init__(_, parent):
_.canvas = Tk.Canvas(parent)
_.canvas.pack()
# _.start_x = _.start_y = 0 ## is this necessary in Ruby?
_.canvas.bind("<1>",_.do_press)
_.canvas.bind("<B1-Motion>", _.do_motion)
_.canvas.bind("<ButtonRelease-1>", _.do_release)
root = Tk.Tk()
root.title("Canvas")
Draw(root)
root.mainloop()
:-P
P.P.S.: I hope I expressed my ideas clearly enough, so you can grasp
what I mean. When content
becomes a bit more complex I feel the limits of my restricted knowledge
of English. Perhaps I should
use part of my time to enhance my English instead of learning one more
computer language.
More information about the Tutor
mailing list