Re: [Tutor] Modifying Source Code while Program is Running
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
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
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
>> 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
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
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
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
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
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
>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
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
> 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
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
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
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
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
| 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