up with PyGUI!

  • Thread starter Zooko O'Whielacronx
  • Start date
O

OKB (not okblacke)

Ed said:
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
 
C

Cameron Laird

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;-).


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 ....
 
E

Ed Leafe

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/
 
C

Carlos Ribeiro

[... ]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: (e-mail address removed)
mail: (e-mail address removed)
 
A

Arthur

_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
 
E

Ed Leafe

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/
 
O

OKB (not okblacke)

Ed said:
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
 
B

Bengt Richter

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
 
C

Carlos Ribeiro

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: (e-mail address removed)
mail: (e-mail address removed)
 
C

Carlos Ribeiro

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: (e-mail address removed)
mail: (e-mail address removed)
 
O

OKB (not okblacke)

Bengt said:
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.
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
 
E

Ed Leafe

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.

Forgive me if this is an oversimplification, but it looks like what
you want is an XML-based definition of your UI objects, and are trying
to approximate that with Python syntax. What you've written looks an
awful lot like an XRC file structure, albeit without the closing tags.

In Dabo, our first attempt at creating a visual form designer was
along the lines of PythonCard: place controls on their container, and
resize/move them visually. Once we started to tackle nested containers,
though, we abandoned that approach for the reasons you cited: it's
simply too confusing to see what goes where. We are now working on
adapting wxGlade to use Dabo classes, as that visually shows the
nesting in a clear an unambiguous tree. Dabo would then know how to
create the form from the XML, or, in the alternative, we would create
Dabo code that the developer could then modify. The latter seems like
it would have to be a one-way process, while keeping things in XML
could allow for two-way editing.

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

Carlos Ribeiro

Forgive me if this is an oversimplification, but it looks like what
you want is an XML-based definition of your UI objects, and are trying
to approximate that with Python syntax. What you've written looks an
awful lot like an XRC file structure, albeit without the closing tags.

Here we go -- Sunday morning, coding and discussing...

I'm avoiding a data-driven approach (XML) because I think that keeping
all declarations in Python will make my code easy to work with in the
long run. I've tried some XML based tools, but found the process to be
too convoluted -- it needs another set of tools and skills, and it
means that I need to be able to read yet another completely different
syntax. Also, I'm trying to avoid visual GUI designers at this point
-- I realized that I simply lose to much time futzing with pixel
alignment details, and that I'm better investing my time doing other
stuff. I've read a comment in the Wing IDE website that puts it very
well:

http://wingware.com/doc/howtos/wxpython
"""
A Caveat: Because Python lends itself so well to writing data-driven
code, you may want to reconsider using a GUI builder for some tasks.
In many cases, Python's introspection features make it possible to
write generic GUI code that you can use to build user interfaces on
the fly based on models of your data and your application. This can be
much more efficient than using a GUI builder to craft individual menus
and dialogs by hand. In general hand-coded GUIs also tend to be more
maintainable.
"""

(It's interesting to note that although Wing folks talk about
"data-drive code", it really applies very well to the declarative
approach)


But while interesting, all this discussion is just revolving around a
few points. I think that we agree on more things than we disagree. We
mostly disagree with the (ab)use of Python as a tool to declare
complex nested elements. I don't think this is a real problem, and I
think that Python can add enough power to the declarations as to make
them more flexible than it's possible using XML or other similar data
format. It's easy to write small blocks of reusable declarations in
Python, and it's easy to mix code and static data on the declarations.
This is more difficult with a XML approach. For example:

class Username(EditBox):
label = _('User name')
size = 12

class UserForm(Form):
class username(Username):
datalink = userfield
class password(EditBox):
label = _('Password')
size = 12
datalink = password
password = True

In the example above, I'm using two features:

1) It's possible to call functions in the middle of the declaration.
In the example, the _() call it's a shorthand convention for gettext()
internationalization code. I like the way it's presented in the class
declaration. It's visible and easily editable.

2) The Username class is declared outside of the form. In this way it
can be used for several form declarations. It's harder to do the same
for individual elements of design with XML. Also, the use of
inheritance makes it clear that some of the parameters can be
individually overriden on each form.

As a side note, the fact that many classes are nested makes easier to
manage the namespace. It's something that we also get for free with
this design.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: (e-mail address removed)
mail: (e-mail address removed)
 
S

Steve Holden

Alex Martelli wrote:
[...]
Basically, easily transportable/tradable goods and services tend to have
more similar prices across different economies -- not considering
absurdly high and punitive tariffs that distort things (generally
raising the prices of clothing here, of cameras in India, etc), a shirt
or a camera should cost the same here and there. Goods and most
particularly services that _aren't_ easily transportable and tradable
are quite a different story; my barber charges me ten times as much as a
Mumbai barber would, taking advantage of the cost and inconvenience it
would be for me to have my head sent to Mumbai for hairstyling...:).
In actual fact what tends to happen is that manufacturers in the wealthy
countries outsource their production to the developing economies and
continue to charge inflated prices in international markets. This is
why, for example, Nike are able to charge $125 in the US for a pair of
trainers that cost them $6 to make under sweatshop conditions in
Malaysia and similarly developing countries.

This is, of course, appreciated by the stockholders in the
multinationals, who see huge profits with greatly-reduced obligations to
support the people who provide the labor.

Microsoft have, if rumor is to be believed, even gone so far as to
outsource their HR department, surely the ultimate irony.

Much of my information on this comes from "No Logo" by Naomi Klein (see
http://www.amazon.com/exec/obidos/tg/detail/-/0312421435/102-9401572-5848961?v=glance),
and I blogged about this in relation to software production in "How Much
Profit is enough?" in
(http://www.artima.com/weblogs/viewpost.jsp?thread=5870

with a mixed reaction of responses.
[...]
Personally, I think there will be _some_ modest reduction of
differences, and movements back and forth, if legal barriers can be
lowered a bit (I don't consider that lowering a certainty), but, judging
from these historical examples, I don't think it will reduce diffences
by ALL that much...
My own personal history involved growing up in the 1950's in a city with
a large immigrant population, mostly from Pakistan and the West Indies,
who had responded to advertising placed in their local papers by
Bradford City employers: the economy was booming, and the indigenous
population could earn far better money than was offered by the jobs the
immigrants took, frequently working in mills or on the buses.

Of course twenty years later the booming textile economy had been
overtaken by the globalization that was inevitable. As is currently
happening in the USA, much of the foreign expansion of competitive
economies was fueled by British capital migrating to countries with a
lower cost of labor, resulting in higher return on capital employed.

Of course the response of (some of) the Bradford population was to
complain along the lines of "they come here and take our jobs", quite
happily ignoring that immigrants had been almost begged to take the
lower-paid jobs that were going begging. Of course by the time the
industry that provided those jobs had faded away the immigrants were in
a much better position to compete across the board for employment, and
were frequently better-motivated (being the sort of people who were
prepared, like myself, to relocate across the globe) to compete for the
remaining jobs.

The racist British National Party found this an ideal situation to
attempt to exploit, with famous consequences in certain hotbeds of
racism. Overall, I am happy to say, the British population seems to
reject such racism as nonsensical.

The laughable thing is that, in general, the American population is
delighted to support outsourcing as long as it leads to a lower cost of
capital acquisition. It's only when the inevitable consequences (chief
among which is a less-globally-competitive American economy) that they
start to whinge and moan.

I think it's to Bush's discredit that the pretends to support a
globalized economy while still attempting to promote protectionism, and
it's to Kerry's discredit that he promotes protectionism by suggesting
tax incentives for companies that don't outsource.

People vote with their wallets, unfortunately without a sufficient
appreciation for the long-term consequences. But then that's the way
they reproduce too, so we shouldn't expect too much of a fundamentally
flawed lifeform. In two hundred years we will have drowned in our own shit!

regards
Steve
 
S

Steve Holden

Arthur wrote:

[...]
And the impact of the the energy of this brew is then labeled a new
imperialism.
Well, it's probably something to do with the way that arms are used to
promote the economic imperative when monetary incentives fail.

regards
St=eve
 
O

OKB (not okblacke)

Ed said:
Forgive me if this is an oversimplification, but it looks like
what
you want is an XML-based definition of your UI objects, and are
trying to approximate that with Python syntax.

You're partially right, I suppose, in that the usual structure of
XML is more like this than the usual structure of Python code. As
Carlos mentioned, however, an important point (which I neglected to
explicitly put into my example) is that if you're doing it in Python you
can include actual Python code in the GUI definition. I admit there's a
certain attraction to totally separating the layout from the code by
using XML (or whatever) to define the layout and then linking it up with
Python code, but on the other hand it's confusing to have a button
defined someplace and have what it does defined in a completely
different place.

--
--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
 
B

Bengt Richter

One problem with this is that it's not possible to define methods
on your widgets in this kind of structure.
^^-- I take it you mean within...
Hm, yes. Need a full lambda or "anonymous def" to do that inline. At least
for non-trivial methods. Wasn't thinking about that. Hm, "not possible" pushes
a button somewhere deep in my psyche though. I guess it's the occasional reward of
discovery that keeps the circuit alive ;-) Not sure ... ;-)
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).
whatever = factory("""
any source format you like # ;-)
""")
Not entirely kidding.
(Also, just for the record: I know you can nest function
definitions in other functions, but this isn't useful here because
I was going to chase down that rabbit trail a bit ;-)
there's no way to access the nested function definition from outside the
There you go again, pushing the "no way" button ;-)
enclosing function, whereas you can reference nested classes with normal
attribute access.)

The trouble with accessing nested functions is there's no unboxed way to mutate
closure variables, otherwise I think you could get around the "no way" building
on something like
... def foo(*a,**k): print 'foo here with', args, a, k
... def bar(*a,**k): print 'bar here with', args, a, k
... def accessnest(self, name, *args, **kw):
... return getattr(self, name)(*args, **kw)
... accessnest.foo = foo
... accessnest.bar = bar
... accessnest.__dict__.update(kw)
... return accessnest.__get__(accessnest)
... 246

Not that this is crisp and clean and lean as a way of expressing design intent ;-)

Regards,
Bengt Richter
 
C

Christophe Cavalaria

Carlos said:
Here we go -- Sunday morning, coding and discussing...

I'm avoiding a data-driven approach (XML) because I think that keeping
all declarations in Python will make my code easy to work with in the
long run. I've tried some XML based tools, but found the process to be
too convoluted -- it needs another set of tools and skills, and it
means that I need to be able to read yet another completely different
syntax. Also, I'm trying to avoid visual GUI designers at this point

Did you check that new project :
http://techgame.net/projects/Framework/wiki/
-- I realized that I simply lose to much time futzing with pixel
alignment details, and that I'm better investing my time doing other
stuff.

That's why I like QtDesigner. The think lets you place as you want the
controls on the form, but you are encouraged to always group the controls
and to never relly on pixel placement. And it is really easy to use once
you know how.
 
G

Greg Ewing

Peter said:
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>

The idea was to be able to specify attributes of the
widget using a suite of assignments instead of a function
call. Not a big difference, but it would tidy things up
a bit and avoid those awkward dangling parentheses that
you get with the above style.

My example was a little off target, btw. It should
have been more like

class MyWindow(Window):

def __init__(self):

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

i.e. the created objects are to be attributes of
*instances* of MyWindow, not its class.
 
C

Carlos Ribeiro

class MyWindow(Window):

def __init__(self):

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

Greg,

I don't know how far have you advanced with your own system. I'm
writing my own, but I decided to focus on HTML generation -- it's a
templating system, but designed to work entirely in Python. But the
basic design can be used for other types of application - for example,
generation of Qt or wxPython code.

I've posted some code last week, but I have improved greatly since,
and solved some problems. There are a few issues where I still haven't
found a satisfactory solution. Here's a sample of code I'm working
with:

class Page(HtmlPage):
class html_head(HtmlHeader):
copyright = trimdocstring("""
Web Application Framework
ABCD/TS - Abusing Class Declarations Templating System
(c) 2004 Carlos Ribeiro
(e-mail address removed)
""")
title = 'Web Application Framework'
style = CSSStyleSheet
class html_body(HtmlBlock, Tag('body')):
class main_document(TwoColumnLayout):
class head(PageHeader):
title = ''
class nav(NavigationPane):
class menu(HtmlMenu)
id = 'navmenu'
options = [("Usuários", "/usuarios"),
("Tarefas", "/tarefas"),
("Notas fiscais", "/notasfiscais"),
("Estoque", "/estoque"),
("Sobre o sistema", "/sobre"),
])
class content(DocumentPane):
text = ''

class AboutPage(Page):
class html_head(Page.html_head):
title = 'About this system'
class html_body(Page.html_body):
title = 'About this system'
class main_document(Page.html_body.main_document):
class content(Page.html_body.main_document.content):
text = trimdocstring("""
<h2>Templating system</h2>
<p>
This is a templating system based on Python
declarations. The main
advantage is the possibility to express complex
data structures using
code-driven intelligence. The system is fully
object-oriented, supports
inheritance, and allows for easy modularization
and code reuse.
</p>
""")

All interesting classes shown above are descendants from a single
HtmlElement class, which declares a method 'text'. The following
sequence renders the AboutPage:

AboutPage().text()

One thing that still bothers me is that I need to redeclare the full
path to the nested classes when I want to override some behavior, as
in:

.... class content(Page.html_body.main_document.content):

That was the best solution that I could find. I tried to use
descriptors to write this code in a slightly simpler way, but couldn't
manage to make them work as wanted, and I'm not even sure if it's
possible.

The resulting html code is being designed for *readability* first, and
is properly indented, which makes easier to debug the system at this
stage. I'm keeping good distance of premature optimization at this
point. It's my intention, in the future, to provide a way to generate
native applications from the same templates, within a 'browser-like'
environment but using native controls for data editing whenever
possible.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: (e-mail address removed)
mail: (e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top