Re: [Tutor] class question
> >>I'm not sure I follow that bit. > > Say you have a master part, # 3245671, this is sort of a "primary machined >number". > > On the blueprint for this part, there will be certain features that don't > have >any dimensional > > information, but instead have a callout of some kind, i.e., "Hole D", or >somesuch. > > At the top of the blueprint is a "tab block" that is a table of "alternate >part numbers", > Ah OK, Yes I've seen that used in produccing similar but different printed circuit boards (my background is in electronics not foundry work) > This was originally a convenience/cost saving thing, I suspect. Almost certainly, and it makes it much easier to add new variants since only the tab values need changing. What it means for you is that you need in parallel to your main app a mechanism for managing the identities through these differeing ID values. Effectively a lookup table and mechanism for tracing designs from raw pattern to finished item. > >>You may also find it useful to think through the state model for your > castings/workpieces. That may help to constrain the number of >Actions/operations required. > > ummm...what's a "state model"? It defines what operations can be done on your objects at any given time depending on the "state" of the object. As a simple example a light can be switched on when it is off and off when it is on, but it cannot be switched off if it is already off. In your can you will have a sequence of operations with dependencies between them such that certain operations can only be done after others have completed. Others cannot be done after others have been done. State models can be table driven which makes them highly configurable so that a single object can be loaded by multiple state models and effectively act like different object types without having to change the code. HTH, Alan G. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Elwin Estle wrote: --- On Wed, 1/26/11, Alan Gauld wrote: From: Alan Gauld Subject: Re: [Tutor] class question To: tutor@python.org Date: Wednesday, January 26, 2011, 1:10 PM Is this really a series of different types of casting or a single Workpiece going through a sequence of Actions each Action having a set of quality data associated? If so it may be that you have a single Workpiece class and a relatively small heirarchy of Actions. No, there are multiple castings, anywhere from smallish parts you can hold in the palm of your hand, up to engine blocks weighing nearly 2 tons. Then each such casting has its own set of actions and chain of classes. There is a process that goes from egg to chick to hen to KFC Chicken Nuggets, but you wouldn't write a single class to model all of those things. You would write a separate class for each distinct stage of the process, and write a process that replaces each data item with the next one in the series. I think you are focused too heavily on the fact that it's the same lump of metal all the way through the pipeline. That's the least important part of the design -- you can do that with a simple record: class Lump: def __init__(self, id, kind): self.id = id self.obj = kind() lumps = [ Lump(1, EngineBlockCasting), Lump(2, EngineBlockCasting), Lump(3, WidgetCasting), Lump(4, MiniCasting), ... ] and then later on: lumps[1].obj = EngineBlockWithHolesDrilled() Although of course you will write functions or methods to move from one class to another, e.g. drill_holes(lumps, 1), rather than do it all by hand. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
--- On Wed, 1/26/11, Alan Gauld wrote: From: Alan Gauld Subject: Re: [Tutor] class question To: tutor@python.org Date: Wednesday, January 26, 2011, 1:10 PM >>Is this really a series of different types of casting or a single Workpiece >>going through a sequence of Actions >>each Action having a set of quality data associated? >>If so it may be that you have a single Workpiece class and a relatively small >>heirarchy of Actions. No, there are multiple castings, anywhere from smallish parts you can hold in the palm of your hand, up to engine blocks weighing nearly 2 tons. >>Is it the casting or the machining that has the quality related data? ie Is >>it casting specific or operation specific? The casting can have quality data associated with it, tho rarely. If there is a machining issue that can be traced back to defective castings, then yes (but we don't really have any process in place for this, normally that sort of thing is the casting supplier's problem). Normally, tho, it is the machining that has the associated quality data., i.e., measure a 2.500 machined bore with a +/- .001 tolerance, using such and such gage, giving some result (like 2.503, for example), measured on such and such date by such and such machine operator. Various bits like this will be associated with a given machining operation. Sometimes machining operations are all done on a single machine, sometimes they span multiple machines. >>Do you know in advance what these operations will be? Can you assign a >>WorkPlan to the Workpiece? Each step of the plan having an associated Action? I would say yes. However, and this ties in with something you ask further down, sometimes that plan may sort of "overlap" For example, say we have a raw casting, 3402963R, that when machined, becomes part # 3402963. But that same raw casting may also be machined into another part number # 3332965, simply by adding or omitting hole or some other feature. So, I suppose one could have separate plans for each finished part number, in which case there might be some duplication of things for each plan. > Each of those operations on separate machines will have a different set of > quality checks associated with it. So here we clearly say it is the Action that has the data associated... > ...or it might be a part that goes from a raw casting to a sort of > "mini-assembly" such as a rocker lever ... > but it is still the same thing, and each one of those steps may have some > sort of quality check involved. So a workpice can consist of other WorkPieces. And again tyhe Actions associated have quality data >>> Lets complicate things even further. One raw casting may be machined into >>> multiple part numbers. >>Is that true? Or is it one type of casting? >>Each instance of casting will surely onmly go through one specific set of >>actions? If we treat them all as generic >>workpieces then the Actions are >>different but the workpiece concept remains constant? >>Or, are we saying that a single original workpiece can be cut into several >>distinct workpieces? Again thats not >>necessarily a problem, objects can >>clone themselves and have the clones diverge thereafter. Yes, that is the case, as described above. >>> This is done through something called a "tabbed" blueprint, wherein there >>> is a master number, but there are "tabs" indicating that if you changes >>> such and such feature, then the part number isn't the master number, but >>> the tabbed number. >>I'm not sure I follow that bit. Say you have a master part, # 3245671, this is sort of a "primary machined number". On the blueprint for this part, there will be certain features that don't have any dimensional information, but instead have a callout of some kind, i.e., "Hole D", or somesuch. At the top of the blueprint is a "tab block" that is a table of "alternate part numbers", vs these "named features". Each of these part numbers will have differing information as to the nature of "Hole D". Perhaps the size of "Hole D" differs from one part number to the next, or perhaps it is omitted all together. It goes along wth the "one casting makes multiple part numbers" thing described above. In and of itself, this perhaps may not seem that complicated...but the blueprints aren't filed under the the actual part number for a given tabbed part, but under the master number. So...you may have part 3458760, but the blueprint for it is filed under 3245671, so you have to go hunt up that blueprint, then hunt up the information on it that describes the actual part in question. All this ties in to your qual
Re: [Tutor] class question
"Elwin Estle" wrote The class in question, does, in fact, deal with a thing. The problem is, the "thing" is highly mutable. You can mutate objects, that is not a problem. But you need to be sure you need to. Is this really a series of different types of casting or a single Workpiece going through a sequence of Actions each Action having a set of quality data associated? If so it may be that you have a single Workpiece class and a relatively small heirarchy of Actions. A raw casting comes into a factory. It is listed as such. When machined, this part number changes to a different part number. The raw casting has no "quality related" stuff, but the machined casting does, Is it the casting or the machining that has the quality related data? ie Is it casting specific or operation specific? ...because, the raw casting may go through multiple operations to get to it's final state. Do you know in advance what these operations will be? Can you assign a WorkPlan to the Workpiece? Each step of the plan having an associated Action? Each of those operations on separate machines will have a different set of quality checks associated with it. So here we clearly say it is the Action that has the data associated... ...or it might be a part that goes from a raw casting to a sort of "mini-assembly" such as a rocker lever ... but it is still the same thing, and each one of those steps may have some sort of quality check involved. So a workpice can consist of other WorkPieces. And again tyhe Actions associated have quality data Lets complicate things even further. One raw casting may be machined into multiple part numbers. Is that true? Or is it one type of casting? Each instance of casting will surely onmly go through one specific set of actions? If we treat them all as generic workpieces then the Actions are different but the workpiece concept remains constant? Or, are we saying that a single original workpiece can be cut into several distinct workpieces? Again thats not necessarily a problem, objects can clone themselves and have the clones diverge thereafter. Perhaps the only thing that changes is the location of a single hole. But again, each one of those part numbers may go through multiple machining operations on different machines, with different quality checks. This is done through something called a "tabbed" blueprint, wherein there is a master number, but there are "tabs" indicating that if you changes such and such feature, then the part number isn't the master number, but the tabbed number. I'm not sure I follow that bit. So, in essence, there's a sort of "network" of "is-a" and "has-a" information. I see a lot of "has-a" but very little "is-a" at this stage. In fact I don't see any "is-a" yet, althopugh I can see where some might emerge in the future. have a sort of "component aggregate" class, which would cover not only single parts, but assemblies I think that will be essential. if a part was as simple as a raw casting that is just machined into a finished part and that's it, it would still be treated as a sort of assembly, One of the key features of assemblies is that they should scale down to a single item just as easily as up to many parts. So there's all this information associated with a given part. I am thinking it has a sort of tree structure. I think there probably is and you should look into the composite pattern to build that. I am just wondering if some of the branches of the tree should be separate classes Probably, but not so many different classes as you currently suspect. ...and yeah, I know, it's kind of a complex problem for a newbie to be thinking about. Yes, very challenging. This is one of the kinds of problem where the best solution is probably not be the first one you think of. But you won't know that till after you try building it! My proposal is only a guess based on a quick review of your description and no local domain knowledge... You may also find it useful to think through the state model for your castings/workpieces. That may help to constrain the number of Actions/operations required. -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
"Karim" wrote Sure, but I come from java world and 1 inheritance is allowed but we can implement multiple interfaces. I like to use Abstract classes in Python then inherit and implement abstract method like in java (at least Sure and that is the normal way of doing it. Not least because you can inherit non abstract methods too! But there is a danger of forgetting that inheritance is not the *only* way. Thats all I was pointing out, inheritance is the norm but not essential. -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
class Raw ---> class Processor ---> class Final 2011/1/26 Tino Dai > > >> >> A raw casting comes into a factory. It is listed as such. When machined, >> this part number changes to a different part number. The raw casting has >> no "quality related" stuff, but the machined casting does, and it can have >> more than one "quality related" thing. >> >> ...because, the raw casting may go through multiple operations to get to >> it's final state. It may get machined on a lathe, then be transferred to a >> CNC machining station where a bolt circle may be drilled and tapped into >> it. Each of those operations on separate machines will have a different set >> of quality checks associated with it. >> >> ...or it might be a part that goes from a raw casting to a sort of >> "mini-assembly" such as a rocker lever (if you know what that is), so we >> have raw casting = one part number, then it gets a bushing pressed into it = >> another part number, then it gets a threaded insert = another part number, >> but it is still the same thing, and each one of those steps may have some >> sort of quality check involved. >> >> Lets complicate things even further. One raw casting may be machined into >> multiple part numbers. Perhaps the only thing that changes is the location >> of a single hole. But again, each one of those part numbers may go through >> multiple machining operations on different machines, with different quality >> checks. This is done through something called a "tabbed" blueprint, wherein >> there is a master number, but there are "tabs" indicating that if you >> changes such and such feature, then the part number isn't the master number, >> but the tabbed number. >> >> So, in essence, there's a sort of "network" of "is-a" and "has-a" >> information. >> >> My idea was to, instead of having just a single "part" class, to have a >> sort of "component aggregate" class, which would cover not only single >> parts, but assemblies of parts. So, even if a part was as simple as a raw >> casting that is just machined into a finished part and that's it, it would >> still be treated as a sort of assembly, with the raw casting being a >> component of the finished part number, if that makes sense. >> >> So there's all this information associated with a given part. I am >> thinking it has a sort of tree structure. I am just wondering if some of >> the branches of the tree should be separate classes that are then tied into >> the "trunk" of the master class, or if the whole thing should be a tree into >> and of itself. >> >> ...and yeah, I know, it's kind of a complex problem for a newbie to be >> thinking about. >> >> >> >> > Here is my two-cents. This code is untested. Import statements haven't been > included, there could be syntax errors, etc etc etc. What I did > was switching off the part_number attribute in the Thing class. For the > functions that "do stuff" to the thing instance, I appended a part-number > (assuming new part number = master number + doing stuff number). The quality > functions will check for that part number before proceeding with the checks. > > > class Thing: # single part class > def __init__(self,part_number='12345'): # 12345 is a default > part number > self.part_number=part_number > > def routeThing(thing): > try: > thing.part_number.append('-someRoutingPartNumber') > > exception AttributeError (e): > e.printStackTrace() > print "Router was not applied to thing" > > def checkQualityRoute1(thing): > if hasattrib(thing,part_number) && > (thing.part_number.find('-someRoutingPartNumber'): > > else: > print "Thing has not be routed yet" > > def checkQualityRoute2(thing): > if hasattrib(thing,part_number) && > (thing.part_number.find('-someRoutingPartNumber'): > > else: > print "Thing has not be routed yet" > > continue for all of the functions that you might need > > HTH, > -Tino > > > ___ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor > > ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
> > > A raw casting comes into a factory. It is listed as such. When machined, > this part number changes to a different part number. The raw casting has > no "quality related" stuff, but the machined casting does, and it can have > more than one "quality related" thing. > > ...because, the raw casting may go through multiple operations to get to > it's final state. It may get machined on a lathe, then be transferred to a > CNC machining station where a bolt circle may be drilled and tapped into > it. Each of those operations on separate machines will have a different set > of quality checks associated with it. > > ...or it might be a part that goes from a raw casting to a sort of > "mini-assembly" such as a rocker lever (if you know what that is), so we > have raw casting = one part number, then it gets a bushing pressed into it = > another part number, then it gets a threaded insert = another part number, > but it is still the same thing, and each one of those steps may have some > sort of quality check involved. > > Lets complicate things even further. One raw casting may be machined into > multiple part numbers. Perhaps the only thing that changes is the location > of a single hole. But again, each one of those part numbers may go through > multiple machining operations on different machines, with different quality > checks. This is done through something called a "tabbed" blueprint, wherein > there is a master number, but there are "tabs" indicating that if you > changes such and such feature, then the part number isn't the master number, > but the tabbed number. > > So, in essence, there's a sort of "network" of "is-a" and "has-a" > information. > > My idea was to, instead of having just a single "part" class, to have a > sort of "component aggregate" class, which would cover not only single > parts, but assemblies of parts. So, even if a part was as simple as a raw > casting that is just machined into a finished part and that's it, it would > still be treated as a sort of assembly, with the raw casting being a > component of the finished part number, if that makes sense. > > So there's all this information associated with a given part. I am > thinking it has a sort of tree structure. I am just wondering if some of > the branches of the tree should be separate classes that are then tied into > the "trunk" of the master class, or if the whole thing should be a tree into > and of itself. > > ...and yeah, I know, it's kind of a complex problem for a newbie to be > thinking about. > > > > Here is my two-cents. This code is untested. Import statements haven't been included, there could be syntax errors, etc etc etc. What I did was switching off the part_number attribute in the Thing class. For the functions that "do stuff" to the thing instance, I appended a part-number (assuming new part number = master number + doing stuff number). The quality functions will check for that part number before proceeding with the checks. class Thing: # single part class def __init__(self,part_number='12345'): # 12345 is a default part number self.part_number=part_number def routeThing(thing): try: thing.part_number.append('-someRoutingPartNumber') exception AttributeError (e): e.printStackTrace() print "Router was not applied to thing" def checkQualityRoute1(thing): if hasattrib(thing,part_number) && (thing.part_number.find('-someRoutingPartNumber'): else: print "Thing has not be routed yet" def checkQualityRoute2(thing): if hasattrib(thing,part_number) && (thing.part_number.find('-someRoutingPartNumber'): else: print "Thing has not be routed yet" continue for all of the functions that you might need HTH, -Tino ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Elwin Estle wrote: > Is it better to have one large sort of "do it all" class, or break > the larger class up into smaller classes? Yes. Or no. It's impossible to answer that question definitively without knowing more about what "it all" is. But I can give some general advice: * Python isn't Java. Don't feel that you must use classes. If your problem is better solved using a procedural or functional approach, go right ahead and use it. Classes aren't compulsory. * The standard model which you should use it: verbs -> functions or methods nouns -> classes or attributes You should be able to answer the question "What *thing* does your class represent?". (The answer can be an abstract thing, but it should be a thing.) If you can't answer that question, then you shouldn't use a class. You should solve the problem using stand-alone functions. * Think about "is-a" and "has-a" relationships: == The class in question, does, in fact, deal with a thing. The problem is, the "thing" is highly mutable. The "is-a" and the "has-a" changes. Here is the scenario: A raw casting comes into a factory. It is listed as such. When machined, this part number changes to a different part number. The raw casting has no "quality related" stuff, but the machined casting does, and it can have more than one "quality related" thing. ...because, the raw casting may go through multiple operations to get to it's final state. It may get machined on a lathe, then be transferred to a CNC machining station where a bolt circle may be drilled and tapped into it. Each of those operations on separate machines will have a different set of quality checks associated with it. ...or it might be a part that goes from a raw casting to a sort of "mini-assembly" such as a rocker lever (if you know what that is), so we have raw casting = one part number, then it gets a bushing pressed into it = another part number, then it gets a threaded insert = another part number, but it is still the same thing, and each one of those steps may have some sort of quality check involved. Lets complicate things even further. One raw casting may be machined into multiple part numbers. Perhaps the only thing that changes is the location of a single hole. But again, each one of those part numbers may go through multiple machining operations on different machines, with different quality checks. This is done through something called a "tabbed" blueprint, wherein there is a master number, but there are "tabs" indicating that if you changes such and such feature, then the part number isn't the master number, but the tabbed number. So, in essence, there's a sort of "network" of "is-a" and "has-a" information. My idea was to, instead of having just a single "part" class, to have a sort of "component aggregate" class, which would cover not only single parts, but assemblies of parts. So, even if a part was as simple as a raw casting that is just machined into a finished part and that's it, it would still be treated as a sort of assembly, with the raw casting being a component of the finished part number, if that makes sense. So there's all this information associated with a given part. I am thinking it has a sort of tree structure. I am just wondering if some of the branches of the tree should be separate classes that are then tied into the "trunk" of the master class, or if the whole thing should be a tree into and of itself. ...and yeah, I know, it's kind of a complex problem for a newbie to be thinking about. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
I know the the law of Murphy. But this one is a must-have.:-) Regards Karim * One way to reduce coupling is with the Law of Demeter: if you want your dog to walk, don't talk to your dog's legs. You will only confuse the dog and it won't get anywhere. http://en.wikipedia.org/wiki/Law_of_Demeter Hope this helps. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Sure, but I come from java world and 1 inheritance is allowed but we can implement multiple interfaces. I like to use Abstract classes in Python then inherit and implement abstract method like in java (at least that's all I remember from Java experience). Indeed I was too direct everybody has the same style. Regards Karim On 01/26/2011 12:08 PM, Alan Gauld wrote: "Karim" wrote Program towards interface that means you have to use inheritance. Just to be picky, you can program by interface without using inheritance. Inheritance is only needed to implement interfaces in languages like C++. In Python (and other dynamically bound OOP languages) you can use polymorphism without inheritance. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
"Karim" wrote Program towards interface that means you have to use inheritance. Just to be picky, you can program by interface without using inheritance. Inheritance is only needed to implement interfaces in languages like C++. In Python (and other dynamically bound OOP languages) you can use polymorphism without inheritance. -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
On 01/25/2011 08:50 PM, Steven D'Aprano wrote: > Corey Richardson wrote: >> On 01/25/2011 06:26 PM, Elwin Estle wrote: >>> Is it better to have one large sort of "do it all" class, or break >>> the larger class up into smaller classes? > >> If you're just learning, go ahead and make a 'do it all' class. Don't do >> it later in your growth as a programmer though. > > Learn bad habits first, then spend years trying to break them! > > *wink* Hey, gotta learn the concepts first, right? ;-) I remember my first "substantial" program, hangman! Quite a mess. Excerpt: def getlist3(self): list3 = [] for i in range(5): list3.append(self.gameWord[i]) self.list3 = list3 I don't even remember what list3 is. I have a whole function for a list comprehension! self.list3 = [char for (idx, char) in enumerate(gameWord) if gameWord.index(char, idx) < 5] (list3 happened to be the hint characters given, remembered while doing) Just proof that it doesn't have to take years, it could take months. ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Corey Richardson wrote: On 01/25/2011 06:26 PM, Elwin Estle wrote: Is it better to have one large sort of "do it all" class, or break the larger class up into smaller classes? If you're just learning, go ahead and make a 'do it all' class. Don't do it later in your growth as a programmer though. Learn bad habits first, then spend years trying to break them! *wink* -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Elwin Estle wrote: Is it better to have one large sort of "do it all" class, or break the larger class up into smaller classes? Yes. Or no. It's impossible to answer that question definitively without knowing more about what "it all" is. But I can give some general advice: * Python isn't Java. Don't feel that you must use classes. If your problem is better solved using a procedural or functional approach, go right ahead and use it. Classes aren't compulsory. * The standard model which you should use it: verbs -> functions or methods nouns -> classes or attributes You should be able to answer the question "What *thing* does your class represent?". (The answer can be an abstract thing, but it should be a thing.) If you can't answer that question, then you shouldn't use a class. You should solve the problem using stand-alone functions. * Think about "is-a" and "has-a" relationships: - if x is a Foo, then use a class Foo and make x an instance of Foo - if x has a Foo, then give x an attribute x.foo which is a Foo * Classes should represent a *single* well-defined thing. That might be a compound thing, or a collection of things -- the class represents the entire collection. If the thing is made of parts, each part could be represented by an attribute. This is okay: class Coffee: def __init__(self): self.style = 'white' self.milk = 'full cream' self.sugars = 1 self.size = 'regular' class Pie: def __init__(self): self.kind = 'cherry' self.slices = 1 self.with_cream = False class SpecialOfTheDay: def __init__(self): self.drink = Coffee() self.snack = Pie() But don't design a class like this: class CoffeeAndPie: def __init__(self): self.style = 'white' self.milk = 'full cream' self.sugars = 1 self.size = 'regular' self.kind = 'cherry' self.slices = 1 self.with_cream = False One slice of coffee? Oh really? * Classes should be more general rather than too specific. But don't go crazy and make it so abstract that you run out of air to breathe, and nobody can understand what the hell the class is for: http://www.joelonsoftware.com/articles/fog18.html * Coupling is usually bad. Aim to reduce coupling, unless you have a good reason for wanting strongly coupled systems. What's coupling? A key and a lock are *highly* coupled: only one key will fit the lock, and no other key will do the job. But, say, a knife and a steak are loosely coupled. Any sharp knife will cut a steak. Sure, some knives are better than others, but at a pitch, you could even use a blunt butter-knife and a lot of effort. Another example: your clothes iron and ironing board have very loose coupling. You can use any iron on any board, and it will be just fine. But the memory cards in your computer are moderately coupled with the motherboard: only some memory cards will fit. You can't use a 1980 64K memory card in a 2011 motherboard. But provided the memory will fit, it doesn't matter which card you use. * One way to reduce coupling is with the Law of Demeter: if you want your dog to walk, don't talk to your dog's legs. You will only confuse the dog and it won't get anywhere. http://en.wikipedia.org/wiki/Law_of_Demeter Hope this helps. -- Steven ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Hello, Design Patterns is the key for code reuse and problem solving. Indeed you have to separate your objects (classes) to use it. The god class is like a script with only one function: not very flexible and easy to debug. Program towards interface that means you have to use inheritance. Try to determine the objects you need for your problem and next step is how arrange it together (relational). Regards Karim On 01/26/2011 01:28 AM, Marc Tompkins wrote: On Tue, Jan 25, 2011 at 3:26 PM, Elwin Estle wrote: Is it better to have one large sort of "do it all" class, or break the larger class up into smaller classes? Seems to me like the one large class would be clearer in some ways. I have something I am trying to do that have somewhere in the neighborhood of 20 attributes that all relate together, however there are sort of "clumps" of attributes that have a sub-relationship to each other and I wondered if they should be their own class, but I am not sure, assuming that is a good idea, how these smaller classes might work together. I have only the foggiest notion of inheritance and I'd kind of like to stay away from that aspect of things until I get a better grasp of individual classes. For me, the question of one big class/multiple smaller classes comes down to reusability. If you find yourself writing the same code over and over again (or cutting/pasting big blocks of code), you should probably break up your classes. -- www.fsrtechnologies.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
"Elwin Estle" wrote Is it better to have one large sort of "do it all" class, or break the larger class up into smaller classes? Usually the latter. But remember that classes model objects. Objects usually have a direct relationship to some kind of "real world" entity - even if its an abstract conceptual entity. So if the attributes and behaviours are all exhibited by the thing you are modelling then they should maybe stay together. But uasually the big thing can be modelled as a composition of smaller things... Seems to me like the one large class would be clearer in some ways. Very rarely is a big lump of code clearer than several small single purpose lumps of code. And big lumps of code are nearly always harder to reuse - one of the other reasons to create classes... I have something I am trying to do that have somewhere in the neighborhood of 20 attributes that all relate together, however there are sort of "clumps" of attributes that have a sub-relationship to each other Without specifics we can't be sure. But it sounds like you have a composite structure. OTOH 20 attributes is not enormous - 200 would be, but not 20. But even 20 is enough to challenge. I have only the foggiest notion of inheritance It doesn't sound like inheritance is an issue here. It sounds like we are talking about composition. But without specific details we can't be sure. Remember that the thing that defines a class should be its operations not its data. Do these smaller "clumps of attributes" have common behaviour associated with them? The data should only be there to support the operations. HTH, -- Alan Gauld Author of the Learn to Program web site http://www.alan-g.me.uk/ ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
On Tue, Jan 25, 2011 at 3:26 PM, Elwin Estle wrote: > > Is it better to have one large sort of "do it all" class, or break the larger > class up into smaller classes? Seems to me like the one large class would be > clearer in some ways. I have something I am trying to do that have somewhere > in the neighborhood of 20 attributes that all relate together, however there > are sort of "clumps" of attributes that have a sub-relationship to each other > and I wondered if they should be their own class, but I am not sure, assuming > that is a good idea, how these smaller classes might work together. I have > only the foggiest notion of inheritance and I'd kind of like to stay away > from that aspect of things until I get a better grasp of individual classes. > For me, the question of one big class/multiple smaller classes comes down to reusability. If you find yourself writing the same code over and over again (or cutting/pasting big blocks of code), you should probably break up your classes. -- www.fsrtechnologies.com ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
On 01/25/2011 06:26 PM, Elwin Estle wrote: > Is it better to have one large sort of "do it all" class, or break the larger > class up into smaller classes? Seems to me like the one large class would be > clearer in some ways. I have something I am trying to do that have somewhere > in the neighborhood of 20 attributes that all relate together, however there > are sort of "clumps" of attributes that have a sub-relationship to each other > and I wondered if they should be their own class, but I am not sure, assuming > that is a good idea, how these smaller classes might work together. I have > only the foggiest notion of inheritance and I'd kind of like to stay away > from that aspect of things until I get a better grasp of individual classes. > If you're just learning, go ahead and make a 'do it all' class. Don't do it later in your growth as a programmer though. Inheritance works like this: class Parent: def __init__(self): print "Parent initialised" class Child(Parent): pass The parenthesis set the superclass or parent class. If you now do: c = Child() You should see "Parent initialised" printed to the terminal. It makes all the 'parents' methods available to it. You can think of it as copying all the code from the parent class into the child class. You can overwrite the methods too: class Animal: def speak(self): print self.noise class Pig(Animal): def __init__(self): self.noise = "Oink!" pig = Pig() pig.speak() Hope it helped, ~Corey ___ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
Ooops, didn't see Alan's post before I sent this... JS >> Your second way seems to make more sense. And instead of raising the >> error, why not just print it: > > There is a very good reason for this and it's important that you > understand > it to write good code. If you use a print statement, you break the benefit > of encapsulation. > > If you were to use that class in a GUI application, for example, you would > never know if the account had become overdrawn. Only by using an exception > could you use that class effectively in both circumstances, and in the > same > way! > > a = BankAccount() > try: > a.withdraw(50) > except: > notify_error() > > Where notify error depends on how you want to communicate that information > to the end-user. (messagebox, display, stdout, stderr, file, etc) > > JS ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
At 03:12 PM 7/13/2007, Alan Gauld wrote: >"Dick Moores" <[EMAIL PROTECTED]> wrote > > > Thanks. You've clarified it for me completely. > > > > Your second way seems to make more sense. > > And instead of raising the error, why not just print it: > >Because that would make the class much less reusable. >It would be limited to applications using stdout. A GUI >banking program would be unable to use the BankAccount >class. But by raising an exception the user gets to decide >what to do, either pop up a dialog, print a message or send >an email to the banks client. > >Its a primary design goal for reuse to de-couple business >logic - like the bank account - from the user interface. > >There is a bit more discussion around this in my >Case Study topic where I convert it from command >line to GUI and again in my InterProcess Comms topic >where I turn the AddressBook into a client-server app. Thanks, Alan. I'll check it out. Dick ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
> Your second way seems to make more sense. And instead of raising the > error, why not just print it: There is a very good reason for this and it's important that you understand it to write good code. If you use a print statement, you break the benefit of encapsulation. If you were to use that class in a GUI application, for example, you would never know if the account had become overdrawn. Only by using an exception could you use that class effectively in both circumstances, and in the same way! a = BankAccount() try: a.withdraw(50) except: notify_error() Where notify error depends on how you want to communicate that information to the end-user. (messagebox, display, stdout, stderr, file, etc) JS ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
"Dick Moores" <[EMAIL PROTECTED]> wrote > Thanks. You've clarified it for me completely. > > Your second way seems to make more sense. > And instead of raising the error, why not just print it: Because that would make the class much less reusable. It would be limited to applications using stdout. A GUI banking program would be unable to use the BankAccount class. But by raising an exception the user gets to decide what to do, either pop up a dialog, print a message or send an email to the banks client. Its a primary design goal for reuse to de-couple business logic - like the bank account - from the user interface. There is a bit more discussion around this in my Case Study topic where I convert it from command line to GUI and again in my InterProcess Comms topic where I turn the AddressBook into a client-server app. HTH, -- Alan Gauld Author of the Learn to Program web site http://www.freenetpages.co.uk/hp/alan.gauld ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
At 12:35 PM 7/13/2007, [EMAIL PROTECTED] wrote: However if you try to withdraw any money after you took out the $25 it would raise the error. The overdrawn function checks if you are in the negatives. Since the balance is checked before the money is taken out, there is no error when you take out the $25. If you wan the error to be raised whenever you go negative simply switch the withdrawal and the function call in withdraw def withdraw(self, amount): self.balance -= amount if self.overdrawn(): raise "Insufficient Funds Error" and if you don't want the money taken out if there is insufficient funds, just add the withdrawn amount back: def withdraw(self, amount): self.balance -= amount if self.overdrawn(): self.balance += amount raise "Insufficient Funds Error, no money withdrawn" Thanks. You've clarified it for me completely. Your second way seems to make more sense. And instead of raising the error, why not just print it: class BankAccount(object): def __init__(self, initial_balance=0): self.balance = initial_balance def deposit(self, amount): self.balance += amount def withdraw(self, amount): self.balance -= amount if self.overdrawn(): self.balance += amount print "Insufficient Funds, no money withdrawn" def overdrawn(self): return self.balance < 0 my_account = BankAccount(15) my_account.withdraw(25) print "Account balance is", my_account.balance Dick ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
However if you try to withdraw any money after you took out the $25 it would raise the error. The overdrawn function checks if you are in the negatives. Since the balance is checked before the money is taken out, there is no error when you take out the $25. If you wan the error to be raised whenever you go negative simply switch the withdrawal and the function call in withdraw def withdraw(self, amount): self.balance -= amount if self.overdrawn(): raise "Insufficient Funds Error" and if you don't want the money taken out if there is insufficient funds, just add the withdrawn amount back: def withdraw(self, amount): self.balance -= amount if self.overdrawn(): self.balance += amount raise "Insufficient Funds Error, no money withdrawn" Chris Henk Allison Transmission phone: 317.242.2569 fax: 317.242.3469 e-mail: [EMAIL PROTECTED] Dick Moores <[EMAIL PROTECTED]> Sent by: [EMAIL PROTECTED] 07/13/2007 03:04 PM To Tiger12506 <[EMAIL PROTECTED]>, cc Subject Re: [Tutor] class question At 05:35 AM 7/13/2007, Tiger12506 wrote: > > === > > class BankAccount(object): > >def __init__(self, initial_balance=0): > >self.balance = initial_balance > >def deposit(self, amount): > >self.balance += amount > >def withdraw(self, amount): > >self.balance -= amount > >def overdrawn(self): > >return self.balance < 0 > > my_account = BankAccount(15) > > my_account.withdraw(5) > > print my_account.balance > > = > > > > This prints the expected "10". > > > > My question is, of what use can "overdrawn" be put? If I change the > > withdrawal amount to 25, it prints the expected "-10", whether the class > > contains the "overdrawn" function or not. > > > > Thanks, > > > > Dick Moores > >A very good question. Now I have one for you. What does your bank do when >you try to withdraw money? First, it checks to see if you have the money in >your account. If you do, it subtracts that out of your balance. Whoever >wrote that code failed to do the check within the withdraw function. > >=== >class BankAccount(object): >def __init__(self, initial_balance=0): >self.balance = initial_balance >def deposit(self, amount): >self.balance += amount >def withdraw(self, amount): >if self.overdrawn(): > raise "Insufficient Funds Error" >self.balance -= amount >def overdrawn(self): >return self.balance < 0 >my_account = BankAccount(15) >my_account.withdraw(5) >print my_account.balance >= But when I run that with a withdrawal of 25, it still prints only "-10". How have you involved the "overdrawn" function? Dick ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
At 05:35 AM 7/13/2007, Tiger12506 wrote: > > === > > class BankAccount(object): > >def __init__(self, initial_balance=0): > >self.balance = initial_balance > >def deposit(self, amount): > >self.balance += amount > >def withdraw(self, amount): > >self.balance -= amount > >def overdrawn(self): > >return self.balance < 0 > > my_account = BankAccount(15) > > my_account.withdraw(5) > > print my_account.balance > > = > > > > This prints the expected "10". > > > > My question is, of what use can "overdrawn" be put? If I change the > > withdrawal amount to 25, it prints the expected "-10", whether the class > > contains the "overdrawn" function or not. > > > > Thanks, > > > > Dick Moores > >A very good question. Now I have one for you. What does your bank do when >you try to withdraw money? First, it checks to see if you have the money in >your account. If you do, it subtracts that out of your balance. Whoever >wrote that code failed to do the check within the withdraw function. > >=== >class BankAccount(object): >def __init__(self, initial_balance=0): >self.balance = initial_balance >def deposit(self, amount): >self.balance += amount >def withdraw(self, amount): >if self.overdrawn(): > raise "Insufficient Funds Error" >self.balance -= amount >def overdrawn(self): >return self.balance < 0 >my_account = BankAccount(15) >my_account.withdraw(5) >print my_account.balance >= But when I run that with a withdrawal of 25, it still prints only "-10". How have you involved the "overdrawn" function? Dick ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] class question
> === > class BankAccount(object): >def __init__(self, initial_balance=0): >self.balance = initial_balance >def deposit(self, amount): >self.balance += amount >def withdraw(self, amount): >self.balance -= amount >def overdrawn(self): >return self.balance < 0 > my_account = BankAccount(15) > my_account.withdraw(5) > print my_account.balance > = > > This prints the expected "10". > > My question is, of what use can "overdrawn" be put? If I change the > withdrawal amount to 25, it prints the expected "-10", whether the class > contains the "overdrawn" function or not. > > Thanks, > > Dick Moores A very good question. Now I have one for you. What does your bank do when you try to withdraw money? First, it checks to see if you have the money in your account. If you do, it subtracts that out of your balance. Whoever wrote that code failed to do the check within the withdraw function. === class BankAccount(object): def __init__(self, initial_balance=0): self.balance = initial_balance def deposit(self, amount): self.balance += amount def withdraw(self, amount): if self.overdrawn(): raise "Insufficient Funds Error" self.balance -= amount def overdrawn(self): return self.balance < 0 my_account = BankAccount(15) my_account.withdraw(5) print my_account.balance = JS ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor