By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
429,262 Members | 2,664 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 429,262 IT Pros & Developers. It's quick & easy.

up with PyGUI!

P: n/a
I'm a fan of Greg Ewing's PyGUI [1]. I used it to code a simple game
for my son [2], and enjoyed it. Programming with wxPython feels like
programming with a C++ tool that has been wrapped in Python.
Programming with PyGUI feels like programming with a real Python tool.

If you're developing a commercial application in Python, wxPython is
currently the only option that offers native widgets on w32. It would
be a boost for Python if PyGUI got a native w32 backend.

Therefore, I offer the following suggestions:

Python programmers: use PyGUI! It's nice. Contribute bug reports and
so forth.

Python developers: Is it too early to include PyGUI in the standard
library? It seems stable to me.

PSF: If anyone applies for a grant [3] to put a proper w32 backend into
PyGUI, please give them money. I would offer to do that job myself,
but (a) I'm not w32 expert and (b) I'm busy trying to make one of those
aforementioned commercial apps.

Thanks,

Zooko, Journeyman Hacker

[1] http://www.cosc.canterbury.ac.nz/~greg/python_gui/
[2] http://zooko.com/log-2004.html#d2004-06-23
[3] http://python.org/psf/call-2004.html

Jul 18 '05
Share this Question
Share on Google+
108 Replies


P: n/a
Carlos Ribeiro <ca********@gmail.com> writes:
Pantone is a table of standard spot colors. It's used in professional
printing because they can guarantee you that the color that you'll see
in the final print is *exactly* the same that you see in your own
printed color reference card. Try that in the GIMP, or in any other OS
design package. In general, conversion between different color models
is *tricky*, and you would be surprised at how precise our eyes are
with regards to small differences.
Interesting. And what kind of printer has Pantone support built in? I
suppose that for such an accuracy you'd have to have a printer that
supports it, otherwise you might miss something while converting to/from
CMYK or RGB.
(I just read about Scribus, though, and about the color management
system that they're using there - littlecms - this is now being
integrated into GIMP. Don't know the results, but it's the right
step).


Scribus is a very nice application, and is evolving very fast.

--
Godoy. <go***@ieee.org>
Jul 18 '05 #51

P: n/a
On Mon, 2004-09-20 at 23:00 -0400, Terry Reedy wrote:
"Cliff Wells" <cl************@comcast.net> wrote in message
news:10************************@devilbox.devilnet. internal...
On Thu, 2004-09-16 at 14:30 -0400, Terry Reedy wrote:
"Alex Martelli" <al*****@yahoo.com> wrote in message
> So I was wrong -- it's happening all right, but tends to be disguised
> (perhaps for marketing reasons). Thanks for the info!

Also for political reasons. The US has reactionaries, left and right,
who
reject the idea that all people have a right to participate in the
global
information economy.
I intentionally restricted myself to one sentence, with one opinion word --
'reactionaries', on a topic people have written books about. However ...
The main problem a lot of people (myself included) have with the so-
called "global economy"
To me, the global information economy is as real as the global Python
community.


Community certainly. Economy less so. The main reason I say "so-
called" is because the widely disparate costs-of-living and
corresponding pay scales make it unrealistic to assume there is anything
"global" about it. Local economies, while clearly needing to
participate in the global market, are just that: local.
is that it mostly benefits the US employer who
can pay wages that are far below cost of living inside the US.


To the extent that all US employers producing similar products have equal
access to such cost savings, the long-term competitive benefit should tend
toward zero and most benefit should go to consumers and non-US workers. It
was Indian software entrepreneurs who pursued US businesspeople more than
the reverse.


I'm not referring to employers when I refer to the damage done by
outsourcing. I'm referring to the work force in first-world countries.
When a US employer can pay far below minimum wage (U.S. minimum) then
the only option for U.S. workers is to also work for that same wage or
find other lines of work. This is already happening. I know many
programming jobs here in Portland now pay as little as $10 an hour.
Unskilled manual labor typically pays at least that, semi-skilled and
skilled manual labor up to three or four times that. Some of this is
undoubtedly due to economic factors that have nothing to do with
programming per se, but I strongly suspect most of it is the direct
result of skills required to be a programmer being "cheapened" (not in a
disparaging sense, just in economic terms), by low-paid programmers in
countries where the cost of living is far lower than in the U.S.
I'm certain there are few people who begrudge others getting work,


I did not try to quantify in my original statement. However, it takes more
than a few people to get myriads of job protection laws passed in countries
around the globe. Dislike of competition for 'my job' is pretty universal.


That's right. But it isn't the foreign worker who is being rejected,
it's US employers who want to pay $5 an hour for skilled workers that
are being curtailed.
[snip]
let's ...have laws that require employers to pay prevailing wage
The prototype 'prevailing wage' law in the US, the 1930s Davis-Bacon Act,
was passed and signed by begruding people. It had the explicit purpose
(and effect) of excluding dark-skinned Americans from participating in the
American construction industry, especially in northern states, by making it
unprofitable to hire them. Its negative effects continue today.


Well, that's certainly *one* interpretation of the intent of that law.
Here's another:

From: http://www.solidarity.com/Davis-Bacon.htm

"""
Then as now, construction is a time and materials industry. Low bid
requirements on public projects allowed contractors from outside an area
to bid and win work based on substandard wages and helped create the
situation where contractors literally ´importedˇ low-wage workers from
around the country rather than use the local labor force.

Abuses were wide spread in the years preceding the Acts passage. Bacon,
a former Banker, explained the need for the law when he detailed for his
colleagues during debate on the bill how a construction firm from
Alabama transported thousands of unskilled workers to a public project
in New York.

´They were herded onto this job, they were housed in shacks, they were
paid a very low wage, and ... it seems to me that the federal government
should not engage in construction work in any state and undermine the
labor conditions and the labor wages paid in that state.ˇ
"""

The point of prevailing wage isn't to exclude foreigners. It's to
prevent corporations from exploiting local economies (U.S. or
otherwise). What you seem to be missing is that the work doesn't get
distributed, it gets moved from place to place, wherever the workers are
cheapest. That isn't a global economy, it's global strip-mining.
(based on the *employer's* country of origin).


Programmers in developing countries generally are employed by local
employers who pay them more than the previous local prevailing wage. In
terms of real economic goods -- food, clothing, housing, internet service,
and so on -- their pay may be comparable to that of programmers in the
'industrial' nations.


I just quit working at a company where Ukrainian developers were paid to
develop products at a fraction of what U.S. developers working on
similar software would have been paid. Were they paid well? Certainly,
by Ukraine standards. I'm not arguing that. I'm arguing that the
company who paid them essentially bypassed U.S. minimum-wage laws that
exist for a reason.
Their apparent cheapness per comparable output is largely a function of
exchange rates at least partly distorted by centuries of government force.
Exchange rates? Um, okay. The bottom line is that when U.S. companies
are allowed to hire Ukrainian developers at the equivalent of $5 an hour
they are certainly going to take advantage of that. And when Manila
starts pushing out developers at $2 an hour, those Ukrainians who were
doing so well a minute ago are going to find themselves out of work.
The bottom line is that corporations exploit workers to whatever extent
they are allowed to. The so-called "global economy" is the latest and
greatest method of doing so. Consider the exploits of Nike, Walmart,
Levis, Reebok, et al to get a foreshadowing of what's to come in the
software trade. I was told flat out at my last job that the main reason
the company had any U.S. employees at all was so that customers would be
able to talk to people who spoke English.
I expect such distortions will lessen as communication makes them less
tenable.
This may be so. Of course I expect the U.S. job market for software
development will be gone by then (or simply seen as a good first job for
students before they can get a better job at Walmart).
I also expect increasing numbers of US knowledge/information
workers with portable skills to take advantage of the distortions while
they last.


Well, I've certainly considered other lines of work, if that's what you
mean.
Cliff

--
Cliff Wells <cl************@comcast.net>

Jul 18 '05 #52

P: n/a
Hans Nowak wrote:
Zooko O'Whielacronx wrote:
I'm a fan of Greg Ewing's PyGUI [1]. I used it to code a simple game
for my son [2], and enjoyed it. Programming with wxPython feels like
programming with a C++ tool that has been wrapped in Python.

This problem is addressed by Wax:


I think it doesn't go far enough. Wouldn't it better to hide the
concept of wxPython ownership by now passing the parent in the
constructor, but instead create the wxPython widget when it is finally
added to its parent? It could also be a good idea to take the occasion
to respect PEP8. Note also that "import wax" would be better than "from
wax import *".

Regards,
Nicolas
Jul 18 '05 #53

P: n/a
Nicolas Fleury wrote:
Hans Nowak wrote:
Zooko O'Whielacronx wrote:
I'm a fan of Greg Ewing's PyGUI [1]. I used it to code a simple game
for my son [2], and enjoyed it. Programming with wxPython feels like
programming with a C++ tool that has been wrapped in Python.
This problem is addressed by Wax:

I think it doesn't go far enough. Wouldn't it better to hide the
concept of wxPython ownership by now passing the parent in the
constructor, but instead create the wxPython widget when it is finally
added to its parent?


I'm not sure what you mean. One known issue is, that there is some redundancy
when creating a control and adding it to its parent:

b = Button(parent, ...)
parent.AddComponent(b, ...)

I am thinking of ways to make this simpler. One possible solution would be to
accept a 'layout' parameter:

b = Button(parent, ..., layout={'expand': 'both', 'border': 2})

....but I'm not sure that actually makes things simpler or more readable.

It's also possible to do something like this:

parent.Add(some_control, parameters_for_control, parameters_for_layout)

I think this is rather ugly, and I don't like the mixing of control constructor
parameters and layout parameters. Aside from that, it's sometimes useful or
necessary to use the control before it's added to the parent. Consider:

from wax import *

class MainFrame(Frame):

def Body(self):
b1 = Button(self, text="b1")
b1.Size = (40, 40)
self.AddComponent(b1)

b2 = Button(self, text="b2")
self.AddComponent(b2)
b2.Size = (40, 40)

self.Pack()

app = Application(MainFrame)
app.Run()
It could also be a good idea to take the occasion
to respect PEP8.
Which recommendations of the style guide does the Wax code violate?
Note also that "import wax" would be better than "from
wax import *".


I'm considering it. This way, it would also be possible to import things on
demand. On the other hand, I don't like to write 'wax.' before everything.

--
Hans Nowak (ha**@zephyrfalcon.org)
http://zephyrfalcon.org/

Jul 18 '05 #54

P: n/a
Hans Nowak wrote:
I'm not sure what you mean. One known issue is, that there is some
redundancy when creating a control and adding it to its parent:

b = Button(parent, ...)
parent.AddComponent(b, ...)

I am thinking of ways to make this simpler. One possible solution would
be to accept a 'layout' parameter:

b = Button(parent, ..., layout={'expand': 'both', 'border': 2})

....but I'm not sure that actually makes things simpler or more readable.

It's also possible to do something like this:

parent.Add(some_control, parameters_for_control, parameters_for_layout)

I think this is rather ugly, and I don't like the mixing of control
constructor parameters and layout parameters. Aside from that, it's
sometimes useful or necessary to use the control before it's added to
the parent. Consider:

from wax import *

class MainFrame(Frame):

def Body(self):
b1 = Button(self, text="b1")
b1.Size = (40, 40)
self.AddComponent(b1)

b2 = Button(self, text="b2")
self.AddComponent(b2)
b2.Size = (40, 40)

self.Pack()

app = Application(MainFrame)
app.Run()


I beg your pardon for possibly stupid comment---I haven't practice GUI
programming for a long time, especially in Python. However I mostly
prefer declarative approach for the problems like that. Therefore,
wouldn't it be interesting to describe the structure with class and
metaclass mechanism, like:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

etc.

with the best regards,
anton.
Jul 18 '05 #55

P: n/a
On Thu, 23 Sep 2004 14:44:52 +0400, anton muhin <an********@rambler.ru> wrote:
I beg your pardon for possibly stupid comment---I haven't practice GUI
programming for a long time, especially in Python. However I mostly
prefer declarative approach for the problems like that. Therefore,
wouldn't it be interesting to describe the structure with class and
metaclass mechanism, like:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

etc.


Thats *exaclty* what I'm doing, after spending a long time evaluating
a lot of GUI packages, Wax included. Not that I didn't like Wax -- I
think the design is very good, and I would put it in the same class as
Greg Ewing's PyGUI, with the advantage that Wax runs in Windows. But I
miss the ability to write a declaration like you've done.

I have tested a metaclass engine yesterday that does something like
you wrote. In my particular case, I'm going to work with automatic
layout generation, so I'm not providing absolute positioning
parameters. But the mechanism is about the same. Here are two
declarations from my test script:

class UserForm(Form):
nickname = TextBox(length=15, default="")
password = TextBox(length=10, default="", password=True)
name = TextBox(length=40, default="")

class ComplexForm(Form):
class Header(Form):
nickname = TextBox(length=15, default="")
password = TextBox(length=10, default="", password=True)
name = TextBox(length=40, default="")
class Comment(Form):
comments = TextBox(length=200, default="", multiline=True)

It already accepts nested classes and some special attributes. There
are a few catches involving hacks to detect the original order of the
attributes in the class declaration. That's going to make a
difference, because one would implicitly assume that the tab order of
the data entry elements is the same as the declaration order. Solved
that, I'm working today on the code generation engine that will
generate the UI from the class declaration. I'll post a note here as
soon as I have something working.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #56

P: n/a
anton muhin wrote:
I beg your pardon for possibly stupid comment---I haven't practice GUI
programming for a long time, especially in Python. However I mostly
prefer declarative approach for the problems like that. Therefore,
wouldn't it be interesting to describe the structure with class and
metaclass mechanism, like:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

etc.

with the best regards,
anton.


Yes. But not in Wax. :-) The way Wax works is pretty much set in stone, and
although there is room for many improvements and shortcuts (passing layout in
constructor, auto-packing, etc), I'm not going to rewrite it so it supports the
above. It's meant as a friendly layer on top of wxPython; as such, I want it
to stay rather close to wxPython, so I'm less interested in writing an
innovative API.

Aside from that, I'm not sure if the construct described above is all that
great... it makes nested classes significant, and uses class attributes to
describe an instance (unless b1 is meant as a template for other buttons). It
also requires a bunch of magic "under the hood". I'd rather use less
surprising constructs. But that's just a matter of opinion; YMMV.

Cheers,

--
Hans Nowak (ha**@zephyrfalcon.org)
http://zephyrfalcon.org/

Jul 18 '05 #57

P: n/a
In article <ma**************************************@python.o rg>,
Cliff Wells <cl************@comcast.net> wrote:
Jul 18 '05 #58

P: n/a
Hans Nowak wrote:
I'm not sure what you mean. One known issue is, that there is some
redundancy when creating a control and adding it to its parent:

b = Button(parent, ...)
parent.AddComponent(b, ...)
What I'm suggesting is to avoid the redundacy and do:
parent.Add(Button(...))

I've done it for some GUI framework where I work encapsulating wxPython.
The drawback is that you need to delay the creation of widgets, which
means some attributes might be stored twice. But it's definitely easier
to use.

Another thing I'm suggesting is a mechanism to not destroy a widget
until it's corresponding python object is destroyed. It's more complex,
but Python has already ownership with refcount, garbage collection, etc.
and I think a truly pythonic GUI framework should use the same ownership
mechanism.
I am thinking of ways to make this simpler. One possible solution would
be to accept a 'layout' parameter:

b = Button(parent, ..., layout={'expand': 'both', 'border': 2})

...but I'm not sure that actually makes things simpler or more readable.
I personally prefer Java-Swing-Layout and wxPython-sizers approach. I
think it's better to add widgets in the layout.
It's also possible to do something like this:

parent.Add(some_control, parameters_for_control, parameters_for_layout)


Again, I think layouts/sizers are very nice, since the way to add can be
very different dependending on the layout/sizer. For example,
specifying col and row when adding to a GridBagLayout.
It could also be a good idea to take the occasion to respect PEP8.


Which recommendations of the style guide does the Wax code violate?


IIRC, method names beginning with lowercase, as all the Python API.
Note also that "import wax" would be better than "from wax import *".


I'm considering it. This way, it would also be possible to import
things on demand. On the other hand, I don't like to write 'wax.'
before everything.


It's just that when you work multiple modules, autocompletion for a
module doing a "from wx import *" is a nightmare (and is also slowing
debuggers, since so many symbols are in each module namespace). If wax
becomes big, it would also be a pain. You can do "import wax as w" ;)

Regards,
Nicolas
Jul 18 '05 #59

P: n/a
Nicolas Fleury wrote:
What I'm suggesting is to avoid the redundacy and do:
parent.Add(Button(...))

I've done it for some GUI framework where I work encapsulating wxPython.
The drawback is that you need to delay the creation of widgets, which
means some attributes might be stored twice. But it's definitely easier
to use.
I'm not sure it's *that* much easier... all you're saving is one parameter.
Another thing I'm suggesting is a mechanism to not destroy a widget
until it's corresponding python object is destroyed. It's more complex,
but Python has already ownership with refcount, garbage collection, etc.
and I think a truly pythonic GUI framework should use the same ownership
mechanism.


Hm. I'm not sure how wxPython handles that, and if it would be possible to
impose such a system on top of it.
It could also be a good idea to take the occasion to respect PEP8.


Which recommendations of the style guide does the Wax code violate?


IIRC, method names beginning with lowercase, as all the Python API.


Wax follows the wxPython standard here. Since most Wax controls derive
directly from wxPython classes, it would make little sense to add lowercase
methods to the mix (next to the existing uppercase methods), or to convert them.
Note also that "import wax" would be better than "from wax import *".


I'm considering it. This way, it would also be possible to import
things on demand. On the other hand, I don't like to write 'wax.'
before everything.


It's just that when you work multiple modules, autocompletion for a
module doing a "from wx import *" is a nightmare (and is also slowing
debuggers, since so many symbols are in each module namespace). If wax
becomes big, it would also be a pain. You can do "import wax as w" ;)


I personally like 'from wax import *', kind of like how Tkinter is usually
imported. Either way currently works, though. Should I use the "lazy"
importing (which is admittedly useful), then the star-import would not be
possible anymore, I think.

--
Hans Nowak (ha**@zephyrfalcon.org)
http://zephyrfalcon.org/

Jul 18 '05 #60

P: n/a
Hans Nowak wrote:
I'm not sure it's *that* much easier... all you're saving is one parameter.
Easier is probably not the good word. It is less redundant and less
error-prone. It has happened to me to make mistakes in ownership of
widgets when copy-pasting code, when these errors would not have occured
if the parent parameter was not passed.

It is also more usable, since you can do things like:
myFrame.SetMenuBar(MenuBar([
Menu("File", [
Item("&New\tCtrl+N", self.onNew),
Menu("Some sub menu...", ...)]
Menu("Edit", ...)]

The problem is that that explicit cross-referencing between parent and
child forces the parent to be created before, removing capabilities like
that one.
Another thing I'm suggesting is a mechanism to not destroy a widget
until it's corresponding python object is destroyed. It's more
complex, but Python has already ownership with refcount, garbage
collection, etc. and I think a truly pythonic GUI framework should use
the same ownership mechanism.

Hm. I'm not sure how wxPython handles that, and if it would be possible
to impose such a system on top of it.


I honestly don't know. I guess a solution could be to create a frame in
two passes, and the wx.Frame created after the first pass is used as
parent of everything created in second pass.

Also, the wxPython mechanism could be completely hidden behind the
wrappers. The wrappers can contain all necessary information to create
the widgets, allowing widgets to be created with a parent when addded to
it and even recreated with another parent if added later to something
else. This way the user will not even have to think about the ownership
issue.
Wax follows the wxPython standard here. Since most Wax controls derive
directly from wxPython classes, it would make little sense to add
lowercase methods to the mix (next to the existing uppercase methods),
or to convert them.


Sorry, I though they were complete wrappers as in PythonCard. I totally
agree to keep things that way if wx widgets are inherited.

Regards,
Nicolas
Jul 18 '05 #61

P: n/a
Nicolas Fleury wrote:
Hans Nowak wrote:
I'm not sure it's *that* much easier... all you're saving is one
parameter.

Easier is probably not the good word. It is less redundant and less
error-prone. It has happened to me to make mistakes in ownership of
widgets when copy-pasting code, when these errors would not have occured
if the parent parameter was not passed.


Admittedly, having to state the parent-child (or container-child) relationship
twice is redundant. I am still thinking of ways to make that work better.
Maybe I'll post some suggestions on my weblog, so people can discuss it there,
rather than on the newsgroup.
It is also more usable, since you can do things like:
myFrame.SetMenuBar(MenuBar([
Menu("File", [
Item("&New\tCtrl+N", self.onNew),
Menu("Some sub menu...", ...)]
Menu("Edit", ...)]
In fact, a nested list would suffice here to contain the structure of the whole
menu. I have an application that uses just that. Maybe something that can be
added as well.
The problem is that that explicit cross-referencing between parent and
child forces the parent to be created before, removing capabilities like
that one.


But adding capabilities as well... see my example in a previous post.

Cheers,

--
Hans Nowak (ha**@zephyrfalcon.org)
http://zephyrfalcon.org/

Jul 18 '05 #62

P: n/a
On Sep 23, 2004, at 6:44 AM, anton muhin wrote:
I beg your pardon for possibly stupid comment---I haven't practice GUI
programming for a long time, especially in Python. However I mostly
prefer declarative approach for the problems like that. Therefore,
wouldn't it be interesting to describe the structure with class and
metaclass mechanism, like:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

etc.


That's the approach we've take with Dabo (albeit with slightly
different names). In fact, you could even avoid setting the size with a
tuple by typing:

class b1(dabo.ui.dButton):
Height = 60
Width = 40
Caption = "Click Me"

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/

Jul 18 '05 #63

P: n/a
anton muhin wrote:
I beg your pardon for possibly stupid comment---I haven't practice
GUI programming for a long time, especially in Python. However I
mostly prefer declarative approach for the problems like that.
Therefore, wouldn't it be interesting to describe the structure
with class and metaclass mechanism, like:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"


I've recently been working on a system that lets you do that kind
of thing. It's a set of metaclasses that wrap the wxPython classes so
you define your GUI with nested class structures. Certain things are
hard here because of the way class definitions are handled in Python,
but I am making progress.

If anyone's interested, you can see an example of what the GUI code
looks like at http://www.brenbarn.net/misc/idealgui.txt . This is code
that actually produces a working program with my current setup. It
won't work for anyone else, of course, because I haven't made my library
available yet. My main goal here, though, is to get it so the code
LOOKS nice, so just seeing how the code looks will give you an idea of
the style.

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #64

P: n/a
I'd just like to add a comment, not to start an endless debate on U.S
economic or trade policy...
IMHO what you are experiencing in the U.S is just another sign of the
globalization process, which is bad from an american perspective, but
good from a global one.

For too long, the industrialized countries have enjoy the power of
their competitiveness and technical inovation while, at the same time,
they have been protecting their less competitive sectors such as
agriculture and labor intensive jobs. But this situation led to a club
of rich nations isolated from a mass of third world countries, whose
primary products weren't allowed to enter the rich markets due to very
rigid policy of subsidies and trade barriers.

But how can IBM, Microsoft, HP, and all those monsters keep on growing
without selling to the so called "emerging markets"? By trading with
Mars?
If the rich want to get richer, sooner or later they will have to even
the field, allowing others to rise from missery in order to
incorporate them to the consumption society.

Now you see China, India, Brazil and other countries that are doing
well, improving the condition of their inhabitants, getting them out
of missery and incorporating them to the global market.
Those foreigners buy american products, now more than before because
they have more money, thus improving the profit of the monsters
mentioned above.
Here in latin america we buy these products, and at the same price or
more in US Dollars (not a penny less), don't you think we deserve
something in exchange?
I don't mean humanitarian supplies, I mean more fair and equitable
rules for trading of products, skills and resources.

After a very hard devaluation of our currency, an argentine programmer
is paid 11 dollars less an hour than an indian one. Now, many educated
people, with knowledge of two or more languages and with high tech
skills can aspire to pay the rent and make a living, making 4 or 5x
less than an american counterpart.
These people worked their ass off to have what they're getting now.

Honestly, do you expect them to be sorry for you?
I'm affraid that there's no way back. A highly skilled programmer in
the third world (or any other kind of proffesional) deserves to get a
job if he/she can do it better and cheaper than an american (or
canadian or whatever..) one.
This is the internet age. I hope that it contributes to make the poor
less poor and the rich not so rich, and maybe, in a distant future we
will have a better world for all of us.
Jul 18 '05 #65

P: n/a
Alright, here's the question I'm going to start asking whenever anyone
starts promoting a new gui for python. Is there an nice gui-driven
gui creation tool to go with this? I realize that you're really happy
with the API and all, but if there were a nice gui maker along with a
nice python ide to go along with it, you'd probably make a lot more
converts. And for once, it'd be nice to see a gui maker that isn't a
thin wrapper of some C++ gui maker and doesn't produce some crappy
non-python data file that another C++ program uses to make a library
or some such bs. Just have it produce a nice python loop or
something, that'd be good. Do that, make it truly cross platform,
free and add a nice python ide, and you're well on your way to making
it the standard python gui.
"Zooko O'Whielacronx" <zo***@zooko.com> wrote in message news:<ma**************************************@pyt hon.org>...
I'm a fan of Greg Ewing's PyGUI [1]. I used it to code a simple game
for my son [2], and enjoyed it. Programming with wxPython feels like
programming with a C++ tool that has been wrapped in Python.
Programming with PyGUI feels like programming with a real Python tool.

If you're developing a commercial application in Python, wxPython is
currently the only option that offers native widgets on w32. It would
be a boost for Python if PyGUI got a native w32 backend.

Therefore, I offer the following suggestions:

Python programmers: use PyGUI! It's nice. Contribute bug reports and
so forth.

Python developers: Is it too early to include PyGUI in the standard
library? It seems stable to me.

PSF: If anyone applies for a grant [3] to put a proper w32 backend into
PyGUI, please give them money. I would offer to do that job myself,
but (a) I'm not w32 expert and (b) I'm busy trying to make one of those
aforementioned commercial apps.

Thanks,

Zooko, Journeyman Hacker

[1] http://www.cosc.canterbury.ac.nz/~greg/python_gui/
[2] http://zooko.com/log-2004.html#d2004-06-23
[3] http://python.org/psf/call-2004.html

Jul 18 '05 #66

P: n/a
On Thu, 2004-09-23 at 14:08 +0000, Cameron Laird wrote:
It's worse than that, Cliff: there's serious reason to fear
that non-price factors might soon work *against* us in the US,
almost as much as they have for us in the past. I see this
running along a couple of lines:
*) "security"-related and DRM-IP-enforcing
export restrictions directly interfere
with our ability to deliver internation-
ally; and
This is actually a reason to change countries rather than lines of work.
The current state of affairs wrt IP in the U.S. is sickening. Of
course, no matter where you go, there's always something that makes you
want to move somewhere else. And if there isn't today, there will be
tomorrow.
*) MS hasn't been alone in habituating
international customers to associate US
software with expense and unreliability.


Hey, let's not get personal <wink>.

--
Cliff Wells <cl************@comcast.net>

Jul 18 '05 #67

P: n/a
On Sep 23, 2004, at 8:31 PM, Corey Coughlin wrote:
Alright, here's the question I'm going to start asking whenever anyone
starts promoting a new gui for python. Is there an nice gui-driven
gui creation tool to go with this? I realize that you're really happy
with the API and all, but if there were a nice gui maker along with a
nice python ide to go along with it, you'd probably make a lot more
converts.


I agree 100%. One of the planned development projects for Dabo is a
true GUI designer. We have several ideas and a few proof-of-concept
attempts, but the major focus on the GUI designer will be after the 0.5
release. The plan is to create a solid basis before adding the exterior
goodies. ;-)

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/

Jul 18 '05 #68

P: n/a
Hans Nowak wrote:
Admittedly, having to state the parent-child (or container-child)
relationship twice is redundant. I am still thinking of ways to make
that work better. Maybe I'll post some suggestions on my weblog, so
people can discuss it there, rather than on the newsgroup.


My suggestion is to do as in Python for normal objects; they exists
because they are referenced. The widget can even be added under
multiple parents; under the hood multiple wx widgets are created.
It is also more usable, since you can do things like:
myFrame.SetMenuBar(MenuBar([
Menu("File", [
Item("&New\tCtrl+N", self.onNew),
Menu("Some sub menu...", ...)]
Menu("Edit", ...)]

In fact, a nested list would suffice here to contain the structure of
the whole menu. I have an application that uses just that. Maybe
something that can be added as well.


Admittedly I did the same thing. But I changed it to something like my
example. Instead of having one piece of code analyzing nested lists or
tuples, everything is delegated to small classes and therefore
expandable by user and more flexible.

It's easier to do that with menus because they are not wx.Window IIRC
and you don't have to pass the parent in constructors. What would be
really cool is to have the same approach for everything:

panel = Panel(
BoxLayout(VERTICAL, [
Label("Some text),
BoxLayout(HORIZONTAL, [
Button("OK", self.onOk),
Button("Cancel", self.onCancel)])]))

What is cool about that approach is that you can do everything with
constructors, but can still do more complex things in mulitple
statements like in wxPython (you can still have add methods). It has
also the advantage to have the capability to present things
hierarchically, as with other suggestions of using metaclasses.
The problem is that that explicit cross-referencing between parent and
child forces the parent to be created before, removing capabilities
like that one.


But adding capabilities as well... see my example in a previous post.


The problem with:
b = Button(parent, ..., layout={'expand': 'both', 'border': 2})
is that the constructor of Button is receiving arguments to a layout it
should not know about. The arguments can also be specific/complex for a
certain type of layout. It mean that widgets contructors, in addition
to parent argument, would also need flags for the layout. I see it the
other way, ownership should be specified when doing the composition
itself, and widgets constructors should only take flags for themselves
and their children if they can have one.

Note that I'm describing what kind of API I would like to use, not
necessarily the one you want to make;)

Cheers,
Nicolas
Jul 18 '05 #69

P: n/a
Hans Nowak wrote:
anton muhin wrote:
class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

I'm not sure if the construct described above is all
that great...


For a while now I've been wondering whether Python could
benefit from an "instance" statement that works similarly
to a class statement but creates instances instead of
classes.

e.g.

class MainFrame(FrameDescription):

instance b1(ButtonDescription):
size = (40, 40)
text = "b1"

Haven't figured out all the details of how it would
work, though...

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Jul 18 '05 #70

P: n/a
Greg Ewing wrote:
For a while now I've been wondering whether Python could
benefit from an "instance" statement that works similarly
to a class statement but creates instances instead of
classes.

e.g.

class MainFrame(FrameDescription):

instance b1(ButtonDescription):
size = (40, 40)
text = "b1"

Haven't figured out all the details of how it would
work, though...


I think you can probably force the current implementation to
work this way, with a little work. You'd need to *slightly*
change the above spelling though, and make sure you were
using one of the standard Python implementations and not,
say, something that didn't follow the language reference:

class MainFrame(FrameDescription):
b1 = ButtonDescription(
size = (40, 40),
text = "b1",
)

That's pretty close to what you asked for. You're welcome,
in advance. <wink>

(Actually, I suspect you wanted slightly different behaviour,
but I'm not clear on what.)

-Peter
Jul 18 '05 #71

P: n/a
>>>>> Greg Ewing <gr**@cosc.canterbury.ac.nz> (GE) wrote:

GE> For a while now I've been wondering whether Python could
GE> benefit from an "instance" statement that works similarly
GE> to a class statement but creates instances instead of
GE> classes.

GE> e.g.

GE> class MainFrame(FrameDescription):

GE> instance b1(ButtonDescription):
GE> size = (40, 40)
GE> text = "b1"

How would this be different from:

b1 = ButtonDescription():
b1.size = (40, 40)
b1.text = "b1"

or from this:

def instance(klass, **kw):
inst = klass()
for k in kw:
# could add a check for __getattr__ here
inst.__dict__[k] = kw[k]
return inst

b1 = instance(ButtonDescription,
size = (40,40),
text = "b1")

--
Piet van Oostrum <pi**@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.***********@hccnet.nl
Jul 18 '05 #72

P: n/a
>>>>> "Luis" == Neuruss <lu****@gmx.net> writes:

Luis> Now you see China, India, Brazil and other countries that
Luis> are doing well, improving the condition of their
Luis> inhabitants, getting them out of missery and incorporating
Luis> them to the global market. Those foreigners buy american
Luis> products, now more than before because they have more money,
Lkuis> thus improving the profit of the monsters mentioned above.

What are these American products they are buying? Coca Cola and Big
Macs (which are probably locally produced)? MSFT Windows?

I don't really see a need for any American products when much cheaper
alternatives are available, from Asia and elsewhere.

However, that's all irrelevant. Corporations are going to move jobs
away from the US anyway, because it makes sense financially. If they
can save a buck, it doesn't matter if that puts 1000 (perceivedly)
overpaid americans out of their jobs. It's not like those specific
laid-off workers were using their salaries to buy the company products
in the first place.

Luis> This is the internet age. I hope that it contributes to make
Luis> the poor less poor and the rich not so rich, and maybe, in a
Luis> distant future we will have a better world for all of us.

Well, at least it contributes to making the rich (people, not
countries) much richer, while reducing the overall wealth of rich
countries. I guess it won't be the end of the world if the first world
countries can bear the burden of the resulting unemployment - it's
much more comfortable to be poor in a country that doesn't routinely
hit -20C on winters ;-).

Personally, I don't care much either way because Finland is one of
those countries with low salaries for engineers, with the unfortunate
twist of the cost of living being high as well.

--
Ville Vainio http://tinyurl.com/2prnb
Jul 18 '05 #73

P: n/a
On Fri, 24 Sep 2004 15:47:33 +1200, Greg Ewing
<gr**@cosc.canterbury.ac.nz> wrote:
For a while now I've been wondering whether Python could
benefit from an "instance" statement that works similarly
to a class statement but creates instances instead of
classes.


I've done something like you want using metaclasses. I've posted it as
another thread, it was a "Call for suggestions". As you may see, I'm
still looking for more people to work with me on this solution :-)
Basically what it does is to process declarations like this:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

.... where FrameDescription and ButtonDescription are both derived from
a base Container class. When constructed, the MainFrame will contain
an **instance** called b1 from the class b1 (that's right, the same
name; the temporary class definition is gone). The metaclass creation
engine also respects the order of the declaration. The orderd list is
stored as a _fields member; in the case above, _fields[0] is size, and
_fields[1] is text. Note that the hash used to store attributes that
is passed to the metaclass can't work this magic alone.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #74

P: n/a
On 23 Sep 2004 21:31:10 GMT, OKB (not okblacke)
<br************@nobrenspambarn.net> wrote:
I've recently been working on a system that lets you do that kind
of thing. It's a set of metaclasses that wrap the wxPython classes so
you define your GUI with nested class structures. Certain things are
hard here because of the way class definitions are handled in Python,
but I am making progress.
I think I have solved the first half of your problem. Please check my
"Call for suggestions" post from yesterday. I implemented a Container
metaclass that can take nested class declarations and generate a
representation with a few important features:

-- it's ordered (in the same order as the original declarations in the
source code)
-- all nested classes are converted to instances

Please check it, and let me know if you're interested. I'm focusing my
work on this part now, I'm purposefully not dealing with the GUI; I
have my own ideas regarding the GUI part, but let us solve one problem
at a time, right?
If anyone's interested, you can see an example of what the GUI code
looks like at http://www.brenbarn.net/misc/idealgui.txt . This is code
that actually produces a working program with my current setup. It
won't work for anyone else, of course, because I haven't made my library
available yet. My main goal here, though, is to get it so the code
LOOKS nice, so just seeing how the code looks will give you an idea of
the style.


It seems like we're looking for similar solutions. I'm looking for
more people to start a separate discussion to avoid spamming c.l.py.
Please drop me a note if you're interested.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #75

P: n/a
On Sep 24, 2004, at 10:01 AM, Carlos Ribeiro wrote:
Basically what it does is to process declarations like this:

class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

... where FrameDescription and ButtonDescription are both derived from
a base Container class. When constructed, the MainFrame will contain
an **instance** called b1 from the class b1 (that's right, the same
name; the temporary class definition is gone). The metaclass creation
engine also respects the order of the declaration.


How is this more powerful/flexible/robust than something like:

class MainForm(dabo.ui.dForm):
def __init__(self, parent=None):
self.addObject(ButtonDescription, "b1")
self.b1.Size = (40,40)
self.b1.Caption = "b1"

....which is the standard syntax in Dabo for adding objects to a form
(frame)?

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/

Jul 18 '05 #76

P: n/a
On Fri, 24 Sep 2004 10:17:06 -0400, Ed Leafe <ed@leafe.com> wrote:
On Sep 24, 2004, at 10:01 AM, Carlos Ribeiro wrote:
[...my sample...]
class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"


[...your question...]
How is this more powerful/flexible/robust than something like:

class MainForm(dabo.ui.dForm):
def __init__(self, parent=None):
self.addObject(ButtonDescription, "b1")
self.b1.Size = (40,40)
self.b1.Caption = "b1"


Ok. I'll try to answer your questions, but first some background is
needed to focus the discussion.

We can broadly define three ways to implement GUI description: (a)
Imperative, (b) Data-driven and (c) Declarative. Dabo uses a
imperative approach (as do wxPython and almost all other GUI packages
for Python). Some packages are available which take a description of
the UI and build it, using XML or some other intermediary data
representation. Glade (for GTk) works this way. I'm using a
declarative approach -- using Python native class declarations to
build the UI definition.

Why do it this way? First of all, it's an *experiment*. It's something
I'm doing because I feel that it has potential to be better than other
approaches. It's also based on my experience with other tools. Delphi
forms are stored in a intermediate format that is read by the
application; it's really data driven, but the language "reads" for the
programmer as a declarative language. It's much more readable than,
for example, a XML file or a Python dict storing the UI definition. I
also remember the old days of dBase 2 and FoxPro (for DOS), where it
was easy to build data entry screens with just a few lines of
declarations embedded in the same program, with no need to create
separate data files, etc.

What I'm trying to do is to bridge the last gap here: having a
readable declaration of the interface, written in pure Python code, in
such a way as to allow the programmer to work with a single language
all the time. As I said, there's nothing wrong with other approaches,
but I *think* that my approach will show its value once we start to
use it for day-to-day coding. I may be wrong, but why can't we try it?

DESIGN GOALS

The system is being designed for readability and flexibility. It's not
being designed to be powerful, in the sense of fine control over the
UI, but to be as simple to use as possible, and both things (power vs.
simplicity) are at odds sometimes. I'm yet to see how big a compromise
must be made.

The first part is the metacontainer engine. It's a metaclass that
handles creation of nested classes in such way as to preserve some
information that is lost when Python parses the code; namely, the
ordering of the declarations. It also converts nested classes into
instances, which is needed for later use.

This engine is totally independent of its use. You can use the engine
anytime a declarative language is useful: form design, reports,
database declarations, etc.. (In fact, the design was inspired by Ian
Bicking's sqlobject way to declare object entities; I just wanted a
way to generalize it for other stuff).

Over this engine (that is already working and is nicely encapsulated),
I'm building a generic Form class. I could be doing the same for
databases, or for reports. Everything will share the same engine and
the same way to write declarations. What will change is the base
classes used for this purpose, and the way the resulting class
definition will be used.

The class description works together with a renderer object. They
collaborate to convert the declaration of the UI into a real
representation -- for example, a wxFrame filled with all controls
needed. It's probably slower than executing code written by hand. But
it's easier to write, because the engine can handle a lot of the stuff
that has to be done manually by the programmer.

This approach is not being design for speed, but nothing prevents it
from being fast. A good part of the "black magic" is done by the
metaclass when the class declaration is first read, parsed and
byte-compiele by Python. The result of the rendering can also be
cached for later use, so it's not really needed to render it everytime
it's needed.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #77

P: n/a
lu****@gmx.net (Neuruss) wrote in message news:<27*************************@posting.google.c om>...
people, with knowledge of two or more languages and with high tech
skills can aspire to pay the rent and make a living, making 4 or 5x
less than an american counterpart.
These people worked their ass off to have what they're getting now.


So did we. I certainly respect the accomplishments of programmers the
world over. However...

I think the real problem is not so much that foreign programmers are
paid less than US programmers. Instead I suspect the problem (from
our point of view) is that their cost of living is so much lower. If
I worked for the salary of an Indian programmer I would have no place
to live, no insurance, and would have a hard time buying food to take
back to my family living under a bridge.

Meanwhile the Indian programmer is living like a king (more or less).

This issue will impact a lot more professions than programming. It's
getting hard to find a function that can't be performed from the other
side of the world anymore. What the American economy can do to
respond to this I have no idea.

On the other hand maybe we should all just move to India. We could
teach them how to play football (the real kind, not that soccer
stuff).
Jul 18 '05 #78

P: n/a
al************@comcast.net (A. Lloyd Flanagan) writes:
I think the real problem is not so much that foreign programmers are
paid less than US programmers. Instead I suspect the problem (from
our point of view) is that their cost of living is so much lower. If
I worked for the salary of an Indian programmer I would have no place
to live, no insurance, and would have a hard time buying food to take
back to my family living under a bridge.

Meanwhile the Indian programmer is living like a king (more or less).

This issue will impact a lot more professions than programming. It's
getting hard to find a function that can't be performed from the other
side of the world anymore. What the American economy can do to
respond to this I have no idea.
Do you really think that the price of the things is really what it is
worth in the US or that it is like that to keep these high salaries? ;-)

I think that this is a cyclic thing: things are expensive because they
cost more due to salaries and salaries are higher because things cost
more.

Here we had experience with several *thousands* of percents of inflation
per year (something along the lines of 800% per month, prices went up
every day). Now things are more stable. I don't know for how long...
I hope forever :-)
On the other hand maybe we should all just move to India. We could
teach them how to play football (the real kind, not that soccer
stuff).


You mean the one that has the 'foot' on the name but is played with the
hands? ;-) It seems to me like there's a contradiction somewhere :-)
Be seeing you,
--
Godoy. <go***@ieee.org>
Jul 18 '05 #79

P: n/a
> What are these American products they are buying? Coca Cola and Big
Macs (which are probably locally produced)? MSFT Windows?

I don't really see a need for any American products when much cheaper
alternatives are available, from Asia and elsewhere.
Of course you are right, and I didn't say that as an absolute
statement, I just
wanted to pinpoint a trend that you can see as positive, from another
point of view.
For example, you can buy american (or european, or japanese) products
that are locally produced, but the profit goes for the corporations
(as usual).
The good news here is that at least a little part of this value goes
for the workers who made them.
When I buy a pair of Nike snickers made in Vietnam, I'm buying
american products. I'm improving the chances that those who work in
marketing, design, accountancy, or whatever sector of the company keep
on living well, and at the same time I'm sure that a few vietnamese
who work producing them will at least feed their family, which is much
better than starving.

Personally, I don't care much either way because Finland is one of
those countries with low salaries for engineers, with the unfortunate
twist of the cost of living being high as well.


You don't have to be affraid because Finland has everything to be rich
and prosperous: a transparent political system, highly educated
people, respect for law and a honest society.
Jul 18 '05 #80

P: n/a
On 23 Sep 2004 14:37:40 -0700, lu****@gmx.net (Neuruss) wrote:
I'd just like to add a comment, not to start an endless debate on U.S
economic or trade policy...
IMHO what you are experiencing in the U.S is just another sign of the
globalization process, which is bad from an american perspective, but
good from a global one.

For too long, the industrialized countries have enjoy the power of
their competitiveness and technical inovation while, at the same time,
they have been protecting their less competitive sectors such as
agriculture and labor intensive jobs. But this situation led to a club
of rich nations isolated from a mass of third world countries, whose
primary products weren't allowed to enter the rich markets due to very
rigid policy of subsidies and trade barriers.

But how can IBM, Microsoft, HP, and all those monsters keep on growing
without selling to the so called "emerging markets"? By trading with
Mars?
If the rich want to get richer, sooner or later they will have to even
the field, allowing others to rise from missery in order to
incorporate them to the consumption society.


That's true. And generally understood. Which is perhaps why the IBMs
and Microsofts tend to play an important and productive role in
accomplishing just that. Enlightened self interest at work.

OK. So this all sounds, big picture, like win/win developments, though
with some inevitable displacement effecting some real human beings.

But what I haven't been quite able to grasp is the basis for the
sentiment of "Globalization" as a dirty word, with the U.S. (and its
evil corporations - as if corporations were something other than an
organizational structure for goal oriented human endeavor) assigned
the role of the heavy. In the more extreme forms of this viewpoint,
"the heavy" being a considerable understatement for the role assigned
the U.S. and its evil lackey corporations.

I don't think, for example, the U.S. is aggressive at all in
protecting its markets with subsidies or trade barriers. If anything
there is the argument that the U.S. should perhaps be doing more in
protecting its markets from goods being produced overseas at
artificially low costs as a result of implicit or explicit subsidies
being provided in the originating country. But being generally
liberal on these kinds of issues seems, at this time, to set the right
leadership tone, and seems to be working - so there is generally a
let-it-be attitude.

The U.S. in anything but the heavy in *my* story.

Is it just that I am a neo-Dadaist PolyAnna?

Art

Jul 18 '05 #81

P: n/a
In article <27*************************@posting.google.com> ,
Neuruss <lu****@gmx.net> wrote:
Jul 18 '05 #82

P: n/a
Ed Leafe wrote:
class MainFrame(FrameDescription):

class b1(ButtonDescription):
size = (40, 40)
text = "b1"

... where FrameDescription and ButtonDescription are both derived
from a base Container class. When constructed, the MainFrame will
contain an **instance** called b1 from the class b1 (that's right,
the same name; the temporary class definition is gone). The
metaclass creation engine also respects the order of the
declaration.


How is this more powerful/flexible/robust than something like:

class MainForm(dabo.ui.dForm):
def __init__(self, parent=None):
self.addObject(ButtonDescription, "b1")
self.b1.Size = (40,40)
self.b1.Caption = "b1"

...which is the standard syntax in Dabo for adding objects to a
form (frame)?


I would say that the former is a great deal more readable. In
particular, this is one case where having to use an explicit "self"
really hurts. You've already had to retype "self.b1" twice just to
specify the size and caption. What if you wanted to specify a color? A
background color? To say nothing of an event handler.

In the same vein as what Carlos Ribeiro said in another post: it's
my opinion that defining the GUI layout is a fundamentally declarative
task, and forcing the programmer to perform it in a procedural fashion
is working against the grain of the problem.

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #83

P: n/a
On Fri, 24 Sep 2004 11:08:22 -0300 Carlos Ribeiro
<ca********@gmail.com> wrote:
I think I have solved the first half of your problem. Please check my
"Call for suggestions" post from yesterday. I implemented a Container metaclass that can take nested class declarations and generate a
representation with a few important features:

-- it's ordered (in the same order as the original declarations in the
source code)
-- all nested classes are converted to instances
My implementation essentially does this as well. However, I
have devised a metaclass (called ClassObj) that does not actually
replace the class with an instance. Instead, each class keeps a reference
to singleton instance. All attributes are stored on the class object, but
methods are forwarded to the instance (since Python won't allow you
to call methods on a class). The advantage of this is that the classes
can even be subclassed. This metaclass largely eliminates the
distinction between classes and objects; a ClassObj can effectively
function as either.
Please check it, and let me know if you're interested. I'm focusing my
work on this part now, I'm purposefully not dealing with the GUI; I
have my own ideas regarding the GUI part, but let us solve one problem at a time, right? <snip> It seems like we're looking for similar solutions. I'm looking for
more people to start a separate discussion to avoid spamming c.l.py.
Please drop me a note if you're interested.


I'm definitely interested. I have put my work-in-progress code up
if you want to look at it. It is at http://www.brenbarn.net/misc/gui/
(You may have to change the import statements in the files slightly; I
haven't bothered to make sure the directory structure there is the same
as on my local system.) This is obviously incomplete, but it gives an
idea of the kind of thing I am doing. Let me know what you think!

--
--Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown

Jul 18 '05 #84

P: n/a
On Fri, 24 Sep 2004 22:12:46 -0700 (Pacific Standard Time), Brendan
Barnwell <br******@brenbarn.net> wrote:
My implementation essentially does this as well. However, I
have devised a metaclass (called ClassObj) that does not actually
replace the class with an instance. Instead, each class keeps a reference
to singleton instance. All attributes are stored on the class object, but
methods are forwarded to the instance (since Python won't allow you
to call methods on a class). The advantage of this is that the classes
can even be subclassed. This metaclass largely eliminates the
distinction between classes and objects; a ClassObj can effectively
function as either.
Well, it took me sometime to figure out if I should leave inner
classes as classes or instantiate them. It's funny because my approach
ends up being similar to yours -- the class is instantiated by the
metaclass, and in the process the original class declaration is lost,
which means that it turns into a singleton for all practical purposes.

The reasons why I decided to instantiate inner classes were:

1) It's easier to process the resultin class declaration, because all
attributes are instances. Before doing it I had to put some "isclass"
checks to take different actions depending on the type of the
attribute. It's not needed anymore (not to the same extent, at least).

2) The original class is not needed really for subclassing. It's not
convenient anyway, because you'ld need dot notation to find the inner
class declaration. My suggestion is that all classes that are supposed
to be subclassed can be safely declared at the top level, as in:

class i_am_a_baseclass(Container):
attr0 = "zzz"

class outer_class(Container):
class inner_class_1(Container):
attr1 = "a"
attr2 = "b"
class inner_class_1(i_am_a_baseclass):
attr3 = "r"
attr4 = "s"

As of now, I really don't know for sure which approach is better. More
experimentation is needed to check what makes more sense in the long
run not only for me (and you), but for other users having a first try
at this concept.
I'm definitely interested. I have put my work-in-progress code up
if you want to look at it. It is at http://www.brenbarn.net/misc/gui/
(You may have to change the import statements in the files slightly; I
haven't bothered to make sure the directory structure there is the same
as on my local system.) This is obviously incomplete, but it gives an
idea of the kind of thing I am doing. Let me know what you think!


Thanks for the code -- now it's really late (2:30am), and I need to
sleep... I'll try to check it tomorrow with a fresh mind.

As for my code, I've changed heavily the code that I've posted
yesterday. I've tested some alternatives and dropped parts of the
code. It's simpler and easier to reuse now. I'm debuggin some advanced
stuff now -- weird bugs pop up sometimes :-P

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #85

P: n/a
Arthur <aj******@optonline.com> wrote:
...
But what I haven't been quite able to grasp is the basis for the
sentiment of "Globalization" as a dirty word, with the U.S. (and its
evil corporations - as if corporations were something other than an
organizational structure for goal oriented human endeavor) assigned
Try Stiglitz's bestseller, "Globalization and Its Discontents" -- the
author's towering stature helps. The book focuses more on the role of
institutions such as the IMF, US-dominated though technically
international, rather than on private corporations or US's
protectionism, though (the aspects are connected, of course, but not as
directly and immediately as an oversimplification might suggest).
I don't think, for example, the U.S. is aggressive at all in
protecting its markets with subsidies or trade barriers. If anything
I do, and it appears to me that such bodies as NAFTA and WTO agree. The
US's so-called "antidumping" policies are a particular bone of
contention.

NAFTA's panel recently decreed, after a fight that lasted years, that
there is no subsidy of Canada's soft wood exports to the US, so the US
long-standing antidumping duties were illegal. The US Dept of Commerce
basically agreed (they won't appeal, they say) -- but the duties remain.

I'm surely not the only observer to see this as the behavior of a
playground bully: what's Canada gonna do about it, take a clue from the
South Park movie?! In such a case the US is basically stating, "we're
the 500-pounds gorilla, rules apply to lesser countries, not us, so
there". And that's wrt their closest neighbor and friend -- AND for
incredibly myopic reasons too. Canada's cheap wood obviously HELPS
crucial US industries such as construction (US house construction uses
MUCH more wood than we do in Europe)... but the wood-loggers' lobby is
strong enough in a key swing state, Oregon (and to some extent
Washington, too, I believe), to perhaps swing the next presidental
election, if it's as close as many think... so, forget the rules and all
the nice words, might makes right.

_Some_ US observers are clear-sighted enough to see how much hate this
kind of behavior builds up in the world over the years. But obviously
not enough.

The cases of cotton and sugar, with subsidies and help from tariffs
amounting to over 100,000 dollars per each of the few thousands of lucky
US cotton and sugar growers who benefit from it, are other good
examples. They're likely to end up in front of the WTO, but it doesn't
really matter because there, for once, the US isn't even _claiming_ an
antidumping issue. Similarly for the huge hidden subsidy to growers of
fruit and even rice (!) in the parched fields of Southern California in
terms of essentially free water in ridiculous quantities (that's
unlikely to become a trade/subsidy issue, but with good water growing
scarcer in the region it's been causing tension with Mexico for a while,
and the tension is growing) - and at a time when millions of Californian
in cities have had problems with water scarcity, too.

In each case, the US does damage to its international "public relation",
to the cause of free trade, AND to a large number of its citizens, in
order to lavish largesse on small, lucky, politically powerful lobbies.

The pattern keeps repeating. Consider the "steel antidumping tariffs"
that your President imposed, then removed -- they damaged your ailing
manufacturing sector (cars and other machinery foremost) and a part of
the construction industry (for those buildings that use substantial
amounts of steel) much more than they helped steel smelters who were in
any case being revived by such strokes of luck as China's insatiable
appetite for steel (which raises worldwide steel prices). The WTO had
little trouble in decreeing that there was absolutely no dumping
involved, i.e., as usual, the US was brandishing "anti-dumping" as an
excuse to play internal electoral politics -- what distinguished this
case was that the political calculations were wrong (the votes to be won
by sucking up to steel producers are in fact fewer than those to be lost
by seriously enraging the manufacturing sector -- both constituencies
being concentrated in the mid-west, more or less).

there is the argument that the U.S. should perhaps be doing more in
protecting its markets from goods being produced overseas at
artificially low costs as a result of implicit or explicit subsidies
being provided in the originating country.
Yeah, right. Tell that to the WTO and NAFTA panels which keep finding
out (over and over and OVER again) that US "antidumping" is invariably
barely veiled protectionism.
But being generally
liberal on these kinds of issues seems, at this time, to set the right
leadership tone, and seems to be working - so there is generally a
let-it-be attitude.
You appear to be unaware of the ill-will and even hate that such issues
as your protectionist attacks against, e.g., Canadian wood, etc,
generate in the countries you thus attack.
The U.S. in anything but the heavy in *my* story.
The US's glaring faults do not mean that other countries are blameless,
far from it. Agricultural subsidies and barriers in Japan and Europe
are horrid, and, again, they damage their own citizens as well as
international trade, all to help a few favourites. And all sorts of
barriers are highest (and most damaging to their own citizens) in poor
countries, mostly against primary goods produced in other poor
countries. But, e.g., Kenya's absurd tariffs against maize didn't tend
to raise international alarm, even though they starved poor children
(even worse than adults) in Turkana or Baringo -- apart from a few of us
crazies who READ the FAO reports, most people around the world didn't
even _hear_ about the whole issue. And the trend in Japan and Europe
appears to be improving (in fits and starts, admittedly, and there may
be regression now that the EU has been joined by one large country with
MANY agricultural-based voters, Poland), while the US trend with the
present administration seems definitely negative. (The Clinton
administration _spoke_ with a lot of bluster and rhetoric that often
sounded anti-free-trade, which may have helped it in internal politics
but surely damaged international perception of the US, but its actual
_actions_ overall were more favourable than damaging to free trade).

Is it just that I am a neo-Dadaist PolyAnna?


Your perception appears to be congruent with that of the mass of US
voters. But try reading, e.g., the Economist magazine for a few years:
it's one source which you definitely can't suspect of a-priori
anti-americanism or anti-capitalism, but DOES wave an unfailing banner
for free trade (the magazine was founded to champion free trade in the
19th century, and on that one aspect it has never wavered). The news
and analyses you will read there may help you see the different
perspectives from which others see US behavior -- particularly
interesting, I hope, as being based on actual facts and sound economic
analysis, as opposed to the instinctive anti-Americanism that one can
observe in so many places.
Alex
Jul 18 '05 #86

P: n/a
In article <1g***************************@yahoo.com>,
Alex Martelli <al*****@yahoo.com> wrote:
Jul 18 '05 #87

P: n/a
Cameron Laird <cl****@lairds.us> wrote:
...
"Globalization" just advertising for a refinement of imperialism?
Of course not, to those of us fundamentally aligned with the
progressivism on display in, to echo your example, *The Econo-
Amartya Sen's book is another excellent display of that "of course not".

Some people have taken Stiglitz's and Sen's books as "warring
Nobel-laureate economists con vs pro globalisation", but that's silly.
Rather, Stiglitz focuses more on some ugly aspects of what parts of the
globalisation process have actually BEEN; Sen, more on the sunny parts
and on what they COULD and SHOULD be.

I'm sure Sen and Stiglitz actually agree on FAR more than what they
disagree on -- unfortunately, it's likely to be stuff the average
street-demonstration participant, laid-off worker, or elected politician
can't possibly understand, unless they take a few years off to get the
needed background, starting with differential equations and moving up
from there;-).
I struggle to bring this all back on-topic. Mention of <URL:
http://www.pbs.org/cringely/pulpit/pulpit20040923.html > is my
current attempt.


Tx for the pointer. DMCA _is_ truly scary. OTOH, one _can_ devotely
pray that MS is overplaying their hand, just like IBM did not all THAT
long ago with their proprietary "token rings", OS/2, and
"microchannels"... IBM almost managed to destroy _itself_ that way,
though Gerstner was there to save it from the brink...

And yes, if emerging third-world nations aren't making sure there's Open
Source for everything they can possibly need, the only explanation must
be the high level of corruption in their polities. It's the only
sensible strategy on any political and economic plane, after all.
Alex
Jul 18 '05 #88

P: n/a
On Sep 25, 2004, at 4:49 AM, OKB (not okblacke) wrote:
You've already had to retype "self.b1" twice just to
specify the size and caption. What if you wanted to specify a color?
A
background color? To say nothing of an event handler.


Obviously, if things were that complex, you could set a reference to
the button and use that reference instead of the 'self' construct.

class MainForm(dabo.ui.dForm):
def __init__(self, parent=None):
self.addObject(ButtonDescription, "b1")
btn = self.b1
btn.Size = (40,40)
btn.Caption = "b1"
There is also nothing to prevent you from writing that button as a
class definition (although I have a personal dislike of a 'class' being
used for an instance). Something like:

class MainForm(dabo.ui.dForm):
def __init__(self, parent=None):
class btn1(ButtonDescription):
Size = (40, 40)
Caption = "b1"
self.addObject(btn1, "b1")

To my eye, that's a lot uglier than writing it as it is: instance
coding. Dressing it up as a class in order to save typing 'self' isn't
justified, IMO.

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/

Jul 18 '05 #89

P: n/a
Ed Leafe wrote:
There is also nothing to prevent you from writing that button as a
class definition (although I have a personal dislike of a 'class'
being used for an instance). Something like:

class MainForm(dabo.ui.dForm):
def __init__(self, parent=None):
class btn1(ButtonDescription):
Size = (40, 40)
Caption = "b1"
self.addObject(btn1, "b1")

To my eye, that's a lot uglier than writing it as it is:
instance
coding. Dressing it up as a class in order to save typing 'self'
isn't justified, IMO.


Well, I see what you mean, but conversely, even in the example you
gave above, it seems to me that the "def __init__" is (or should be)
superfluous. The very fact that you are defining a button inside a
panel clearly indicates that you want the button to be added to the
panel. Restating this information repeatedly with an __init__ and self
references and explicit "add" methods is cumbersome.

Admittedly, the need to use the word "class" is unfortunate, but I
prefer to simply ignore that little keyword in the definition. That is,
what about this:

frame:
panel:
button1:
caption = "One"
button2:
caption = "Two"

I think the indentation here clearly indicates the intended nesting
structure of the GUI layout. Python requires me to use the word "class"
before each component to get a valid syntactical construct, but I find
it much easier to put single keyword ahead of each GUI object definition
than to wade through a series of method definitions to extract
information about how the components are structured inside one another.

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #90

P: n/a
In article <1g***************************@yahoo.com>,
Alex Martelli <al*****@yahoo.com> wrote:
Cameron Laird <cl****@lairds.us> wrote:
...
"Globalization" just advertising for a refinement of imperialism?
Of course not, to those of us fundamentally aligned with the
progressivism on display in, to echo your example, *The Econo-


Amartya Sen's book is another excellent display of that "of course not".

Some people have taken Stiglitz's and Sen's books as "warring
Nobel-laureate economists con vs pro globalisation", but that's silly.
Rather, Stiglitz focuses more on some ugly aspects of what parts of the
globalisation process have actually BEEN; Sen, more on the sunny parts
and on what they COULD and SHOULD be.

I'm sure Sen and Stiglitz actually agree on FAR more than what they
disagree on -- unfortunately, it's likely to be stuff the average
street-demonstration participant, laid-off worker, or elected politician
can't possibly understand, unless they take a few years off to get the
needed background, starting with differential equations and moving up
from there;-).
I struggle to bring this all back on-topic. Mention of <URL:
http://www.pbs.org/cringely/pulpit/pulpit20040923.html > is my
current attempt.


Tx for the pointer. DMCA _is_ truly scary. OTOH, one _can_ devotely
pray that MS is overplaying their hand, just like IBM did not all THAT
long ago with their proprietary "token rings", OS/2, and
"microchannels"... IBM almost managed to destroy _itself_ that way,
though Gerstner was there to save it from the brink...

And yes, if emerging third-world nations aren't making sure there's Open
Source for everything they can possibly need, the only explanation must
be the high level of corruption in their polities. It's the only
sensible strategy on any political and economic plane, after all.
Alex


Exactly. Well, there's much to talk over--I suspect we both agree,
for example, that IBM has other profound structural challenges--but
let me summarize my response to reference to Sen, DMCA, and so on
with this explicit assertion: one of the great cruelties afoot is
that "globalization" and development are widely regarded as syno-
nyms for "compliance with IMF dictates". We know, of course, that
the possibilities in the world are far richer than this, and that
the true high fliers will be the people and peoples who make their
own ways in the world. Think, in our own narrow domains, of Linux
and Guido and now Miguel and ....
Jul 18 '05 #91

P: n/a
On Sep 25, 2004, at 7:47 PM, OKB (not okblacke) wrote:
Well, I see what you mean, but conversely, even in the example you
gave above, it seems to me that the "def __init__" is (or should be)
superfluous. The very fact that you are defining a button inside a
panel clearly indicates that you want the button to be added to the
panel. Restating this information repeatedly with an __init__ and self
references and explicit "add" methods is cumbersome.


Actually, I just used the __init__() method because that would be more
familiar to most Python folk. Dabo has a method named afterInit() that
is designed for things such as adding contained objects, so that
__init__() is available for the usual instance initialization stuff.

I guess I don't see how this is any more cumbersome than creating
ersatz "class" definitions in an attempt to avoid writing explicit
code. In my form, I want 5 controls added, and I want particular
properties set on each. So there are 5 addObject() commands, and just
as many lines setting props as necessary. You would write 5 class
definitions, each of which has just as many lines setting props within
that class definition. The only difference that I can see is yours
relies on an implicit technique to actually add the objects to their
container, while mine uses an explicit one.

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/

Jul 18 '05 #92

P: n/a
On Sat, 25 Sep 2004 17:08:49 -0400, Ed Leafe <ed@leafe.com> wrote:
[... ]The only difference that I can see is yours
relies on an implicit technique to actually add the objects to their
container, while mine uses an explicit one.


You are missing the point. There is an important difference between
"imperative" and "declarative". Both are explicit -- the only thing
that is implicit in the declarative version is the way the class
declaration is going to be processed by the metaclass constructor. The
descriptive style is more flexible, because the description can be
passed around to other objects that can use it for anything
imaginable. For example, a database entity descriptor (similar to the
ones implemented in sqlobject) can be passed to the report generator
wizard, or to the form generator wizard. The same form description can
be used with multiple target environments much easier than an
imperative version. It isolates the description of what you want from
the actual implementation for the target environment.

To some extent, the choice between declarative and imperative styles
is a matter of personal taste. But also, it's about how to model
problems using programming languages. There's a reason why some people
use functional or declarative languages instead of imperative ones. As
such, we may be forcing Python's syntactic limits by using it for this
type of stuff. That's why I'm calling this an **experiment**. We need
to have something to work with for some time to check if we are
productive and if we feel comfortablee with the way we're working.

As such, I invite you to try it a little bit, and to see how does it
fit into your programming environment. I'm not in a hurry -- I just
want to do it right and to make something useful. And you can rest
assured that your observations are being taken with the most respect
and interest on my part.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #93

P: n/a
On Sat, 25 Sep 2004 10:35:30 +0200, al*****@yahoo.com (Alex Martelli)
wrote:

_Some_ US observers are clear-sighted enough to see how much hate this
kind of behavior builds up in the world over the years. But obviously
not enough.


I don't have the differential equations at my fingertips to prove it,
but have in fact been involved in international business transactions
my entire career, and in part based on this non-abstract experience
would contend that there is much more hatred than justified by the
facts.

If the U.S. is winning, it must be cheating.

Yes, it gets involved in trade wars on particular fronts. And fights
those wars hard enough. but those are particular fronts, for
particular reasons.

Which then provide some ammunition for polemicists.

Which is unfortunately how I hear your post.

If held to no more than the standards of the rest of the realized
world, the U.S. is the example, not the counter-example. Perhaps I
have the particular view of a provincial New Yorker, but I see U.S.'s
greatest asset, and its greatest competitive advantage, to be its
diversity. It does business comfortably anywhere in the world,
because everywhere in the world is well represented in its population.
It was more luck than altruism that relatively open immigration
policies made more sense here than it might have, for example, in the
Old World. But among the results is the fact that Nerw York is
already well globalized, without needing to get out of bed.

And the impact of the the energy of this brew is then labeled a new
imperialism.

Bah.
Art
Jul 18 '05 #94

P: n/a
On Sep 25, 2004, at 6:31 PM, Carlos Ribeiro wrote:
You are missing the point. There is an important difference between
"imperative" and "declarative". Both are explicit -- the only thing
that is implicit in the declarative version is the way the class
declaration is going to be processed by the metaclass constructor.
Sorry, but it just doesn't seem explicit to me. Defining a class
doesn't mean instantiating one instance of a class at the place where
the class is defined, but that seems to be exactly what your metaclass
constructor does.

Perhaps Python lacks the syntax - if it had an 'instance' keyword
instead of forcing you to use 'class', it might be clearer.
The same form description can
be used with multiple target environments much easier than an
imperative version. It isolates the description of what you want from
the actual implementation for the target environment.
Again, I don't see how it is any different. I can use either style
with multiple targets, and add logic to either to get different effects
in each environment.
To some extent, the choice between declarative and imperative styles
is a matter of personal taste.
The impression that I am getting is that it's purely a matter of taste.
But also, it's about how to model
problems using programming languages. There's a reason why some people
use functional or declarative languages instead of imperative ones. As
such, we may be forcing Python's syntactic limits by using it for this
type of stuff.
Exactly. 'Class' has a specific meaning in Python. It does not mean
'contained instance'.
That's why I'm calling this an **experiment**. We need
to have something to work with for some time to check if we are
productive and if we feel comfortablee with the way we're working.
I understand that it's an experiment. My question is if the goal of
this experiment is just to do something differently, or if there is an
ultimate benefit that one can hope to gain if the experiment is a
success. I see what you're doing and how it is different; I guess I
still don't see that this is gaining any power or flexibility.
As such, I invite you to try it a little bit, and to see how does it
fit into your programming environment. I'm not in a hurry -- I just
want to do it right and to make something useful. And you can rest
assured that your observations are being taken with the most respect
and interest on my part.


My problem is that I am in a 'hurry': I need to continue to develop
Dabo, and make it as powerful and flexible for our users as it can be.
I am interested in any alternatives that would benefit our users; my
curiosity is about the payoff for adopting an alternative approach such
as yours. If such a payoff isn't there, I can't spend a lot of time
pursuing it. That's why I'm constantly asking you to explain the
benefit, not just the theory, behind this idea.

___/
/
__/
/
____/
Ed Leafe
http://leafe.com/
http://dabodev.com/

Jul 18 '05 #95

P: n/a
Ed Leafe wrote:
I am interested in any alternatives that would benefit our users;
my curiosity is about the payoff for adopting an alternative
approach such as yours. If such a payoff isn't there, I can't spend
a lot of time pursuing it. That's why I'm constantly asking you to
explain the benefit, not just the theory, behind this idea.


Well, admittedly I've only begun doing this, but my idea is that
the benefit is in readability. Suppose your code is structured like
this:

class frame(wxFrame):
def __init__(self, parent):
button1 = wxButton(parent=self, ...)
button2 = wxButton(parent=self...)
panel = wxPanel(parent=self...)
listBox1 = wxComboBox(parent=panel...)
listBox2 = wxComboBox(parent=panel...)
button3 = wxButton(parent=panel...)
text = wxTextCtrl(parent=panel...)
sizer1 = wxBoxSizer(...)
sizer1.Add(listBox1)
sizer1.Add(listBox2)
sizer1.Add(button3)
sizer1.Add(text)
panel.SetSizer(sizer1)
sizer2 = wxBoxSizer(...)
sizer2.Add(button1)
sizer2.Add(button2)
sizer2.Add(panel)
self.SetSizer(sizer2)
# etc.
###

How am I supposed to know, just by looking at that, which
controls are in which sizers and what the relationship is between the
two sizers? I have to visually parse every single line -- not just the
creation of each widget, but also the line that adds it to a sizer. And
there could easily be an inconsistency -- you might accidentally give a
widget a parent that's inconsistent with the sizer you add it to. With
a nested structure it becomes clear:

class frame(wxFrame):
class sizer1(wxBoxSizer):
class button1(wxButton):
# name, size, etc.
class button2(wxButton):
# etc.
class panel(wxPanel):
class sizer2(wxBoxSizer):
class listBox1(wxComboBox): # etc.
class listBox2(wxComboBox): # etc.
class button3(wxButton): # etc.
class text(wxTextCtrl): # etc.

Now, I can see your point: this does amount to essentially an abuse
of the "class" keyword. But to me this is a small price to pay for the
increase in readability and the reduction in redundancy. Why should I
have to separately specify that: a) a certain widget is being created;
b) it has a certain parent; c) it goes in a certain sizer; c) that sizer
goes in the parent widget? I regard these all as essentially
restatements of a single overall fact about the widget's position in the
interface.

So, yes, this is a very unusual use for the word "class". But the
point here is not the keywords being used. The idea is to have the
structure of the GUI reflected clearly in the layout of the code. If
Python's syntax were more flexible, this could perhaps be done in other
ways -- I'm not saying I want that -- but as it is the only real way to
construct nested structures in Python is with class definitions.

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #96

P: n/a
On 26 Sep 2004 02:31:33 GMT, "OKB (not okblacke)" <br************@NObrenSPAMbarn.net> wrote:
Ed Leafe wrote:
I am interested in any alternatives that would benefit our users;
my curiosity is about the payoff for adopting an alternative
approach such as yours. If such a payoff isn't there, I can't spend
a lot of time pursuing it. That's why I'm constantly asking you to
explain the benefit, not just the theory, behind this idea.
Well, admittedly I've only begun doing this, but my idea is that
the benefit is in readability. Suppose your code is structured like
this:

class frame(wxFrame):
def __init__(self, parent):
button1 = wxButton(parent=self, ...)
button2 = wxButton(parent=self...)
panel = wxPanel(parent=self...)
listBox1 = wxComboBox(parent=panel...)
listBox2 = wxComboBox(parent=panel...)
button3 = wxButton(parent=panel...)
text = wxTextCtrl(parent=panel...)
sizer1 = wxBoxSizer(...)
sizer1.Add(listBox1)
sizer1.Add(listBox2)
sizer1.Add(button3)
sizer1.Add(text)
panel.SetSizer(sizer1)
sizer2 = wxBoxSizer(...)
sizer2.Add(button1)
sizer2.Add(button2)
sizer2.Add(panel)
self.SetSizer(sizer2)
# etc.
###

How am I supposed to know, just by looking at that, which
controls are in which sizers and what the relationship is between the
two sizers? I have to visually parse every single line -- not just the
creation of each widget, but also the line that adds it to a sizer. And
there could easily be an inconsistency -- you might accidentally give a
widget a parent that's inconsistent with the sizer you add it to. With
a nested structure it becomes clear:

class frame(wxFrame):
class sizer1(wxBoxSizer):
class button1(wxButton):
# name, size, etc.
class button2(wxButton):
# etc.
class panel(wxPanel):
class sizer2(wxBoxSizer):
class listBox1(wxComboBox): # etc.
class listBox2(wxComboBox): # etc.
class button3(wxButton): # etc.
class text(wxTextCtrl): # etc.

I could see a way to write this in terms of instances. Also playing a trick so that keyword
arg CC=True would return a custom class instead of an instance, for repeated use of a
particular customization:

CustButtton = Button(CC=True, bgcolor='lightgreen', namefmt='cbtn%s', nextnameno=100)
CustistBox = ListBox(CC=True, kind=ListBox.DROPDOWN, width=40, maxdrop=10) # default namefmt is cls.__name__+'%s'

myFrame = (
Frame(
Sizer(
CustButton(size= ... etc),
CustButton(size= ... etc),
Panel(
Sizer(
CustListBox(etc),
CustListBox(etc),
CustButton(etc),
Text( etc )
)
)
)
)
)

IOW, an *args tuple of child instances is passed to each constructor, and the whole thing
would make a tree of instances. To make customized instances from the same custom class,
I thought to make the base classes return custome classes with class variables preset per
keyword args in the case where there is a CC=True keyword arg. Some thought is required to
make this support whole custom subtrees...
....
# attribute access could be hacked to allow access to the tree in terms of attribute
paths naming supplied or auto-generated names, e.g.,

myFrame.frame1.sizer1.cbtn101.text='Hi' # (default names except CustButtons)
Now, I can see your point: this does amount to essentially an abuse
of the "class" keyword. But to me this is a small price to pay for the
increase in readability and the reduction in redundancy. Why should I
have to separately specify that: a) a certain widget is being created;
b) it has a certain parent; c) it goes in a certain sizer; c) that sizer
goes in the parent widget? I regard these all as essentially
restatements of a single overall fact about the widget's position in the
interface.

So, yes, this is a very unusual use for the word "class". But the
point here is not the keywords being used. The idea is to have the
structure of the GUI reflected clearly in the layout of the code. If
Python's syntax were more flexible, this could perhaps be done in other
ways -- I'm not saying I want that -- but as it is the only real way to
construct nested structures in Python is with class definitions.

You don't mean that ("...only real way...") as broadly as it sounds, do you?

Regards,
Bengt Richter
Jul 18 '05 #97

P: n/a
On Sat, 25 Sep 2004 21:58:02 -0400, Ed Leafe <ed@leafe.com> wrote:
Sorry, but it just doesn't seem explicit to me. Defining a class
doesn't mean instantiating one instance of a class at the place where
the class is defined, but that seems to be exactly what your metaclass
constructor does.
I'm not entirely satisfied with it either, but I'm trying to be
pragmatic and to keep a neutral stance on this. I just thought about a
slightly different approach to the problem; I don't know if I can make
it work, but it may be a good solution.

Imagine if, instead of instantiating the inner classes automatically
when the outer class is declared, the process is deferred until the
outer class is instantiated. In this way, the outer class would still
contain just classes; but the instance would contain only instances.
It's a relatively small change, and it's still different from the
usual class creation stuff, but it's less of a surprise.
I understand that it's an experiment. My question is if the goal of
this experiment is just to do something differently, or if there is an
ultimate benefit that one can hope to gain if the experiment is a
success. I see what you're doing and how it is different; I guess I
still don't see that this is gaining any power or flexibility.


No, it's not just to do something different. I hope to be able to
develop a system that is more readable and more flexible than the
traditional approach. OKB already did a good job of explaining some of
the advantages. I would like to sum it up this way: there is a lot of
information encoded in the way the classes are structured that you
have to spell explicitly with the traditional form. That's a big gain.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #98

P: n/a
On 26 Sep 2004 04:15:57 GMT, Bengt Richter <bo**@oz.net> wrote:
I could see a way to write this in terms of instances. Also playing a trick so that keyword
arg CC=True would return a custom class instead of an instance, for repeated use of a
particular customization:

CustButtton = Button(CC=True, bgcolor='lightgreen', namefmt='cbtn%s', nextnameno=100)
CustistBox = ListBox(CC=True, kind=ListBox.DROPDOWN, width=40, maxdrop=10) # default namefmt is cls.__name__+'%s'

myFrame = (
Frame(
Sizer(
CustButton(size= ... etc),
CustButton(size= ... etc),
Panel(
Sizer(
CustListBox(etc),
CustListBox(etc),
CustButton(etc),
Text( etc )
)
)
)
)
)


It may sound like a silly excuse, but this sequence of closing
parenthesis is as unpythonic as it could be :-) In practice, it does
keep some of the proposed advantages of our little class creation
system. In theory, it's still different, because it's imperative, not
declarative. Is it a big difference? Maybe it doesn't sum up to
anything that big. I really don't know -- I'm still inclined to work
with the class declaration as a better, more concise and consistent
way to do what I want. But I concede that I'm lacking good arguments
-- it's more a 'hunch' than something that I can really argue about.
For now, it's more about "trust me, it will work" than anything
else...

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #99

P: n/a
Bengt Richter wrote:
myFrame = (
Frame(
Sizer(
CustButton(size= ... etc),
CustButton(size= ... etc),
Panel(
Sizer(
CustListBox(etc),
CustListBox(etc),
CustButton(etc),
Text( etc )
)
)
)
)
)


One problem with this is that it's not possible to define methods
on your widgets in this kind of structure.
If Python's syntax were more flexible, this could perhaps be done
in other ways -- I'm not saying I want that -- but as it is the
only real way to construct nested structures in Python is with
class definitions.

You don't mean that ("...only real way...") as broadly as it
sounds, do you?


Sorry, you're right. Obviously dictionaries and lists can be
nested. A key point, though, is the one I mentioned above: classes are
the only structure which allow you define nested structures with
arbitrary in-line code. The "in-line" proviso there may seem obtuse,
but I think it's important. For instance, if you define a button, you
should be able to define the event handler for a click on that button
right there, as part of writing the button code. Having to separate the
event-handling code out into a separate routine leads to
spaghettification, and also introduces a bunch of naming problems (you
need to have a consistent naming convention that links a widget to its
event handler).

(Also, just for the record: I know you can nest function
definitions in other functions, but this isn't useful here because
there's no way to access the nested function definition from outside the
enclosing function, whereas you can reference nested classes with normal
attribute access.)

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
Jul 18 '05 #100

108 Replies

This discussion thread is closed

Replies have been disabled for this discussion.