Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Ed Singleton
On 25/11/05, Alan Gauld <[EMAIL PROTECTED]> wrote:
> > Just had a quick look at Smalltalk, and at first glance the overview
> > of the ideas behind it seems amazing, but the language seems quite
> > ugly, and it seems to be very IDE led.
>
> Adherents will defend its simplicity but I confess I strugglred for
> a long time with SmallTalk before learning to love it :-) And yes
> it is IDE led although the IDE can be 'removed' when deploying
> applications. But much depends on the implementation, my favourite
> for PCs is Dolphin SmallTalk from ObjectArts. Its not a traditional
> SmallTalk (ala Xerox SmallTalk 80) but very much one for the '90's

I'm definitely going to investigate it further, as it does seem
interesting, but I remember the first time I looked into Python, I
read the tutorial and was quite bemused as it didn't seem like I'd
learned anything.  It was all so obvious that I didn't feel there was
anything to learn.

As it was I was able to very quickly plunge much deeper and end up
asking lots of difficult questions that in any other language you
wouldn't approach for many years.

> > This immediately seemed to me to be a case for classes.
> > You provide a way for a user to create a new class by
> > subclassing the page class (from their point of view
> > probably through adding a few new fields to
> > a form).
>
> That might be part of the problem, if you think of a class in terms
> of its data attributes then that is nearly always the wrong starting
> point. Classes express behaviour, the data is only there to support
> the behaviour. Thats why methods are polymorphic but not attributes.

If classes express behaviour, then what expresses the structure of the
data?  (ie what attributes there are going to be and what values they
are likely to accept).

You need (the option of) a data definition in order to generalise. 
Using my web server example from earlier, you need to be able to say
that for any type of page, whatever it's attributes, you can create a
web form to search for that type of page by iterating through it's
attributes and creating a relevant form field for each type.

> So you think of a class having an interface and users extending
> or modifying the behaviour, not the data. If you follow that route
> you might find you don't need to write self modifying code,
> you simply load new classes with a common interface into an
> existing hook structure.

I definitely had the opposite in mind.  The behaviours of all the
classes would be the same (and would be fairly simple, a method for
rendering the page with a template, a method to update the data based
on a form submission).  Users would basically be able to change the
data structure (add and remove attributes).

> > However it doesn't really seem that Python is suited to this.  Indeed
> > it doesn't really seem that Python is suited to a persistent
> > environment.
>
> What makes you think that? Most persistent environments
> (ie long running server processs) are written in C/C++ (or
> maybe Java nowadays) which are far less dynamic than Python.

I'm sure Python is quite possibly the least worst at this, but that
doesn't make it good at it.

> > Having a program running for a long time (months) is
> > possible certainly, but it seems to be fighting against the language
>
> Not at all, at least no more than in languages like C which require
> recoding, recompiling, stopping and then restarting the server to
> make changes. Thats why a simple framework with loadable
> modules it usally preferred to self modifying code!

Again, I'm sure it is better than C, but I definitely have had the
feeling that this is not something the language was designed for, and
that not many other people seem to be trying it.

Ed
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] files - strings - lists

2005-11-26 Thread Kent Johnson


Andrzej Kolinski wrote:
> 
>   OK, I made some progress I think. I added a few lines to Kent's script 
> to get closer what I really am after:

Congratulations! See some notes below.

> 
> ==
> lines = open('liga050926.sbk')   # to get the data from a real file
> 
> #lines = iter(data)  # getting data from a string, you don't need this 
> when reading a file
> 
> lines.next()# skip two headers
> lines.next()
> 
> header = lines.next().split()
> hands = int(header[2])
> rounds = int(header[3])
> boards = hands*rounds
> 
> lines.next()
> 
> 
> allScores = {}  # accumulate scores into a dictionary whose key is the name
> 
> # Now we can process the names and scores in a loop
> try:# you don't say how you know the end of the names, I just run to 
> the end of data
> while True:
> names = lines.next().strip()
> player1 = names.split()[0]
> player2 = names.split()[2]

This could be
   names = lines.next().strip().split()
   player1 = names[0]
   player2 = names[2]
or even
   player1, player2 = lines.next().strip().split(' - ')
>
> lines.next()# skip line after name
> scores = [ int(lines.next().split()[2]) for i in range(rounds) ]
> tScores = 0
> for i in scores:
> iScore = float(i)
> tScores = tScores + iScore

This could be
 tScores = float(sum(scores))
> 
> allScores[player1] = tScores/boards
> allScores[player2] = tScores/boards
>
> except: # no more lines
> if lines.next() == '1,1':
> pass

I'm not sure what the two lines above are doing? It looks like you don't have a 
good way to detect the end of the data and you just catch some exception...you 
should figure out a clean way to exit the loop. Maybe when you read the names 
line you can look for '1,1' and break out of the loop, if that is what always 
follows the data you care about.

>
> for player1, tScores in allScores.items():
> print player1, tScores
> =
> 1.I singled out the players names.
> 2.I added the players scores and divided by the number of boards 
> played.
> 3.The output contents is what I wanted:
> 
> Chrabalowski 0.875
> Kowalski -0.
> Kolinski 1.2916667
> Bohossian 1.2916667
> Stankiewicz -1.167
> Cwir -0.7083 ...
> 
> 4.The next step for me would be to read the data from more, 
> similar files (from 2 to 10) representing different games and generate 
> an average score for each participating player (a player does not 
> necessary plays each game and I would eventually like to calculate 
> averages of best six out of maximum ten games). Tough! How should I 
> start this next step? (I would like to keep both options open:
> final ranking = (all tScores)/all boards), or
> final ranking = average(RScores/boards, RScores/boards, 
> RScores/boards, ...)
> game1   
>  game2game3)

I would save more data for each player. Instead of just keeping the average for 
the player, I would keep a list of pairs of (tScore, boards) for each game. 
Instead of 
 allScores[player1] = tScores/boards
you could say
 playerScores = allScores.get(player1, [])
 playerScores.append( (tScores, boards) )
 allScores[player1] = playerScores

all of which can be written more tersely (and obscurely) as
 allScores.setdefault(player1, []).append( (tScores, boards) )

Of course you need a loop to read all the files and you will initialize 
allScores before the loop. Then when you finish with the files you can retrieve 
the players' stats and process them either way you want.

BTW what game is this? It seems odd that both players get the same score.

> 
> Thanks Kent, Chris and Danny. After many, many months of using or 
> modifying (and using) existing scripts, with your invaluable help I feel 
> I can write script that is original and extremely useful to me!

Glad to hear it!

Kent


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Kent Johnson
Ed Singleton wrote:
>>>This immediately seemed to me to be a case for classes.
>>>You provide a way for a user to create a new class by
>>>subclassing the page class (from their point of view
>>>probably through adding a few new fields to
>>>a form).
> 
> The behaviours of all the
> classes would be the same (and would be fairly simple, a method for
> rendering the page with a template, a method to update the data based
> on a form submission).  Users would basically be able to change the
> data structure (add and remove attributes).

It seems to me that rather than having a new class for each type of data, you 
need a class whose attributes are dynamic. I imagine you could have a list of 
page types, each of which has a list of attributes. A new page type is created 
not by defining a new class but by making a new entry in the types table. The 
data for a page might be as simple as just a dict, or maybe it makes sense to 
wrap it in a class, but the class would be the same for all pages. A page would 
be rendered by combining a template with the dict containing its data. Form 
submissions would be handled by referring to the list of attributes for the 
type and extracting the corresponding data.

You might have a class to wrap the page data and another one to wrap the types 
table. These would provide operations on the contained data and be common to 
all types.

For persistence you could take a couple of approaches. You could persist the 
lists and dicts directly using pickle or shelve or an object database. You 
could persist them in a relational database by using a generic table with one 
row for each data item - the columns would simply be object id, column name and 
data. SQLite might work very well for this as it allows multiple data types 
within a single column.

The shift is from looking at the problem as one of dynamic classes, to one of 
dynamic data. Python is excellent for working with dynamic data!

BTW have you looked at Django? I don't think it is quite as dynamic as you want 
on the model side but it has a lot of support for quickly generating a 
presentation of a changing model.
http://www.djangoproject.com/

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Alan Gauld
>> point. Classes express behaviour, the data is only there to support
>> the behaviour. Thats why methods are polymorphic but not attributes.
>
>If classes express behaviour, then what expresses the structure of the
> data?  

Why do you care? If the program behaves as you expect it what does 
it matter what data it uses or how. That should be hidden from you 
inside the classes. Worrying about data is a feature of traditional 
Information Modelling/Structured Analysis style programming, 
OOP is all about inter-communicating objects sending messages to 
each other, each requesting and providing services to the others.

> (ie what attributes there are going to be and what values they
> are likely to accept).

You need to think about the objects that you pass around as part 
of the messages, but those obnjects are in turn accessed via messages 
so their structure is not important. What does matter is the 
relationships between the objects, and they are related by message 
paths not fixed data relationships. This switch in thinking is the 
fundamental difference between traditional and OOP design.

> You need (the option of) a data definition in order to generalise. 

No, you need the ability to modify behaviour.
Most traditional programmers think in terms of modifying 
behaviour in terms of big if/elif trees

if obj.type == sometype
doSomeTypeThing()
elif obj.type == another
doAnotherTypeTHing
etc...

Whereas in OOP you simply say

obj.doThing()

And the right kind of doThing will happen because obj 
knows how to respond to that message in the appropriate way.

> Using my web server example from earlier, you need to be able to say
> that for any type of page, whatever it's attributes, you can create a
> web form to search for that type of page by iterating through it's
> attributes and creating a relevant form field for each type.

So you want, for a given page to create a Form and search.

But that's behaviour of the Page, just let it create its own form
and do its own searches, not your problem. Create the right 
kind of Page and it will do the work for you...

> I definitely had the opposite in mind.  The behaviours of all the
> classes would be the same (and would be fairly simple, a method for
> rendering the page with a template, a method to update the data based
> on a form submission).  

Thats fair enough and the parent Page class would do just that, 
but the template class would have methods that the Page called, 
and you can subclass or data drive the templates to return the 
appropriate strings to the page. (Since web pages after all are 
just collections of strings - or evenone big string...)

> Users would basically be able to change the
> data structure (add and remove attributes).

So maybe attributes are objects too? Maybe you page needs 
to know how to handle attributes and you can create pages by 
adding attributes from a pick list, each attribute knowing how 
to render itself and how to respond to searches?

There are lots of ways to address this is we think of the world 
in terms of intercommunicating objects not static data structures 
with a few overeaching functions controlling it all.

> I'm sure Python is quite possibly the least worst at this, but that
> doesn't make it good at it.

Which brings me back to my original question, what environment 
do you think is good at it? Are you aware of such an environment 
or merely wishing that such a thing could be invented?

> Again, I'm sure it is better than C, but I definitely have had the
> feeling that this is not something the language was designed for, 
> and that not many other people seem to be trying it.

The language is a general purpose language like C and as such is 
designed to cover that type of operation, however the reason it's 
not generally used for long running server processes is the same 
reason that most of these are written in C: speed and resource usage.

Server processes are usually required to run in the background, 
getting in the way as little as possible (think print spoolers), or to 
serve large numbers of clients requesting services(think databases)
In the first case they need to consume as few resources as possible 
and in the latter they need to be low resource and very high speed.

Because python is interpreted it tends to be a lot slower than C 
and because it needs the interpreter to be loaded in memory its 
also quite hih resource usage, so in that sense its not ideal for 
server or daemoin usage, but the language itself is as good as 
any other if speed/resources are not the key issues.

Alan G
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Object-oriented design process

2005-11-26 Thread Kent Johnson
Alan Gauld wrote:
> That might be part of the problem, if you think of a class in terms 
> of its data attributes then that is nearly always the wrong starting 
> point. Classes express behaviour, the data is only there to support 
> the behaviour. Thats why methods are polymorphic but not attributes.
> 
> So you think of a class having an interface and users extending 
> or modifying the behaviour, not the data. If you follow that route
> you might find you don't need to write self modifying code, 
> you simply load new classes with a common interface into an 
> existing hook structure.

I think of a class in terms of data attributes *and* behaviour. To me they are 
inseparable. To the client of the class, it is the behaviour that is important, 
but inside the class and when designing / discovering classes, I tend to look 
at what data I need to represent and solve a problem and what operations I need 
on that data and look for ways to group them together into cohesive classes.

Alan, you and I have very different approaches to OO design and I don't mean to 
say my way is right, just an alternative!

I tend to design from the bottom up - not exclusively, but in general I make 
small parts and combine them to make larger parts until I have something that 
does what I want. I refactor constantly as my understanding of a problem and 
the solution increase. This way I always have complete working code for some 
section of the problem. I rarely use stubs of any kind.

To start I will take some small section of the problem and think about what 
kind of data and operations on the data I need to solve it. For a very simple 
problem I might just write some functions to operate on the data. As I expand 
into larger parts of the problem I might find that several functions are 
operating on the same data and decide that they belong in a class. Or it might 
be clear from the start that I want to create a class around the data.

When one chunk is done to my satisfaction, I take on another, and another. I am 
creating building blocks, then using the building blocks to create larger 
blocks. Some of the blocks are classes, others are functions.

I write unit tests as I go, sometimes test-first, sometimes test-after, but 
always alternating writing code with writing tests so I know the code works and 
I have a safety net when I need to refactor or make other major changes.

At any time I may discover that I made a bad decision earlier, or realize that 
there is a better way to structure the code or data. Then I stop and rework 
until I am happy with what I have. The unit tests give me confidence that I 
haven's broken anything in the process. It's a very organic process, I 
sometimes think of it as growing a program.

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Ed Singleton
On 25/11/05, Alan Gauld <[EMAIL PROTECTED]> wrote:
>
> Hi Ed,
>
> This is a longish response because you are raising some
> very interesting (and deep) issues from a computer science
> point of view.
>
> > Well, self-modifying isn't inherently necessary.  What I guess I
> > really need is persistent classes as well as persistent objects.
>
> Python classes can be persistent just like any other object,
> theres nothing intrinsically different between a class object
> and any other kind of object (except that classes as objects
> are kind of mind bending as a concept!)
>
> > I always tend to think of classes as templates for objects rather
> > than factories.
>
> They are both.
>
> > In my mind, object methods are just calls to the class which
> > are evaluated every time they are called.
>
> The methjods are function attributes of a class which are selected
> by the class dispatch mechanism in response to messages sent to
> instances. In Python that means the getattr() methods look up
> the right method in response to receipt of a message.
>
> > Objects should be strict instances of classes that can't be
> > modified except for the values of their attributes.
>
> Attributes in a pure OOP language include both the contained data
> and functions. In other workds methods can be added/removed and
> modified as well as the data. In fact many would argue that the
> internal data not only cannot be modified externally but should not
> even be seen - the Data Hiding school of thought.
>
> > Class Page(object):
> >def print(self):
> > printPage(self)
>
> What does that gain you?
>
> > And have all my methods call functions (passing on parameters as
> > necessary).  That way if I change a function, it will be changed for
> > every instance of every object of that class.
>
> You mean like this:
>
> >>> class C:
> ...   def m(self): print 'm'
> ...
> >>> def f(o): print 'other m'
> ...
> >>> c = C()
> >>> c.m()
> m
> >>> C.m = f
> >>> c.m()
> other m
> >>>
>
> > And couldn't I write a function that would add functions or attributes
> > to classes and objects?
>
> Of course, just like I did there.
>
> > Am I trying to use the wrong language for this?  I love Python but I
> > seem to keep coming up against lots of practical issues with it
>
> Python is a pretty good language for this kind of thing,
> its just that this kind of thing is intrinsically difficult.
> The only lanuages I know of which are better than Python
> at it are Lisp and Smalltalk (and even Smalltalk
> has some limitations compared to Python). Do you have
> experience of a language which is more flexible in this regard?
> I'm curious because you seem to assume that its almost
> normal to be able to do these things, whereas in my
> experience its usually impossible rather than just difficult...

My background is in languages that are horrifically worse than python,
but I'm overly demanding I guess.  I think I have a good instinct for
what computers should be doing for me.  Everytime I'm doing something
repetitious I get exasperated because I know the computer should be
performing the repetitions rather than me.

I had the misfortune a couple of days ago of having to knock up a
couple of web pages in ASP.  A very basic search form, results page
and details page.  I had to open up a connection to the database, open
a recordset, concatenate a strings to make an SQL query, etc, etc.

It was horrible.  I copied and pasted a lot of the code, but even so
it involved doing ridiculous amounts of unnecessary work.

Maybe I'm just lazy, but then most progress has been made by people
who were either curious or lazy.

> > define the behaviours I want without having to bother with how the
> > computer is actually going to handle them.
>
> Believe it or not thats been the holy grail of language
> designers since the days of COBOL - The Common Business
> Oriented Language - which allowed business people to
> write theitr own programmes in "standard, everyday English",
> like:
>
> PROGRAM ID - HELLO
>
> PROCEDURE DIVISION
>MAIN-LINE-MODULE
>MOVE 0 TO COUNTER
>OPEN INPUT IN-FILE
>PERFORM READ IN-FILE UNTIL END-OF-FILE = "YES"
>ADD 1 TO COUNTER
>DISPLAY "LINE NUMBER ", COUNTER
>CLOSE IN-FILE
>STOP RUN.
>
> At the time it was considered revolutionary and programmers
> trembled at the prospect of instant redundancy. As it happened
> your average businessman found COBOL about as readable as pigin
> English! But that hasn't stopped us trying...
>
> One thing we have discovered is that the more natural the
> language seems to get the less flexible the language gets.
> Python is the closest I've seen yet to a general purpose
> language that is truly readable, but thats still a long
> way from being plain English! But I digress :-)

I can quite imagine that natural language isn't the way forward,
though I can also imagine that for business reasons readability won't
be the way forward (however I do love readab

Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Ed Singleton
On 26/11/05, Kent Johnson <[EMAIL PROTECTED]> wrote:
> Ed Singleton wrote:
> >>>This immediately seemed to me to be a case for classes.
> >>>You provide a way for a user to create a new class by
> >>>subclassing the page class (from their point of view
> >>>probably through adding a few new fields to
> >>>a form).
> >
> > The behaviours of all the
> > classes would be the same (and would be fairly simple, a method for
> > rendering the page with a template, a method to update the data based
> > on a form submission).  Users would basically be able to change the
> > data structure (add and remove attributes).
>
> It seems to me that rather than having a new class for each type of data, you 
> need a class whose attributes are dynamic. I imagine you could have a list of 
> page types, each of which has a list of attributes. A new page type is 
> created not by defining a new class but by making a new entry in the types 
> table. The data for a page might be as simple as just a dict, or maybe it 
> makes sense to wrap it in a class, but the class would be the same for all 
> pages. A page would be rendered by combining a template with the dict 
> containing its data. Form submissions would be handled by referring to the 
> list of attributes for the type and extracting the corresponding data.
>
> You might have a class to wrap the page data and another one to wrap the 
> types table. These would provide operations on the contained data and be 
> common to all types.
>
> For persistence you could take a couple of approaches. You could persist the 
> lists and dicts directly using pickle or shelve or an object database. You 
> could persist them in a relational database by using a generic table with one 
> row for each data item - the columns would simply be object id, column name 
> and data. SQLite might work very well for this as it allows multiple data 
> types within a single column.
>
> The shift is from looking at the problem as one of dynamic classes, to one of 
> dynamic data. Python is excellent for working with dynamic data!
>
> BTW have you looked at Django? I don't think it is quite as dynamic as you 
> want on the model side but it has a lot of support for quickly generating a 
> presentation of a changing model.
> http://www.djangoproject.com/

>From this and what Alan said, I think I'm starting to get it.  Each
attribute could be an object or an entry in a list.  Each type would
be a collection or list of a particular set of attributes.  The
collection of types would be an object which is easily persisted.

I could pass the type of the page as a parameter when I create it, and
could have a method in the class that looks up the particular type and
adds all the relevant attributes to the object with sensible default
values.  Adding new pagetypes would be easy enough cause they're just
an entry in the types list.

Can you create an object whose default action is to return a certain
value?  For example could I have a header object that where when you
call page.header it returns a value but I can also have
page.header.update().  Or (I think) I know that methods can have
attributes, but can attributes have methods?

I need a bit more time to sit down and think this through (I've gained
a lot of information and at least a little enlightenment over the last
few days), but I think this is really starting to come together.

Ed
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Alan Gauld
Hi Ed,

> Maybe it's just knowing what'll be possible in 10 years time and being
> impatient for it.

The problem is that over twenty years ago when I was at university the 
Japanese anounced that they would have launched a 5th generation 
computer language by 1990. They gave up and we are still waiting.

Part of the problem is that we are familiar with how easily our brains 
can perform certain types of thought process so we asssume it must 
be easy to do on a computer. But our brains work very differently 
to computers and attempts to mimic the brain have so far been 
dismal failures.

Sadly, I think 10 years will see less progress in software than you hope!

Pessimistically,

Alan G
Author of the learn to program web tutor
http://www.freenetpages.co.uk/hp/alan.gauld


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Ed Singleton
On 26/11/05, Alan Gauld <[EMAIL PROTECTED]> wrote:
> >> point. Classes express behaviour, the data is only there to support
> >> the behaviour. Thats why methods are polymorphic but not attributes.
> >
> >If classes express behaviour, then what expresses the structure of the
> > data?
>
> Why do you care? If the program behaves as you expect it what does
> it matter what data it uses or how. That should be hidden from you
> inside the classes. Worrying about data is a feature of traditional
> Information Modelling/Structured Analysis style programming,
> OOP is all about inter-communicating objects sending messages to
> each other, each requesting and providing services to the others.

I get this now.  It goes back to what I said earlier about the "I
don't care how it works" philosophy.

Each object doesn't care how any other works.  You could completely
re-engineer the internals of an object and that would be fine as long
as the interface is the same.  As long as the methods and attributes
keep returning sensible values then everything is fine.

However, I'm still slightly uncomfortable with it.  It smells to me a
bit like the "as long as it works, its fine" school of thought.  For
my own sanity and peace of mind I like to have my data structures well
defined, as at the end of the day it's the data that matters (I can
rebuild functionality but data is given to me by other people and can
rarely be gotten back).

> > (ie what attributes there are going to be and what values they
> > are likely to accept).
>
> You need to think about the objects that you pass around as part
> of the messages, but those obnjects are in turn accessed via messages
> so their structure is not important. What does matter is the
> relationships between the objects, and they are related by message
> paths not fixed data relationships. This switch in thinking is the
> fundamental difference between traditional and OOP design.
>
> > You need (the option of) a data definition in order to generalise.
>
> No, you need the ability to modify behaviour.
> Most traditional programmers think in terms of modifying
> behaviour in terms of big if/elif trees
>
> if obj.type == sometype
> doSomeTypeThing()
> elif obj.type == another
> doAnotherTypeTHing
> etc...
>
> Whereas in OOP you simply say
>
> obj.doThing()
>
> And the right kind of doThing will happen because obj
> knows how to respond to that message in the appropriate way.

But writing a different doThing() for each object can be a huge waste
of time.  You want to be able to write one doThing() that is going to
work on each object (of a particular type).  This requires either
knowing that all your objects are going to be similar in some respect,
or writing a huge if..elseif as you mentioned.

Even just saying every object has a doThing() is starting to create a
data structure.

> > Using my web server example from earlier, you need to be able to say
> > that for any type of page, whatever it's attributes, you can create a
> > web form to search for that type of page by iterating through it's
> > attributes and creating a relevant form field for each type.
>
> So you want, for a given page to create a Form and search.
>
> But that's behaviour of the Page, just let it create its own form
> and do its own searches, not your problem. Create the right
> kind of Page and it will do the work for you...

But then I've got to create lots of different behaviours instead of
one simple generalised behaviour.

> > I definitely had the opposite in mind.  The behaviours of all the
> > classes would be the same (and would be fairly simple, a method for
> > rendering the page with a template, a method to update the data based
> > on a form submission).
>
> Thats fair enough and the parent Page class would do just that,
> but the template class would have methods that the Page called,
> and you can subclass or data drive the templates to return the
> appropriate strings to the page. (Since web pages after all are
> just collections of strings - or evenone big string...)
>
> > Users would basically be able to change the
> > data structure (add and remove attributes).
>
> So maybe attributes are objects too? Maybe you page needs
> to know how to handle attributes and you can create pages by
> adding attributes from a pick list, each attribute knowing how
> to render itself and how to respond to searches?

This combined with what Kent said, is what really solved the problem for me.

> There are lots of ways to address this is we think of the world
> in terms of intercommunicating objects not static data structures
> with a few overeaching functions controlling it all.

I've really gained a huge amount just from this one topic.  Not least
of which is that classes aren't necessarily a good answer to OOP
problems.

> > I'm sure Python is quite possibly the least worst at this, but that
> > doesn't make it good at it.
>
> Which brings me back to my original question, what environment
> do you think is go

Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Alan Gauld
>From this and what Alan said, I think I'm starting to get it.  Each
> attribute could be an object or an entry in a list.  Each type would
> be a collection or list of a particular set of attributes.  The
> collection of types would be an object which is easily persisted.

Absolutely!

> Can you create an object whose default action is to return a certain
> value?  For example could I have a header object that where when you
> call page.header it returns a value but I can also have
> page.header.update().  

Absolutely, in fact its quite normal.

> Or (I think) I know that methods can have
> attributes, but can attributes have methods?

They can if the attributes are objects in their own right...

HTH

Alan G.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Object-oriented design process

2005-11-26 Thread Alan Gauld
Hi Kent,

>> point. Classes express behaviour, the data is only there to support 
>> the behaviour. Thats why methods are polymorphic but not attributes.
>> 
>> So you think of a class having an interface and users extending 
>> or modifying the behaviour, not the data.

> I think of a class in terms of data attributes *and* behaviour. To me 
> they are inseparable. To the client of the class, it is the behaviour 
> that is important, 

I was talking from the point of view of the client, although the client 
of one class is likely to be the internals of another!

> but inside the class and when designing / discovering classes, 
> I tend to look at what data I need to represent and solve a 
> problem and what operations I need on that data 

I look at data when designing a class - or more specifically 
a method. I will naturally need some data to build a method, the 
data I need will be part of the class. And when I look at the 
totality of the methods I design the data attributes to maximise 
synergy between methods. But I always define the external 
behaviour before considering the internal data needevto provide 
that.

> and look for ways to group them together into cohesive classes.

I never use commonality of data to define a class. OK I lie, 
sometimes its just convenient to do it that way, but as a principle
such classes are rarely extensible, they tend to be more like 
records in structured programming speak.

> Alan, you and I have very different approaches to OO design 
> and I don't mean to say my way is right, just an alternative!

I don;t think our results are different, (based on the code and ideas 
I've seen you present here), but our way of verbalising the approach 
is different.

> I tend to design from the bottom up - not exclusively, 

I do top down design for the class strucure but design and 
build the classes from bottom up. In so doing I will of course 
discover new vclasses that must be slotted ito the structure. 
But my first cut is usually to build a framework of "abstract" 
classes that work together to solve the problem, then I go 
back filling in the methods from the bottom up, and testing 
each method as each slots into the abstract framework, 
gradually becoming more concrete as it builds.

> but in general I make small parts and combine them to make 
> larger parts until I have something that does what I want. 

Me too, but in the context of a preconceived framework.

> I refactor constantly as my understanding of a problem 
> and the solution increase. 

I occasionally refactor at the method level, I very occasionally 
refactor at the class level, but thats rare once I have the abstradt 
framework in place.

> This way I always have complete working code for some 
> section of the problem. I rarely use stubs of any kind.

And I have stubs for everything! So there we differ 
I rarely, if ever. write production methods without first 
testing the concept with a stub.:-)

> To start I will take some small section of the problem 
> and think about what kind of data and operations on 
> the data I need to solve it. 

Inwill take the same approach but I will think about the objects, 
then I think about the responsibilities and collaborators (CRC 
Cards are my friends!). Then I write the abstract structure 
based on the CRCs and  test it, if it works I go back and fill 
in the methods. In doing so I will discover what data I need.

> For a very simple problem I might just write some functions 
> to operate on the data. 

For very simple problems I very rarely use OOP, I tend to 
find it most helpful when the problem gets beyond a certain 
size (depends on lamguage etc, but for Python around 50 -100 lines)

> Some of the blocks are classes, others are functions.

I've built hybrid programs occasionally but in general if a 
procedural approach starts to break I will tend to rework 
it into pure OOP rather than mix paradigms.

> I write unit tests as I go, sometimes test-first, sometimes test-after, 

I like the idea of test first but for me it doesn't work well, but 
I do test on a method by method basis once past the initial 
framework. (The famework is tested class by class since they 
are only stubs). And individual classes get tested at the >>> 
prompt before veing tried in the framework - one of the great 
joys of Python is interactive testing at the >>>.

> The unit tests give me confidence that I haven's broken anything 
> in the process. 

Me too, but at the method level.

> It's a very organic process, I sometimes think of it as growing 
> a program.

Yep, I agree. As I said I don;t think our end results are very far 
apart, we have some minor differences of approach but the focus 
is still on behaviour from an external point of view and data in the 
intenal view, I think.

And so far as design goes its definitely healthy to compare and 
contrast approaches. Design is the truly creative bit of software 
engineering and its always good to know that there is more than 
one way 

Re: [Tutor] Modifying Source Code while Program is Running

2005-11-26 Thread Danny Yoo
> I had the misfortune a couple of days ago of having to knock up a couple
> of web pages in ASP.  A very basic search form, results page and details
> page.  I had to open up a connection to the database, open a recordset,
> concatenate a strings to make an SQL query, etc, etc.
>
> It was horrible.  I copied and pasted a lot of the code, but even so it
> involved doing ridiculous amounts of unnecessary work.

Hi Ed,

I don't know how well ASP supports abstraction, but copying and pasting is
usually the wrong solution: that's exactly where we should be thinking
about writing functions and organizing those functions in libraries.

If a block of code is being copied around, that unit of work captures some
concept we have, and functions are a good way to formally capture that
concept as an abstraction.  We can --- and often must! --- lift ourselves
up by using abstractions, or risk drowning in the tedious details.

Guy Lewis Steele Jr. wrote a hilarious talk about this in "Growing a
Language":

http://www.brics.dk/~hosc/local/HOSC-12-3-pp221-236.pdf


> > Basically I just wonder what your background is that you seem to
> > expect these kind of dynamic facilities? I'd certainly be interested
> > in investigating it further.
>
> Maybe it's just knowing what'll be possible in 10 years time and being
> impatient for it.

If we're chasing for a "silver bullet" in programming languages, we might
wait for a very long time indeed.  *grin*

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Scientific Notation + 18 digit precision

2005-11-26 Thread Hubert Fitch




I am using Python 2.3 under Windows XP Home 
edition
 
I am too old to learn all the tricks of Python, and my main 
purpose is for Physics calculations
 
I do have some questions, but perhaps my useage of Python as 
an Algebraic Calculator will be interesting to someone?
 
Python is the best precision Algebraic Calculator solution 
that I have found so far. I like the large global space for 
variables.
 
Using the Idle GUI to run .py modules, I can then use direct 
mode calculations in the Python shell, after I have  defined a large list 
of variables by global assignment statements.
 
For my purposes, this requires about 7 .py definition modules, 
which all accumulate these assignments as keys and data, within the scope of the 
calling Python script. The most important module is the first one which enters a 
lot of physical constants.
 
I am not ready to begin any new module or calculation unless 
all the needed physical constants and derived variables are present within the 
scope of my calling program. 
 
Example of a Calling Script .py file 
("NoPrintParameters.py"):
 
The purpose of this file is to enter Physical 
data variables and values, and assignment formulas that define new 
variables, (without printing anything to the Shell Screen, unless I decide 
to do so in the following Display Section.
 
To accomplish this, I have two similar function modules that I 
call: 
A Display Module Function, and a RunModule 
Function.
 
(The Display Function was written for me by the head of our 
Physics Deparment, and I adapted it to create the Run Module 
Function)
 
The display function operates on each line in the .py file and 
provides 4 formatted columns for:
Variable Name, Data (18 digits ), Assignment Formula, and 
Comments.
 
(After All this data is on screen I can "Save Copy As" to RTF 
file format, which prreserves the Shell window formatted data. (Saving in 
Word document files or Text files will not preserve the formatted 
data).
 
The Run Module Function exectues all assignments, but no 
display is produced in the Shell screen.
This is necessary to get all assignments within global 
memory.
 
(As each new Python module was created, and ran for the first 
time, I always hoped to see only the Idle GUI blue screen characters, but 
usually I get some undefined variable errors. It is fun to finally get all of 
these errors resolved! There is so much going on, as the modules run, and I am 
always amazed that they really work!))
 
##   IMPORT  
DISPLAY FUNCTIONfrom displayPyFile import 
DisplayPyFile##   IMPORT  RUN 
MODULE FUNCTION (No Display)from runPyModule import RunModule ## 
---# Load and Run Files (No 
Display)# ---# 
#   RUN Main DEFINITION FILE   
(NO DISPLAY) RunModule ('pythondef.py',globals() ) #   
RUN Other DEFINITION FILEs (NO DISPLAY) RunModule 
('R1Parameters.py',globals() )RunModule ('R0Parameters.py',globals() 
)RunModule ('R10Parameters.py',globals() )RunModule 
('R2Parameters.py',globals() )RunModule ('R3Parameters.py',globals() 
)RunModule ('deBroglieRelativistic.py',globals() )## 
--#   
DISPLAY LINES in:# 
-#DisplayPyFile 
('pythondef.py',globals() ) #DisplayPyFile ('R1Parameters.py',globals() 
)#DisplayPyFile ('R0Parameters.py',globals() )#DisplayPyFile 
('R10Parameters.py',globals() )#DisplayPyFile ('R2Parameters.py',globals() 
)#DisplayPyFile ('R3Parameters.py',globals() )##DisplayPyFile 
('Section1.py',globals() )#DisplayPyFile ('ClassicalSelfForces.py',globals() 
)#DisplayPyFile ('Definitions.py',globals() )#DisplayPyFile 
('Topics.py',globals() )#DisplayPyFile ('deBroglieRelativistic.py',globals() 
)##
 
As you can see, I can display any (or all) modules by deleting 
the # comment character,  however in this example, the only file that 
will produce screen output is "Topics.py" 
I could remove all the # characters, to display all .py file 
definitions, but that would be too much data to see at once.
 
The main point of all the defintiion files is to be able to 
make direct mode calculations in the Python Shell, and to be able to write 
shorter scripts for a series of calculations which use these 
definitions.
 
Many assignments are execution order sensitive. The next 
assignment formula depends on the previous assignments.
 
 
Now for the questions:
 

Most data and results are displayed properly formatted in scientific 
notation, but sometimes large numbers resulting from calculations 
are not converted to scientific notation.
 
For example: mu0*I0/r0 = 1209755258303.6067 (should have 
been 1.2097552583036067e+012).
 
I must then count about 7 or about 15 digits to detrmine how 
many places to the left to manuually move the  decimal point, and manually 
add the e+012. Why does Python sometimes do this? 

 
Is there an easy  way to convert these large numbe

Re: [Tutor] files - strings - lists

2005-11-26 Thread Kent Johnson
Andrzej Kolinski wrote:
> 
>   OK, I made some progress I think. I added a few lines to Kent's script 
> to get closer what I really am after:

Congratulations! See some notes below.

> 
> ==
> lines = open('liga050926.sbk')   # to get the data from a real file
> 
> #lines = iter(data)  # getting data from a string, you don't need this 
> when reading a file
> 
> lines.next()# skip two headers
> lines.next()
> 
> header = lines.next().split()
> hands = int(header[2])
> rounds = int(header[3])
> boards = hands*rounds
> 
> lines.next()
> 
> 
> allScores = {}  # accumulate scores into a dictionary whose key is the name
> 
> # Now we can process the names and scores in a loop
> try:# you don't say how you know the end of the names, I just run to 
> the end of data
> while True:
> names = lines.next().strip()
> player1 = names.split()[0]
> player2 = names.split()[2]

This could be
names = lines.next().strip().split()
player1 = names[0]
player2 = names[2]
or even
player1, player2 = lines.next().strip().split(' - ')
>
> lines.next()# skip line after name
> scores = [ int(lines.next().split()[2]) for i in range(rounds) ]
> tScores = 0
> for i in scores:
> iScore = float(i)
> tScores = tScores + iScore

This could be
  tScores = float(sum(scores))
> 
> allScores[player1] = tScores/boards
> allScores[player2] = tScores/boards
>
> except: # no more lines
> if lines.next() == '1,1':
> pass

I'm not sure what the two lines above are doing? It looks like you don't have a 
good way to detect the end of the data and you just catch some exception...you 
should figure out a clean way to exit the loop. Maybe when you read the names 
line you can look for '1,1' and break out of the loop, if that is what always 
follows the data you care about.

>
> for player1, tScores in allScores.items():
> print player1, tScores
> =
> 1.I singled out the players names.
> 2.I added the players scores and divided by the number of boards 
> played.
> 3.The output contents is what I wanted:
> 
> Chrabalowski 0.875
> Kowalski -0.
> Kolinski 1.2916667
> Bohossian 1.2916667
> Stankiewicz -1.167
> Cwir -0.7083 ...
> 
> 4.The next step for me would be to read the data from more, 
> similar files (from 2 to 10) representing different games and generate 
> an average score for each participating player (a player does not 
> necessary plays each game and I would eventually like to calculate 
> averages of best six out of maximum ten games). Tough! How should I 
> start this next step? (I would like to keep both options open:
> final ranking = (all tScores)/all boards), or
> final ranking = average(RScores/boards, RScores/boards, 
> RScores/boards, ...)
> game1   
>  game2game3)

I would save more data for each player. Instead of just keeping the average for 
the player, I would keep a list of pairs of (tScore, boards) for each game. 
Instead of 
  allScores[player1] = tScores/boards
you could say
  playerScores = allScores.get(player1, [])
  playerScores.append( (tScores, boards) )
  allScores[player1] = playerScores

all of which can be written more tersely (and obscurely) as
  allScores.setdefault(player1, []).append( (tScores, boards) )

Of course you need a loop to read all the files and you will initialize 
allScores before the loop. Then when you finish with the files you can retrieve 
the players' stats and process them either way you want.

BTW what game is this? It seems odd that both players get the same score.

> 
> Thanks Kent, Chris and Danny. After many, many months of using or 
> modifying (and using) existing scripts, with your invaluable help I feel 
> I can write script that is original and extremely useful to me!

Glad to hear it!

Kent

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Scientific Notation + 18 digit precision

2005-11-26 Thread Kent Johnson
Hubert Fitch wrote:
> Now for the questions:
>  
> Most data and results are displayed properly formatted in scientific 
> notation, but sometimes large numbers resulting from calculations are 
> not converted to scientific notation.
>  
> For example: mu0*I0/r0 = 1209755258303.6067 (should have 
> been 1.2097552583036067e+012).
>  
> Is there an easy  way to convert these large numbers to the scientific 
> notation format? Can we write a function call that I could use 
> to convert the numbers to scientific notation whenever I need to do so 
> from the Python shell in direct mode?

You can use string formatting to get closer control of the way numbers print. 
For example:
 >>> x= 1209755258303.6067
 >>> x
1209755258303.6067
 >>> '%e' % x
'1.209755e+012'

See the docs for details:
http://docs.python.org/lib/typesseq-strings.html

> And sometimes I get an incorrect result for integer calculations. This 
> does not happen very often, but it worries me that it may happen when I 
> don't know about it. A calculation involving integers will sometimes 
> give an unexpected zero result.

Do you know that integer division is truncated? For example
 >>> 3/4
0

You can fix this by making sure one of the operands is a float:

 >>> 3.0 / 4
0.75

Future versions of Python will do this for you. You can enable it by this 
import:
 >>> from __future__ import division
 >>> 3/4
0.75

Kent
-- 
http://www.kentsjohnson.com

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Object-oriented design process

2005-11-26 Thread Kent Johnson
Alan Gauld wrote:
> I never use commonality of data to define a class. OK I lie, sometimes 
> its just convenient to do it that way, but as a principle
> such classes are rarely extensible, they tend to be more like records in 
> structured programming speak.

Very few of my classes are ever extended with subclasses.

I don't like to make classes that are just data containers, but I find that 
when I do make a class like that, I often find some behaviour to go with it. 
Usually pretty quickly :-) and then I have a real class that is pulling it's 
weight.

> I do top down design for the class strucure but design and build the 
> classes from bottom up. In so doing I will of course discover new 
> vclasses that must be slotted ito the structure. But my first cut is 
> usually to build a framework of "abstract" classes that work together to 
> solve the problem, then I go back filling in the methods from the bottom 
> up, and testing each method as each slots into the abstract framework, 
> gradually becoming more concrete as it builds.

I guess I have an idea of where I am going, what the eventual pieces will be, 
but I don't generally build any kind of framework in advance and I don't use 
many abstract classes.

I think you work at a much larger scale (of program size) than I do, that may 
be one reason for the different approach. Most of my programs are small or 
medium size, I'm not sure I have ever worked on a project I would really call 
large.

> I occasionally refactor at the method level, I very occasionally 
> refactor at the class level, but thats rare once I have the abstract 
> framework in place.

I refactor constantly. I think of it as building the framework as I go, letting 
it emerge from the code. When I am done I often have a very highly tuned, 
application-specific framework, but I didn't imagine it from the start, I 
evolve it as I develop the overall solution.

> Inwill take the same approach but I will think about the objects, then I 
> think about the responsibilities and collaborators (CRC Cards are my 
> friends!). Then I write the abstract structure based on the CRCs and  
> test it, if it works I go back and fill in the methods. In doing so I 
> will discover what data I need.

I sometimes use something like CRC cards. How do you test the abstract 
structure? With stubs and mock objects?

>> Some of the blocks are classes, others are functions.
> 
> I've built hybrid programs occasionally but in general if a procedural 
> approach starts to break I will tend to rework it into pure OOP rather 
> than mix paradigms.

I don't have any problem mixing. The procedural parts are usually low-level 
utility functions or high-level drivers. I just do what seems to work best for 
each part of the problem.
> 
>> I write unit tests as I go, sometimes test-first, sometimes test-after, 
> 
> 
> I like the idea of test first but for me it doesn't work well, but I do 
> test on a method by method basis once past the initial framework. (The 
> famework is tested class by class since they are only stubs). And 
> individual classes get tested at the >>> prompt before veing tried in 
> the framework - one of the great joys of Python is interactive testing 
> at the >>>.

I do very little of this. For me the problem with testing at the >>> prompt is 
that the tests aren't captured. By writing the tests as unit tests, they are 
run repeatedly. When I change the implementation of a class I can re-run the 
tests and be pretty confident I haven't broken anything. If my original tests 
were interactive I have to remember how I tested and run them again by hand.

Kent
-- 
http://www.kentsjohnson.com

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Scientific Notation + 18 digit precision

2005-11-26 Thread Chris or Leslie Smith
| The display function operates on each line in the .py file and
| provides 4 formatted columns for: 
| Variable Name, Data (18 digits ), Assignment Formula, and Comments.
| 

There are a couple of recipes at ASPN that might be useful with table 
generation:
 
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/267662
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/302380

[x]
| Now for the questions:
| 
| Most data and results are displayed properly formatted in scientific
| notation, but sometimes large numbers resulting from calculations are
| not converted to scientific notation.  
| 
| For example: mu0*I0/r0 = 1209755258303.6067 (should have been
| 1.2097552583036067e+012). 
| 

Apparently python doesn't agree ;-) Part of the answer has to do with how you 
show the result and part has to do with the size of the number. There are two 
representations of the number that are possible, str() and repr(). Here's a 
sample of both using your number:

##
>>> n=1209755258303.6067
>>> print n
1.2097552583e+012
>>> print str(n)
1.2097552583e+012
>>> print repr(n)
1209755258303.6067
>>> n
1209755258303.6067
>>> n=n*10**5
>>> n
1.2097552583036066e+017
##

As you can see, even the repr() form of the number eventually is too large to 
display in non-exponential form..  How were you displaying the value to the 
screen?


| I must then count about 7 or about 15 digits to detrmine how many
| places to the left to manuually move the  decimal point, and manually
| add the e+012. Why does Python sometimes do this?  
| 
| Is there an easy  way to convert these large numbers to the
| scientific notation format? Can we write a function call that I could
| use to convert the numbers to scientific notation whenever I need to
| do so from the Python shell in direct mode?   

If you check the python language reference section on "String Formatting 
Operations" that will show you that you can use a format to create the desired 
number representation. If you want exponential, the %e is the format you want:

##
>>> for i in range(1,17,3):
...  fmt='%%.%ie' % i
...  print fmt,'\t', fmt % n
... 
%.1e  1.2e+012
%.4e  1.2098e+012
%.7e  1.2097553e+012
%.10e  1.2097552583e+012
%.13e  1.2097552583036e+012
%.16e  1.2097552583036067e+012
##

So if you want 17 places after the decimal try

print "%.17e"  %  n

| Another perhaps related thing is the way exact numbers like light
| speed = C (or C/2) are presented (  C = 299792458 ). 
|
It's not clear what the problem is here. Can you clarify?
 
| And sometimes I get an incorrect result for integer calculations.
| This does not happen very often, but it worries me that it may happen
| when I don't know about it. A calculation involving integers will
| sometimes give an unexpected zero result.   

Watch out for the truncated division (presently the default for python). 
There's a nice write up at

http://www.ferg.org/projects/python_gotchas.html

(see section 3).  Either convert one of the numbers to float or import the 
future behavior as described in the link above.

##
>>> 2/3
0
>>> float(2)/3
0.3
>>> from __future__ import division
>>> 2/3
0.3
>>> 2//3  #with the future behavior in effect, the truncated division is 
>>> obtained with //
0
##

/c
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor