Re: [Edu-sig] Design Patterns

2005-08-27 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Scott David Daniels
 
> > If I am not violating the Uniform Access Principal how do we express on
> what
> > basis I am not?
> 
> This to me has to do with the set of calls in your API. 

Yes but according to the Uniform Access Principle:

"All services offered by a module should be available through a uniform
notation, which does not betray whether they are implemented through storage
or through computation."

My API is designed exactly and explicitly to betray this. That *is* my API.

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Scott David Daniels


> My strongest reaction has
> to do with your wish to deny me the ability to make another choice

If that is a reference to my opinion about the visibility of the built-in
property function, and its real world impact...

if I thought my opinion had would likely have impact, I would likely think
about it harder ;)

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Scott David Daniels
Arthur wrote:
> I have a line segment - defined as the segment connecting 2 points.  The
> interface allows the points to be picked and moved.
> 
> The line segment has a length.  I choose line.getLength() as my API  
> Am I - in fact - violating the Uniform Access Principal. 
> If I am, am I violating good programming practice?

OK, my take is no -- you are choosing an API.  My strongest reaction has
to do with your wish to deny me the ability to make another choice; API
design is an art, not a science, and not engineering.  The whole API
is what you should evaluate.  I am certain we cannot produce a set of
rules that guarantee a good API, not can we provide rules to avoid a
bad API.

> If I am not violating the Uniform Access Principal how do we express on what
> basis I am not?

This to me has to do with the set of calls in your API.  It is hard to
say with a coordinates and length API, it is easier with something
richer like triangles, rectangles, and polygons.  The length of the
sides of all of those things should show up the same way; either as
attributes or method calls.  Variations between polygons and triangles,
for example, would make me think you are letting your implementation
show through too much.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


[Edu-sig] Design Patterns

2005-08-27 Thread Arthur

>In my MVC example, the Viewer expected a 'shape' object to support a
>specific API:  verts and edges needed to be available as attributes.  

Let me try to practice better what I think I am preaching and follow your
lead in making the discussion more concrete and less theoretical.

I have a line segment - defined as the segment connecting 2 points.  The
interface allows the points to be picked and moved.

The line segment has a length.  I choose line.getLength() as my API which I
feel idiomatically expresses in Python that we are calculating the length as
it happens to be when the call is made.  I could quite easily wrap it in a
property function and have a line.length attribute - but find it less
expressive. 

Am I - in fact - violating the Uniform Access Principal. 

If I am, am I violating good programming practice?

If I am in violation of the UAP principal, but not in violation of good
programming practice - what are the bounds of the UAP principal.  And how do
we teach that?

If I am not violating the Uniform Access Principal how do we express on what
basis I am not?

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]
 
> "Information hiding" means sparing me the details.  In an open source
> world,
> I might be able to see those details if I really cared about them.  In the
> case of a private bank, fat chance.

Yes, we are at the core of some considerable sensitivity in my (other)
world.  And yes, we are touching upon emotion and politics as well as API
design.

Pausch advocates exposing folks to a 3d API that spares the user the need to
understand what "rotate" and "translate" means to everybody else in the
known world working in 3d. 

I disagree, to say the least.

There is not a theory adequate to settle our disagreement.

We end up, as Laura says (I think), only able to make judgment calls as to
what is and what is not appropriate as to what to expose and what not to
expose, depending on what we are trying to accomplish.

Judgment calls are to me a-theoretical.

I think I understand the basic theory - and reserve to the right to do
little more than take it under advisement.

Art  


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Kirby Urner
> Separating these matters in an educational setting is more than
> problematic.
> 
> Art

In an educational setting, I use analogies.  

Think of interacting with a waiter in a restaurant.  Your expectation is you
name the foods and drinks you want, and after a period of time, those items
arrive at your table.  Later still, you pay for it all plus leave a tip.
That's the API.  

But in some restaurants, the waiter is proud to memorize your order, and
writes nothing.  In some, the order is written down, but punched into a
computer and the bill comes as a machine-printed slip.  

In most restaurants, the food is prepared in a kitchen not visible to
customers.  In others, it's prepared right in front of you, behind a
counter, while you watch.

Customers come to restaurants fully expecting to use the waiter API.  But
they may have little insight into the nuts and bolts of how this API is
wired up behind the scenes.

Maybe the waiter is part time.  Maybe the cook lives in Hoboken.  These
details, though real, are "hidden" from the customers (but may come out in
conversation).  Furthermore, the inner workings may change.  A new
computerized checkout device is installed.  Waiters need to be retrained,
but not customers.  The API is the same.

In my MVC example, the Viewer expected a 'shape' object to support a
specific API:  verts and edges needed to be available as attributes.  

class Vpyview(object):
"""
A viewer: view using VPython
"""

def display(self, shape):
self._garbagecollect()
self._showverts(shape.verts)
self._showedges(shape.edges, shape.verts)
time.sleep(.1)

But my Model class (a Triangle) defined neither per se.  The information was
there, but the API was not in accordance with the Viewer's needs.  

Presumably this Viewer is used with other shapes (polyhedra even!) and we
don't want to write exceptional code just around triangles -- that'd get
messy in a hurry.  

My solution, in this case, was to subclass Triangle2 and supply the missing
attributes in the subclass.  

In the case of edges, this was a static list, defined once and for all in
the constructor.  

In the case of verts, I used a property, so that the Viewer could just ask
for verts (not a callable) and so that a triangle could quickly figure
coords (also a property) behind the scenes. 

The upshot:  shape.verts, in the eyes of the viewer, is simply a dictionary
of xyz tuples with vertex label keys.

class Triangle2(BaseTriangle):
"""
Model
"""

...

@property
def coords(self):
return {'A':self._pA, 'B':self._pB, 'C':self._pC}

def _reset(self):
...
self._pA = (0.0, 0.0, 0.0)
self._pB = (a  , 0.0, 0.0)
self._pC = ((a**2 + b**2 - c**2)/(2.0*a),
 math.sqrt((-a+b+c)*(a-b+c)*(a+b-c)*(a+b+c))/(2*a),
 0.0) 

class TriAdapter(Triangle2):
"""
Make a triangle work like a Shape, i.e. add
edges and verts attributes
"""

def __init__(self, a,b,c):
Triangle2.__init__(self, a,b,c)
self.edges = [('A','B'),('B','C'),('C','A')]

@property
def verts(self):
return self.coords

Why allow coords and verts to be properties?  Because these triangles are
themselves mutable and the vertices may change position, even if how they're
connected (the edges) doesn't change.  Could I have gotten by without
properties?  Sure, but the code wouldn't have any easier to read or
understand, or use.  I'd still need to recompute everything when an edge was
resized.
 
This seems a real world enough example to get the point across:  an API is
like a contract, and once it's engrained, you may want to write adapters
rather than tear into working code.  Adapters aren't the same as properties,
but they're another piece of the theory/nomenclature, and their
implementation may *include* using properties.

Another real world example:  you go to a foreign country and the electrical
sockets are different.  Your appliance would work, if only you could plug it
in.  Do we go out and buy wire cutters, strip off the plug and attach a new
one?  No, hardly.  We go out and buy an adapter, or bring one with us (like
I did to Gothenburg).  

OO has adapters too, and properties may be a part of that.

OO is about objects and the analogies are with objects in reality.  Do we
have properties in reality?  You go to a bank and withdraw cash from your
ATM.  You (not you personally, because you know better) may imagine banks
have big vaults full of cash, but actually they've loaned out the deposits
and carry rather little cash.  They may need to borrow from a different bank
to cover your withdrawal.  Do you need to care?  No.  You just want the ATM
API to work as usual.  

"Information hiding" means sparing me the details.  In an open source world,
I might be able to see those details if I really cared about them.  In the
case of a private bank, fat chance. 

"Information hiding"

Re: [Edu-sig] Design Patterns

2005-08-27 Thread Arthur


> -Original Message-
> From: Laura Creighton [mailto:[EMAIL PROTECTED]
> 
> My guess is that you think that properties violate 'Explicit is better
> than implicit.'

Not exactly.

More like I think that it encourages "theory", and I appreciate Python as
a-a-theoretical.

The counter argument is that Python is so a-theoretical as to not be opposed
to the imposition, with it, of any theoretical approach a practitioner might
find appropriate or want to explore.  And properties fit in there somewhere.

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]
> 
> > Kirby seems comfortable in the Meyerist camp.
> >
> 
> I think you might be reading something too sinister into "information
> hiding" and are therefore against it.

I did put a ;) after my comment on information hiding - taking the
opportunity to be a bit glib, and knowing it.

But still to me, OOP theory is just that - theory.  In certain domains, it
may be the best we have - so we go with it.  In other circumstances, every
decision can be purposeful and specific to the problem at hand, and the
actual and concrete can overrule the theoretical.

It's a matter of knowing where one is in a specific circumstance, I guess.

Separating these matters in an educational setting is more than problematic.

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Arthur


> -Original Message-
> From: Laura Creighton [mailto:[EMAIL PROTECTED]


> One nice thing about overwriting __getattr__ and __setattr__ is
> that when you are done you have something that fairly shrieks
> 'black magic here'.  Properties look innocuous. Some people go quite
> nuts with them, and use them whenever possible, as if there was
> something wrong with simple assignment in the first place. 

Yes. Yes.

And in that way can be a bit of a trap to those of us feeling our way.  A
trap I find I fell into a bit.

Which = in essence - is why I thought a discussion of the subject pertinent.

I have disagreed with an aspect of Python design, which in IMO consciously
obscures functions and concepts related to the copying of objects.  Guido
seems to feel strongly that too much visibility here encourages overuse by
novices.

Maybe true. But I think the lesson inherent in "copy" is worth the risk.

IMO, the degree of visibility of properties is a clearer case of this kind
of issue.  Less upside to it.

Art 


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-27 Thread Laura Creighton
In a message of Fri, 26 Aug 2005 18:24:33 EDT, Arthur writes:

>And am hoping he is quite wrong in the assessment that "information hiding"
>is a base requirement for information science. ;) 

He is quite correct, but 'hiddenness' is not an infinite human good,
such as health.  It is quite possible to hide too much.  Whether
'having things work like magic' is a good thing or not is always
a tricky judgement call.

>Kirby seems comfortable in the Meyerist camp.
>
>But I feel my anti-Meyerist sentiments are somehow bound to my pro-Python
>sentiments.  So am having trouble with my Meyerist Python friend's stance
>.
>
>Art

My guess is that you think that properties violate 'Explicit is better 
than implicit.' 

In the example in http://www.python.org/2.2.3/descrintro.html#property
where x is restricted to positive values.

>>> a = C()
>>> a.x = 10
>>> print a.x
10
>>> a.x = -10
>>> print a.x
0 #  I think that Art thinks this is too much magic
>>> a.setx(12)
>>> print a.getx()
12
>>> 

One nice thing about overwriting __getattr__ and __setattr__ is
that when you are done you have something that fairly shrieks
'black magic here'.  Properties look innocuous. Some people go quite
nuts with them, and use them whenever possible, as if there was
something wrong with simple assignment in the first place.   Worst of 
all, they are easy enough to use that all the would-be-Nannies in the 
world can trivially write code to prevent you doing what they think is 
unwise.  This is most irritating when you are wiser -- or more 
imaginative than they are.  

This bit us the other day.  Somebody naively thought that not allowing 
certain variables to be set to zero would be a swell way to avoid 
divide by zero errors.

The problem is that the natural idiom used all over the codebase is:

x = fast-way-to-solve-the-equation-works-most-of-the-time(**argv)
if x is 0: # too bad
 x = do-it-the-hard-and-slow-way(**argv)

He stuck his property in, and all over campus people started getting
weird mysterious errors.  People who tried to debug it and suddenly
found out that _assignment_ 'wasn't working' concluded that
'_Python_ was broken'.  Their mental model of 'how computer languages
work' doesn't include properties.

Laura
___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-26 Thread Kirby Urner
> Kirby seems comfortable in the Meyerist camp.
> 

I think you might be reading something too sinister into "information
hiding" and are therefore against it.

The brutal real world truth is the client wants an API that works today, but
will complain if it doesn't deliver tomorrow, even if specs shift in the
mean time.  A lot of programming arises from this dual use:  freedom to use
now, freedom to change it under the hood later.  

Properties help insert a layer between mutable programmer code and a slick
API that clients like and want to keep using.  It's a matter of keeping a
favorite notation relatively static, thereby insulating users from messy
inner details.  That's *one* meaning of information hiding, and I think a
benign one.

My world assumes you have access to source code.  Information hiding is
relative to something.  If you have no source code at all, then it's all
hidden, and so what's the point of even talking about what's hidden or not?

> But I feel my anti-Meyerist sentiments are somehow bound to my pro-Python
> sentiments.  So am having trouble with my Meyerist Python friend's stance.
> 
> Art

I think you're espousing an open source ethic, but maybe confuse the purpose
of properties with something "information hiding" needn't mean.  It could
just mean a notational integrity that insulates programmers from other
programmers.  It's like wearing business suits or casual dress.  We don't
want to keep adjusting our eyeballs from one freakazoid API to another.
Just give us a uniform integrated control panel please, and do your behind
the scenes work behind the scenes (but let us peek if we get curious).

Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-26 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Scott David Daniels
> 
> This is close to what I meant.  I dislike properties that don't behave
> as if they were attributes.  

Not exactly sure what that means.

Seems there is a lot to this topic.  I get to the fact that there is a
Uniform Access Principle - with some authority behind it.

"""
The Uniform Access Principle, as published in Bertrand Meyer's
Object-Oriented Software Construction, states that "All services offered by
a module should be available through a uniform notation, which does not
betray whether they are implemented through storage or through computation."
It is described further with "Although it may at first appear just to
address a notational issue, the Uniform Access principle is in fact a design
rule which influences many aspects of object-oriented design and the
supporting notation. It follows from the Continuity criterion; you may also
view it as a special case of Information Hiding."
"""

I guess I am intuitively anti-Meyerist. 

And am hoping he is quite wrong in the assessment that "information hiding"
is a base requirement for information science. ;) 

Kirby seems comfortable in the Meyerist camp.

But I feel my anti-Meyerist sentiments are somehow bound to my pro-Python
sentiments.  So am having trouble with my Meyerist Python friend's stance.

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-26 Thread Scott David Daniels
Kirby Urner wrote:
>>So I find that rejecting it as naïve is fundamentally unresponsive.
>>Art
> 
> However in this case I don't think your views were rejected as naïve.  On
> the contrary, your views permeated a sophisticated discussion of use cases,
> and design patterns more generally (s'been a rich thread) plus Scott sort of
> liked your using () to connote dynamism (I didn't).  

This is close to what I meant.  I dislike properties that don't behave
as if they were attributes.  That is, I'd like two accesses to the same
property of a particular object to return the same value until the
object has been "changed," and I don't like read access to a property
to be a "real" change.  There are three exceptions I allow in my
personal aesthetic:

   * debugging code: All's fair for this case.  Properties are
 _golden_ for allowing tracking things into a
 lot of code without changing that code.

   * instrumentation: Measurements can be accumulated about behavior,
  but shouldn't interact with normal operation.

   * performance:Achieving the same results with different
 performance is often the whole point of systems
 programming style programming.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]


> I *enjoy* your exotic other-worldliness.

Other than what, I'm wondering ;)

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Kirby Urner

Hi Andre --

If you scroll back, you'll see I was specifying a triangle object in which
sides a,b,c were passed to a constructor, *and* could be respecified on the
fly, thereby changing the triangle.  A validator made sure the proposed
triangle was legal (triangle inequality not violated).  Other than that,
just go ahead and respecify a,b,c at will:

>>> ok = Triange(3,4,5)
>>> ok  # whatever __repr__
>  
>>> ok.b = 3
>>> ok
>

So it went from right to isosceles just there, thanks to rebinding of side
b.  

However, *only* sides could be respecified in this way.  That was the game.
Think of it as an abcTriangle.  This design has its limitations and
shouldn't always be used.  It's handy when that's what you want.

Angles A,B,C and xyz coordinates pA, pB, pC turned out to be consequent
read-only values, but I decided to make them work like attributes from the
user's point of view.  You could get them, but not set them (directly).

Down the road, I might add scale(), rotate() and translate() methods.  These
would be callables and expect arguments -- except I've already implemented
scale() a different way, using __mul__:

>>> newok = ok * 3
>>> newok



Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread André Roberge
Disclaimer: I haven't followed this thread as closely as I should.

Picking up on a few words from the discussion
(namely "triangle" and "properties").

When I think of a real life triangle, I can describe it
in terms of various "properties", such as: the length of
each of its three sides, its area, the three internal
angles, its perimeter, etc.  Of course, most of these
properties are interdependent.

If I want to refer to a triangle property using the
"dot" notation, I want to write:
triangle.area
triangle.perimeter
triangle.shortest_side
triangle.longest_side
etc.

Now, imaging taking a program similar to "Paint"
and drawing a triangle.
Then change it somewhat (by flipping it, lengthening one
side, etc). [Unlike "paint", our program keeps track of
objects' nodes.]

Suppose I am lengthening one side from 100 horizontal pixels to 120
horizontal pixels (looking at the status bar where such information
is displayed).
When I change one value, others may change too.
When I change one value, I am first and foremost
interested about that particular value ... I don't
want to have to think of what other values
("properties") may need to change.

--- Now, back to computer programming

Python properties make it possible to think of all of an
object's attribute on an equal footing (given an appropriate
design for the class to which the object belong).  Without
properties, I have to distinguish between values that
can be assigned directly and those that must be computed.
Of course, a lot of work has to be done behind the scene
to keep things consistent.

Java's "recommended" way would be to use a set method
for assignment and a get method for retrieval
(with the same required work done behind the scene).

I find Python's properties much more elegant (and simpler
for the end user) than having a whole bunch of get_this()
set_that() to use.

André

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Kirby Urner
> So I don't feel as off topic or off base as perhaps I should.
> 
> Apologies.
> 
> Art

I don't feel you've been off topic or off base at all in this thread (nor
really that much in general).  The considerations you have about properties
were worth raising.

My point is I don't think your contribution was dismissed.  On the contrary,
use cases were presented, e.g. a Triangle with an attributes-only API.  

You've said since that you'd prefer a subtle namespace in which callables
denote "on the fly" computing, whereas non-callables suggest more static or
basic attributes of Triangles.  That's all fine and good, but notice we're
not dismissing your proposal by calling it naïve, let alone off topic.

No, in my case, I've given thought to your preferences, as I would to those
of a peer professional, and then thought "but I like properties and will
continue using them, plus encourage my students to consider using them in
their own code."  That's where I came out.  Different place.  And so it is
among professional programmers.

It's clear to me that you and I have very different world views.  That makes
our discussions more interesting.  I *enjoy* your exotic other-worldliness.
Makes mine more palatable as well.  :-D

Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Kirby Urner
> So I find that rejecting it as naïve is fundamentally unresponsive.
> 
> Art
> 

However in this case I don't think your views were rejected as naïve.  On
the contrary, your views permeated a sophisticated discussion of use cases,
and design patterns more generally (s'been a rich thread) plus Scott sort of
liked your using () to connote dynamism (I didn't).  

The tone was always peer to peer.

And we came out in different places re properties, which is fine.  I'm not
going to change my ways just because of peer group considerations -- I'm not
that feckless.
 
Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Arthur


> -Original Message-
> From: Arthur [mailto:[EMAIL PROTECTED]
> 
> So I find that rejecting it as naïve is fundamentally unresponsive.

Just to add - 

I would feel my approach - no question -  more misplaced most other places.

But think Guido's ability to retain a sense of naivety in the midst of the
highly technical underpinning of his task is largely what makes Python what
it is.

So I don't feel as off topic or off base as perhaps I should.

Apologies.

Art




___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Arthur


> From: Kirby Urner [mailto:[EMAIL PROTECTED]
 
> You're welcome to your opinions.  Sometimes you whine when it seems your
> opinions are taken for what they're worth though, which *sometimes* (not
> all
> the time) ain't much in my book.

We are in agreement.  That is precisely when I whine.

But there are times, in my view, where a naïve view is quite worthy of
expression, provided it is recognized as such.

I believe I both recognize when I am presenting a naïve view, and when such
a view is worthy of expression.

So I find that rejecting it as naïve is fundamentally unresponsive.

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design Patterns

2005-08-25 Thread Kirby Urner

> >I think use cases were described, and demonstrated, in which the property
> >feature made sense, e.g. we wanted an attributes-based API into our
> >triangle object, but sometimes the results were computed on the fly.
> 
> And I notice that without the use of properties, that which is computed on
> the fly is identified as such.  So that properties allow us to have an API
> that which is unrevealing on this matter. I am not excited yet.

Yes, you weren't excited by some other software engineer's design.  But
that's different from not seeing a use case (one would hope).  

I don't want my user to care what's "on the fly" in my triangle.  I want to
use attributes for all read-only properties.  Simple and to the point.

Adding () here and not there just clutters the space with irrelevant detail.
I'll tell my user to look at the source code if said user cares that much
about what's "on the fly."

> Yes, I think I understand. *With* properties we can change our mind after
> our API is set in stone and nobody will notice or need to adjust.
> 

That was another use case, not identical to the first (i.e. the case of just
wanting to use attributes, which could easily have been based on properties
right from the start, i.e. there need be no after thoughts).

> So that properties and their use case encourage us to release less
> revealing API's all the time, to cover ourselves in the event we set 
> our API in stone prematurely.
> 

They help us craft less cluttered and stupid APIs yes.  Your idea to have ()
every so often, because it's on the fly -- I don't want that.  My triangle
is not that dumb 'n ugly, sorry (Python supports more than one aesthetic).

> I don't like properties.
> 

I do.

> And certainly no more so from what I have learned from this attempt at
> getting more clarity about them.
> 
> And like to think my naivety on this kind of matter is a purposeful
> naivety.
> 
> Art

You're welcome to your opinions.  Sometimes you whine when it seems your
opinions are taken for what they're worth though, which *sometimes* (not all
the time) ain't much in my book.

Kirby



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-24 Thread Kirby Urner
> Here's some code, which as yet doesn't actually make use of VPython -- but
> that's where it's going.
> 

And here's where it (the code) went.  

Very minimal, at this point but enough to get VPython actually doing
something with the triangle.  

A student could start with this code and start adding stuff e.g. make it
more colorful, add defaults (e.g. radius), cycle through random triangles in
main() -- using a try loop to catch illegals -- and so on.

Kirby

===

class Vpyview(object):
"""
A viewer: view using VPython
"""

def __init__(self):
self._garbage = []

def display(self, shape):
self._garbagecollect()
self._showverts(shape.verts)
self._showedges(shape.edges, shape.verts)
time.sleep(.1)

def _garbagecollect(self):
for g in self._garbage:
g.visible = 0

def _showedges(self, edges, verts):
for e in edges:
v0 = vector(verts[e[0]])
v1 = vector(verts[e[1]])
edge = cylinder(pos=v0, axis=v1-v0, radius = 0.1)
self._garbage.append(edge)

def _showverts(self, verts):
for v in verts:
v0 = vector(verts[v])
sph = sphere(pos=v0, radius=0.1)
self._garbage.append(sph)

from visual import *
import time

def main():
"""
Main call sequence
"""
thescene = display(title='MVC Demo', center=(0,0,0),
 background=(.5, .5, .5))
thescene.autoscale = 0
theviewer = Vpyview()
theshape = TriAdapter(3,3,3)
pulser = Pulser(theshape, theviewer)
pulser.run()



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-24 Thread Kirby Urner
> I might be a dead horse who is dead wrong, but the issue about how
> properties fit into Python is certainly not straightforward in the least,
> and responding as if it were is grossly unfair - to the question raised.
> 
> Art

I think use cases were described, and demonstrated, in which the property
feature made sense, e.g. we wanted an attributes-based API into our triangle
object, but sometimes the results were computed on the fly.  Martelli shows
this same use case with a rectangle object (Python in a Nutshell, pg. 85).

As for using decorator syntax to define properties, Scott has shown how this
might be done.  However, this approach is entirely optional.

Python coders may flag private attributes and methods with _ and __, with
the latter causing name mangling based on class name:

>>> class Foo(object):
def __hidden(self):
pass

>>> dir(Foo)
['_Foo__hidden'...]



Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-24 Thread Kirby Urner
> -Original Message-
> From: [EMAIL PROTECTED] [mailto:edu-sig-
> [EMAIL PROTECTED] On Behalf Of Chuck Allison
> Sent: Tuesday, August 23, 2005 6:19 PM
> To: Kirby Urner
> Cc: edu-sig@python.org
> Subject: Re: [Edu-sig] Design patterns
> 
> Hello Kirby,
> 
> Thanks for this good input (you too, Scott). My syllabus is at
> http://uvsc.freshsources.com/html/cns_439r.html. I like your point
> about cutesy having its place. I just don't see a way to use what's in
> HFDP as the basis for a programming assignment, but maybe it will come
> after a few days. As a professor, I like having my ducks in a row a
> priori, but that's not happening this first time around. Since I teach
> 3 upper division courses, I'm just a little nervous about having time
> to invent sufficient material. I was just hoping someone had had a
> similar teaching experience I could "borrow" from. All comments
> appreciated. Thanks again.

Hi Chuck --

I don't have HFDP in front if me, but if it does MVC at all, I can imagine
using the Triangle we've been discussing as a model, then adding viewer and
controller objects, making the triangle change in some way (controlling it),
while displaying (viewing it).

Here's some code, which as yet doesn't actually make use of VPython -- but
that's where it's going.  

Note that my viewer expects to work with a 'shape' object, which is supposed
to have attributes verts (a dictionary of labeled vertices) and edges (a
list of vertex pairs, using those labels).  Since my triangle object wasn't
written that way, I subclass a Triangle2 as TriAdapter, solely for the
purpose of making it behave like a shape.

Kirby

===
# uses code already/recently posted to this list for BaseTriangle

class Triangle2(BaseTriangle):
"""
Model
"""

@property
def coords(self):
return {'A':self._pA, 'B':self._pB, 'C':self._pC}

def _reset(self):
a,b,c = self.a, self.b, self.c # for brevity
self.perimeter = a + b + c
s = 0.5 * self.perimeter
self.area = math.sqrt(s * (s - a)*(s - b)*(s - c))
self.A = math.acos((-a**2 + b**2 + c**2)/(2.0*b*c))
self.B = math.acos(( a**2 - b**2 + c**2)/(2.0*a*c))
self.C = math.acos(( a**2 + b**2 - c**2)/(2.0*a*b)) 
self._pA = (0.0, 0.0, 0.0)
self._pB = (a  , 0.0, 0.0)
self._pC = ((a**2 + b**2 - c**2)/(2.0*a),
 math.sqrt((-a+b+c)*(a-b+c)*(a+b-c)*(a+b+c))/(2*a),
 0.0) 

def __mul__(self, scalar):
a = self.a * scalar
b = self.b * scalar
c = self.c * scalar
return self.__class__(a,b,c) 

__rmul__ = __mul__


class TriAdapter(Triangle2):
"""
Make a triangle work like a Shape, i.e. add
edges and verts attributes
"""

def __init__(self, a,b,c):
Triangle2.__init__(self, a,b,c)
self.edges = [('A','B'),('B','C'),('C','A')]

@property
def verts(self):
return self.coords

class Pulser(object):
"""
A controller:  makes a shape bigger in steps, 
then smaller, back to original
"""

def __init__(self, shape, viewer):
self.shape = shape
self.viewer = viewer

def run(self):
for i in range(15):
self.viewer.display(self.shape)
self.shape = self.shape * 1.1
for i in range(16):
self.viewer.display(self.shape)
self.shape = self.shape * (1/1.1)

class Vpyview(object):
"""
A viewer: view using VPython -- very unfinished
"""

def display(self, shape):
self._showverts(shape.verts)
self._showedges(shape.edges)

def _showedges(self, edges):
# stub method
for e in edges:
print e

def _showverts(self, verts):
# stub method
for v in verts:
print v, verts[v]

def main():
"""
Main call sequence -- maybe loop through random 
triangles eventually
"""
theviewer = Vpyview()
theshape = TriAdapter(3,3,3)  
pulser = Pulser(theshape, theviewer)
pulser.run()



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-24 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Scott David Daniels


> Arthur wrote:
> > ... more to my point is the fact that I don't expect my programming
> language
> > to solve the problem of decoupling my API from my code. Because I don't
> > expect it to be a solvable problem.
> 
> I don't know if I'm beating a dead horse, but I don't claim properties
> solves the problem of decoupling an API from its current implementation.
> I do claim it provides another tool to express a properly decoupled
> API.

Yup. You're beating a dead horse.

Everything I can find about properties in Java and C# relate it to
encapsulation and data hiding.

Everything I can find about Python relate that the language does not attempt
to support encapsulation and data hiding in the Java and C# sense.

I might be a dead horse who is dead wrong, but the issue about how
properties fit into Python is certainly not straightforward in the least,
and responding as if it were is grossly unfair - to the question raised.

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Scott David Daniels
Chuck Allison wrote:
> My syllabus is at http://uvsc.freshsources.com/html/cns_439r.html. 
> 
One thing I've always wanted to see if the class is small enough:
 Groups shuffling other group's previous layers, and providing
 feedback (but not grades) to the original group.  It is
 always a shock the first time you see someone else trying to
 use code you thought was clear.  The reason for no grades is
 to eliminate the "grade race gaming" among groups.

A good MVC exercise is a "fairy chess" (e.g. kriegspiel) server
and clients.  A sample sequence of constraints:
(1) single game
(2) single game with observers
(3) game with observers w/o enough info to "cheat" by players.
(4) multi-game server.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Scott David Daniels
Arthur wrote:
> ... more to my point is the fact that I don't expect my programming language
> to solve the problem of decoupling my API from my code. Because I don't
> expect it to be a solvable problem. 

I don't know if I'm beating a dead horse, but I don't claim properties
solves the problem of decoupling an API from its current implementation.
I do claim it provides another tool to express a properly decoupled
API.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Chuck Allison
Hello Kirby,

Thanks for this good input (you too, Scott). My syllabus is at
http://uvsc.freshsources.com/html/cns_439r.html. I like your point
about cutesy having its place. I just don't see a way to use what's in
HFDP as the basis for a programming assignment, but maybe it will come
after a few days. As a professor, I like having my ducks in a row a
priori, but that's not happening this first time around. Since I teach
3 upper division courses, I'm just a little nervous about having time
to invent sufficient material. I was just hoping someone had had a
similar teaching experience I could "borrow" from. All comments
appreciated. Thanks again.


Tuesday, August 23, 2005, 5:29:33 PM, you wrote:


>> -Original Message-
>> From: Chuck Allison [mailto:[EMAIL PROTECTED]
>> Sent: Monday, August 22, 2005 12:43 PM
>> To: Kirby Urner
>> Cc: 'Arthur'; 'Scott David Daniels'; edu-sig@python.org
>> Subject: Re[2]: [Edu-sig] Design patterns
>> 
>> Hello Kirby,
>> 
>> Since this discussion has swerved a little, I'd like to pose a query.
>> I've been using patterns since 1995 and am teaching a course starting
>> Wednesday (a full semester course) on Design Patterns using the Heads
>> First book. My query: do you have any ideas you might proffer for
>> programming assignments? I'd like to give a handful of programming
>> assignments throughout the semester that aren't as short and cutesy
>> as what's in the book. Any ideas would be greatly appreciated!


KU> Hi Chuck --

KU> You could throw out ideas for big projects that Python has gotten used for:
KU> a) air traffic control and 
KU> b) languages training for the military
KU> c) some other example only you know about (like El Fish)

KU> (or are you teaching this as a Java class and just lurk with snake charmers
KU> for ideas -- like I might do in a Ruby conference full of gem smiths).

KU> In case 'a)' there's a backend database to consult, and a Tk canvas object
KU> for showing airplanes along their vectors, converging/diverging from airport
KU> termini.

KU> In case 'b)', Python was glue around the game engine, knitting to a speech
KU> recognizer that'd give feedback as to how a soldier/player was doing using
KU> Arabic in Iraq (e.g. 'game over' if things were going badly -- like if a
KU> cuss word was said).

KU> I draw both of these examples from Pycon in March 2005, though I could have
KU> chosen other examples from EuroPython or OSCON, also events on my calendar
KU> this year.

KU> Probably an important design pattern common to both of these applications is
KU> MVC (model-view-controller).  A key design pattern ideal is loose coupling
KU> without losing coupling i.e. you want to stay connected, but you don't want
KU> to overdo it, in case you want to recombine the various components down the
KU> road.  MVC would let us swap in a different database on the back, and only
KU> have to teach the model about it, while the controllers and outputted views
KU> would go against the same API and use the same markup (or whatever).

KU> That being said, I think cutesy, short (even sexy) programs *are* what's
KU> needed in an intro design patterns course, since it's the *patterns* that
KU> matter, not industrial strength vertical market source code, crufted with
KU> 10,001 years of specific knowledge domain content (like the stuff I do for
KU> RHDS/MDRC -- clinical data around heart procedures, and tons more pattern
KU> language where that came from (not being an MD, I never had to learn much of
KU> it)).

KU> But I haven't seen your syllabus and don't know where in the curriculum your
KU> particular course fits in.  I'm simply extrapolating from my own position,
KU> and our circumstances may not match (e.g. you probably didn't spend most of
KU> the day mixing wood stains and applying them to wood products -- like,
KU> welcome to Oregon/SiliconForest).

KU> Kirby


KU> ___
KU> Edu-sig mailing list
KU> Edu-sig@python.org
KU> http://mail.python.org/mailman/listinfo/edu-sig



-- 
Best regards,
 Chuck

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]

> They're not here to whine about not being mere "math notations" as if that
> would be an improvement.

That's one way to attempt to characterize my point - or Graham's point, for
that matter.  

Except that it of course misses the point. And is a bit obnoxious.

The usual.

My target, if anything, is not Python - but the pressure on it to be more
Java and C# like.

But more to my point is the fact that I don't expect my programming language
to solve the problem of decoupling my API from my code. Because I don't
expect it to be a solvable problem. 
  
Seems to me to make more sense if my programming language provides the
environment for deriving concrete solutions to defined problems.

And project management tools (and human beings interacting with human
beings) manage phase-in and change.

Whatever.

Art



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Kirby Urner

> In his mind, (and I think in yours as well) computer languages are more
> like mathematical notation than a form of technology.  And as such, 
> evolution is slower - not at the pace of the changes in the underlying 
> technology.

However I'm sometimes in the mood to not draw this line between notation and
technology, looking at language as technology, as tools.  And yes, different
technologies evolve at different rates.  Bucky kept saying the lead time
from prototype to mainstream was a key variable, and in electronics might be
about 3 years, whereas in housing it might be at least 10 if not more.  So
he figured housing prototypes in the 1940s might pan out in the 1960s, and
to some extent they did (and didn't).  Plus he kept making prototypes, as
did his students (J. Baldwin and Joe Clinton come to mind).

> 
> Though certainly not uninfluenced by those developments.  The most
> important technological development he seems to point to is the 
> increasing raw power and speed of processors, which allow languages 
> to design away from a preoccupation with performance issues.

However it's also important that, given this opportunity for faster physical
cycling, per the silicon chip computer, software engineers were able to rise
to the occasion and give us VHLLs like Python, i.e. were able to take
advantage of those extra fast cycles and yet still make the language
parsable and machine friendly enough for a CPU (which is ultimately nothing
more than a fast arithmetical/logical unit, no matter how fast it goes).

> He thinks - though without great confidence in his intuition here - that
> Java is an example of a language headed down a dead-end evolutionary path.
> Than so must too be C#.
> 

A language has a half life.  Big expensive systems that aren't broken don't
need to be replaced, only tinkered with, so you have this long aftermarket
for language skills, even when the language itself is "officially" dead.
FORTRAN is a good example.  At the OSCON/Stonehenge party this year, Jeff
Zucker (a Perl saint) and I met up with a FORTRAN guy who to this day works
on optimizing FORTRAN compilers, to run more effectively against today's
chips.  Because lots of big fancy computer models still perform useful
service and make heavy use of FORTRAN.

> Despite having some understanding that it must be annoying to hear
> high-fallutin theory from someone at my level in this domain, I persist.
> 
> And it seems to me that the evolutionary successful language will include
> in its approach clear and concise constraints on its ambitions.
> 

So far you haven't said anything I disagree with.  Just adding emphasis:
software had to meet the integrated chip designers at least half way, and
computer languages aim for a layer in a long term archeology that could
include working bits for centuries, if not millennia -- just as centuries
old math notation still expresses algorithms in useful form today (your
original point).

> If I am understanding "properties" mostly correctly, and in fact their
> reason for being is to allow for a fundamental midstream redesign of a
> program without alteration of that program's API, I am thinking something
> to the effect that it is only possible to do the impossible in half-
> measures, and half-measures are only half-measures and who wants to work 
> in an environment of half-measures.

In Java, you should probably work out ahead of time if you want to use
private variables cloaked in protective getters/setters, so that you might
continue fiddling with the guts indefinitely, even as your users experience
and enjoy a simple attributes-based API that hardly ever changes (like the
front panel on a TV:  channel and volume, yet no tubes inside (not even a
picture tube these days)).

In Python, you have more liberty to wrap what used to be a simple attribute
in a property, and so maybe don't have to hard code so many design decisions
up front.  Java coders may be more likely to practice "defensive
programming" than Python coders and make everything private and
method-protected up front.  This philosophy is manifest throughout the
language (with its private, protected, and public attributes -- whereas in
C++ you also have friends [1]).  Some say Python is a "consenting adults"
language, with permissions by convention vs. enforced by a nanny compiler
(I'm not saying the latter can't be a nice experience also).

> I don't think mathematical notation, for example, includes the concept of
> the half-measure.
> 
> Whatever.
> 
> Art

For me, non-executing math notation needn't be enshrined as the ideal.  So
much about math involves insulating one's self from having to deal with real
world complexity (only to discover it later, one hopes in some manageable
form).  Computer languages ventured off into the wild west and took on
whatever features we needed to do real time accommodation of client wishes.
So I'm not nostalgic for the good old days, before we had computer science.
I don't pine for a "math ru

Re: [Edu-sig] Design patterns

2005-08-23 Thread Kirby Urner


> -Original Message-
> From: Chuck Allison [mailto:[EMAIL PROTECTED]
> Sent: Monday, August 22, 2005 12:43 PM
> To: Kirby Urner
> Cc: 'Arthur'; 'Scott David Daniels'; edu-sig@python.org
> Subject: Re[2]: [Edu-sig] Design patterns
> 
> Hello Kirby,
> 
> Since this discussion has swerved a little, I'd like to pose a query.
> I've been using patterns since 1995 and am teaching a course starting
> Wednesday (a full semester course) on Design Patterns using the Heads
> First book. My query: do you have any ideas you might proffer for
> programming assignments? I'd like to give a handful of programming
> assignments throughout the semester that aren't as short and cutesy
> as what's in the book. Any ideas would be greatly appreciated!


Hi Chuck --

You could throw out ideas for big projects that Python has gotten used for:
a) air traffic control and 
b) languages training for the military
c) some other example only you know about (like El Fish)

(or are you teaching this as a Java class and just lurk with snake charmers
for ideas -- like I might do in a Ruby conference full of gem smiths).

In case 'a)' there's a backend database to consult, and a Tk canvas object
for showing airplanes along their vectors, converging/diverging from airport
termini.

In case 'b)', Python was glue around the game engine, knitting to a speech
recognizer that'd give feedback as to how a soldier/player was doing using
Arabic in Iraq (e.g. 'game over' if things were going badly -- like if a
cuss word was said).

I draw both of these examples from Pycon in March 2005, though I could have
chosen other examples from EuroPython or OSCON, also events on my calendar
this year.

Probably an important design pattern common to both of these applications is
MVC (model-view-controller).  A key design pattern ideal is loose coupling
without losing coupling i.e. you want to stay connected, but you don't want
to overdo it, in case you want to recombine the various components down the
road.  MVC would let us swap in a different database on the back, and only
have to teach the model about it, while the controllers and outputted views
would go against the same API and use the same markup (or whatever).

That being said, I think cutesy, short (even sexy) programs *are* what's
needed in an intro design patterns course, since it's the *patterns* that
matter, not industrial strength vertical market source code, crufted with
10,001 years of specific knowledge domain content (like the stuff I do for
RHDS/MDRC -- clinical data around heart procedures, and tons more pattern
language where that came from (not being an MD, I never had to learn much of
it)).

But I haven't seen your syllabus and don't know where in the curriculum your
particular course fits in.  I'm simply extrapolating from my own position,
and our circumstances may not match (e.g. you probably didn't spend most of
the day mixing wood stains and applying them to wood products -- like,
welcome to Oregon/SiliconForest).

Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread ajsiegel


- Original Message -
From: Scott David Daniels <[EMAIL PROTECTED]>

>  If I wait until I have actual users, I can get
> real statistics on how the use the API.  We decouple our work this 
> way.

But in my look of it, properties are a "solution" to one of a nearly infinite 
set
of these kinds of possibilites. And in that sense a half-measure. Certainly
many areas will remain where our API and our design are irretrievably
coupled.

All I can try to do is offer the perspective of of a mid-brow developer, who 
tries.

Again, in the case of the development of PyGeo -  and willing to refactor 
until the cows come home  - the solutions to problems seemed to be mostly
a process of discovery.  When I found a better way to do something than I had
before, I knew it was better and I knew why it was better. And Python 
as a languagfe and as as disclipline seemed more than cooperative as a partner, 
and guide in the process.

"Properties" being a rare distraction.

Art


 



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Scott David Daniels
Chuck Allison wrote:
> Since this discussion has swerved a little, I'd like to pose a query.
> I've been using patterns since 1995 and am teaching a course starting
> Wednesday (a full semester course) on Design Patterns using the Heads
> First book. My query: do you have any ideas you might proffer for
> programming assignments? I'd like to give a handful of programming
> assignments throughout the semester that aren't as short and cutesy
> as what's in the book. Any ideas would be greatly appreciated!

What subject and to whom?  If programming and/or CS, I'd be tempted
to give a chain of assignments where the requirements swerve, showing
the value of malleability in code design.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-23 Thread Scott David Daniels
Arthur wrote:
> If I am understanding "properties" mostly correctly, and in fact their
> reason for being is to allow for a fundamental midstream redesign of a
> program without alteration of that program's API, I am thinking something to
> the effect that it is only possible to do the impossible in half-measures,
> and half-measures are only half-measures and who wants to work in an
> environment of half-measures.  
> 
> I don't think mathematical notation, for example, includes the concept of
> the half-measure.

OK, how about this explanation.  If I am providing software support to a
group of scientists running experiments, I can give them an API and the
fastest-to-write code that passes tests.  Once I've done that, they can
get to work using the software while I go about the work of making the
software more reasonably designed and responding to efficiency problems
that they actually encounter.  We use the API as a "treaty point" --
they stick to using it, and I stick to providing it.  This structure
can also be used to provide the "for free work-alike" and the "pricey
efficient" versions.

Properties allows me to determine later (perhaps after watching how
they actually use the API) whether I should precalculate the triangle
angles, recalculate them each time, or find an even fancier version
where I compute them each the first time on demand and re-use those
results, invalidating the angles whenever a side is changed.  If I
have to make those design decisions up front, I have to assume a
pattern of use.  If I wait until I have actual users, I can get
real statistics on how the use the API.  We decouple our work this way.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


[Edu-sig] Design patterns

2005-08-23 Thread Arthur
>> I guess.
>> 
>> Though I can't say I find there to be much consensus out there about what
>> language features truly make for robust software development from group
>> or community efforts.  


>There's a long history of coders seeking consensus, but not arriving at any
>set in stone answers (no carved tablets at the Smithsonian), in part
>because the backdrop is always shifting, in terms of languages and
>technologies.  

Interesting to read Paul Graham's article "The Hundred-Year Language" which
- as noted in the article heading - was derived from his keynote at PyCon
2003.

http://www.paulgraham.com/hundred.html

"""
Languages evolve slowly because they're not really technologies. Languages
are notation.
"""

In his mind, (and I think in yours as well) computer languages are more like
mathematical notation than a form of technology.  And as such, evolution is
slower - not at the pace of the changes in the underlying technology. 

Though certainly not uninfluenced by those developments.  The most important
technological development he seems to point to is the increasing raw power
and speed of processors, which allow languages to design away from a
preoccupation with performance issues.

He thinks - though without great confidence in his intuition here - that
Java is an example of a language headed down a dead-end evolutionary path.
Than so must too be C#. 

Despite having some understanding that it must be annoying to hear
high-fallutin theory from someone at my level in this domain, I persist.  

And it seems to me that the evolutionary successful language will include in
its approach clear and concise constraints on its ambitions.

If I am understanding "properties" mostly correctly, and in fact their
reason for being is to allow for a fundamental midstream redesign of a
program without alteration of that program's API, I am thinking something to
the effect that it is only possible to do the impossible in half-measures,
and half-measures are only half-measures and who wants to work in an
environment of half-measures.  

I don't think mathematical notation, for example, includes the concept of
the half-measure.

Whatever.

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-22 Thread Chuck Allison
Hello Kirby,

Since this discussion has swerved a little, I'd like to pose a query.
I've been using patterns since 1995 and am teaching a course starting
Wednesday (a full semester course) on Design Patterns using the Heads
First book. My query: do you have any ideas you might proffer for
programming assignments? I'd like to give a handful of programming
assignments throughout the semester that aren't as short and cutesy
as what's in the book. Any ideas would be greatly appreciated!

Monday, August 22, 2005, 11:08:42 AM, you wrote:

KU> There's a long history of coders seeking consensus, but not arriving at any
KU> set in stone answers (no carved tablets at the Smithsonian), in part because
KU> the backdrop is always shifting, in terms of languages and technologies.

KU> The design patterns movement is the latest chapter in the series, drawing
KU> inspiration from that 'pattern language' book beloved by the architects, and
KU> followed by a big splash by the Gang of Four (an allusion to recent Chinese
KU> political history).  O'Reilly's 'Head First Design Patterns' is one of the
KU> most pedagogically sophisticated in this tradition to date (I'm still
KU> somewhat awed by it, though I've heard others express a wish for still
KU> greater content density): 
KU> http://www.oreilly.com/catalog/hfdesignpat/ 

KU> We had the structured programming revolution, which tossed out the GOTOs,
KU> and the object oriented revolution.  Under the hood, we've been moving to
KU> virtual machine platforms with their own byte code languages.  This paradigm
KU> has taken over at Microsoft and places (i.e. .NET).  Python is one of these
KU> VM languages, as are Java and C# (the latter being system languages, less
KU> agile, yet very necessary, as implementation languages for Python itself
KU> among other things).

-- 
Best regards,
 Chuck

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-22 Thread Kirby Urner
 
> I guess.
> 
> Though I can't say I find there to be much consensus out there about what
> language features truly make for robust software development from group or
> community efforts.  

There's a long history of coders seeking consensus, but not arriving at any
set in stone answers (no carved tablets at the Smithsonian), in part because
the backdrop is always shifting, in terms of languages and technologies.  

The design patterns movement is the latest chapter in the series, drawing
inspiration from that 'pattern language' book beloved by the architects, and
followed by a big splash by the Gang of Four (an allusion to recent Chinese
political history).  O'Reilly's 'Head First Design Patterns' is one of the
most pedagogically sophisticated in this tradition to date (I'm still
somewhat awed by it, though I've heard others express a wish for still
greater content density):  http://www.oreilly.com/catalog/hfdesignpat/ 

We had the structured programming revolution, which tossed out the GOTOs,
and the object oriented revolution.  Under the hood, we've been moving to
virtual machine platforms with their own byte code languages.  This paradigm
has taken over at Microsoft and places (i.e. .NET).  Python is one of these
VM languages, as are Java and C# (the latter being system languages, less
agile, yet very necessary, as implementation languages for Python itself
among other things).

> Python itself can be thought of as a robust community
> effort - in C, which itself probably pre-dates/ignores much of the lessons
> of what is necessary for such effort. Java seems obsessed with these kinds
> of concerns - which is why I do in fact find coding in it as a solo as a
> kind of foolishness.

And now we have IronPython in C#.

C is like clay -- it can be anything you want it to be if you're good at it,
which Guido and friends are (I'm not -- I enter the picture as an xBase
coder, working up the dBase II, III, IV, FoxPro fish ladder (we've always
had an interactive 'dot prompt,' which is why Python's >>> seems so natural
to us (there're other FoxPro geeks out there, bending a Python framework
into a familiar shape (named Dabo), as I learned at Pycon in DC last March
[1]))).  

The object orientation was always there in Python, but user-defined classes
were originally 2nd class citizens.  Getting them to be top level, unifying
types and classes, has been a long haul saga within the Python community.
I'm still a bit hazy myself on how to subclass some of the primitive types.
Where do you store the value?  I appreciated getting a history lesson on
Python's origins and early evolution from Guido himself in Sweden, where he
talked to a packed upper floor room full of mostly newbies (EuroPython had a
friendly newbie track).

> OTOH, I find code readability absolutely satisfying, even without an
> expectation that anyone else will in fact be reading it.
> 
> Whatever.
> 
> Art

I'm glad to hear it, as I do expect PyGeo code will be eyeballed by many
more newbies as time goes on, ready to get their feet wet as strangers in a
strange land.  Your coding style will be an early influence on these little
penguins.

One of the challenges I had @ OSCON was how to talk about Elastic Interval
Geometry (EIG) as inspired by Kenneth Snelson and others, without being off
topic.  Because the best open source EIG apps are written in Java (Springie
and Fluidiom), and the best closed source offering (Alan's SpringDance) is
in Delphi.  My solution:  write the presentation manager itself in Python,
such that at any given moment, even if the slides were showing Java
creations, the screen itself would be Python + Pygame driven (I also went
out over the Internet to demo the Java applets live, but only for a few
minutes).

This strategy worked well IMO (plus I got positive feedback from people in
the audience who came up to me during the rest of the conference).  My code,
though somewhat quirky (look at the weird way I pass parameters -- inside a
parameters object), isn't especially crash prone, does what it's supposed to
do.[2]  I too am an influence, and fortunately just one of many (my stuff
should be part of a balanced diet).

Kirby

[1] http://mybizmo.blogspot.com/2005/03/pycon-2005.html

[2] http://www.4dsolutions.net/ocn/oscon2005.html



___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]
> 
> A lot of these lessons about robust software development come from group
> or
> community efforts.  Some aspects of Python maybe don't much excite you
> because you're primarily a solo coder (as am I much of the time).


I guess.

Though I can't say I find there to be much consensus out there about what
language features truly make for robust software development from group or
community efforts.  Python itself can be thought of as a robust community
effort - in C, which itself probably pre-dates/ignores much of the lessons
of what is necessary for such effort. Java seems obsessed with these kinds
of concerns - which is why I do in fact find coding in it as a solo as a
kind of foolishness. 

OTOH, I find code readability absolutely satisfying, even without an
expectation that anyone else will in fact be reading it.

Whatever.

Art




___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Kirby Urner
> Why do I find this unsatisfying?
> 

I think part of the picture is you're coding for yourself i.e. your APIs are
used internally by your own code.  Refactoring *everything* is always a
possibility.

Suppose you'd already published a Triangle class API and then discovered you
needed more dynamism.  The property feature lets you sneak in some methods
without changing the already-published API and breaking client code.

A lot of these lessons about robust software development come from group or
community efforts.  Some aspects of Python maybe don't much excite you
because you're primarily a solo coder (as am I much of the time).

Kirby


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Kirby Urner
> Though when we add another dimension, all tetras are projectively
> equivalent. Part of why I can't adjust to a focus on a tetra that happens
> to be regular in some way.
> 
> Art
> 

Well, another way of putting it is:  all tetrahedra are the same regular
one, except not because of viewpoints.

Kirby


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Scott David Daniels
Arthur wrote:
> 
> As an API matter, I find myself liking the clue that "()" provides as to
> whether one is accessing something designed be determined dynamically.  

In general I agree with that sentiment.

> I find myself leaning towards the option of making the use of properties go
> away in PyGeo.

If you want to keep anything as properties, I'd keep the ones those
properties with the least dynamic nature.

--Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]
> 
> Good point about all triangles being equivalent given projection.  In
> nailing down the angles, we've inadvertently defined a fourth vertex:  the
> point of view.  Given we're talking four vertices, we should maybe rename
> our class Tetrahedron ;-D.

Good solution - as it leaves open the question as to where is the triangle
and where is the point of view ;)

Though when we add another dimension, all tetras are projectively
equivalent. Part of why I can't adjust to a focus on a tetra that happens to
be regular in some way.

Art




___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Kirby Urner
> PyGeo has a Triangle object, inherited from the Plane object.  It exists
> mostly for drawing purposes, as the portion of the plane enclosed by the
> infinite lines connecting any 3 points.  Since all Triangles are
> projectively equivalent, in the context of PyGeo there is little to be
> gained by saying much of anything about any particular triangle - and
> little
> is.
> 
> 
> Art

Good point about all triangles being equivalent given projection.  In
nailing down the angles, we've inadvertently defined a fourth vertex:  the
point of view.  Given we're talking four vertices, we should maybe rename
our class Tetrahedron ;-D.

A transformation that has no impact on angles, is scaling.  A feature I'd
like to add to the Triangle sub/class is scalability -- using operator
overloading why not?

Here a design question is:  should mytri * 3 change mytri, or should it
return a new object.  My preference is for the latter, since we can always
rebind mytri to the output of __mul__.  Should I also define __div__ while
I'm at it?

class Triangle2(BaseTriangle):

 def _reset(self):
 self.perimeter = self.a + self.b + self.c
 s = 0.5 * self.perimeter
 self.area = math.sqrt(s * (s - self.a)
   *(s - self.b) * (s - self.c))
 self.A = math.acos((-self.a**2 + self.b**2 + self.c**2)
/ (2.0 * self.b * self.c))
 self.B = math.acos((self.a**2 - self.b**2 + self.c**2)
/ (2.0 * self.a * self.c))
 self.C = math.acos((self.a**2 + self.b**2 - self.c**2)
/ (2.0 * self.a * self.b))

 def __mul__(self, scalar):
 a = self.a * scalar
 b = self.b * scalar
 c = self.c * scalar
 return Triangle2(a,b,c)

 __rmul__ = __mul__

>>> reload(trig)

>>> from trig import Triangle2 as Tri
>>> mytri = Tri(3,4,5)
>>> mytri = mytri * 3
>>> mytri.area
54.0
>>> mytri.a
9
>>> math.degrees(mytri.C)
90.0

Other enhancements:

I could add xyz coordinates as read-only, but have translation, rotation and
scale methods (this last already defined) make them change.

Having xyz coordinates will allow me to feed triangle objects to draw
objects, e.g. for output to VPython, POV-Ray, VRML or what-have-we.
 
Kirby


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Arthur


> -Original Message-
> From: Kirby Urner [mailto:[EMAIL PROTECTED]
> A weakness in the above design:  we only check for violations of triangle
> inequality in the constructor, yet allow changes to a,b,c through the API.

Among my list of unsupportable theories is one to the effect that any
attempt to build a truly OOP hierarchy of geometric objects requires one to
get to geometric fundamentals and that requires one to get down to
projective ideas.  Apparently there is in OOP theory a nearly irresolvable
paradox of the relation of the circle to an ellipse in a OOP hierarchy.  But
from a projective point of view they are only the same object, viewed from
different perspectives, i.e. they are projectively equivalent.  So
attempting to distinguish them as different levels of some hierarchy is
bound to be problematic.  It's really a geometric problem disguised as a
programming one. 

IOW, attempting to fit these objects into an OOP hierarchy chain can only be
an attempt to fit a round ellipse into a square circle, or vice versa ;)

PyGeo has a Triangle object, inherited from the Plane object.  It exists
mostly for drawing purposes, as the portion of the plane enclosed by the
infinite lines connecting any 3 points.  Since all Triangles are
projectively equivalent, in the context of PyGeo there is little to be
gained by saying much of anything about any particular triangle - and little
is.


Art 


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Scott David Daniels
> 
> I'd propose two reasons why properties are so successful.
> 
> The first explanation comes from eXtreme Programming.  One big goal of
> XP is to stop wasting time doing "big design up front." 

Then my situation is a bit ironic. What I don't seem to have realized - at
least to my own satisfaction - is some rational scheme for the use of
properties.  They are used - somewhere in the range from haphazardly to
intuitively.  So I am left to refactor working code to give some scheme to
my use of properties.  And since this refactoring is coming at a fairly late
stage of design, I don't feel the same need to leave my XP options open to
the extent that I might had I thought more thoroughly about the use of
properties earlier in the process.  So where I come out on the use of
properties now might not be the same as where I would have come out at some
different point.

Why do I find this unsatisfying? 

As an API matter, I find myself liking the clue that "()" provides as to
whether one is accessing something designed be determined dynamically.  So I
find myself leaning towards the option of making the use of properties go
away in PyGeo.  


Art


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Kirby Urner
Scott:
> def writeprop(viewvar):
>  '''decorator makes a property from access and a write method'''
>  def view(self):
>  return getattr(self, viewvar)
>  def buildprop(writemethod):
>  return property(view, writemethod)
>  return buildprop
> 

Pretty fancy Scott and again, highly worthy of study.  

An element in this design pattern is using a function (writeprop) to build
the decorator function (buildprop) that'll transform the following def (e.g.
def c).

Scott used the same technique when he enhanced my hypertoon program (a
VPython cartoon generator) with decorator syntax.

@f1(args)
def f2:
   pass

uses f1(args) to build a function which then takes f2 as its argument,
rebinding the result to f2, i.e. f2 = (f1(args))(f2), where f1(args) by
itself returns a callable.

In this case, buildprop returns a curried property function (curried in that
the 'view' method is already bound, defined in terms of getattr).

The decorator returns a function the effect of which is equivalent to 'c =
property(view, c)' i.e. c-the-function goes in as buildprop's writemethod
and is rebound to make c a property.

>  @writeprop('_c')
>  def c(self, v):
>  self.check(v, self.a, self.b)
>  self._c = v
>  self._reset()

Here's a similar base triangle class without the decorators:

class BaseTriangle2(object):
 @classmethod
 def check(klass, a, b, c):
 '''Check three lengths for suitability as triangle sides'''
 if a >= b + c:
 raise ValueError, 'Too long: %s >= %s + %s' % (a, b, c)
 if a <= abs(b - c):
 raise ValueError, 'Too short: %s <= abs(%s - %s)' % (a, b,c)

 def __init__(self, a, b, c):
 self.check(a, b, c)
 self._a = a
 self._b = b
 self._c = c
 self._reset()

 def __repr__(self):
 return '%s(%s, %s, %s)' % (self.__class__.__name__,
self.a, self.b, self.c)

 def _reset(self):
 '''Called whenever the sides of the triangle change'''
 pass

 def _seta(self, v):
 self.check(v, self.b, self.c) # fixed typo in original
 self._a = v
 self._reset()
 
 def _setb(self, v):
 self.check(v, self.a, self.c)
 self._b = v
 self._reset()

 def _setc(self, v):
 self.check(v, self.a, self.b)
 self._c = v
 self._reset()

 def _geta(self):  return self._a
 def _getb(self):  return self._b
 def _getc(self):  return self._c

 a = property(_geta, _seta)
 b = property(_getb, _setb)
 c = property(_getc, _setc)

Kirby


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Scott David Daniels
Arthur wrote:
>>What beyond sugar for leaving off a "()" when trying to retrieve a value
>>from a method are we accomplishing by using properties? I have tended to
>>look at properties mostly  an accommodation to those coming from other
>>languages which have something similar, but never as something that was
>>core
>>to Python or a Pythonic approach to things.  Am I missing something
>>fundamental?
> 
> 
> The searching I do on this point only confirms to me that my own confusion
> is well shared - perhaps indicating this to be an area not totally OT for
> this forum.
> 
> Ray Hettinger's "How-To Guide for Descriptors"
> 
> http://users.rcn.com/python/download/Descriptor.htm
> 
> covers properties, but the use case given is extremely unsatisfying -
> essentially offering a situation where a fundamental design change has been
> made to a program in mid-stream, and since properties were used in the
> initial design, the change can be made with little refactoring. 

I'd propose two reasons why properties are so successful.

The first explanation comes from eXtreme Programming.  One big goal of
XP is to stop wasting time doing "big design up front."  I've spent
enough time in companies where long design meetings (months) produced
huge design documents.  The documents themselves had a tendency to look
like everything was nailed down, while not really answering a lot of
questions that had to be solved when writing the code.  The length of
time spent producing the document, and the general unavailability of the
group that wrote it (they typically moved into other committees to write
other design documents), led to an increasingly rigid design that
reflected neither discoveries or innovations from the coders nor changes
in requirements (or at least our understanding of those requirements).
XP can be seen as a reaction to that problem.

The second explanation is much lower level.  In O-O code, there is a
distinction between interface and implementation.  Essentially, the
interface to an object is how the object behaves from a user of that
object's point of view.  The implementation is how that object
accomplishes its behavior.  When you separate these concerns, you
can more likely keep a programs complexity (in the sense of debugging/
extending) from growing exponentially with the number of lines of code.
Properties let you to hide the trade-off between accessing a stored
value and computing it on the fly.  Without properties, the interface
to classes that want to reserve the access/calculate tradeoff must
use the Java-like "getVar" functions to fetch any values that might be
calculated.


 > What would it take to create a @property decorator that allows one
 > to set as well as get? Would we want to?

def writeprop(viewvar):
 '''decorator makes a property from access and a write method'''
 def view(self):
 return getattr(self, viewvar)
 def buildprop(writemethod):
 return property(view, writemethod)
 return buildprop


Triangle as an example:

import math

class BaseTriangle(object):
 @classmethod
 def check(klass, a, b, c):
 '''Check three lengths for suitability as triangle sides'''
 if a >= b + c:
 raise ValueError, 'Too long: %s >= %s + %s' % (a, b, c)
 if a <= abs(b - c):
 raise ValueError, 'Too short: %s <= abs(%s - %s)' % (a, b,c)

 def __init__(self, a, b, c):
 self.check(a, b, c)
 self._a = a
 self._b = b
 self._c = c
 self._reset()

 def __repr__(self):
 return '%s(%s, %s, %s)' % (self.__class__.__name__,
self.a, self.b, self.c)

 def _reset(self):
 '''Called whenever the sides of the triangle change'''
 pass

 @writeprop('_a')
 def a(self, v):
 self.check(v, self.b + self.c)
 self._a = v
 self._reset()

 @writeprop('_b')
 def b(self, v):
 self.check(v, self.a, self.c)
 self._b = v
 self._reset()

 @writeprop('_c')
 def c(self, v):
 self.check(v, self.a, self.b)
 self._c = v
 self._reset()

# One kind of triangle with angles:

class Triangle(BaseTriangle):
 @property
 def perimeter(self):
 return self.a + self.b + self.c

 @property
 def area(self):
 "Heron's Formula"
 s = 0.5 * self.perimeter
 return math.sqrt(s * (s - self.a) * (s - self.b) * (s - self.c))

 @property
 def A(self):
 return math.acos((-self.a**2 + self.b**2 + self.c**2)
  / (2.0 * self.b * self.c))

 @property
 def B(self):
 return math.acos((self.a**2 - self.b**2 + self.c**2)
  / (2.0 * self.a * self.c))
 @property
 def C(self):
 return math.acos((self.a**2 + self.b**2 - self.c**2)
  / (2.0 * self.a * self.b))

# Another kind of triangle with angles:

class Triangle2(BaseTriangle

Re: [Edu-sig] Design patterns

2005-08-21 Thread Kirby Urner
Hi Arthur --

Yes, decorator syntax isn't designed to integrate with properties quite the
same way.  

All a decorator does is run the subsequently defined function f2 through the
f1 in @f1, rebinding f2 to the returned output of f1.  E.g. 'f2 = f1(f2)'
and '@f1; def f2(): pass' amount to the same thing.

The non-decorator version of Triangle, with properties, might be:

>>> import math

>>> class Triangle(object):

 def __init__(self, a,b,c):
 "Construct a triangle"
 if (c >= a + b) or (a >= b + c) or (b >= a + c):
 raise ValueError("Illegal edges: %s/%s/%s" % (a, b, c))
 self.a = a
 self.b = b
 self.c = c

 def getArea(self):
 "Heron's Formula"
 s = 0.5 * (self.a + self.b + self.c)
 return math.sqrt( s * (s - self.a) *
 (s - self.b) * (s - self.c))

 def getA(self):
return math.acos((-self.a**2 + self.b**2 + self.c**2)
 / (2.0 * self.b * self.c))

 def getB(self):
return math.acos((self.a**2 - self.b**2 + self.c**2)
 / (2.0 * self.a * self.c))

 def getC(self):
return math.acos((self.a**2 + self.b**2 - self.c**2)
 / (2.0 * self.a * self.b))

 A = property(getA, doc='Angle A in radians')
 B = property(getB, doc='Angle B in radians')
 C = property(getC, doc='Angle C in radians')
 area = property(getArea, doc="Triangle's area")
 
>>> mytri = Triangle(3,4,5)
>>> math.degrees(mytri.C)
90.0
>>> math.degrees(mytri.A)
36.86989764584402
>>> mytri.area = 6

Traceback (most recent call last):
  File "", line 1, in -toplevel-
mytri.area = 6
AttributeError: can't set attribute

Alex Martelli's example in 'Python in a Nutshell' is similar:  a rectangle's
area is computed on the fly (pg. 85).

Note that defining attributes in this way doesn't mean we only find out an
attribute is really a property much further along in the code (everything is
expressed in one line) -- which was the problem decorators addressed i.e. a
long function def might obscure the fact that we're defining a classmethod
(the older f1 = classmethod(f1) had to come at the end).

>>> help(Triangle) # now get us this useful section in the documentation:

 |  --
 |  Properties defined here:
 |  
 |  A
 |  Angle A in radians
 |  
 |   = getA(self)
 |  
 |  B
 |  Angle B in radians
 |  
 |   = getB(self)
 |  
 |  C
 |  Angle C in radians
 |  
 |   = getC(self)
 |  
 |  area
 |  Triangle's area
 |  
 |   = getArea(self)
 |  Heron's Formula
 |  
 |  --

I think it's fine to call it "syntactic sugar" when we make object
attributes call their associated accessors and mutators behind the scenes.

Conceptually, we're giving the user of the class a simpler API while giving
ourselves as programmers a lot of control over what triggers what.

It's easy to think of angles and area as attributes, even if we don't allow
them to be set except through changes to edges.  Why should we force a user
to remember what's a method and what's not, given edges, angles and area
(could add perimeter too).

A weakness in the above design:  we only check for violations of triangle
inequality in the constructor, yet allow changes to a,b,c through the API.

Kirby 


___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Arthur
> 
> What beyond sugar for leaving off a "()" when trying to retrieve a value
> from a method are we accomplishing by using properties? I have tended to
> look at properties mostly  an accommodation to those coming from other
> languages which have something similar, but never as something that was
> core
> to Python or a Pythonic approach to things.  Am I missing something
> fundamental?

The searching I do on this point only confirms to me that my own confusion
is well shared - perhaps indicating this to be an area not totally OT for
this forum.

Ray Hettinger's "How-To Guide for Descriptors"

http://users.rcn.com/python/download/Descriptor.htm

covers properties, but the use case given is extremely unsatisfying -
essentially offering a situation where a fundamental design change has been
made to a program in mid-stream, and since properties were used in the
initial design, the change can be made with little refactoring. 

Somehow I don't expect a programming language to accommodate the possibility
of a midstream change in a programs design/intentions of the kind cited
here.  New design, and the expectation would be to need to recode to the new
design.  All within bounds, of course. OOP, I think, does try to address
this issue to a reasonable degree. 

But the properties use case in this article is, to my intuition, a stretch
beyond those reasonable bounds.

I can't believe that a language or coding style intended to accommodate the
range of possibilities for the kind of fundamental midstream redesign
referenced in this use case could lead anywhere else but to some kind of
madness.   

The fact is that I do use properties to a limited degree in PyGeo -  the
actual implementation of properties being trivial enough.  Much less trivial
is the why and when.  The brain dead use of properties in PyGeo being
definitely on my list for refactoring.  Just not sure whether I should be
consistent in avoiding them, or consistently using them, or when is which
and which is when.

Art




___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-21 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Scott David Daniels
> 
> Here's how to do the angles in 2.4 w/ properties:
> 
> 



>  @property
>  def A(self):
>   return math.acos((-self.a**2 + self.b**2 + self.c**2)
>/ (2.0 * self.b * self.c))

Hmmm...

We seem to be saying that @property works out-of-the box as a decorator in
2.4 - at least where we want read only properties. 

I can only assume that this is more of a side-effect of the introduction of
decorators, than a feature fully designed into the language. Which is not to
say that it is not a fortunate side effect.

But it is unfortunate combo for me - since I never fully understood the
purpose of properties, and don't fully get the mechanics of decorators.  

My most important points of confusion:

What beyond sugar for leaving off a "()" when trying to retrieve a value
from a method are we accomplishing by using properties? I have tended to
look at properties mostly  an accommodation to those coming from other
languages which have something similar, but never as something that was core
to Python or a Pythonic approach to things.  Am I missing something
fundamental?

and

Am I correct that the use of property as a "built-in" decorator is not
designed into the language  - at least in the same way that @classmethod has
been? What would it take to create a @property decorator that allows one to
set as well as get? Would we want to?


Art



___
Edu-sig mailing list
[EMAIL PROTECTED]
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-19 Thread Kirby Urner
 
> Now you can do:
> 
>  t = Triangle(3,4,5)
>  t.c, math.degrees(t.C)
>  t.a/math.sin(t.A), t.b/math.sin(t.B), t.c/math.sin(t.C)
>  t.b = t.c = 3
>  t.c, math.degrees(t.C)
>  t.a/math.sin(t.A), t.b/math.sin(t.B), t.c/math.sin(t.C)
> 
> This takes advantage of the fact that property with a single parameter
> defines only the "get value" accessor, and makes setting or deleting
> the property illegal.
> 
> -- Scott David Daniels
> [EMAIL PROTECTED]

Totally excellent Scott.  Thank you.

Kirby


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-19 Thread Scott David Daniels
Kirby Urner wrote:
> I’ve been thinking that a good way to introduce program design might involve
> objects of type Triangle, i.e. instances of the Triangle class.

> Anyway, here's a design question:  do we want to compute the angles and
> store them as properties at the time of construction, i.e. in the init?  Or
> do we want to make getAngles() a method?  Compromise:  call _getAngles from
> the init.

Here's how to do the angles in 2.4 w/ properties:


class Triangle(object):

 def __init__(self, a,b,c):
 "Construct a triangle"
 if (c >= a + b) or (a >= b + c) or (b >= a + c):
 raise ValueError("Illegal edges: %s/%s/%s" % (a, b, c))
 self.a = a
 self.b = b
 self.c = c

 def area(self):
 "Heron's Formula"
 s = 0.5 * (self.a + self.b + self.c)
 return math.sqrt( s * (s - self.a) *
 (s - self.b) * (s - self.c))
 @property
 def A(self):
return math.acos((-self.a**2 + self.b**2 + self.c**2)
 / (2.0 * self.b * self.c))
 @property
 def B(self):
return math.acos((self.a**2 - self.b**2 + self.c**2)
 / (2.0 * self.a * self.c))
 @property
 def C(self):
return math.acos((self.a**2 + self.b**2 - self.c**2)
 / (2.0 * self.a * self.b))


Now you can do:

 t = Triangle(3,4,5)
 t.c, math.degrees(t.C)
 t.a/math.sin(t.A), t.b/math.sin(t.B), t.c/math.sin(t.C)
 t.b = t.c = 3
 t.c, math.degrees(t.C)
 t.a/math.sin(t.A), t.b/math.sin(t.B), t.c/math.sin(t.C)

This takes advantage of the fact that property with a single parameter
defines only the "get value" accessor, and makes setting or deleting
the property illegal.

-- Scott David Daniels
[EMAIL PROTECTED]

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


Re: [Edu-sig] Design patterns

2005-08-19 Thread Arthur


> -Original Message-
> From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
> Behalf Of Kirby Urner
> Sent: Friday, August 19, 2005 8:30 PM
> To: edu-sig@python.org
> Subject: [Edu-sig] Design patterns
> 
> Anyway, here's a design question:  do we want to compute the angles and
> store them as properties at the time of construction, i.e. in the init?

PyGeo emphasizes dynamism.  

So on the one hand I am anxious  - for performance reasons - to push as much
processing as I can into __init__. IOW, start-up time for a construction is
much less a concern than the responsiveness when there is change, i.e. when
a point of the construction is picked and moved and all the implications of
that move needs be determined and all elements affected by it redrawn. 

And exactly for the same reason, there are clear constraints as to what I
can in fact put in __init__.  Everything intended to be dynamic needs to be
in methods calculated on the fly.

What I end up with to get decent performance is a patterns of registration.
Part of __init__ for any element is a process with registers it on a chain
of dependencies, so that when a point is in fact picked and moved the point
knows what other elements of the construction depend - directly and
indirectly - on its position and only those elements are recalced and
redrawn.

The moral of the story is, I think, it depends on what in more precise terms
you are trying to do.

The great fun of building PyGeo has been that I always had a pretty clear
idea of what I was trying to do.  Given that, it seemed a process of simply
discovering the way to do it.  That is as opposed to inventing the way to do
it.  The way to do it was pretty much dictated by the intent of the project,
and was more and less sitting there.  I have just needed to find it.

Art


___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig


[Edu-sig] Design patterns

2005-08-19 Thread Kirby Urner
I’ve been thinking that a good way to introduce program design might involve
objects of type Triangle, i.e. instances of the Triangle class.

>>> mytri = Triangle(3,4,5)
>>> mytri.area
6.0
>>> mytri.C
90.0

Now isn’t it true that 3 sides uniquely determine a triangle *except* some
triangles have handedness, and if they're not allowed to flip on the
griddle, you can have two of the same edge lengths (e.g. 3-4-5) that can't
be made to have the same orientation?  We might learn about such asymmetries
by playing Tetris.  The "L" pieces come in two varieties.

Anyway, here's a design question:  do we want to compute the angles and
store them as properties at the time of construction, i.e. in the init?  Or
do we want to make getAngles() a method?  Compromise:  call _getAngles from
the init.

The advantage of always running a method is you always use the a,b and c of
the moment, so if these change e.g. mytri.a = 7, then getAngles() will take
that change into account.  

If angles A,B and C are computed from a, b, c in the constructor and saved
as instance variables, then a subsequent change to b must force a change to
A,B and C, as well as in area and perimeter.  We could do this in more than
one way.  Which way is best?

I think we might go for a class that lets users modify a,b and c as
properties, but doesn't encourage direct access to A,B and C.  Angles are a
result of the sides, but we don't go in the other direction.  Trying to set
mytri.A would raise an exception.  

However, even with sides, we need to patrol for violations of triangular
inequality.  No two lengths are allowed to sum to less than the third
length, and if they exactly equal it, then two of the angles are 0, one is
180, and area is 0.

Here's a version that uses the getAngles() and getArea() approach.  A,B,C
aren't saved as instance variables at all, but as references in a dictionary
that gets returned, but is not saved in the object.  It still needs an
underunder repr.

class Triangle:

def __init__(self, a,b,c):
"Construct a triangle"
if (c > a + b) or (a > b + c) or (b > a + c):
raise Exception("Illegal edges")
self.a = a
self.b = b
self.c = c

def getArea(self):
"Heron's Forumula"
s = 0.5 * (self.a + self.b + self.c)
return math.sqrt( s * (s - self.a) * 
(s - self.b) * (s - self.c) )

def getAngles(self):
a,b,c = self.a, self.b, self.c  # for brevity
angles = {} # empty dictionary
A = math.acos((-a**2 + b**2 + c**2)/(2.0*b*c) )
B = math.acos(( a**2 - b**2 + c**2)/(2.0*a*c) )
C = math.acos(( a**2 + b**2 - c**2)/(2.0*a*b) )
angles['A'] = round(math.degrees(A),5)
angles['B'] = round(math.degrees(B),5)
angles['C'] = round(math.degrees(C),5)
return angles

Kirby


-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.338 / Virus Database: 267.10.13/78 - Release Date: 8/19/2005
 

___
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig