Re: Is behavior of += intentional for int?
On Sun, Aug 30, 2009 at 05:43:42PM +, OKB (not okblacke) wrote: > Derek Martin wrote: > > > If Python is to say that objects have values, > > then the object can not *be* the value that it has, because that is a > > paradoxical self-reference. It's an object, not a value. > > But does it say that objects have values? I don't see where you > get this idea. Yes, it does say that. Read the docs. :) http://docs.python.org/reference/datamodel.html (paragraph 2) > class A(object): > pass > a = A() > > What is the "value" of the object now bound to the name "a" In Python, the value of objects depends on the context in which it is evaluated. But when you do that, you're not getting a value that is equivalent to object, but of some property of the object. The object has no intrinsic value until it is evaluated. In that sense, and as used by the python docs, I would say that the value of the object a is "true" -- you can use it in boolean expressions, and it will evaluate as such. > I would say that in Python, objects do not have values. > Objects are values. You can say that, but if you do you're using some definition of "value" that's only applicable in Python and programming languages which behave the same way. It would be more correct to say that an object is a collection of arbitrary data, which has a type and an identity, and that the data in that collection has a value that evaluates in context. An object is an abstract collection of data, and abstractions have no value. You can not measure them in any meaningful way. The data contained in the collection does, however, have a value. When you reference an object in an expression, what you get is not the value of the object, but the value of some peice of data about, or contained in, that object. It is this property of objects, that the value evaluated depends on the context, that I think demonstrates that an object is *not* a value. Values never change, as we've said in this thread: 3 is always 3. 'a' is always 'a'. But an object x can evaluate to many different values, depending on how it is used. The definition of the object would need to allow for it to do so, but Python allows that, and even encourages it. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpPXZKHxLKRw.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Is behavior of += intentional for int?
On Sun, Aug 30, 2009 at 04:26:54AM -0700, Carl Banks wrote: > On Aug 30, 12:33 am, Derek Martin wrote: > [snip rant] I was not ranting. I was explaining a perspective. > > THAT is why Python's behavior with regard to numerical objects is > > not intuitive, and frankly bizzare to me, and I dare say to others who > > find it so. > > > > Yes, that's right. BIZZARE. > > You mean it's different from how you first learned it. I mean exactly that I find it "strikingly out of the ordinary; odd, extravagant, or eccentric in style or mode" as Webster's defines the word. Whether it is so because it is different from how I first learned it, or for some other reason, it is so nonetheless. I have elsewhere gone into great detail about why I find it so. If you need it to be simple, then feel free to simplify it. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpDMB4n3PKex.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Is behavior of += intentional for int?
On Sun, Aug 30, 2009 at 03:52:36AM -0700, Paul McGuire wrote: > > It is surprising how many times we > > think things are "intuitive" when we really mean they are "familiar". > > Of course, just as I was typing my response, Steve D'Aprano beat me to > the punch. Intuition means "The power or faculty of attaining to direct knowledge or cognition without evident rational thought and inference." Very naturally, things which behave in a familiar manner are intuitive. Familiar and intuitive are very closely tied. Correspondingly, when things look like something familiar, but behave differently, they are naturally unintuitive. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpMl4G8ABoo7.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Is behavior of += intentional for int?
On Sun, Aug 30, 2009 at 03:42:06AM -0700, Paul McGuire wrote: > Python binds values to names. Always. No, actually, it doesn't. It binds *objects* to names. This distinction is subtle, but important, as it is the crux of why this is confusing to people. If Python is to say that objects have values, then the object can not *be* the value that it has, because that is a paradoxical self-reference. It's an object, not a value. > Is it any odder that 3 is an object than that the string literal > "Hello, World!" is an object? Yes. Because 3 is a fundamental bit of data that the hardware knows how to deal with, requiring no higher level abstractions for the programmer to use it (though certainly, a programming language can provide them, if it is convenient). "Hello, World!" is not. They are fundamentally different in that way. > For a Python long-timer like Mr. D'Aprano, I don't think he even > consciously thinks about this kind of thing any more; his intuition > has aligned with the Python stars, so he extrapolates from the OP's > suggestion to the resulting aberrant behavior, as he posted it. I'm sure that's the case. But it's been explained to him before, and yet he still can't seem to comprehend that not everyone immediately gets this behavior, and that this is not without good reason. So, since it *has* been explained to him before, it's somewhat astonishing that he would reply to zaur's post, saying that the behavior zaur described would necessarily lead to the insane behavior that Steven described. When he makes such statements, it's tantamount to calling the OP an idiot. I find that offensive, especially considering that Steven's post displayed an overwhelming lack of understanding of what the OP was trying to say. > You can dispute and rail at this core language concept if you like, > but I think the more entrenched you become in the position that "'3 is > an object' is bizarre", the less enjoyable your Python work will be. While I did genuinely find the behavior bizarre when I encountered it, and honestly still do, I learned it quickly and moved past it. I'm not suggesting that it be changed, and I don't feel particularly strongly that it even should change. It's not so much the language I'm railing against, but the humans... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpacvVblOJRP.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Is behavior of += intentional for int?
On Sun, Aug 30, 2009 at 10:34:17AM +, Steven D'Aprano wrote: > > He's saying that instead of thinking the integer value of 3 itself being > > the object, he expected Python's object model would behave as though the > > entity m is the object, and that object exists to contain an integer > > value. > > > What is "the entity m"? The entity m is an object. Objects, in computer science, are abstractions created by humans to make solving a large class of problems easier to think about. An object is a piece of data, upon which you can perform programmatic actions, which are grouped together with the values contained in that data. It's an abstraction which translates, in the physical sense, to a group of memory locations with a reference in a symbol table. > Ah wait, I think I get it... is m a memory location? No, it isn't. It is an abstraction in the programmer's mind that sits on top of some memory. For that matter, the memory location is itself an abstraction. It is not a memory location, but a particular series of circuits which either have current or don't. It is simply convenient for us to think of it as a memory location. > That would be how Pascal and C (and presumably other languages) > work, but not Python or Ruby or even VB (so I'm told) and similar > languages. Well, except that, in fact, they do work that way. They simply present a different abstraction to the programmer than C or other languages. They have to work that way, at the lowest level, because that is how the hardware works. > > Numbers are fundamentally different from objects. The number 3 is a > > symbol of the idea of the existence of three countable objects. It can > > not be changed > > Doesn't this contradict your claim that people expect to be able to > mutate numbers? That you should be able to do this? This is where you continually fail. There is no contradiction at all. What I'm saying is that in my view, numbers CAN'T mutate; they are not objects! They are values, which are a means of describing objects. Only the objects which hold the values can mutate. However in Python they don't, and can't, but they EASILY could with a different design. You, however, seem to be completely stuck on Python's behavior with regard to numeric objects, and fail to see past that. Python's model is only one abstraction, among multiple possibilities. > You can't have it both ways -- if people think of objects as > mutable, and think of numbers as not-objects and unchanging, then > why oh why would they find Python's numeric behaviour to be > unintuitive? Because in Python, they ARE objects, which they think should be mutable, but in Python when they try to change the *value* of the object, they don't get the same object with a different value; they get a completely different object. This is counter to their experience. If you don't like the Buick example, then use algebra. We've been down this road before, so I'm probably wasting my time... In algebra, you don't assign a name to a value, you assign a value to a variable. You can, in a different problem, assign a different value to that variable, but the variable didn't change; only its value did. In Python, it's the opposite. > What I think is that some people, such as you and Zaur, have *learned* > from C-like languages that numbers are mutable not-objects, and you've > learned it so well that you've forgotten that you ever needed to learn > it. No, this is precisely why I provided the real-world examples -- to illustrate to you that there was no need to learn it in computer science, because the concept applies in the real world quite intuitively in every-day situations. I think rather it is YOU who have learned the concept in Python, and since then fail to imagine any other possible interpretation of an object, and somehow have completely forgotten the examples you encountered before Python, from algebra and from the real world. > Human beings are excellent at reifying abstract things into (imaginary) > objects. I don't know what the word "reifying" means, but irrelevant. Such things are abstract, and in fact not objects. > No, the length of a car is an object which *is* a length, it doesn't > *have* a length. It is not an object. It is an abstract idea used as a description of an object. > None of this explains why you would expect to be able to mutate the > value three and turn it into four. Again, you fail. I *DO NOT* expect that. I expect to be able to mutate the object m, changing its value from 3 to 4. > I think you have confused yourself. No Steven, on this topic, it is only you who have been confused, perpetually. Although, it could be said that Python's idea of what an object is also is itself confused... Python (or at least the docs) actually refrains from formally defining an object. The docs only say that an object has an identity, a name, and a value. W
Re: Is behavior of += intentional for int?
On Sat, Aug 29, 2009 at 07:03:23PM +, Steven D'Aprano wrote: > On Sat, 29 Aug 2009 11:11:43 -0700, zaur wrote: > > > I thought that int as object will stay the same object after += but with > > another integer value. My intuition said me that int object which > > represent integer value should behave this way. > > If it did, then you would have this behaviour: No, you wouldn't; the behavior you described is completely different from, and incompatible with, what zaur wrote. He's saying that instead of thinking the integer value of 3 itself being the object, he expected Python's object model would behave as though the entity m is the object, and that object exists to contain an integer value. In that case, m is always m, but it has whatever integer value it is told to hold at any point in time. The self-referential addition would access the value of m, add the operand, and store the result back in the same object as the object's value. This is not the way Python works, but he's saying this is the intuitive behavior. I happen to agree, and argued at length with you and others about that very thing months ago, when some other third party posted with that exact same confusion. By contrast, your description maintains the concept of numerical value as object that Python uses, and completely misses the point. I did find the description you gave to be highly enlightening though... It highlighted perfectly, I think, exactly why it is that Python's behavior regarding numerical values as objects is *not* intuitive. Of course, intuition is highly subjective. I believe it boils down to this: People expect that objects they create are mutable. At least, unless they specify otherwise. It is so in some other programming languages which people may be likely to be familiar with (if they are not taking their first forray into the world of computing by learning Python), and even "real world" objects are essentially always mutable. If you have a 2002 Buick LeSabre, it has a number of attributes, including its length, which might be 8.5 feet, for instance. However, this is not fixed: by adding modified body parts, or as an extreme example by sawing off the trunk of the car, the length and indeed the object itself has been changed. However, despite having been modified, it is at least in some sense still the same object: it is still a 2002 Buick LeSabre, and it still has the same *identity* (the same VIN number). It's the same object, but its value(s) changed. [Not that it matters, but I do not own such a car. :)] Numbers are fundamentally different from objects. The number 3 is a symbol of the idea of the existence of three countable objects. It can not be changed (though it can be renamed, if you so choose -- just don't expect most people to know what you're talking about). It is unintuitive that 3 is an object; it is rather what we use to describe objects -- the value of the object. It is an abstract concept, and as such it is not an object at all. You cannot hear 3, taste 3, nor smell 3. You can neither see nor touch 3, though you can certainly see 3 *objects* if they are present, and you can certainly see the symbol '3' that we use to represent that idea... but you can not see three itself, because there is no such object. The only way to see three is to envision 3 of some object. The number 3 does not have a value; it IS a value (it is the symbolic representation of the value of three). To say that 3 is an object that has a value is a bit like saying the length of a car is an object that itself has a length. It just doesn't compute. THAT is why Python's behavior with regard to numerical objects is not intuitive, and frankly bizzare to me, and I dare say to others who find it so. Yes, that's right. BIZZARE. Of course, none of this is real. In the end, it's all just a bunch of wires that either have current or don't. It's only how *WE* organize and think about that current that gives it any meaning. So you're free to think about it any way you like. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpyymVqHadto.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Mon, Aug 24, 2009 at 04:40:14PM -0300, Gabriel Genellina wrote: > En Mon, 24 Aug 2009 14:40:24 -0300, Derek Martin > escribió: > > >Why is it so hard for you to accept that intelligent people can > >disagree with you, and that what's right for you might be bad for > >others? > > Ask the same question yourself please. I accept it. But I reserve the right to voice my dissent, and am doing so. The Usual Suspects in this forum seem to suggest that the change is some silver bullet that makes Python suddenly Right With The World, and I say it just ain't so. I happen to opine that the old behavior was better, and I will not be dissuaded from that opinion just because a few prominent posters in this forum suggest that I'm an idiot for disagreeing with them. My original post in this thread, if you weren't paying attention, was in opposition to several people trying to cram the idea down the throats of other posters that leading zeros to represent octal numbers is inherently evil, and that anyone who suggests otherwise is an Apostate to be damned for all eternity. Alright, I exaggerate. Slightly. :) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpOhCKxjgCon.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Mon, Aug 24, 2009 at 05:03:28PM +, Steven D'Aprano wrote: > On Mon, 24 Aug 2009 11:21:46 -0500, Derek Martin wrote: > > since the old syntax is prevalent both within and without the > > Python community, making the change is, was, and always will be a > > bad idea. > > Octal syntax isn't prevalent *at all*, except in a small number of > niche areas. Steven, don't be obtuse. Where octal is used in programming, the leading zero is prevalent. > You've said that this change is a hardship for you, because on your > terminal 0 and o are hard to distinguish. Personally, I'd say that's a > good sign that your terminal is crappy and you should use a better one, The terminal I use is just fine. Stringing together similar characters always has the possibility of confusing the reader. The human mind tends to see what it expects, and fills in the gaps when it does not. It wouldn't matter much if I changed my terminal font, unless I made the font big enough to be not especially useful, except for the rather exceptional case of detecting 0o1 and similar patterns in python code. The suggestion is asinine, and you know it. > but putting that aside, let's accept that. To you, for whatever reason, > 0o looks just like 00. It doesn't look "just like" 00, but similar enough that you have to pay close attention. > Okay then. Under the current 2.x syntax, 0012 would be interpreted as > octal. Under the new 3.x syntax, 0o12 which looks just like 0012 also > would be interpreted as octal. You have argued that it might not be any > harder to type the extra 'o' to get an octal literal, but that it will > hurt readability. I quote: > > "Writing 0o12 presents no hardship; but I assert, with at least some > support from others here, that *reading* it does." Let me clarify my statement. Writing 0o12 is easy -- there is no hardship to type the characters 0o12 (well, actually it feels a bit cumbersome, to be honest). Remembering to do so, however, when virtually everwhere else one uses octal writes it 012, is not easy. Then I stand corrected: There is indeed hardship. > But according to you, reading 0o12 is just like reading 0012. 0o12 under > the new syntax gives decimal ten, and it looks just like 0012 in the old > syntax, which also gives ten. So there's no difference in reading, But there *IS* a difference in reading, because 0o12 is not the same as 0012, and which one you use *matters*. In particular, it will matter with the adoption of Python 3.x, where the latter will be an error. But it matters even in 2.6 because right now, you can write it either way, and that is (I think) even more confusing... There is also still discussion (mentioned in the relevant PEP) about making 0012 *valid decimal*. That should never, ever, ever happen. Why is it so hard for you to accept that intelligent people can disagree with you, and that what's right for you might be bad for others? -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp98RVkdfZRq.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Mon, Aug 24, 2009 at 04:47:43PM +, Steven D'Aprano wrote: > Except of course to anyone familiar with mathematics in the last, oh, > five hundred years or so. Mathematics has used a positional system for > numbers for centuries now: leading zeroes have been insignificant, just > like trailing zeroes after the decimal point: > > 9 = 09 = 009 = 9.0 = 9.00 = 0009.000 etc. Dude, seriously. No one ever *uses* leading zeros in the context of mathematics except in 2nd grade math class. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpCgRpbc7UrM.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Mon, Aug 24, 2009 at 08:31:13AM -0700, Carl Banks wrote: > On Aug 24, 6:56 am, Derek Martin wrote: > > I think hard-coding dates is more uncommon than using octal. ;-) > > [It unquestionably is, for me personally.] > > You just don't get it, do you? I think I get it just fine, thanks. > Do you really think this is a contest over what's more common and > the winner gets to choose the syntax? You really think that's the > issue? No, I think it's about egos. Someone got the idea that 0o1 was better than 01, and had to be Right. And had the power to make it happen, or at least (sadly) convince the people with the power. I'm simply presenting an argument that the need for the change is not so clear. You say the old syntax is retarded. I say the new syntax, and the very act of making the change itself is retarded. I think my argument is very solid and persuasive; but of course some minds are invulnerable to persuasion. I might not even disagree that the old syntax could be improved upon, except that it already is what it is, and the new syntax is NOT better; I personally believe it's not only not better, but that it's actually worse. Others have agreed. > It is not. The issue is that C's arcane octal notation is MIND- > BOGGLINGLY RETARDED. As I said, I searched the web on this topic before I bothered to post. I did a bit of research. One of the things that my search turned up: A lot of smart people disagree with you. If the use of the leading zero boggles your mind, then perhaps your mind is too easily boggled, and perhaps you should seek a different way to occupy your time. This is yet another case where some Pythonista has gotten it in his head that "There is One Truth, and the Old Way be Damned, my way is The Way, and Thus Shall It Be Evermore." And worse yet, managed to convince others. Well, there's no such thing as One Truth, and there are different perspectives that are just as valid as yours. I'm expressing one now. This change sucks. I already know that my rant won't change the syntax. The only reason I bothered to post is because I do actually quite like Python -- something I can say of only one other programming language -- and I think the powers that be are (in some cases) making it worse, not better. I hoped to open a few minds with a different perspective, but of course I should have known better. 0o1 is not better than 01. On my terminal it's hard to see the difference between 0 and o. YMMV. But since YMMV, and since the old syntax is prevalent both within and without the Python community, making the change is, was, and always will be a bad idea. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpP7sETirZLX.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Mon, Aug 24, 2009 at 05:22:39PM +0200, Hendrik van Rooyen wrote: > > Assuming I'm right about that, then the use of a leading 0 to > > represent octal actually predates the prevalence of using 0 in dates > > by almost two decades. > > Not quite - at the time I started, punch cards and data entry forms were > already well established practice, and at least on the English machines, (ICL > 1500/1900 series) octal was prevalent, but I don't know when the leading zero > octal notation started, and where. I said "prevalence." The key is that the average person did not start using leading zeros in dates until (I think) much, much later, and that's what's relevant to this discussion. If it were not commonplace for people to use decimal numbers with leading zeros, this whole thread would be a moot point, the python devs likely never would have considered changing the syntax, and we would not be having this discussion. Most people did not work as data entry clerks on ICL computers... :) Those participating in this thread have pretty much all seem to agree that the only places where decimal numbers with leading zeros really are common are either in rather specialized applications, such as computer-oriented data or serial numbers (which typically behave more like strings, from a computer science perspective), or the rather common one of dates. The latter case is perhaps what's significant, if any of those cases are. I tend to think that within the computer science arena, the history and prevalence of the leading 0 indicating octal far outweighs all of those cases combined. > I think you give it credence for far more depth of design thinking than what > actually happened in those days - some team working on a compiler made a > decision (based on gut feel or experience, or precedent, or whim ) and that > was that - lo! - a standard is born! Rather, I think you give the folks at Bell Labs way too little credit. They designed a programming language and an operating system that, while certainly not exactly the same as their original incarnations, even then contained a lot of features and design principles that remain state-of-the-art (though perhaps their specific implementation details have since been improved) and in many ways superior to a lot of what has come since (e.g. virtually anything that came out of Microsoft). [That's just my opinion, of course... but shared by many. :)] I don't think that happened by mere accident. That's not to say they were perfect, but those guys had their proverbial $#!t together. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpTSmevmuY7i.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Mon, Aug 24, 2009 at 08:56:48AM -0500, Derek Martin wrote: > On Sun, Aug 23, 2009 at 01:13:32PM +, Matthew Woodcraft wrote: > > A more common case is dates. > > I suppose this is true, but [...] > I tend to also discount this example, because when we write dates > with leading zeros, usually it's in some variation of the form > 08/09/2009, which, containing slashes, is a string, not a number In fact, now that I think of it... I just looked at some old school papers I had tucked away in a family album. I'm quite sure that in grammar school, I was tought to use a date format of 8/9/79, without leading zeros. I can't prove it, of course, but feel fairly sure that the prevalence of leading zeros in dates occured only in the mid to late 1980's as computers became more prevalent in our society (no doubt because thousands of cobol programmers writing business apps needed a way to convert dates as strings to numbers that was easy and fit in small memory). Assuming I'm right about that, then the use of a leading 0 to represent octal actually predates the prevalence of using 0 in dates by almost two decades. And while using leading zeros in other contexts is "familiar" to me, I would certainly not consider it "common" by any means. Thus I think it's fair to say that when this syntax was selected, it was a rather good choice. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgphWLB493GWi.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Sun, Aug 23, 2009 at 01:13:32PM +, Matthew Woodcraft wrote: > Dennis Lee Bieber writes: > > About the only place one commonly sees leading zeros on decimal > > numbers, in my experience, is zero-filled COBOL data decks (and since > > classic COBOL stores in BCD anyway... binary (usage is > > computational/comp-1) was a later add-on to the data specification model > > as I recall...) > > A more common case is dates. I suppose this is true, but I can't remember the last time I hard-coded a date in a program, or worked on someone else's code with hard-coded dates. I'm fairly certain I've never done it, and if I had, I obviously would not have used leading zeros. I think hard-coding dates is more uncommon than using octal. ;-) [It unquestionably is, for me personally.] I tend to also discount this example, because when we write dates with leading zeros, usually it's in some variation of the form 08/09/2009, which, containing slashes, is a string, not a number, and can not be used as a date literal in any language I know. We do it for reasons of format, which again implies that it has more the characteristics of a string than of a number. To use such a thing in any programming language I can think of would require translation from a string. > I've seen people trip over this writing things like > > xxx = [ > date(2009, 10, 12), > date(2009, 12, 26), > date(2010, 02, 09), > ] I've never seen anyone do this (no doubt because it would be an error), but as I said, I don't think I've ever seen hard-coded dates in any programs I've worked on. I've never encountered anyone having problems with octals who was not a total noob at programming. The changing of this syntax seems like much ado about nothing to me, and as such is annoying, consider that I use it very often. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpJdmZ75Hu7Q.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Sun, Aug 23, 2009 at 06:13:31AM +, Steven D'Aprano wrote: > On Sat, 22 Aug 2009 22:19:01 -0500, Derek Martin wrote: > > On Sat, Aug 22, 2009 at 02:55:51AM +, Steven D'Aprano wrote: > >> And the great thing is that now you get to teach yourself to stop > >> writing octal numbers implicitly and be write them explicitly with a > >> leading 0o instead :) > > > > Sorry, I don't write them implicitly. A leading zero explicitly states > > that the numeric constant that follows is octal. > > That is incorrect. No, it simply isn't. It is a stated specification in most popular programming languages that an integer preceded by a leading zero is an octal number. That makes it explicit, when used by a programmer to write an octal literal. By definition. End of discussion. > (Explicitness isn't a binary state Of course it is. Something can be either stated or implied... there are no shades in between. Perhaps you mean "obvious and intutitive" where you are using the word "explicit" above (and that would be a matter of subjective opinion). The leading zero, however, is undoubtedly explicit. It is an explicitly written token which, in that context, has the meaning that the digits that follow are an octal number. One simply needs to be aware of that aspect of the specification of the programming language, and one will clearly know that it is octal. My point in mentioning that many other programming languages, by the way, was NOT to suggest that, "See, look here, all these other folks do it that way too, so it must be right." It was to refute the notion that the leading zero as octal was in some way unusual. It is, in fact, ubiquitous in computing, taught roughly in the first week of any beginning computing course using nearly any modern popular programming language, and discussed within the first full page of text in the section on numerical literals in _Learning Python_ (and undoubtedly many other books on Python). It may be a surprise the first time you run into it, but you typically won't forget that detail after you run into it the first time. > However, octal numbers are defined implicitly: 012 is a legal base 10 > number, or base 3, or base 9, or base 16. Not in any programming language I use today, it's not. In all of those, 012 is an octal integer literal, per the language spec. > There's nothing about a leading zero that says "base 8" apart from > familiarity. That is simply untrue. What says base 8 about a leading zero is the formal specification of the programming language. The only way using octal could be implicit in the code is if you wrote something like: x = 12 in your code, and then had to pass a flag to your compiler or interpreter to tell it that you meant to use octal integer literals instead of decimal ones. That, of course, would be insane. But specifying a leading zero to represent an octal number zero is very much explicit, by definition. > We can see the difference between leading 0x and leading 0 if you > repeat it: repeating an explicit 0x, as in 0x0xFF, is a syntax > error, while repeating an implicit 0 silently does nothing > different: No, we can't. Just as you can type 0012, you can also type 0x0FF. It's not different AT ALL. In both cases, the marker designated by the programming language as the base indicator can be followed by an arbitrary number of zeros which do not impact the magnitude of the integer so specified. Identical behavior. The key is simply to understand that the first 0 is not a digit -- it's a syntactic marker, an operator if you will (though Python may not technically think of it that way). The definition of '0' is overloaded, just as other language tokens often are. This, too, is hardly unusual. > There are a bunch of languages, pretty much all heavily influenced > by C, which treat integer literals with leading 0s as oct: C++, > Javascript, Python 2.x, Ruby, Perl, Java. As so often is the case, > C's design mistakes become common practice. Sigh. That it is a design mistake is a matter of opinion. Obviously the people who designed it didn't think it was a mistake, and neither do I. If you search the web for this topic (I did), you will find no shortage of people who think the recent movement to irradicate the leading zero to be frustrating, annoying, and/or stupid. And by the way, this representation predates C. It was at least present in B. > FORTRAN 90 uses a leading O (uppercase o) for octal That clearly IS a design mistake, because O is virtually indistinguishable from 0, especially considering varying fonts and people's variable eye sight quality. > Algol uses an explicit base: 8r12 to indicate octal 10. This is far better than 0o01. I maintain that 0o1 is only marginally bett
Re: Annoying octal notation
On Fri, Aug 21, 2009 at 04:23:57PM -0700, James Harris wrote: > You misunderstand. I was saying that taking a leading zero as > indicating octal is archaic. Octal itself is fine where appropriate. I don't see that the leading zero is any more archaic than the use of octal itself... Both originate from around the same time period, and are used in the same cases. We should just prohibit octal entirely then. But I suppose it depends on which definition of "archaic" you use. In the other common sense of the word, the leading zero is no more archaic than the C programming language. Let's ban the use of all three. :) (I believe C is still the language in which the largest number of lines of new code are written, but if not, it's way up there.) > The chmod command doesn't require a leading zero. No, but it doesn't need any indicator that the number given to it is in octal; in the case of the command line tool, octal is *required*, and the argument is *text*. However, the chmod() system call, and the interfaces to it in every language I'm familiar with that has one, do require the leading zero (because that's how you represent octal). Including Python, for some 20 years or so. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpf8DJDYdSjx.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Sat, Aug 22, 2009 at 02:55:51AM +, Steven D'Aprano wrote: > > I can see how 012 can > > be confusing to new programmers, but at least it's legible, and the > > great thing about humans is that they can be taught (usually). > > And the great thing is that now you get to teach yourself to stop writing > octal numbers implicitly and be write them explicitly with a leading 0o > instead :) Sorry, I don't write them implicitly. A leading zero explicitly states that the numeric constant that follows is octal. It is so in 6 out of 7 computer languages I have more than a passing familiarity with (the 7th being scheme, which is a thing unto itself), including Python. It's that way on Bourne-compatible and POSIX-compatible Unix shells (though it requires a leading backslash before the leading zero there). I'm quite certain it can not be the case on only those 6 languages that I happen to be familiar with... While it may be true that people commonly write decimal numbers with leading zeros (I dispute even this, having to my recollection only recently seen it as part of some serial number, which in practice is really more of a string identifier than a number, often containing characters other than numbers), it's also true that in the context of computer programming languages, for the last 40+ years, a number represented with a leading zero is most often an octal number. This has been true even in Python for nearly *twenty years*. Why the sudden need to change it? So no, I don't get to teach myself to stop writing octal numbers with a leading zero. Instead, I have to remember an exception to the rule. Also I don't think it's exactly uncommon for computer languages to do things differently than they are done in non-CS circles. A couple of easy examples: we do not write x+=y except in computer languages. The POSIX system call to create a file is called creat(). If you think about it, I'm sure you can come up with lots of examples where even Python takes liberties. Is this a bad thing? Not inherently, no. Will it be confusing to people who aren't familiar with the usage? Quite possibly, but that is not inherently bad either. It's all about context. > Use of octal isn't common. It's common enough. Peruse the include files for your C libraries, or the source for your operating system's kernel, or system libraries, and I bet you'll find plenty of octal. I did. [Note that it is irrelevant that these are C/C++ files; here we are only concerned with whether they use octal, not how it is represented therein.] I'd guess there's a fair chance that any math or scientific software package uses octal. Octal is a convenient way to represent bit fields that naturally occur in groups of 3, of which there are potentially limitless cases. > You've given two cases were octal notation is useful, but for every > coder who frequently writes umasks on Unix systems, there are a > thousand who don't. I gave two cases that I use *daily*, or very nearly daily. My hats currently include system admin, SQA, and software development, and I find it convenient to use octal in each of those. But those are hardly the only places where octal is useful. Have a look at the ncurses library, for example. Given that Python has an ncurses interface, I'm guessing it's used there too. In fact if the Python source had no octal in it, I would find that very surprising. > It's no hardship to write 0o12 instead of 012. Computer languages are not write-only, excepting maybe Perl. ;-) Writing 0o12 presents no hardship; but I assert, with at least some support from others here, that *reading* it does. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp2DtXpzfNjd.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Sat, Aug 22, 2009 at 10:03:35AM +1000, Ben Finney wrote: > > and the former is virtually indistinguishable from 00012, O0012, or > > many other combinations that someone might accidentally type (or > > intentionally type, having to do this in dozens of other programming > > languages). > > Only if you type the letter in uppercase. The lower-case ‘o’ is much > easier to distinguish. It is easier, but I dispute that it is much easier. > Whether or not you find ‘0o012’ easily distinguishable as a non-decimal > notation, it's undoubtedly easier to distinguish than ‘012’. 012 has meant decimal 10 in octal to me for so long, from its use in MANY other programming languages, that I disagree completely. > > I can see how 012 can be confusing to new programmers, but at least > > it's legible, and the great thing about humans is that they can be > > taught (usually). I for one think this change is completely misguided. > > These human programmers, whether newbies or long-experienced, also deal > with decimal numbers every day, many of which are presented as a > sequence of digits with leading zeros — and we continue to think of them > as decimal numbers regardless. Having the language syntax opposed to > that is ...consistent with virtually every other popular programming language. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpaLprG9uUPz.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
On Fri, Aug 21, 2009 at 08:25:45PM +, Benjamin Peterson wrote: > > More than flushing out bugs, it will *cause* them in ubiquity, > > requiring likely terabytes of code to be poured over and fixed. > > 2to3, however, can fix it for you extreme easily. Sure, but that won't stop people who've been writing code for 20 years from continuing to type octal that way... Humans can learn fairly easily, but UN-learning is often much harder, especially when the behavior to be unlearned is still very commonly in use. Anyway, whatever. This change (along with a few of the other seemingly arbitrary changes in 3.x) is annoying, but Python is still one of the best languages to code in for any multitude of problems. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpqtjVMR59uV.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Annoying octal notation
John Nagle wrote: > Yes, and making lead zeros an error as suggested in PEP 3127 is a > good idea. It will be interesting to see what bugs that flushes > out. James Harris wrote: > It maybe made sense once but this relic of the past should have been > consigned to the waste bin of history long ago. Sigh. Nonsense. I use octal notation *every day*, for two extremely prevalent purposes: file creation umask, and Unix file permissions (i.e. the chmod() function/command). I fail to see how 0O012, or even 0o012 is more intelligible than 012. The latter reads like a typo, and the former is virtually indistinguishable from 00012, O0012, or many other combinations that someone might accidentally type (or intentionally type, having to do this in dozens of other programming languages). I can see how 012 can be confusing to new programmers, but at least it's legible, and the great thing about humans is that they can be taught (usually). I for one think this change is completely misguided. More than flushing out bugs, it will *cause* them in ubiquity, requiring likely terabytes of code to be poured over and fixed. Changing decades-old behaviors common throughout a community for the sake of avoiding a minor inconvenience of the n00b is DUMB. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp5360ytwKYC.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: basic thread question
On Tue, Aug 18, 2009 at 03:10:15PM -0500, Derek Martin wrote: > I have some simple threaded code... If I run this > with an arg of 1 (start one thread), it pegs one cpu, as I would > expect. If I run it with an arg of 2 (start 2 threads), it uses both > CPUs, but utilization of both is less than 50%. Can anyone explain > why? Ah, searching while waiting for an answer (the e-mail gateway is a bit slow, it seems...) I discovered that the GIL is the culprate. Evidently this question comes up a lot. It would probably save a lot of time on the part of those who answer questions here, as well as those implementing solutions in Python, if whoever is maintaining the docs these days would put a blurb about this in the docs in big bold letters... Concurrency being perhaps the primary reason to use threading, essentially it means that Python is not useful for the sorts of problems that one would be inclined to solve they way my code works (or rather, was meant to). It would be very helpful to know that *before* one tried to implement a solution that way... especially for solutions significantly less trivial than mine. ;-) Thanks -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpN8wmTPdqR4.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
basic thread question
I have some simple threaded code... If I run this with an arg of 1 (start one thread), it pegs one cpu, as I would expect. If I run it with an arg of 2 (start 2 threads), it uses both CPUs, but utilization of both is less than 50%. Can anyone explain why? I do not pretend it's impeccable code, and I'm not looking for a critiqe of the code per se, excepting the case where what I've written is actually *wrong*. I hacked this together in a couple of minutes, with the intent of pegging my CPUs. Performance with two threads is actually *worse* than with one, which is highly unintuitive. I can accomplish my goal very easily with bash, but I still want to understand what's going on here... The OS is Linux 2.6.24, on a Ubuntu base. Here's the code: Thanks -=-=-=-=- #!/usr/bin/python import thread, sys, time def busy(thread): x=0 while True: x+=1 if __name__ == '__main__': try: cpus = int(sys.argv[1]) except ValueError: cpus = 1 print "cpus = %d, argv[1] = %s\n" % (cpus, sys.argv[1]) i=0 thread_list = [] while i < cpus: x = thread.start_new_thread(busy, (i,)) thread_list.append(x) i+=1 while True: pass -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgphh3xk5mOZY.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Mon, Jan 05, 2009 at 01:23:04PM -0500, Steve Holden wrote: > Even if they really are small-minded or stupid I agree this wouldn't be > helpful behavior. But neither would your characterization of Python's > assignment model as "bizarre" (even ignoring that you SHOUTED IT AT US), > and I have yet to see you admit that such a characterization was, shall > we say, inappropriate. Actually I did, in one of my two most recent posts. But as Steve D'Arpano just pointed out (even though he clearly disagreed with me), such a characterization is subjective, and as such you can't rightly say it's inappropriate. That's the largest part of my point in posting in this thread. Many folks do exactly that, very often. Someone disagrees with you, tries to shed some light on a different perspective, or simply fails to understand something, and some members of this community treat them like heretics, fools, or criminals. I understand why the assignment model works the way it does, and it's quite sensible, *when you understand it*. However, I do also think that to someone who has not encountered such a model before, and who has not had it explained to them, and/or who has not the background to understand why it is implemented that way, it very likely might seem "markedly unusual in appearance, style, or general character and often involving incongruous or unexpected elements;" as dictionary.com defines the term bizarre. So no, I don't think that's a mischaracterization at all. As for using the term in all caps, I did so precisely because it was clear to me that many people here think that it could not be unusual, and I wanted to emphasize the fact that other perspectives exist... That they are not the same as yours does not invalidate them! > It takes little to admit one is in the wrong even when one isn't. I've > had to learn to do it because I often *am* wrong about things. Could you > be persuaded to consider the possibility that you met with a somewhat > hostile reaction (whether or not such a reaction was useful or > necessary) because you were, in a small way, poking people in the side > with a sharp stick? I fully expected to receive a hostile reaction, because I am criticising the behavior of the collective, and supplying a dissenting perspective -- something I knew from the start would trigger such hostility *because it always does*. I have witnessed hostile reactions time and time again in this forum, from some of the same people who are dumping on me for suggesting that the assignment model might be something other than obvious, and from others, for much less: I expect it because I see it in response to nothing more than asking a simple question, when the question displays a clear indication that the poster has missed something critical preventing them from understanding how to achieve their goals. My intent was exactly to point out this behavior, in an attempt to call to people's attention that it is what they are doing, and thereby discourage it. I fully expected a negative response. You in particular have responded quite well, but the rest of the community by and large has sadly not failed to live up to my expectations, even in the face of me saying that that is exactly what they are doing. Quite impressive. Some of the comments from people include the idea that the assignment model is nothing special, if you've encountered any one of a dozen other languages. I didn't realize programming in any of those languages was a prerequisite for posting questions here, or for programming with Python. And that speaks to my ultimate point: Some members of the community seem to make assumptions about what people know or should know, or have experienced, and talk down to people who haven't met their expectations. They meet different perspectives with hostility. Posts which phrase questions in terms commonly used in other programming paradigms are generally even more likely to be met with that same hostility, when they could simply instead explain politely that Python behaves according to a different model than what they are used to. Often this happens, but too often not without someone also letting the OP know what a mindless jerk he is... *This* is the "common understanding" which I'd hoped could be reached... But you were right... it's very difficult for people to admit that they might be wrong. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpdBC9eN0T5h.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
Forgive my indulgence, I find this rather academic discussion kind of interesting, as it turns out. On Sun, Jan 04, 2009 at 10:55:09PM -0600, Derek Martin wrote: > > You can't argue that one semantic or another is more intuitive > > without offering evidence. > > I think I have though, not that it matters, since that was never > really my point. Python's assignment model requires more explanation > than the traditional one, simply to state what it does. That alone is > evidence (but not proof). Here's (I think) a better argument, FWIW: The traditional model ties a name to some (usually predefined and static) storage (a memory address, or at least the start of a string of them). This is a very concrete thing to represent, and the conceptualization of variables as named bins in such languages captures this very succinctly, and requires no understanding of the underlying implementation for the programmer to use (at least with primitive data types, which are all that are used generally when variables are first introduced). The Python model binds a name to a particular Python object, which is itself an abstraction; understanding requires understanding first what an "object" is, and I think at least in some measure some knowledge about how Python is implemented (primitive data types are actually objects; and also recall the recent discussion about what constitutes a "value" in Python). The abstraction, and the requirement to partially understand the underlying implemenation, make the Python model inherently more complicated, and therefore also inherently less intuitive. That also is not proof, but as I said, real proof is rather hard to come by... And FWIW, remember that I never suggested that all this was without good reason, and I'm not attempting to advocate for simplifying the model. :) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgphDXw471YZc.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Sun, Jan 04, 2009 at 09:56:33PM -0600, Grant Edwards wrote: > On 2009-01-05, Derek Martin wrote: > > On Sat, Jan 03, 2009 at 11:38:46AM -0600, Grant Edwards wrote: > >> One presumes that Mr. Martin finds anything different from his > >> first computer language to be BIZARRE. He should try out > >> Prolog or something genuinely different. > > > > One's presumption would be mistaken. However thank you for > > illustrating my point so precisely, which was after all the > > condescending and insulting way people "communicate" with > > people whom (they think) know less than they do in this forum, > > and not actually how difficult or easy the assignment model of > > Python is to understand. > > I'm sorry, but I really don't see how Python's assignment model > could be considered bizarre by anybody who's familiar with more > than one or two languages. And... what if one wasn't? The OP of this thread clearly didn't understand... Whereas if you've read the thread, clearly I do. Of course, had you read my post, you probably would have understood that my comment about the model being bizarre was intended to be viewed from the perspective of someone who *had not* seen anything like it before, which is LOTS of relatively new programmers, whether or not it might be old hat to anyone here. The ultimate point of my post was not so much about whether the assignment model of Python was or wasn't easy to understand; it was about the idea that when someone doesn't understand, we should try to help them instead of making snide remarks about how stupid or small-minded they are. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpVxUxyCvEmP.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Sun, Jan 04, 2009 at 09:30:20PM -0500, Steve Holden wrote: > > I'm going to go out on a limb and assert that there's NO POSSIBLE WAY > > a student could intuit Python's variable assignment behavior, having > > never been exposed to that same behavior prior. It needs to be > > taught. > > > As does assignment of any kind. I'm not sure that's true. Having taken algebra prior to learning Basic, I intuitively understood what this program would do when I executed it, the first time I saw the code, and before I read the explanation: 10 let x = 10 20 print x [Well, to be honest it's been a very long time since I've programmed in Pet BASIC, and the syntax may be wrong. The point is, just as I did then, I am positive that you intuitively understand what the above is intended to do, even if it is not valid BASIC syntax -- because if you did not, we would not be having this discussion.] > You can't argue that one semantic or another is more intuitive > without offering evidence. I think I have though, not that it matters, since that was never really my point. Python's assignment model requires more explanation than the traditional one, simply to state what it does. That alone is evidence (but not proof). I haven't proven it scientifically, and I'm not willing to jump through the necessary hoops (which would require a psychological study) to do so simply to win an argument on Usenet. It's not about winning... it's about illumination. ;-) > You're perhaps familiar with some algebra that I didn't study. Not unless you never studied it at all... ;-) > In algebra and number theory identity and equality are equivalent. Indeed. The point of bringing up algebra is that it provides a background against which someone might be very likely to intuit what variable assignment does in traditional programming languages -- at least accurately enough to use it effectively without needing to understand the underlying implementation and worry about any corner cases. It really doesn't need to be explained, unless the student has no prior background in either math or computers. In the case of passing parameters things unavoidably get hairy, but at least at the moment we're not discussing that, and also that has no analogous in (at least high school) mathematics (at least, that I can think of) or much of anywhere else from whence a student might draw any insights. As for there being no assignment in algebra, is that not really what variable substitution is? They have different names, but in my estimation they perform exactly the same function. You're assigning specific values to the variables in an expression so that you can solve for a constant... just like in a computer program. There is even an allocation of memory: it's in your brain. :D > This is far from the case in programming languages, so any analogy > based on it is specious to some degree. Programming isn't > mathematics (except perhaps for functional programming). I agree; but I wasn't making an analogy. I was pointing out (an extremely likely) basis for intuition. > It's difficult to think of a single aspect of Python that doesn't cause > confusion in a typical year. Surely some cause more than others... and surely some are more surprising than others. ;-) > The confusion is sometimes caused by ill-informed comment. While > well-informed, you appear to feel that everyone else should share > your idea of what's intuitive and what's BIZARRE. Alright, perhaps I exaggerated when I said bizarre, but I did explain exactly what I meant, and I believe that what I said in my explanation is at least arguably true. I stand by the idea that it's much less intuitive than the traditional assignment model, and despite your protestations of lack of proof, I'm pretty sure you agree. ;-) Ultimately, none of this really matters, as perhaps my point is that Python *is different* from what A LOT of folks learning it have already seen (if anything), and it's often easy for them to misunderstand the Python way. As you said, let's provide light, not heat, when we come across people who get confused between Python and something else. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpE0oLCW41pi.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Sat, Jan 03, 2009 at 11:38:46AM -0600, Grant Edwards wrote: > > Or are they also "BIZARRE"!? > > One presumes that Mr. Martin finds anything different from his > first computer language to be BIZARRE. He should try out > Prolog or something genuinely different. One's presumption would be mistaken. However thank you for illustrating my point so precisely, which was after all the condescending and insulting way people "communicate" with people whom (they think) know less than they do in this forum, and not actually how difficult or easy the assignment model of Python is to understand. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp7GzFxWB35W.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Sat, Jan 03, 2009 at 10:15:51AM +, Marc 'BlackJack' Rintsch wrote: > On Fri, 02 Jan 2009 04:39:15 -0600, Derek Martin wrote: > > > On Tue, Dec 30, 2008 at 02:21:29PM +, John O'Hagan wrote: > > What the Python community often overlooks, when this discussion again > > rears its ugly head (as it seems to every other hour or so), is that its > > assignment model is BIZARRE, as in it's conceptually different from > > virtually all other languages substantially taught in undergraduate > > computer science programs. > > What's the difference between Python and Java or C# here!? Or are they > also "BIZARRE"!? I am happily ignorant of C#. As for Java, take the following code: a = 6; a = 5; In Python, when you execute the equivalent code, it causes two different objects to spring into existence, the first of which may be cleaned up by the GC (except that since we're using small integers, that's not likely to happen). Unless I'm misinformed (which is very possible, my experience with Java has been extremely limited) in Java that's not the case... the storage is allocated to the name a when you execute its declaration, and the *same storage* is reused upon subsequent assignment. That behaves exactly like named bins. > > And for that matter, it's pretty unintuitive generally. > > Names and objects are quite "natural" IMHO. There are many real world > objects which we attach one or more names to, or refer to in sequences > like "please give me the third book on that shelve" (``shelve[2]``). Indeed, but the way we assign names to them does not behave as it does in Python. Nor does Python's assignment work like it does in algebra, or anywhere else the Python student is particularly likely to have seen variable assignment before encountering it in Python. Let's define intuitive, shall we? From dictionary.com (choosing the definition which most easily makes my point): intuitive: adj. capable of being perceived or known by intuition. I'm going to go out on a limb and assert that there's NO POSSIBLE WAY a student could intuit Python's variable assignment behavior, having never been exposed to that same behavior prior. It needs to be taught. > > That is, in what I'll call "normal" computer languages, a variable name > > is thought of as the address of a bin where some data is stored, and the > > name is inexorably tied to that bin. > > You just call that "normal" or "intuitive" because that's what you > learned first. In a sense, yes... but isn't that what intuition really is? You can figure something out whithout being told how it works... That's either because it's immediately obvious from observing it, or it behaves like something you've seen before. That is what intitive is. > I think the "bin model" is more complex because you don't just have a > name and an object but always that indirection of the "bin". I cheerfully disagree. :) "Named bins" is essentially how algebra works, and how several generations of computer languages, not to mention the actual machine language those generated, behaved, before the current crop. Those interpretations came first, because, much as in the evolution of any other science, that was the model which was most intuitive or easily explained. But you need not take my word for it. Simply read the archives and see for yourself how much confusion this has caused on this list. [Please include the closely related behavior of parameter passing in your search.] -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpilB7yH4CC6.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Fri, Jan 02, 2009 at 12:50:44PM -0800, Erik Max Francis wrote: >>> Identity isn't defined on math objects, only on Python objects; there >>> is no notion of 'is' in math. >> >> This is also false, it even has its own operator (which requires >> Unicode to display): ≡ > > That can mean a number of things, one of which means "is identically > equal to," Quite so. > but identity means something different in mathematics than it means > here. But for non-mutable objects, aren't they essentially the same? Mathematics has no concept of "objects" in the sense that computer science does, so of course the best you can really do is draw parallels. > In mathematics, identity means a relationship that is true > regardless of the value of the variables involved (as opposed to > equality which is only true under more specific circumstances). Does 2 = 2 not qualify? Isn't it true that 2 ≡ 2 and 2 is 2? :) Yet there are no variables at all... The "objects" of mathematics are numbers, which are constants, which as such I would argue always have the same "identity" as themselves. Other components of mathematics are "expressions", which may or may not evaluate to constants, depending on the set conditions. Python has those too, and they are not the same as objects. > In computer science, identity means that two expressions are > represented by the same object, something which not only has no > meaning in mathematics, We're getting way off track here, but I would argue this is also false. Take sets, for example: A = { 1, 2, 3 } B = { 1, 2, 3 } Is it not true that A ≡ B and in fact these two sets are the same, i.e. they are not actually two different sets at all; the have the same identity, even considering a definition of "identity" which reflects that in Python? A and B are in fact simply two different names we've given to the same mathematical entity. The major difference between mathematics and Python is that mathematical objects are essentially unique, i.e. the constant 1 is arguably always the same 1 wherever it appears, because there is no mathematical need to have multiple instances of the constant 1: Wherever you see the symbol '1' OR an expression which evaluates to the constant 1, it refers to a *concept* of the numerical value representing mathematical singularity and wholeness. In python, you can have multiple instances of objects which are identical to each other (though for this simple case, even python only creates one instance of the object). > but which should also be clear since > mathematical identities need not have any individual variables on > either side of the triple bar; take, for instance, the > trigonometric identity > > cos^2 theta + sin^2 theta = 1. Is theta not a variable? :) Not that it matters... > Even if you write this equation with the triple bar to represent a > mathematical identity (which it is), it obviously doesn't say anything > about which "objects" are the same as each other. I don't imagine I would agree, based on what I just said. To elaborate, each side of the expression contain symbols which always evaluate to the same constant. The identity of a constant is constant. :) Thus the objects on both sides are indeed the same identical mathematical entity... they are just expressed differently. It's just like if you refered to your kitchen table (assuming you have only one kitchen table) as "the table" or as "the large table I eat on in the kitchen..." No matter what you call it, it's still the same table. In the case where the identity can not be reduced to constants, the two expressions still evaluate to the same mathematical entity... except that you need to set the conditions (i.e. give values to the variables) to find out what that actually is. It seems exactly analogous to Python to me, except that again, unlike Python, there is no possibility that there can ever be two instances of the same object and thus applying the term "identity" to mathematical objects is not useful. It's not that it is meaningless, it just isn't very interesting. Clearly though, 2 is not 3, and these two mathematical objects do not have the same identity. Perhaps there is no concept of identity in mathematics precisely because it is unnecessary: 1 is always 1, by definition. But that is the definition of "is"... :) But the discussion is bordering on philosophy, and I will resign from it at this point, having previously made the points I intended to. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpAiEkpMH3gD.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Fri, Jan 02, 2009 at 09:05:51PM +0100, Bruno Desthuilliers wrote: >> Python seems rather weird, and I think from the frequency >> with which these discussions occur on this list, clearly it *IS* >> difficult for a neophyte Python programmer to understand the >> assignment model. > > Took me about half an hour to grasp, not even being "CS grad" (nor > whathever "grad" FWIW). By that time, I had a couple monthes working > experience with VB, and had learned (but never seriously used) bits of > C, C++, Java and Pascal. It took me about a half a second to grasp the "named bins" concept -- i.e. as soon as I was finished reading the words that explained it I understood it, so I'd say that based on your half-hour number, Python's model is substantially more complicated. My own experience was kind of similar... When I read about Python's model I didn't understand it the first time around, had to re-read the section I read that described it, and then had to play with it to see for myself how it worked. I'd estimate it took 10 minutes. I'm not a CS grad either (my degree is in information technology) but I did take the first two years of CS classes at my local college (as a bridge to a masters degree in CS, which I never completed), and I've been programming as a hobbyist, in school, and in my profession for 25 years. I would argue that ideally, it should not take an experienced programmer 10 minutes to understand variable assignment. :) [Note that I'm including the semantics for passing arguments to functions as part of "assignment" for purposes of this discussion.] -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpkihamKsYya.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Fri, Jan 02, 2009 at 11:43:30AM -0500, Steve Holden wrote: > Derek Martin wrote: > > What the Python community often overlooks, when this discussion again > > rears its ugly head (as it seems to every other hour or so), is that > > its assignment model is BIZARRE, as in it's conceptually different > > from virtually all other languages substantially taught in > > undergraduate computer science programs. And for that matter, it's > > pretty unintuitive generally. > > > I'd definitely argue against bizarre. It's actually very easy to > understand, and Python is by no means the only language to have used it. Clearly the first and third are true. :) But CS programs still generally teach primarily C/C++, Java, and (some form of) assembly AFAICT. A few odd ones pop up here and there along the way (I studied with scheme, for example), but they vary and are highly program-dependent. What the average CS grad sees is, AFAICT, still very much what I described. Those languages also behave similarly to what students see in mathematics (e.g. algebra etc.). With only that to go on, Python seems rather weird, and I think from the frequency with which these discussions occur on this list, clearly it *IS* difficult for a neophyte Python programmer to understand the assignment model. And this is, in part, because it's kind of difficult to explain precisely, as has oft been demonstrated in this forum. > I'd argue that this approach is out of date and overly-restrictive, Sure, I already hinted that it's useful... but it's still uncommon, in the experience of most CS students -- not even taking into account the number of people who program who have never studied in a formal CS program. > I'd instead say that Python uses ephemeral names for long-lived objects, > where other languages use the addresses of ephemeral objects. Your ideas > of "simple" and "sensible" are being conditioned by your experience. Of course... I'd argue that our experience is a large part of what makes things simple or sensible. Things that behave like other things we are very familiar will be simple to understand. Python's assignment model is probably new to most people when they first start using it. To look at Python's code, at first glance assignment seems to be the same as everywhere else you've encountered it... Only once someone starts to write "real" programs does the difference really matter. > > It's small wonder that neophytes try to cram Python behaviors into > > terms and computing concepts they already understand from learning > > other languages, and that they fail to do so. What's mystifying is > > that when Pythonistas reply to their messages, they universally seem > > confused at how this could possibly happen, and often enough actually > > seem offended (or at least offensive) when it inevitably does happen... > > > Generally speaking we try not to be offensive first on this list. Perhaps I've misused the term Pythonista... I meant roughly, "people who frequent this list/news group who seem to consider themselves experts at programming Python (and for the most part, are)." I consider myself pretty well informed about Python (though not an expert by any means), and I still read this list often (I use the mailing list interface), because I still find that I learn useful things from the posts to it from time to time. But I often see python "experts" lambasting people who clearly from their posts are new at python, because their code is bad, their understanding is bad, or in this case even accusing the learning materials of being sub-par. I realize that some of this is meant in jest, but a lot of it isn't, and it can be quite difficult for someone who doesn't speak your language natively (or even one who does, given the medium) to tell the difference. There are better ways to foster understanding... ;-) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpmcWKAkQA4R.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On Tue, Dec 30, 2008 at 02:21:29PM +, John O'Hagan wrote: > Fortunately, unlike the murky world of philosophy, Python (AIUI) > simplifies this question by simply declaring that yes, in the case > of mutable objects, we may say that we are still referring to the > same object although we've changed it, and no, in the case of > immutable objects, we may not, and must exchange it if we want a > different "value" (a word too fraught with ambiguity in this context > to use unquoted!). That's sort of true; it would seem to be more accurate to say that whenever a name is assigned to an object and subsequently reassigned, the name no longer is associated with the original object. In the case of mutable objects, the object can be changed by performing an assignment of *part* of the object through its original name, i.e. strings may be mutable, but the following code still produces two different objects: a = 'hello' a = 'goodbye' The first object so created is orphaned; it's been given the Russian non-person treatment. It still exists, but the authorities (i.e. the python interpreter) don't acknowledge it and provide the rest of the world no way to communicate with it, and eventually it is reaped by the garbage collector. :) What the Python community often overlooks, when this discussion again rears its ugly head (as it seems to every other hour or so), is that its assignment model is BIZARRE, as in it's conceptually different from virtually all other languages substantially taught in undergraduate computer science programs. And for that matter, it's pretty unintuitive generally. That is, in what I'll call "normal" computer languages, a variable name is thought of as the address of a bin where some data is stored, and the name is inexorably tied to that bin. You can change what's in the bin, but the name you gave the bin always points to the same bin. This tends to be conceptually true even if it might technically not be true in a given implementation of a language. Python is very different from this. Names are not addresses of bins; they are instead simply ephemeral labels which are given to bins, where the bin is a Python object which contains specific data at the time of assignment. A second assignment of that name doesn't change what's in the original bin; it actually (probably) first creates a new bin, then removes the name from the original bin and assigns it to the new one. Intuitively, it's a bit like saying your kitchen table is no longer a kitchen table, and now the thing where you wash your dishes is a kitchen table. It doesn't really make a lot of sense (whether or not it's so for good reason), and it makes describing the assignment model necessarily convoluted, whereas the "named bins" model from the majority of other languages people are likely to have been exposed to is simple and sensible. It's small wonder that neophytes try to cram Python behaviors into terms and computing concepts they already understand from learning other languages, and that they fail to do so. What's mystifying is that when Pythonistas reply to their messages, they universally seem confused at how this could possibly happen, and often enough actually seem offended (or at least offensive) when it inevitably does happen... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp6S7INF1qUN.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: why cannot assign to function call
On a mostly not related note: On Tue, Dec 30, 2008 at 07:52:26AM -0800, Aaron Brady wrote: > According to some rules, these are ungrammatical sentences, due to > plurality disagreement. Ex: > > The Morning Star is ... > The Evening Star is ... > *The Morning Star and The Evening Star is... > *The Morning Star and The Evening Star are... > > Neither of the latter two is correct. (* marks ungrammatical.) As > such, the listener isn't sure what meaning to take. This statement is false. The latter of the two is grammatically correct. The subject is a compound subject joined by the conjunction "and" which indicates that there are two subjects, and thus the plural form of the verb is necessary and correct. > Identity isn't defined on math objects, only on Python objects; there > is no notion of 'is' in math. This is also false, it even has its own operator (which requires Unicode to display): ≡ Still, the point you're trying to make is right: this stuff is hard to talk about, and the model actually encourages the use of ambiguous or even contradictory explanations. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpvXlslLQieE.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Official definition of call-by-value (Re: Finding the instance reference...)
On Tue, Nov 18, 2008 at 09:23:30AM +, Steven D'Aprano wrote: > > How I can answer the question, "are the objects a and b the same or > > different"? I can look at every aspect of each object, looking for > > something that is different. > > Well, sure, if you care *that much* about potentially trivial aspects. I > have a ten dollar note with a spec of dirt on one corner, and a ten > dollar note with a slightly larger spec of dirt on a different corner. > I'd agree with you that they are not "the same" in every aspect, but > they're the same in every way I care about. It's trivial to show that this is not necessarily the case -- you just haven't thought of all the ways in which a difference might matter to you.. Suppose that one of the 10-dollar bills had a serial number which was never printed by the government (i.e. it is counterfiet). Are they still the same in every way that you care about? What is the value of these two objects? Is it the same? The answer, in both cases, is, "it depends." The value of both is context-specific, just as I argue is the value of a python object. First let's briefly examine the value of the counterfiet: The "intrinsic" value (or rather, the value generally accepted by the authorities) of the counterfeit is zero. However, if you have one in your hand, and you pass it to a merchant who is not able to detect that it is a counterfeit, then, isn't its value $10 in that context? If you walk away from the merchant with $10 worth of goods (and/or change in non-counterfeit currency), then I would say it would have to be, *in that context*. Now suppose that the merchant is actually a U.S. Secret Service agent investigating counterfeit money. He notices the bill and arrests you. What is the value of the bill now? I doubt you could really measure it, except perhaps in terms of the amount of money it would cost you to defend yourself in court (if your case went to court), the amount of hastle to deal with the authorities, etc. Suffice it to say that the value is rather negative, possibly with a very high magnitude, depending on what happens next. What about the genuine $10 bill? If you take it to your local mall, or your local gas station, or your corner grocer, it's clearly worth $10... or is it? Prices of gasoline vary from station to station, city to city, state to state, even if the gas is sold by the same company. A can of peas might be $0.89 at a market in New Hampshire, or the same can of peas might be $1.59 at a market in down town Manhattan. And if you take your $10 bill to pay for your favorite cup of coffee at Starbucks in your city, it might cost you $4 with change back of $6... But if you bring that same $10 bill to a Starbucks in a small city in Germany, good luck getting any coffee... Just as in the real world, the value of a Python object depends on the context in which it is evaluated. > > What are the aspects of the object that I can look at? > > > > id(obj) will give me the identity but I know that will be different and > > so its irrelevant. > > Philosophically, no, not irrelevant. You haven't explicitly defined "the > same" in enough detail to make that call. Perhaps because the objects are > in different locations (different IDs) is enough to make them different, > even if everything else about them is identical. > > For example, consider the two electrons around a helium nucleus. They > have the same mass, the same speed, the same spin, the same electric > charge, the same magnetic moment, they even have the same location in > space (technically, the same wave function). They are identical in every > possible way. Are they the same electron, or two different electrons? > What does the question even mean? > > My point is that as a philosophical position, identity may or may not > count as "sameness". It depends on the circumstances. > > > > > What else can we look at? We can go through each > > attribute of the objects looking for an attribute that one has and the > > other doesn't, or for attributes of the same name that are different. > > > > We look at .__class__, .__delattr__, and so on and they are all the > > same until we come to .foo and note that a.foo and b.foo are different. > > One is an int(1) object, the other is an int(2) object. So we can say > > that a and b are different. > > Philosophically, sure, but practically, perhaps not. The foo attribute > may be entirely irrelevant to your purposes, the equivalent of a random > speck of dirt or a slight tear on a ten dollar note. > > Luckily, Python doesn't try to guess whether differences are significant > or not. You can override the __eq__ method on classes and choose for > yourself what properties of a class are differences that make a > difference and which are mere markers of no particular concern. > > > > Lets do the same with these two objects: > > > > a = int(2) > > b = int(3) > > > > When we do that, we find no difference!
Re: Official definition of call-by-value (Re: Finding the instance reference...)
On Sun, Nov 16, 2008 at 09:30:45AM +, Arnaud Delobelle wrote: > [...] > > If you like, you could think of the value of an object as the set of > > all possible values to which the object may evaluate in every possible > > context, given a particular state of the object. > > This definition looks a bit circular to me ;) Why, because it has the word "value" in the definition? It's not circular. The thing being defined is "value of an object". The word "value" has a pre-existing well-understood natural language definition. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpJNlOWqxfA7.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Official definition of call-by-value (Re: Finding the instance reference...)
On Sun, Nov 16, 2008 at 08:38:25AM +, Steven D'Aprano wrote: > I believe that the language reference says that objects have an identity, > a type and state, but I'm too lazy too look it up. I'd be happy with that > definition. They do indeed say value, not state. As I said in a different message, I'd agree that it's not a very clear definition. > > I don't see how saying "the value of an object is itself" is > > particularly useful. We already have a word for what an object is, it > > is "object". :-) > > I didn't say it was very useful. As far as I'm concerned, asking what the > value of an object is is not a useful question. Now we agree. :) > > The result of x==y depends solely on the behavior (methods) of x. > > Nonsense. It's wrong to say *solely*, but the value of x==y does indeed depend on the behavior of the methods. > I think the value of x is "a thing which claims to be equal to > everything on Tuesdays, and equal to nothing every other day". That isn't its *VALUE* -- it's its *IDENTITY*. My weight is not my identity... but in a certain context, it could be considered my value. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpVW1VzHngyK.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Official definition of call-by-value (Re: Finding the instance reference...)
On Sun, Nov 16, 2008 at 06:06:20AM +, Steven D'Aprano wrote: > >>> * Do all objects have values? (Ignore the Python > >>> docs if necessary.) > >> > >> If one allows null values, I am current thinking yes. > > > > I don't see a difference between a "null value" and not having a value. > [...] > It wasn't until the fifth century C.E. that Indian mathematicians > invented the concept of zero, and it took many centuries for the > idea to get to Europe via the Arabs. I think he meant None... Or at least, I personally see a distinction between zero and None (and so do the Python docs). Zero is a value, whereas None is specifically intended to denote the lack of any value. I would, FWIW, only make such a distinction in the context of a computer program... Clearly in mathematics and elsewhere, zero is the lack of a value (it is the value of nothingness). > "The value of the object is the number of sheep in the paddock, unless > the number of sheep is zero, in which case the object has no value..." > which is needlessly complicated. For conversation, yes... but technically correct. > I say that 0 is a perfectly fine value. So is None, [], {}, and any other > null-value. I recommend you don't complicate and confuse matters by > trying to treat them differently. > http://www.python.org/doc/1.5.2/api/noneObject.html 7.1.2 The None Object PyObject * Py_None The Python None object, denoting lack of value. This object has no methods. > > The value of a class is it's attributes? Are you saying that attributes > > of an object are part of its value? That would mean that 'a' and b' > > below have different values? > > > > class My_int(int): > > def __init__(self): self.foo = None > > That won't work you know. Perhaps not, but it illustrates the point. This *does* work: >>> class myint(int): ... def __init__(self, val): ... int.__init__(val) ... self.foo = None ... >>> b=myint(3) >>> b 3 >>> b.foo >>> print b.foo None >>> a=3 >>> a==b True So, your description of value is not consistent with Python's behavior... Python says the two objects I just created have the same value. But by your definition, they don't. One of you is wrong... ;-) > That depends on whether the existence of foo makes a difference to you or > not. Consider pickle. Since pickle can't predict what aspects of the > object are important, it must treat *everything* as significant, and > pickle will absolutely treat a and b as having different values. I don't think that's clear... pickle will treat a and b as having different *data*... For what it's worth, I think the statement in the language reference that all objects have a type, an ID, and a value is quite a poor choice of words. Back in 2000, Frederik Lundh put it much more accurately, I think: http://effbot.org/zone/python-objects.htm I think it's up for debate whether the value of attribute of an object is part of the object's value, if that attribute can never be the evaluated value of the object itself in an expression -- though only because it's a semantic argument, and the semantics haven't been defined. I don't think choosing to say that it is or isn't makes any practical difference, at all. > But other functions may have weaker constraints. Consider sum([a, b]). > The function sum makes no promises that it will return the same type as > it's arguments. Since, *for the purposes of addition*, the foo attribute > has no significance, sum() makes no promise whether the sum of a and b > will include the foo attribute. In fact it does not. As far as addition > is concerned, a and b have the same value, and the foo attribute is lost. You seem to be making my point, that the value of an object is context-specific... > > I propose that attributes are not part of a class' (or any other > > object's) value and that a class object has no value. Both of these suggestions are clearly problematical, as when used in an expression, an object can (and usually does) evaluate to some value for the purpose of evaluating the expression, and that value may be an attribute of the class, depending on what we decided is the right answer to the question above. > I see you are still insisting that value is something that objects > "have" rather than "are". This falls down, say, for a date object which has the value of the string representation of the date when printed, and a numeric value (or some other time object) when used in other expressions, both from a philisophical and practical standpoint. Furthermore it falls down semantically; an object has parts that are not part of its value, and therefore the value and the object can not be the same. The value is merely one attribute (natural language, not Python definition) of the object. [...] > In other words: the value of an expression is the object that the > expression evaluates to. So too is the value of an object. :) -- Derek D. Martin http://www.pizzashack.org/
Re: Official definition of call-by-value (Re: Finding the instance reference...)
On Thu, Nov 13, 2008 at 11:58:18AM -0800, [EMAIL PROTECTED] wrote: > I have yet to see any reasonable definition of a Python value in the > Python docs or elsewhere, despite the fact that a value is one of > the three defining characteristics of an object, a central concept > in Python. Why does it need to be defined in the Python docs? Is this really even an important question to answer? Are you unable to write correct functional programs in Python without having it answered? I suspect it's not an issue... Let's assume for the moment that it is, though. The term "value" already has a meaning... the one ascribed to it by its use in natural language. One on-line dictionary includes this among its definitions: magnitude; quantity; number represented by a figure, symbol, or the like: the value of an angle; the value of x; the value of a sum. It seems clear that this, or something extremely close to this, is what is meant in the Python docs by the unqualified use of the term. So, then, what is the value of a Python object? As has been alluded by others, it is not possible to formally define or enumerate what such a value is, in general terms, because the term "object" refers to to a thing with neither a deterministic nor static identity; in the abstract an object has no inherent or intrinsic value. The best you can hope to do is define it in context. To illustrate: In natural language and the physical world, an object has any number of values; for example a book has a title, a topic, a weight, a height, a length, a width, a page count, a word count, a purchase price, a printing cost, a number of copies sold, a profit per unit sold, etc. to the limits of your imagination regarding ways to describe books. Which of these is its "value" depends upon the context in which you are discussing the book. To the reader, the value is the price he pays for the book, or perhaps some measure of the enjoyment he derives from reading it (possibly the amount he would be willing to pay to buy it). To the seller, the value is perhaps best represented by the profit per unit sold. To the publisher's shipper (think FedEx), the value might best be described in terms of its weight... Just as in the physical world, in Python an object can be defined such that it evaluates to different values in different contexts, even though its state may not have changed between those different contexts. Therefore the value of an object is dependent upon its data attributes AND its behaviors defined as methods, as well as the context in which it is accessed, and is the value to which the object evaluates in a given expression or context. If you like, you could think of the value of an object as the set of all possible values to which the object may evaluate in every possible context, given a particular state of the object. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpbIUrXOwI9A.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: open a shell prompt froma python program
On Thu, Oct 30, 2008 at 02:47:48AM -0700, gaurav kashyap wrote: > Simply i want to open a shell prompt from a python program. If this is literally true, then you just need to figure out what command will open a terminal window from the shell prompt. Once you figure that out, it's as simple as: cmd = "whatever your shell command is" os.system(cmd) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpjESdNVsDLA.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: open a shell prompt froma python program
On Thu, Oct 30, 2008 at 03:53:52AM -0700, gaurav kashyap wrote: > HI, > I am getting the following error: > > konsole: cannot connect to X server > > do i need to install the related files. Maybe, but given that error message, probably not. You would do yourself a great favor by providing a lot more detail about what you are trying to do... On a Unix/Linux system, unlike Windows, there is no one single "shell prompt window" -- there are lots of them. They all need the X Window System (a suite of software which provides a GUI interface to Unix systems -- it's not "built in" like it is in Windows). X works as a client-server model, and you need to make sure X authentication is handled properly. Depending on what you are doing, this can be either very easy, or very complicated. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpnBx41jvOnI.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Python suitable for Midi ?
On Tue, Oct 28, 2008 at 06:54:57PM +0200, Chuckk Hubbard wrote: > The problem I've run into is that I can't set the audio to a higher > priority than the GUI (Tkinter). If I move the mouse over the app, no > matter what, I get audio dropouts. AFAICT this is the same for all > Python, regardless of what modules one uses: you can't assign system > priorities to different threads. If you're planning to pipe MIDI to > another app for playback, maybe it won't be an issue for you. FWIW... You could take your own advice, and devide your application in two: one process manages the GUI, and the second is a back-end process that plays the MIDI. Your GUI can even launch the back end, which will inherit the priority of the GUI, after which the GUI can reduce its own priority (the priority of the back end will not be affected by the change)... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpIZwcieNKvY.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: How to examine the inheritance of a class?
On Fri, Oct 24, 2008 at 11:59:46AM +1000, James Mills wrote: > On Fri, Oct 24, 2008 at 11:36 AM, John Ladasky <[EMAIL PROTECTED]> wrote: > > etc. The list of subclasses is not fully defined. It is supposed to > > be extensible by the user. > > Developer. NOT User. It's a semantic argument, but John's semantics are fine. A library is code intended to be consumed by developers. The developers *are* the users of the library. *End users* use applications, not libraries. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpug97BBp01J.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Python equivalent for C module
On Mon, Oct 20, 2008 at 10:28:15AM -0700, Gary Herron wrote: > > The other weird behavior was, once I changed the value of DEBUG, > > dprint() started to behave oddly. No matter what I passed as an > > argument (and no matter what I set the value of DEBUG to be), it > > started printing the exact literal string: > > > > DEBUG: %s [...] > I don't believe it -- send your *actual* code, and we'll all have a look. When I finally had access to my code again, my error was immediately obvious. I'd typed: print("DEBUG: %s") Weird thing was, I remembered it actually working. And it had... In between testing the two cases, I'd accidentally deleted the module and had to recreate it. The first time no bug, second time, well, resutled in this thread. I'm chalking the whole thing up to coding when not sufficiently awake to do so. ;-) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpPHO8fo3dXL.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Python equivalent for C module
On Mon, Oct 20, 2008 at 10:43:55PM +, Steven D'Aprano wrote: > All of this is just splitting hairs, Indeed... :) > because you don't really mean Python is making a copy of the name > 'DEBUG', but of the *data* that DEBUG refers to, namely the object > True. Well, as long as we're having semantic discussions... If you reread my post, it should be clear that what you wrote above can not possibly be the case. If you recall, my intent was to make a copy of a means of accessing the value known by the name "DEBUG" contained in the debug module, which could be accessed from any module in the program. Clearly the data itself *must not* be a copy, or else what I was trying to do would never have worked. What I was refering to as a copy was in fact essentially the name, or more accurately (as regards my conception of purpose) a reference to the data. > > The *object* very much is: it is immutable. > > So what? The *name* DEBUG is not read-only. You may have missed where I explained that the name refers to two different things, and that I, speaking in loose terms, was refering to both things simultaneously but in different contexts. I was speaking loosely -- I was using "read-only" as a figure of speech of sorts, and elaborated *correctly* what actually happens. Again, if you reread my original post with that explanation in mind, I think you'll find that this is the only sensible interpretation for what I wrote. > Actually it is a very common convention in Python circles. I often use it > myself. However it's not the only one, and from time to time I use > others. I would consider using DEBUG unusual, but not excessively so. To be honest, same here. My post contained throw-away C code that I typed up on the fly, and the same goes for the Python -- I simply translated the C code literally, so to speak. As has been pointed out in a different thread (by Bruno himself, if I'm not mistaken), the code hastily posted here need not represent the code that one would write in "real" programs. But I find it offensive that certain people here can't resist lambasting some posters who have simple questions, because the code they posted isn't up to their particular favorite coding "standards" (i.e. conventions), and I will speak out about it, especially when it's done to me. I didn't ask about coding conventions, but Bruno's response was roughly 75% about how my code sucks, and maybe 25% about answering my question. And what part did answer my question was completely redundant. It was roughly 95% a waste of time and energy for both him and me, though I did learn about the logging module... > Deary deary me... you come along here, asking noob Python questions, and > then get shirty when people give you friendly and perfectly good answers. Well, we disagree that the answer Bruno provided was either friendly or perfectly good. I did receive perfectly good answers, and if you read the whole thread, you saw me accept such answers graciously. Bruno's answer smacked of a superiority and arrogance that is not uncommon among certain frequent posters. He has no idea what my program does, or what my real code looks like, but apparently deigns himself the Code Police, and finds it necessary to punnish people for posting code which does not conform to his idea of Programming Law. I can't deny that I should have been able to answer my own question with only a few more moments thought... Though I don't think it's quite right to characterize questions about scope as "noob" questions. I suspect actual noobs don't yet know enough to ask such questions. > Are you trying to ensure that the next question you ask remains > unanswered? Not at all, just trying to preempt the pound of attitude that often goes with the ounce of answers. But if the choice is between no answer, and an answer that barely manages to avoid calling me an idiot (especially over coding style), I'd rather have no answer. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp1spA6WQhn4.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Python equivalent for C module
On Mon, Oct 20, 2008 at 07:29:16PM +0200, Bruno Desthuilliers wrote: > This should have been: > > fprintf(STDERR, "DEBUG: %s", msg); No, it shouldn't have. If I turn on debugging, I want the debug messages to go to stdout, so that they can be captured along with the output (of which there is almost none anyway) to clearly indicate when they happened. > STDOUT is for *normal* program outputs. Debug informations, warnings, > and all verbosity should go to STDERR. That's your opinion, and I disagree. Besides which, if you're running a program in debug mode, you're DEBUGGING... "normal" does not apply. You're being rather presumptuous... you don't even know how my program is being used. > >Then in the modules that wanted to use it, I did: > > > >from debug import DEBUG, dprint > >But I got some weird behavior. The imported copy > > It's not a copy. Actually, I'm pretty sure it is; i.e. there are two copies of the name: one in the namespace of the module, and one in the namespace of the file into which I imported it. At the time they are created, they both point to the same object. Is that not the very definition of a copy? The object itself may exist only in one place, but it has two names; one in each namespace. > >of DEBUG is > >read-only; > > It's not read-only. The *object* very much is: it is immutable. The name of that object is DEBUG, and thus DEBUG is read-only. You can make DEBUG point to a different object by binding a different value to it, but if that value is of an immutable type, it will still be a read-only object. In the sentence I wrote, as well as in general, "DEBUG" actually refers to two different things: the object bound to the name, and the name itself. It's up to the reader to infer which sense is correct given the thing being said about it. It just so happens that the English sentence I wrote refers to both simultaneously. > Just use a fully qualified name, so you dont make DEBUG local: > > import debug > print debug.DEBUG > debug.DEBUG = True > print debug.DEBUG Right, several people have already pointed this out. Which leads me to believe that the point of your reply was to berate me into following your conventions, which I have no interest in doing, in part because they are counterproductive to my goals, and in part because they are counter to the way I've been programming for 25 years. Fortunately, it's not your call how I write my code. > Now note that ALL_UPPER names are - by convention - considered > 'constants'. If this is supposed to be altered, don't write it ALL_UPPER. YOUR convention, not mine. > Also and FWIW, Python has a logging module in it's stdlib. Please use it > instead of any half-backed squared-wheel homegrown solution. Note that the correct possessive form of "it" is "its" with no apostrophe. This was the only thing of value which you contributed, though really, using that is way overkill for my needs. If I've written bad code, by all means, please correct it. If I've written code in a style that you happen not to like, please feel free to keep that to yourself. > My 2 cents Must be Zimbabwe currency... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpcR9dOjsCO1.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Python equivalent for C module
I'd like to know if it's possible to code something in Python which would be equivalent to the following C: [Assume bool is typedef'd to int, and TRUE and FALSE are #defined to 1 and 0, respectively] debug.c #include bool DEBUG; void dprint(char *msg) { if (DEBUG){ printf("DEBUG: %s", msg); } } end of debug.c The idea being that all modules of the program would "import" this code via the header file: debug.h extern bool DEBUG; void dprint(char *msg); end of debug.h I'm specifically trying to avoid having to create a debug object and pass it around... All modules should have visibility into the state of whether DEBUG is turned on or off, and be able to use dprint(). Can Python do this? I tried creating debug.py as such: debug.py DEBUG = True def dprint(msg): if DEBUG: print("DEBUG: %s" % msg) end Then in the modules that wanted to use it, I did: from debug import DEBUG, dprint But I got some weird behavior. The imported copy of DEBUG is read-only; if you update it, the name DEBUG points to a different object which the other modules can't see. After doing some reading of the docs, this behavior is explained and understood (though obviously not what I want). It just occured to me that I might be able to get around that by using a setter function in the module itself... I'll try this later. The other weird behavior was, once I changed the value of DEBUG, dprint() started to behave oddly. No matter what I passed as an argument (and no matter what I set the value of DEBUG to be), it started printing the exact literal string: DEBUG: %s whenever it was called. It was as if the function couldn't see the parameter msg, which was passed via the call. Most unexpected, and definitely undesirable. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp4DKmvYHFbt.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: indentation
On Sun, Oct 19, 2008 at 06:05:08PM +, Jorgen Grahn wrote: > Doesn't pretty much everyone use spaces and a four-position indent? I can't speak for everyone, or even "pretty much everyone"... but I know of several people who favor the idea of "indent with tab, align with space." The advantage to this scheme is that anyone using a half-sane editor can very easily change the level of indentation to their preference, meanwhile keeping the rest of the code aligned properly (though this may well interfere with keeping line lengths to 80 columns, or some other decided-upon number). I favor this myself actually, though I rarely use it for Python code I write, because that almost invariably needs to work with someone else's code who insists on the "standard" you mentioned. I know plenty of people who prefer a full 8-column indent, feeling that it makes indentations (and therefore the logical blocks wich the indentation is meant to indicate) much clearer, though most of them are primarily C coders. Some switch to 4 for python, and some prefer to keep 8 for pretty much everything they write. > I don't think I've ever come across any half-decent Python code > which didn't follow that convention. I have. :) Unless one defines a lack of tabs as a criteria of "half-decent Python code" -- which I obviously don't. > [0] This is an old and tedious topic ... This is very true... though clearly to anyone who hasn't encountered it before, it is rather new. > my view on TABs is that they are useless iff they aren't > rendered the same way everywhere. The size 8 is hard-coded into > terminals, printers and programs since ancient times; thus > anything else is wrong. This, on the other hand, is quite false -- not your opinion, perhaps, but all of the facts you've put forth in support of it. The tab size of nearly every tty device I've interacted with in the last 25 years *defaulted* to 8, but is configurable using any of various terminal control programs, such as tabs, stty, etc. (though I wouldn't know how to do this on Windows, or if it's even possible/relevant)... The utility of adjustable tabs is what I already stated above. I'm not saying you should change it... just that it is very much *not* hard-coded. In fact, most of the terminal devices I've used let you set arbitrary tab stops at whatever column positions you like. Occasionally useful, though not to me personally. One thing is for sure: it's essential that whatever formatting you decide to use, everyone touching that code needs to use the same one, or else the result is an annoying mess. Vim (and quite probably other editors) solves this by providing a way to set the options in the file you're editing, which is one of many reasons why I favor it over anything else. For example, at the top of your file: #!/usr/bin/python # vim:ts=4:sw=4:expandtab Though of course, using this kind of mechanism quickly becomes gross if everyone is using a different editor, and they all support a similar but different mechanism for doing so. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpWonPLlq6C1.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Set Environment for java based tools thru python script
On Mon, Oct 13, 2008 at 05:07:16PM -0700, [EMAIL PROTECTED] wrote: > I run a Java app with subprocess from Python script. This python > script is called from another Python Wrapper. > > > python = subprocess.Popen(["toolname.sh", "-args", arg1, arg2], > stdout=subprocess.PIPE, > stderr=subprocess.PIPE) This (toolname.sh) looks like a shell script (though technically, there's no reason it couldn't be a python script). Unfortunately, from what you've written here, it's neither clear what processes start what processes, nor what the intended result is. You have said you have 3 programs, but you've only shown the interactions between two of them. My suggestion would be to rewrite your request, explicitly name the processes (even if it is just with letters, A, B, and C), and show which processes start which other processes, and probably explain a little about what each one is supposed to do. That said, see below. > I can run it manually from the command line. But fails when I execute > the wrapper Python script > > How do I source the java environment from the wrapper. It fails with > the following message. > > ...16605 Segmentation fault $JAVA_HOME/bin/java $JAVA_OPTIONS - > classpath $CLASSPATH xx "$@" Again, it's not clear what you're trying to do, but I'm assuming you have some script that sets environment variables, and that's what you mean by "source the java environment..." If so, you can't. You either need to source the environment before running the Python program, or have the python program read a file that contains the environment and do its own parsing, setting the environment variables appropriately. A child process, in general, can not insert environment variables into the environment of its parent. If what you're trying to do isn't covered by the above, then I think you'll need to try to explain it better. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpBooNZ2b3rY.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Using subprocess module to launch a shell shell script that itself forks a process
On Tue, Oct 07, 2008 at 05:43:41PM -0700, Samuel A. Falvo II wrote: > p = subprocess.Popen( > command, > shell=True, > stdin=subprocess.PIPE, > stdout=subprocess.PIPE, > stderr=subprocess.STDOUT, > close_fds=True > ) > > outputChannel = p.stdout > output = outputChannel.read() You call read with no arguments. This is highly problematic in the context of interprocess communication, unless you can be 100% positive that none of the children will write anywhere besides STDOUT, and won't try to read from STDIN in the meanwhile. Python's read() with no args reads until the end of file, which in IPC contexts is bad... Normally the child process won't close stdout until it exits. So, if it did any other output in between, say, to STDERR, the child will block waiting for the parent to read STDERR, meanwhile the parent is blocked waiting for input from the child's STDOUT, which results in a deadlock. Both processes sleep forever. The exact same thing can happen if either the shell script or a process started by the shell script tries to read from STDIN. Since Java is launched by the shell script, it inherits the shell script's STDIN, STDOUT, and STDERR file descriptors (i.e. the two processes share the same STDIO). Thus if the java process writes to STDERR, that also could be causing your deadlock. On Wed, Oct 08, 2008 at 11:24:39AM -0700, Samuel A. Falvo II wrote: > On Oct 7, 6:23 pm, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > > Is your shell script doing something else, apart from invoking the java > > process? > > Obviously, yes. It's far from obvious. I can't count the number of scripts I've seen whose sole purpose was to launch a Java program (with the right environment)... You would do well to avoid being dismissive and listen to those who respond with help, when you are the one who obviously doesn't understand the behavior you're getting, and you're the one asking for help. > The script is some 150 lines long. But the hang-up > occurs because of the forked Java process, not the other lines. I'm betting it's because the Java program is writing warnings to STDERR (more data than will fit in the STDIO buffer), which you're not reading... > > If not, you could just invoke java directly from Python. Also, > > you set stdin=PIPE - is your java process expecting some input? you're not > > writing anything to stdin. > > It does not expect input from stdin. However, this does not affect > any OTHER scripts or commands I run. Irrelevant... Unless "any OTHER scripts" encompases all possible combinations of process interactions, and you can demontstrate that it does so, this proves nothing. > Let's remember to look at the objective facts: for shell scripts that > launch child processes of their own, Python hangs. For all other > types of commands, it works 100% as expected. These are not facts which are in evidence. We don't know what your script is doing, and it's clear that you yourself are not able to explain the behavior you are seeing, therefore there is no reason for us to conclude that the above statements are true and correct. Most likely, they are not. > > Anyway, it's better to use the communicate method instead (it uses select > > to read from both stdout and stderr): > > That doesn't help me. Please explain why it doesn't. The most likely cause of the behavior you are seeing is the deadlock I described, above. Using select() (i.e. using communicate()) should generally fix about half the cases... The rest would be fixed by redirecting STDIN of the child (or at least the Java process) from /dev/null, most likely. Then of course, there could be other explanations. But this being overwhelmingly the most likely one, if you don't try those solutions, there's no point in trying to help you further... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp8zdVYVQEhV.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Test if list contains another list
On Mon, Sep 29, 2008 at 04:12:13AM -0700, [EMAIL PROTECTED] wrote: > Derek Martin: > >Unless you're doing lots and lots of these in your application,< > > I don't agree. That's library code, so it has to be efficient and > flexible, because it's designed to be used in many different > situations That's fair, but lots of folks writing Python code will look at that and say, "What the [EMAIL PROTECTED] is this doing?!?" As I already suggested, code that implements non-obvious algorithms ought to explain what it's doing in comments, so that the neophyte programmers charged with maintaining the library aren't tempted to rewrite the code so that it's easier to understand what it's doing. It can be as simple as: # Use Morris-Pratt algorithm to search data Then, anyone not familiar with the algorithm can easily look it up, and see why it was written that way. I think it's just as important to do that in code you post on the list, since a) the person asking the question obviously doesn't know what you're doing, or they wouldn't have needed to ask the question, and b) there are lots of other folks reading the list who could benefit from the same knowledge. :) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpsqKgyV2byd.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Test if list contains another list
On Fri, Sep 26, 2008 at 01:39:16PM -0700, [EMAIL PROTECTED] wrote: > # building prefix-function > m = 0 > for i in xrange(1, len_sub): > while m > 0 and sub[m] != sub[i]: > m = table[m - 1] > if sub[m] == sub[i]: > m += 1 > table[i] = m > > # searching > m, i = 0, 0 > for x in items: > while m > 0 and sub[m] != x: > m = table[m - 1] > if sub[m] == x: > m += 1 > if m == len_sub: > return True > i += 1 > > return False Quite a lot faster than mine... even without using psyco. Which is interesting, especially because if I change my search loop to work like yours, but leave out all your other optimizations, mine runs roughly as fast as yours (i.e. execution time is negligible to a user running the program in both cases, even with the large example data you gave). This leads me to point out two caveats with your version: 1. Guavat posted a version which returns a list of all the indexes where a match is found... which is what I mimiced. Yours returns only true or false indicating whether or not it found a match. The main difference in performance seems to come due to your iteration over the list items, versus my comparing a sublist-sized slice of the whole to the sublist. But this alone is an invalid optimization, because it doesn't produce the same results... If you only want to know if a match exists, it's great; but if you want to know *where*, or *how many times*, you lose. That could be fixed though, by counting the elements as you loop through them... I didn't attempt to determine the performance hit for doing that, but I assume it's negligible. I also imagine that that was your original purpose for the unused variable i... 2. Your secondary optimizations add a great deal of complexity to your code, making the algorithm much harder to understand. However they don't appear to buy you much, given that the cases they optimize would probably be rare, and the difference in execution time gained by the optimization is not noticable to the user. Unless you're doing lots and lots of these in your application, or maybe if you know in advance that your data will contain many instances of the cases you optimized, I think you're better off leaving the optimizations out, for the sake of code clarity. At the very least, if you're going to write complicated optimizations, you ought to have explained what you were doing in comments... :) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpcipqEw7nQM.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Test if list contains another list
On Thu, Sep 18, 2008 at 03:24:16AM -0700, [EMAIL PROTECTED] wrote: > I looked inside this thread for my query which brought me the > following google search result > "Test if list contains another list - comp.lang.python | Google > Groups" > > But then I was disappointed to see the question asked was not exactly > right. [...] > def findAllMatchingList(mainList, subList): > resultIndex = [] > globalIndex = 0 > for i in range(len(mainList)): > if i < globalIndex: > continue > globalIndex = i > increment = 0 > for j in range(len(subList)): > if mainList[globalIndex] == subList[j]: > globalIndex += 1 > increment += 1 > if j == (len(subList)-1): > resultIndex.append(globalIndex-increment) > else: > break > > return resultIndex I didn't time them to compare, but how about this instead: >>> def find_needle_in_haystack(needle, haystack): >>> ... r = [] ... L = len(needle) ... for i in range(len(haystack)): ... if haystack[i:i+L] == needle: ... r.append(i) ... return r >>> # this fails because "3" is not 3... >>> >>> find_needle_in_haystack([1,2,3], ["a","b",1,2,"3","9"]) >>> [] >>> find_needle_in_haystack([1,2,3], [1,2,3]) >>> [0] >>> find_needle_in_haystack([1,2,3], ["a","b",1,2,3,"9"]) >>> [2] >>> find_needle_in_haystack([1,2,3], ["a","b",1,2,3,"9","q",1,2,3]) >>> [2, 7] -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpNKYFN6mu45.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
test list post
Sorry for the noise, my recent posts seem to have been eaten by the list management software, as far as I can tell. Just testing if that's still the case. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp611hi0GmSx.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Wed, Sep 03, 2008 at 03:16:00PM -0700, Dennis Lee Bieber wrote: > On Wed, 3 Sep 2008 03:09:18 -0400, Derek Martin <[EMAIL PROTECTED]> > declaimed the following in comp.lang.python: > > > > > struct run { > > int speed; > > direction_type direction; > > }; > > > > Not a function. Describes an action. Sure, you'll probably never see > > this example in a real program. But that doesn't mean you can't do > > it, and it doesn't make it inherently wrong. Someone somewhere might > > very well find a legitimate use case. > > > > Does neither for me... It defines a (physics) VELOCITY (a direction > and a speed, but lacking in starting position and in duration). OK... so, let me ask you then: I have a computer program that graphs the state of a particular act of running over time t. The only information the program cares about is the speed and direction of that particular instance of running. What would your data structure look like? > An action, "run", would, in my mind require taking this vector and > multiplying it by some duration, and adding the result to some starting > position. I can not be held responsible for your mind... ;-) You're talking about a computational action... which I already said is NOT what I'm talking about. At any given point in time, if someone is running, they have a direction and a speed. The structure I described is sufficient to describe that state. In this extremely silly example, the starting point, end point, and any intermediary positions are not interesting to the problem, which has intentionally been left undefined, because it is an EXAMPLE. Examples are not required to be especially useful or meaningful, and I would guess that the vast majority of examples in, say, introduction to comp sci texts are not (think "hello world"). They need only illustrate something. This particular point was that an object in a computer program can describe some physical action -- in whole or only in part -- without actually needing to have any executable code associated with that state (i.e. it can be a data only, rather than an object with executable methods). The "thing" being described being an action may lend itself to using the name of that action, i.e. a verb, as the name of the object. Though, actually, the example I described above is (minimally) useful. Assuming you had an array of such structs, with say, the index representing the time t in seconds, then it provides you with a graph of the path taken during the act of running. You could superimpose this graph on a map and, given a particular starting point, determine where the person running ended up. You might be inclined to say that the object should be a runner, and you're free to think of it that way if you like... but the fact is the object DOES NOT describe a runner. It describes an instance of running at a moment in time. You might also be inclined to say that the name "run" is a bad choice, because it should be something retarded like state_of_run_at_time_t; but unless you're unbelievably obtuse, then looking at the code, it gets the point across. It may not be the most ideal name, but given the number of times I've seen "foo" used as an identifier in real programs... well, is it really so bad? -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp0vGu5I07IT.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Wed, Sep 03, 2008 at 06:40:10AM +, Marc 'BlackJack' Rintsch wrote: > On Tue, 02 Sep 2008 19:54:12 -0400, Derek Martin wrote: > > >> And if they model an action there must be some way to activate the > >> action > > > > That's a reasonable assumption, but as I also said, the object might > > just describe the action -- essentially the equivalent of a struct in C. > > ``struct``\s in C describe *actions*!? Functions do this. struct run { int speed; direction_type direction; }; Not a function. Describes an action. Sure, you'll probably never see this example in a real program. But that doesn't mean you can't do it, and it doesn't make it inherently wrong. Someone somewhere might very well find a legitimate use case. Besides which, I was not talking about programmatic actions; I was talking about verbs -- actions that people do. You are putting narrow-minded constraints on your ideas about how to program. Sometimes thinking outside the box is useful... > >> but the instances of `Popen` are no actions. There's no way to > >> "execute" a `Popen` instance. > > > > Yes there is... you execute it when you instantiate the object. > > But then the instance itself isn't an action but the result of one. So? A class doesn't represent an action, remember? It represents a thing. Isn't that what you said? > > At the time of instantiation, you "open" the "P" (pipes). For an > > object which describes an action, I think it's perfectly sensible that > > instantiation is when the action occurs, […] > > Here I disagree again. Because the type/class name of an instance should > be a name of the "thing"/concept of the instance, not the action used to > create it. You're making an assertion based on your personal opinion. That's a fine guideline, but there's no requirement to do so. I can name my classes anything I want. There's no reason I can't write: Class Think: def __init__: self.thoughts = happy print "Thinking %s thoughts!" %s self.thoughts This is a silly example that does nothing useful, but that doesn't exclude the possibility that someone might conceive of a similar example that is actually useful. Maybe you're just not creative enough, and I'm too lazy. > >> Maybe from your POV. Facts: It doesn't use the `popen()` function > > > > So? Neither does the C version of popen(), but that function is still > > called popen()! > > Now you lost me. The C version of `popen()` isn't recursive, why on > earth should it be, so what's that statement supposed to mean!? Sorry, did I go too fast for you? Your "facts" seem to be suggesting that for Python's Popen class to be named Popen, it should use the C popen() function. I can't imagine any other reason why you mentioned it doesn't... It need not use popen() to do what popen() does... In fact, it need not do what popen() does to be called Popen! It's just a name... the author can call it whatever he wants. As it happens, it was called Popen because it does essentially what popen() does. The fact that it doesn't USE popen() to do it is... not interesting? > >> to three file objects, more attributes and methods), the function used > >> on Windows under the hood is called `CreateProcess()` not > >> `CreatePipe()`. > > > > How does Windows implement popen()? [I think they call it _popen() > > though...] > > Doesn't matter because the `Popen()` implementation doesn't use `popen()`. No, that's exactly why it *does* matter. Because neither is popen() implemented using popen()! See! There you go again! Does it matter, or doesn't it?!? What are you trying to say?!? Sorry, but you are contradicting yourself (repeatedly), and your arguments don't make any sense. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpvhafSwjqFj.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Wed, Sep 03, 2008 at 12:20:18AM -0400, Miles wrote: > Derek Martin wrote: > > On Tue, Sep 02, 2008 at 10:55:54PM +, Marc 'BlackJack' Rintsch wrote: > >> but the instances of `Popen` are no actions. There's no way to > >> "execute" a `Popen` instance. > > > > Yes there is... you execute it when you instantiate the object. At > > the time of instantiation, you "open" the "P" (pipes). > > The subprocess module is also supposed to replace os.system and > os.spawn*, neither of which involve opening pipes. Sigh... wasn't finished, sent by accident. Anyway, to continue... The subprocess module also can be used to replace these two functions, though to be honest, it's not clear to me why one would do so. On the whole, I choose not to use the subprocess module because I find it tedious, and less tedious interfaces (like os.system() and os.popen(), and even the popen2 module) exist. [But, you can probably guess that I write code almost exclusively for POSIX-ish systems...] If all you want is the equivalent of os.system() or os.spawn(), then it seems to me the subprocess module is overly heavy-handed, leaving a bunch of not useful state laying around in your environment... Not to mention you probably already need the os module, so you could save yourself the trouble and overhead of importing subprocess. > All rationalizations aside, I think Popen is a poor name for the > class. Even within this thread, a number of people clearly disagree with you. To say nothing of the maintainers... :) I really think it's not worse (and actually better) than "process"... for reasons I already explained. The argument that the object is a process is spurious. The object is, in actuality, an instance of *COMMUNICATION* between two processes. It's true that a process is started as a result, so that the first process has a second to be able to communicate with; and a (tiny) bit of information (the PID) is maintained about that process, mostly for no useful reason... However the object mainly is a collection of pipes, and some methods for communicating over them, to another process that, out of necessity just happens to be a child of the current one. If you think about what the methods do, and understand how they actually work, I think it will become clear that this is the case. Does communicate() operate on the process? ABSOLUTELY NOT -- it operates on the pipes. poll() and wait() may arguably act upon the process (they actually request information about the process from the kernel), but the goal in doing so is to find out the status of the communication: is it done, and if so was it successful? If you abstract the concept from its implementation, this is clearly true. I could concede that it may not be clear to someone unfamiliar with C programming (perhaps especially in a Unix environment, though Windows does have a similar, but apparently broken function) what "popen" means or does, but the manual has ample references to explain that, I think. It's no less clear than the popen() function itself! > But I would imagine the odds of it ever being changed are miniscule > (Python 4?). The truth is, in the end, I personally don't really care; though if it were changed, I would hope something genuinely better were chosen. I feel strongly that "process" ain't it. My motivation in posting in this thread is mostly to point out how silly it is to argue or complain about the name of some bit of logic in a programming language, especially once it's already been released (though I doubt most of the participants got the point). The time to do this is when the feature is in the planning stages, if ever... Some people take this stuff way, way too seriously, and also can't seem to imagine that another perspective besides their own exists, and especially that their own might just not be optimal/correct. Posting to Usenet/maling lists and saying "Why is X called X? It should be called Y!" is not likely to ever produce any sort of useful result. ;-) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgphiAy6Q03Hs.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Wed, Sep 03, 2008 at 12:20:18AM -0400, Miles wrote: > Derek Martin wrote: > > On Tue, Sep 02, 2008 at 10:55:54PM +, Marc 'BlackJack' Rintsch wrote: > >> but the instances of `Popen` are no actions. There's no way to > >> "execute" a `Popen` instance. > > > > Yes there is... you execute it when you instantiate the object. At > > the time of instantiation, you "open" the "P" (pipes). > > The subprocess module is also supposed to replace os.system and > os.spawn*, neither of which involve opening pipes. Uh... it's a replacement for os.popen(), which -- guess what -- opens pipes. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpFzhcvw9B48.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Tue, Sep 02, 2008 at 10:55:54PM +, Marc 'BlackJack' Rintsch wrote: > On Tue, 02 Sep 2008 18:15:07 -0400, Derek Martin wrote: > > >> Classes represent "things", and class names should be nouns. > > > > Is that a law? > > It's a common guideline. Right. It's a guideline. > > Classes are instantiated by invoking their class names as a function > > call -- the computing equivalent of a verb. Why then, must they be > > named as nouns? Can you not, in fact, have classes which describe (or > > model) actions? Wouldn't you name them using verbs if you did? > > Me personally no. I would use `FooAction` instead of `Foo` or something > similar. Maybe you would, but I think a lot of folks would just use the action name (i.e. the verb). > And if they model an action there must be some way to activate > the action That's a reasonable assumption, but as I also said, the object might just describe the action -- essentially the equivalent of a struct in C. > but the instances of `Popen` are no actions. There's no way to > "execute" a `Popen` instance. Yes there is... you execute it when you instantiate the object. At the time of instantiation, you "open" the "P" (pipes). For an object which describes an action, I think it's perfectly sensible that instantiation is when the action occurs, though there could be other times (e.g. if the object had an "execute" method) which make as much sense. > > My point is, if you don't think Popen is a good name for the class, > > that's your opinion, but it is only that: an opinion. > > Like your opinion that it *is* a good name. Yes, exactly. > > Yet some of you state your case as if it is incontrovertable fact. > > I've given a good case as to why it IS a good name (one which I > > genuinely support), and disagree as you may, none of the points any of > > you have made invalidate or even weaken my argument. > > Maybe from your POV. Facts: It doesn't use the `popen()` function So? Neither does the C version of popen(), but that function is still called popen()! :-D As I've already said a few times now, it is conceptually based on popen(). The fact that it doesn't use popen() is not interesting; it (or the portion of it that corresponds to what popen() does) is implemented almost exactly the same way as the C popen() function (except in Python, rather than C). That, to me, is much more interesting. pclose() does what Popen.wait() does, essentially. Sure, the class has a few extre bells and whistles that the C implementation doesn't have, but: > it gives something more complex than a simple pipe Gosh, one would hope that it would be universally true that an object-oriented implementation of something that was originally designed using conventional programming techniques would provide more than one piece of the conventional implementation... We might even hope that it would improve upon 40-year-old implementations, wherever possible... > to three file objects, more attributes and methods), the function used on > Windows under the hood is called `CreateProcess()` not `CreatePipe()`. How does Windows implement popen()? [I think they call it _popen() though...] > `Popen` creates a process and represents a proxy object to communicate > with it, so `Process` is a good name for that concept/"thing". I disagree; the point of that process creation is the communication between the two processes. Calling it a process does not reflect this very important aspect of the object. The Popen object is not a process; it is a collection of pipes and methods used to communicate with one. > It's a way more self explaining name, even for people who know the > `popen()` function I, and apparently the maintainers (at least at the time they added this thing) don't agree. In fact I think it's quite the opposite. If I came across such a "process" object without knowing what it was, I would expect that a process object described a running process, i.e. gave information about things like executable path name, cpu and memory utilization, perhaps a list of all open file descriptors (but not just three specific ones), etc; or something similar. This object provides none of that. It does not, in fact, describe a process at all. It is quite distinct and different from the concept of a process, indeed. > because there's a concept called "process" but none called "popen". Anything that exists can be conceptualized and therefore is a concept. The popen concept exists, and is more than just a concept; it has a concrete implementation in C AND Python and numerous other languages. Verbs can be concepts too. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpeShX0WeeW7.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Tue, Sep 02, 2008 at 05:22:51PM -0300, Gabriel Genellina wrote: > > The name popen is an abbreviation of "pipe open" -- the function, and > > the class, open pipes to communicate with another process. What you > > said is correct; however there are numerous other ways to open > > subprocesses. The focus of popen is the communication aspect -- the > > opening and control of the pipes -- not the subprocess. That's the > > key difference between popen() and all the other methods of starting a > > subprocess. > > Totally irrelevant here - we are talking about the subprocess > module, not the popen C function. I was talking about both actually. I can't agree that it's not relevant... The Popen class clearly takes its name from the function of the same name, and does exactly the same thing (plus what pclose() does, plus saving the pid of the forked process). Seems pretty relevant to me. > >> > The C library's popen() function, on which this class is based, > > No, subprocess.Popen does not use -directly or indirectly- the C > popen function. It uses fork or CreateProcess in Windows. I didn't say it used it. I said it was based on it. It is (conceptually). > > The Linux man page unfortunately copies (verbatim) the FreeBSD man > > page, which gets it wrong. You can not open a process, but you can > > definitely open a pipe. > > (Ok, if it doesn't agree with you, it must be wrong) See my last post for accreditation of my comment. A common argumentation tactic of the closed-minded and the small-minded is to resort to insinuation to attack the validity of other's comments without providing any basis for doing so. Nice job. > Classes represent "things", and class names should be nouns. Is that a law? Classes are instantiated by invoking their class names as a function call -- the computing equivalent of a verb. Why then, must they be named as nouns? Can you not, in fact, have classes which describe (or model) actions? Wouldn't you name them using verbs if you did? That said, this is the most valid point anyone has made... You should have made it when the module was being designed. :-D My point is, if you don't think Popen is a good name for the class, that's your opinion, but it is only that: an opinion. Yet some of you state your case as if it is incontrovertable fact. I've given a good case as to why it IS a good name (one which I genuinely support), and disagree as you may, none of the points any of you have made invalidate or even weaken my argument. Lastly, the maintainers obviously thought it was a good name when they included it... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpjs8JNQejpd.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Tue, Sep 02, 2008 at 06:47:39PM +, Marc 'BlackJack' Rintsch wrote: > That's why I think the name `Popen` is not so good for it. Because it > does more than `popen()` and if it is called `Subprocess` or just > `Process` then it would be merely an implementation detail, that the > `popen()` function is called at some point. The module is subprocess, and the class is Popen. The underlying implementation doesn't really matter; the class still does essentally the same as the combination of popen() and pclose(): it opens pipes to a subprocess, and allows the parent to wait until that process has terminated, and closes the pipe(s). The rationale for naming the class Popen is exactly the same as the rationale for naming the analogous functions. Do you think that subprocess.pipe() is not as good a name as subprocess.subprocess()? > If it is at all, because `popen()` on C level can just open a pipe > in *one* direction. That also is not (necessarily) true. Some Unix implementations provide bidirectional implementations of popen(). See, for example, the OS X popen() man page. It's existed in BSD Unix for years... > > Note that in all of these links that talk about popen, the focus is on > > opening pipes or file objects, not on subprocesses: > > > > http://www.opengroup.org/onlinepubs/009695399/functions/popen.html > > http://docs.python.org/lib/os-newstreams.html http://us3.php.net/popen > > http://docs.hp.com/en/B9106-90010/popen.3S.html > > http://www.faqs.org/docs/artu/ch07s02.html > > And all of the links talk about the `popen()` function, > not about the functionality the `Popen` class provides. Which is > much more than that simple pipe `popen()` returns. Well, you're comparing a class to a function, so no surprise there. But it's not really that much more, if you include pclose(). With the exception that it allows you to connect multiple streams instead of only one, and it saves the PID of the child (which for the most part is not especially useful), the functionality is identical. If you actually look at the Python implementation of the subprocess.Popen class, the implementation is essentially identical to the C implementation of the popen() and pclose() functions except that the latter saves the PID returned by the call to fork() in a class attribute, and opens 3 pipes instead of 1. If C's popen() and pclose() functions were written as a C++ class instead of two separate functions, it would look rather a lot like python's subprocess.Popen class. > > The Linux man page unfortunately copies (verbatim) the FreeBSD man > > page, which gets it wrong. You can not open a process, but you > > can definitely open a pipe. > > Ah, when their terminology doesn't match yours, they must get it > wrong. ;-) Nice try... Their terminology doesn't match the original author's. Here's the original AT&T System 7 man page: http://www.freebsd.org/cgi/man.cgi?query=popen&apropos=0&sektion=0&manpath=Unix+Seventh+Edition&format=html When describing what this function does, it states, "It creates a pipe..." Besides which, the BSD folks felt the need to quote "open", indicating that clearly they knew that no process is being "opened" by the function call. You start processes, you don't open them. This should have been a clue to the BSD manual page writer that they had the sense wrong; it's very obviously the pipe that gets opened, not the process. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpHERUiFlmDu.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Tue, Sep 02, 2008 at 01:57:26PM +, Marc 'BlackJack' Rintsch wrote: > > I would argue that they don't represent processes at all; the object is > > a set of files which connect the standard I/O streams of a subprocess to > > its parent, and methods to operate on those files. > > And the process' ID, an attribute with the process' return code, a method > to wait until the process is finished and file objects to communicate > with the process. The name popen is an abbreviation of "pipe open" -- the function, and the class, open pipes to communicate with another process. What you said is correct; however there are numerous other ways to open subprocesses. The focus of popen is the communication aspect -- the opening and control of the pipes -- not the subprocess. That's the key difference between popen() and all the other methods of starting a subprocess. > > The C library's popen() function, on which this class is based, > > provides a means to open a file and connect it to the standard steams > > of a subprocess, making it more closely analogous to what the Popen > > class does/provides. As such, "Popen" is a better name to describe > > this object than "subprocess" would be. > > Is strongly disagree. The class provides an interface to start and > communicate with a `Subprocess`. Instances stand for processes. There's more than one way to look at it. You can disagree all you like, but your interpretation disagrees with the historical intent of popen. > With your reasoning the `file` type should be called `open`. In this case, the file is a pipe, and the 'p' in popen represents the pipe. Unix, by and large, doesn't care that it's a pipe -- file I/O is intended to work the same way regardless of whether it's a pipe, a socket, a file on disk, a special device file, or any other file-like object you can imagine. That's why I said "file" instead of "pipe" in my explanation. Note that in all of these links that talk about popen, the focus is on opening pipes or file objects, not on subprocesses: http://www.opengroup.org/onlinepubs/009695399/functions/popen.html http://docs.python.org/lib/os-newstreams.html http://us3.php.net/popen http://docs.hp.com/en/B9106-90010/popen.3S.html http://www.faqs.org/docs/artu/ch07s02.html The Linux man page unfortunately copies (verbatim) the FreeBSD man page, which gets it wrong. You can not open a process, but you can definitely open a pipe. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpmN360qDTwf.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Inquiry regarding the name of subprocess.Popen class
On Tue, Sep 02, 2008 at 12:27:49PM +, Marc 'BlackJack' Rintsch wrote: > > The Python class is a generalization of the standard Posix function of > > (almost) the same name: > > http://opengroup.org/onlinepubs/007908775/xsh/popen.html > > So it's a name of a *function* and it's a little bit unsuitable for a > *class*. As Jeremy wrote: the instances represent *processes* not > "popen"s, whatever that may be. I would argue that they don't represent processes at all; the object is a set of files which connect the standard I/O streams of a subprocess to its parent, and methods to operate on those files. The C library's popen() function, on which this class is based, provides a means to open a file and connect it to the standard steams of a subprocess, making it more closely analogous to what the Popen class does/provides. As such, "Popen" is a better name to describe this object than "subprocess" would be. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpR91MGDIrTx.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Processes in Linux from Python
On Mon, Sep 01, 2008 at 08:40:42AM +0200, Diez B. Roggisch wrote: > Johny schrieb: > >To get a number of the http processes running on my Linux( Debia box) > >I use > >ps -ef | grep "[h]ttpd" | wc -l [...] > The shell does the exact same thing. And by the way: i think you miss a > > grep -v grep Indeed not. The brackets around the 'h' (which make it a character class, or range if you prefer) prevent the regex from matching itself. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpsslNfAlrcv.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: How to delete a last character from a string
On Fri, Aug 29, 2008 at 07:37:50PM +, Steven D'Aprano wrote: > On Fri, 29 Aug 2008 14:46:53 -0400, Derek Martin wrote: > > > On Fri, Aug 29, 2008 at 07:28:40PM +0100, [EMAIL PROTECTED] wrote: > >> dirListFinal = [] > >> for item in dirList: > >>print item > >>if item.endswith('\\') == True: > > > > if item[-1] == '\\': > > Which will fail badly if item is the empty string. Sure. I made 2 assumptions: 1. The OP didn't say how endswith() was failing. My assumption was it was missing from his version of python (i.e. he's using a version that predates the feature). I have no idea if that's possible or not... I've used python 2.4 almost exclusively. I've run into a number of cases where some clever trick I found on-line didn't work because it was new in Python 2.5 (or whatever), so it was easy for me to lazily assume that it could be the case here. 2. If his particular use case didn't exclude the possibility of an empty string, he'd be smart enough to check that first, or wrap it in a try block. > Rajat, rather than trying to invent your own code to join directory > paths, you should use the os.path module: > > >>> import os > >>> os.path.join('/dir', 'x', 'y', 'z', 'file.txt') I agree completely, though I do find that there's one thing missing from this module's support, which your example illustrates nicely: a way to find out what the root of the current filesystem is (for some definition of current which I will let the reader figure out). You explicitly wrote '/dir', which would likely be wrong on non-Unix OSes, though IIRC it might work anyway, depending on your particular environment (e.g. cygwin). I usually end up doing this via the following function: def _get_path_root(path): '''recursive algorithm to determine the name of the root of the file system in (hopefully) an os-independent way''' if os.path.dirname(path) == path: return path return _get_path_root(os.path.dirname(path)) You can, depending on your needs, either pass it the absolute path of your script, or the absolute path of your data file(s). For the sake of performance, I get the real absoulte path outside function: x = _get_path_root(os.path.realpath(foo)) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpVmSIx79HR5.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: How to delete a last character from a string
On Fri, Aug 29, 2008 at 07:28:40PM +0100, [EMAIL PROTECTED] wrote: > dirListFinal = [] > for item in dirList: >print item >if item.endswith('\\') == True: if item[-1] == '\\': -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp5fVWPp4Aiz.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Setting my Locale
On Wed, Aug 27, 2008 at 01:25:49AM -0300, Gabriel Genellina wrote: > En Tue, 26 Aug 2008 07:52:21 -0300, Robert Rawlins > >How can I get a list of available locales? > > I'd like to know how to retrieve that too... On a Linux system (and likely most modern Unix systems): locale -a -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpWZRSPsSXRy.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: programming toolbox
On Fri, Aug 22, 2008 at 08:17:27AM -0500, William Purcell wrote: > I am still wondering if C++ would be worth learning and I think it could be > answered by these three questions... > > 1. Are programs written in C++ better (in any form of the word) than > programs written in python or vise versa or equal? > 2. Is compiled better than interpreted? > 3. Is it necessary to know any more languages than python to be a > respectable programmer, i.e. to be able to take care of most programming > problems (text manipulation, gui programming, scientific computation, web > stuff)? I think the answer depends on what your goals are. If you want to be a well-rounded programmer, it's good to experience a number of different languages, so you can see different approaches to different problems. Languages like Python tend to obscure to some degree how things actually work inside the machine, whereas languages like C/C++ encourage that a bit more (though assembler much more so). I think it's also a good idea to have more languages under your belt if you want to be a professional programmer. The more tools you have in your toolbox, the more marketable you are... If you only want to learn to program to solve your own problems, then it doesn't really matter. The only reason to learn additional languages is if you find a case where what you've learned doesn't solve your problem, or the solution is a lot harder than it should be. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpCpPVKZ7JLW.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Having trouble with tail -f standard input
On Thu, Aug 21, 2008 at 02:58:24PM -0700, sab wrote: > I have been working on a python script to parse a continuously growing > log file on a UNIX server. If you weren't aware, there are already a plethora of tools which do this... You might save yourself the trouble by just using one of those. Try searching for something like "parse log file" on google or freshmeat.net or whatever... > The input is the standard in, piped in from the log file. The > application works well for the most part, but the problem is when > attempting to continuously pipe information into the application via > the tail -f command. The command line looks something like this: > > tail -f | grep | python parse.py The pipe puts STDIN/STDOUT into "fully buffered" mode, which results in the behavior you're seeing. You can set the buffering mode of those files in your program, but unfortunately tail and grep are not your program... You might get this to work by setting stdin to non-blocking I/O in your Python program, but I don't think it will be that easy... You can get around this in a couple of ways. One is to call tail and grep from within your program, using something like os.popen()... Then set the blocking mode on the resulting files. You'll have to feed the output of one to the input of the other, then read the output of grep and parse that. Yucky. That method isn't very efficient, since Python can do everything that tail and grep are doing for you... So I'd suggest you read the file directly in your python program, and use Python's regex parsing functionality to do what you're doing with grep. As for how to actually do what tail does, I'd suggest looking at the source code for tail to see how it does what it does. But, if I were you, I'd just download something like swatch, and be done with it. :) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpgsg6JnEM88.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: python custom command interpreter?
On Thu, Aug 21, 2008 at 05:17:41AM +, Marc 'BlackJack' Rintsch wrote: > On Wed, 20 Aug 2008 18:46:42 -0400, Derek Martin wrote: > > > How so? What could be easier than "rm -rf directory"? > > C:\>rm -rf directory Yeah, except the application specified by the OP is to remove directories during a kickstart install of Linux... so your comment is worthless. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp8JF1NO4bc7.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Negative integers
On Wed, Aug 20, 2008 at 02:38:11PM -0700, johnewing wrote: > I am trying to figure out how to test if two numbers are of the same > sign (both positive or both negative). I have tried > > abs(x) / x == abs(y) / y Zero is a problem, no matter how you slice it. Zero can be considered positive or negative (mathematically, 0 = -0). If you want zero to be treated always as positive, you can write this: def same_sign(a, b): return (abs(a) == a) == (abs(b) == b) If you want to respect zero's duplicitous nature, you have to write it like this: def same_sign(a, b): if a == 0 or b == 0: return True return (abs(a) == a) == (abs(b) == b) The first version *almost* works for the duplicitous zero: >>> sign(-0, 1) True >>> sign(0, 1) True >>> sign(0, -1) False Close, but no cigar. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpQtTAL0kmlA.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: python custom command interpreter?
On Wed, Aug 20, 2008 at 03:19:19PM -0400, joey boggs wrote: > In the end I'd like to be able to run a custom interpreter and just feed it > one command and a directory. The end result in the kickstart something like > this: > > %post --interpreter #!/usr/bin/myinterpreter > DROP /tmp/directory > DROP /tmp/directory2 What is the problem you are trying to solve? Are you asking how to write a shell in Python? > How would I setup the interpreter to take the DROP command? You wouldn't... "setup" is a noun. You might "set up" an interpreter though. > I've been reading and searching all day but I haven't found anything > close to what I'm doing. I realize that using custom commands in > this case is overkill but in the end is used to make the users life > easier. How so? What could be easier than "rm -rf directory"? > If anyone can point me to some documentation I would be more than > grateful. I'd be happy to, but I can't imagine what sort of documentation would help you. It sounds like what you want to do, basically, is write a program to read commands from stdin, parse them to make sure the syntax is right, and then execute the equivalent code in Python. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpZSb18bJrz2.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: sending to an xterm
On Fri, Aug 08, 2008 at 08:25:19PM +, Kent Tenney wrote: > Howdy, > > I want to open an xterm, send it a command and have it execute it. You can't do that. xterm doesn't execute shell commands passed on stdin... It can, however, execute one passed on the command line. Instead of just running xterm, you can run "xterm -e 'cmd foo bar'" where cmd is the program to run and foo and bar are its arguments. The problem is that as soon as the program exits, xterm will exit also. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpMXKtm5Rt7A.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Tue, Jul 22, 2008 at 08:19:05PM +0700, Lie Ryan wrote: > But until the dictionary is rewritten, it is incorrect usage. That's complete nonsense, much like the rest of your argument. People use words all the time that aren't even IN a dictionary. Their absence from any dictionary makes them no less capable of conveying meaning. The dictionary does not define language; humans do, through their every-day use of words. Dictionaries record how words are commonly used, and are written by stubborn, pedantic old men with nothing better to do than sit around their oak desks debating the meaning of words... meanwhile the rest of the just USE words to communicate our ideas. Dictionaries are like technical documentation: written with the best of intentions, and mostly accurate at the time of writing, but out of date by the time they are published. [No offense meant to dictionary writers... I mostly fit that description myself, excepting that I am not quite yet an "old" man.] > FOR DECADES, people used the term PC for all sorts of things, I never said they didn't. That also is completely irrelevant. It's still the case that "PC" is commonly (these days MOST commonly, by far, at least in the US where all this technology was invented and named) used to refer to Intel-compatible hardware running a Microsoft OS. That fact, by itself, justifies the use in this case and any other. This is the very nature of language. > Apple's personal computer is NOT a PC? Aren't you contradicting > yourself? No, of course I'm not. > Just like what Apple, you have just said: "I'm Apple, I'm a > personal computer, but I'm not a personal computer." Completely > nonsense. Yes, I agree: what you wrote is complete nonsense. Only that isn't what I said at all. I said Apple isn't a PC. The term "PC" and the term "personal computer" are separate and distinct. One has only 2 letters, the other has 16 letters in two words. The latter ONLY means a (non-specific) computer designed for personal use. The former can mean that, though that usage is far less common than the one I was using: an Intel compatible personal computer on which Microsoft operating systems run. The software industry has been marketing titles as "For PC" since the creation of the IBM PC, and did not stop doing so when other PC-compatibles arrived on the scene, nor even when IBM stopped making them. So what did they mean by "PC" after IBM stopped making them? They meant, very clearly, that their software was intended for Intel-compatible hardware running a Microsoft OS. Does that mean that PC hardware running Linux is not a PC? Of course not -- except when the term is used in a context where it does mean exactly that. ;-) > Last, probably my strongest argument: "If the folder has been called > WinBuild/WindowsBuild, there is no need for arguments. PC as Windows is > an arguable usage, Windows as Windows is not arguable." There is no need for arguments now! The only reason there are arguments now is because a few stubborn people irrationally refuse to accept the term "PC" as it is most commonly used in modern English, as has been the case for most of my lifetime. Finally, the person who named the build can call it whatever they want... that's one of the perks of creating something: you get to name it. They could have called it "VanillaIceCreamBuild" or "Vinny'sSkankyHoBuild" -- it's their choice what to call it. The name of a thing need not reflect its purpose, orientation, meaning, or any other concrete or abstract property of the thing. It's just a name. Look, I've already said I don't like the term, and in fact I think that eventually, as PC hardware (and the software that runs on it) continues to evolve, it's going to become problematic. Except that it won't: when it becomes a problem, English-speaking humans will invent a new word to describe the class of computers they're discussing. That is how language works. But in the mean time, we have no other word to refer to the class of hardware that is based on Intel chipsets and is designed specifically to be compatible with Microsoft Windows (or indeed running said Windows). We need a word to distinguish this class of machines from Apple computers (which ironically now also use Intel, but are still clearly distinct from PCs, partially because they mainly run Windows), Sun computers, SGI computers, etc. The term "PC" has been relegated to that role, and the fact is that the vast majority of those computers run Windows today. It's also a fact that the overwhelming majority of English-speaking humans commonly use the term "PC" to mean what I've said (and also other similar things). Your complaints and arguments about alternate meanings of "PC" are irrelevant, pointless, and futile. Even if the maintainers are convinced to change the name, it does not change the fact that the term will continue to be used that way by millions of humans, nor that they are not wrong for doing so, since it is
Terminology (Re: Strong/weak typing)
On Fri, Aug 01, 2008 at 03:57:10PM +, Alan Franzoni wrote: > [EMAIL PROTECTED] was kind enough to say: > > > I'm writing Python as if it were strongly typed, never recycling a > > name to hold a type other than the original type. [...] > Python *is* strongly typed. That's debatable. It depends on what definition of "strongly typed" you are using, and Martin's usage was not incorrect. There are, unfortunately, lots of them: http://en.wikipedia.org/wiki/Strong_typing On Fri, Aug 01, 2008 at 11:23:31AM -0700, Carl Banks wrote: > The strength of dynamic typing (Pythonistas prefer the terms dynamic > vs static for what you describe, and use weak vs stong for something > else) lies mostly in the freedom it gives you. Pythonistas can be extremely irritating. Some attributes I've observed of (some of) them: - stubborn insistence on their own narrow definitions of terms, and complete refusal to accept that other definitions of those terms exist and are in common usage - stubborn refusal to accept that other terms exist which describe some facet of programming they prefer to call by their own Elite Pythonista name. - A fundamental lack of understanding that not everyone who posts here was born speaking Python - extreme impatience with anyone who does not immediately understand what they are saying - superior/condescending tone leveled at anyone who profers an opinion which differs with the Pythonista hive mind. Is precision in terminology important? Sure, especially when the topic tends to be somewhat complex and/or abstract. But words are just words -- they have meaning that we impart to them, and there is rarely only one to describe a particular concept. There also is rarely only one meaning for each word. Computer Science has evolved increasingly rapidly over the last 40 years or so, and along with it so has its terminology. Each computer language brings with it a unique perspective on programming, and almost out of necessity its own terminology to describe the philosophy behind its design. THIS DOES NOT RENDER WRONG OTHER TERMS OR USAGES. It merely augments the already rich natural language we have to describe what we do. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpdANC3vBRJ5.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Attack a sacred Python Cow
On Sun, Jul 27, 2008 at 09:39:26PM +0200, Bruno Desthuilliers wrote: > >As for the latter part of #3, self (or some other variable) is > >required in the parameter list of object methods, > > It's actually the parameter list of the *function* that is used as the > implementation of a method. Not quite the same thing. The idea that Python behaves this way is new to me. For example, the tutorials make no mention of it: http://docs.python.org/tut/node11.html#SECTION001130 The Python reference manual has very little to say about classes, indeed. If it's discussed there, it's buried somewhere I could not easily find it. > consistency mandates that the target object of the method is part of > the parameter list of the *function*, since that's how you make > objects availables to a function. Fair enough, but I submit that this distinction is abstruse, and poorly documented, and also generally not something the average application developer should want to or have to care about... it's of interest primarily to computer scientists and language enthusiasts. The language should prefer to hide such details from the people using it. > >however when the method is *called*, it is omitted. > > Certainly not. Seems not so certain to me... We disagree, even after your careful explanation. See below. > You need to lookup the corresponding attribute *on a given object* > to get the method. Whether you write > > some_object.some_method() > > or > > some_function(some_object) > > you still need to explicitely mention some_object. But these two constructs are conceptually DIFFERENT, whether or not their implementation is the same or similar. The first says that some_method is defined within the name space of some_object. The second says that some_object is a parameter of some_function... Namespace != parameter! To many people previously familiar with OO programming in other languages (not just Java or C++), but not intimately familiar with Python's implementation details, the first also implies that some_method is inherently part of some_object, in which case explicitly providing a parameter to pass in the object naturally seems kind of crazy. The method can and should have implicit knowledge of what object it has been made a part. Part of the point of using objects is that they do have special knowledge of themselves... they (generally) manipulate data that's part of the object. Conceptually, the idea that an object's methods can be defined outside of the scope of the object, and need to be told what object they are part of/operating on is somewhat nonsensical... > >Thus when an object method is called, it must be called with one fewer > >arguments than those which are defined. This can be confusing, > >especially to new programmers. > > This is confusing as long as you insist on saying that what you > "def"ined is a method - which is not the case. I can see now the distinction, but please pardon my prior ignorance, since the documentation says it IS the case, as I pointed out earlier. Furthermore, as you described, defining the function within the scope of a class binds a name to the function and then makes it a method of the class. Once that happens, *the function has become a method*. To be perfectly honest, the idea that an object method can be defined outside the scope of an object (i.e. where the code has no reason to have any knowledge of the object) seems kind of gross to me... another Python wart. One which could occasionally be useful I suppose, but a wart nonetheless. This seems inherently not object-oriented at all, for reasons I've already stated. It also strikes me as a feature designed to encourage bad programming practices. Even discounting that, if Python had a keyword which referenced the object of which a given peice of code was a part, e.g. self, then a function written to be an object method could use this keyword *even if it is defined outside of the scope of a class*. The self keyword, once the function was bound to an object, would automatically refer to the correct object. If the function were called outside of the context of an object, then referencing self would result in an exception. You'll probably argue that this takes away your ability to define a function and subsequently use it both as a stand-alone function and also as a method. I'm OK with that -- while it might occasionally be useful, I think if you feel the need to do this, it probably means your program design is wrong/bad. More than likely what you really needed was to define a class that had the function as a method, and another class (or several) that inherits from the first. > The point is that you don't get access to the object "within itself". > You get access to an object *within a function*. Thus methods are not really methods at all, which would seem to suggest that Python's OO model is inherently broken (albeit by design, and perhaps occasionally t
Re: Attack a sacred Python Cow
On Sun, Jul 27, 2008 at 08:19:17AM +, Steven D'Aprano wrote: > > You take the name down to a single letter. As I suggested in an earlier > > post on this thread, why not take it down to zero letters? > > The question isn't "why not", but "why". The status quo works well as it > is, even if it isn't perfect. Prove that implicit self is a good idea -- > or at least prove that it is an idea worth considering. Come on, this sounds like a schoolyard argument. This comes down to a matter of style, and as such, is impossible to prove. It's largely a question of individual preference. That said, the argument in favor is rather simple: 1. This is an extremely common idiom in Python 2. It is completely unnecessary, and the language does not suffer for making it implicit 3. Making it implicit reduces typing, reduces opportunities for mistakes, and arguably increases consistency. As for the latter part of #3, self (or some other variable) is required in the parameter list of object methods, however when the method is *called*, it is omitted. It is implied, supplied by Python. Thus when an object method is called, it must be called with one fewer arguments than those which are defined. This can be confusing, especially to new programmers. It can also be argued that it makes the code less ugly, though again, that's a matter of preference. > It's not enough to show that a change "isn't bad" -- you have to show > that it is actively good. But he did... he pointed out that *it saves work*, without actually being bad. Benefit, without drawback. Sounds good to me! > "Don't need to look at the method signature" is not an argument in favour > of implicit self. Yes, actually, it is. If there is a well-defined feature of Python which provides access to the object within itself, then the opportunities for mistakes when someone decides to use something else are lessened. > You don't need to look at the method signature when you're using an > explicit self either. That isn't necessarily true. If you're using someone else's code, and they didn't use "self" -- or worse yet, if they chose this variable's name randomly throughout their classes -- then you may well need to look back to see what was used. It's bad programming, but the world is full of bad programmers, and we don't always have the choice not to use their code. Isn't one of Python's goals to minimize opportunities for bad programming? Providing a keyword equivalent to self and removing the need to name it in object methods is one way to do that. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpBl0pdqGhaD.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Attack a sacred Python Cow
On Sun, Jul 27, 2008 at 08:13:53AM +, Steven D'Aprano wrote: > On Sun, 27 Jul 2008 10:23:06 +0800, Marcus.CM wrote: > > > Well after reading some of these posts on "sacred python cow" on the > > "self" , i would generally feel that most programmers who started with > > C++/Java would find it odd. > > You know, there are some programmers who haven't started with C++ or Java. Indeed, I'm one of them. In fact, I've never written even a single program in either language (except maybe hello world or the equivalent), and still, I have always thought that explicitly naming the class instance variable in the parameter list of the object's methods was a wart (albeit a very minor one) in Python. It's a waste of typing. > > And its true, i agree completely there should not be a need to put > > "self" into every single member function. If you were writing an > > application and one of your classes adds the same variable to each > > of its member function you would do away with it too. > > Would I? How would I do that here? You missed the point. The variable "other" in your posted class is not intended to always refer to the same *object*... Whereas "self" is and does, and that was what was meant. In such a case, you'd obviously convert the variable to a class property. Regardless of how it's implementd, it's such a common idiom to use self to refer to object instances within a class in Python that it ought to be more automatic. Personally, I kind of like the idea of using @ and thinking of it more like an operator... Kind of like dereferencing a pointer, only with an implied pointer name. class foo: def __init__(): @.increment = 2 def bar(a) return a + @.increment I'm sure all the Pythonistas will hate this idea though... ;-) To be honest, it smacks a little of Perl's magic variables, which I actually hate with a passion. This is the only place in Python I'd consider doing something like this. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpq0OmSJMzPS.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Attack a sacred Python Cow
On Sat, Jul 26, 2008 at 12:06:05AM -0400, Terry Reedy wrote: > There is no requirement to have 'self' in the parameter list. But there is a requirement to have *something* which refers to the object instance. Why can't this be implicit with a keyword defined in python to refer to it? > So the proposal would have to be that the compiler scan the function > body and decide which dotted name prefix is the one to be implicitly > added. Have fun writing the discovery algorithm. That's crazy talk. > Or the proposal would have to be that 'self' is mandatory for all > programmers in all languages. I think *that* would be pernicious. > People are now free to write the more compact 's.sum = s.a + s.b + s.c' s = self There, your problem is fixed. Besides, in general, it's better programming practie to use meaningful names, with fairly obvious and well-understood exceptions. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpEV6qhBweow.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Mon, Jul 21, 2008 at 02:47:31PM -0700, Lie wrote: > Common usage isn't always correct. Actually it is, inherently... When usage becomes common, the language becomes redefined, and its correctness is therefore true by identity (to borrow a mathematical term). The scholars complain for a while, but eventually capitulate, and re-write the dictionary. Language bends to its use by the people, not the other way around. Your assumption is the opposite, and therefore all of your argument is false. > For example, a physicist would not use weight when he meant mass. > much, but in technical environment doing so would embarrass him. In > this analogy, I consider download page for a software source code to > be a technical area. Your analogy is still broken. The term "PC" has been used BY TECHNCIAL PEOPLE, IN A TECHNICAL CONTEXT, to mean Microsoft on Intel, FOR DECADES. + Authors of technical books, manuals, and other forms of documentation have refered to them as PCs... for decades. + Educators in CS and EE at major universities have refer to them as PCs, since at least as early as 1988 (when I started college). + Industry news publications such as Computer World have refered to them as PCs, for decades. + There are even whole magazines dedicated to them! (PC Magazine, PC Shopper, PC World, PC Gamer, etc.) They are dedicated to Microsoft on Intel, and have existed (at least in some cases) long before Apple started talking about PCs in their ads. All of this has been going on, essentially since there has been such a thing as the IBM PC. I'm sorry, but you sir, are quite simply, plainly, and completely, wrong. With a catastrophic amount of written documentation, written by technical people in the computer industry over the last 20+ years, to prove it. > > > Apple popularizes the term by explicit marketing, > > > > And here is the last point you are missing: Apple does no such > > thing. > > They did, by using the term PC to refer to other computers. APPLE CAN NOT POPULARIZE A TERM WHICH IS ALREADY POPULAR. > This kind of advertising Apple (the computer company) used is > misleading, since it implied that their PC is not a PC. They haven't implied anything; they're stating it outright! Apple sells personal computers, but they do not sell PCs. Apple's personal computer is NOT a PC, and never was, and never will be. It's an Apple. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpM3T8xzDRmR.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Mon, Jul 21, 2008 at 12:32:00PM -0700, Lie wrote: > > The term "PC" is commonly used in English, in the United States > > and other English speaking countries, to mean a computer running > > Microsoft Windows. > > As far as I am aware, they're like that because most people aren't > even aware that there are other OSes than Microsoft Windows. You are missing two points. The first one: It doesn't matter what the reasons are for the terminology to be common. It only matters that it IS common. It is; and it is therefore "correct" in the sense that it conveys a meaning to the overwhelming majority of English speakers, which is the intended one. As for the question of whether or not it is appropriate to refer to Windows installations as "PC", it's as simple as that. It is, by definition (via common usage). That is what this thread is about. > The reason why the world hasn't evolved to the two predictable cases > ("all kinds of microcomputers" or "IBM-PC and clones"), is what I'll > explain below. Your explanation is irrelevant to the argument of whether or not the term PC is an inappropriate term to describe a Windows installation, which is what this thread is about. That is the premise put forth by the OP, and that is the notion to which I am responding. It simply is not wrong or inappropriate in any sense; it is in fact correct, regardless of how the meaning or usage resulted, and regardless of any ADDITIONAL meanings the term may have. For what it's worth, your explanation is also WRONG; the term PC began to be popularly used in the United States to describe Intel-based Microsoft machines when there was a proliferation of other kinds of personal computers available to consumers. When it was first used this way, the IBM PC was *NOT* the most popular personal computer... the Commodore 64 was. It dates from a time when the Commodore VIC-20 and C64, Atari 400 and 800, Timex Sinclair, and other computers were all very popluar home machines. The term probably originated primarily because IBM chose to name their computer the IBM PC, and because of Americans' predeliction to abbreviate everything that's more than 2 syllables. ;-) > > It wasn't something that Apple started; it's been used this way > > in increasingly common usage for at least 20 years, although > > exactly what combination of hardware and software was being > > refered to as a "PC" has evolved over that timeframe. > > Apple popularizes the term by explicit marketing, And here is the last point you are missing: Apple does no such thing. They are only using a term in a way that has previously been popularized by the computer industry as a whole, and its market (i.e. consumers, predominantly American consumers historically) for *DECADES*. If I'm not mistaken, their ad campaign mentioning PCs is less than 10 years old (though I can't quickly find any references as to the date). The popularization of the term PC to refer to Intel-compatible machines running Microsoft OSes PREDATES APPLE'S AD CAMPAIGN BY OVER 10 YEARS. Therefore none of your points are valid or relevant, as to the question of whether the usage of the term "PC" to describe windows builds of Python is appropriate. Can we return to the subject of Python now? -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpaJhm9UM6EY.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Sat, Jul 19, 2008 at 02:56:07AM -0700, Lie wrote: > government, etc. IBM PC is one of the first computers that ordinary > people could possess, when IBM-clones appeared on the market, they're > referred as PCs too because they are Personal Computer, a computer > that is designed for personal use. Just to be clear, this statement is WRONG. PC-clones were so called because they were clones of the IBM-PC. The term is very specific to IBM-compatible hardware. http://en.wikipedia.org/wiki/Pc_clone IBM PC compatible computers are those generally similar to the original IBM PC, XT, and AT. Such computers used to be referred to as PC clones, or IBM clones since they almost exactly duplicated all the significant features of the PC, XT, or AT internal design, facilitated by various manufacturers' ability to legally reverse engineer the BIOS through cleanroom design. Wikipedia's article on the personal computer accurately reflects the multiple meanings of the term, and points out the common usage to mean a Windows box: http://en.wikipedia.org/wiki/Personal_computer Today a PC may be a desktop computer, a laptop computer or a tablet computer. The most common operating systems are Microsoft Windows, Mac OS X and Linux, while the most common microprocessors are x86 compatible CPUs. However, the term "PC" is often used only to refer to computers running Microsoft Windows. So please stop your whining and get used to the idea that THE REST OF THE WORLD uses PC to mean a Windows box. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpWskQ7X4hnX.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Sat, Jul 19, 2008 at 02:56:07AM -0700, Lie wrote: > On Jul 19, 6:14 am, Derek Martin <[EMAIL PROTECTED]> wrote: > > On Fri, Jul 18, 2008 at 03:46:13PM -0700, Joel Teichroeb wrote: > > Much like the English word "bank" (and numerous others), the term "PC" > > has come to have several meanings, one of which is the above. You may > > not like it, but we're pretty much stuck with the term, so you may as > > well get used to it. > > That's not the point, It very much IS the point. Language evolves based on common usage patterns of the people who use it. The term "PC" is commonly used in English, in the United States and other English speaking countries, to mean a computer running Microsoft Windows. That's a simple fact that you can not escape, no matter how much you may not like it (it just so happens that I also don't like it, but I realized long ago the futility of arguing against its usage). It's still a fact, and I described roughly how that fact came to be. It wasn't something that Apple started; it's been used this way in increasingly common usage for at least 20 years, although exactly what combination of hardware and software was being refered to as a "PC" has evolved over that timeframe. PC was a short form of "personal computer", which is how IBM came up with the name. Nevertheless, with the ubiquity of IBM hardware, and subsequent popularity of clones running Microsoft operating systems, the term "PC" has, in the present day, come to mean "a personal computer based on Intel-compatible hardware running a flavor of Microsoft Windows." It is used this way by the consumer computer industry, and it is used this way by the common population. Ipso facto "PC" means a windows box, in common English usage today. You don't have to like it, and you don't even have to acknowledge it. But if you choose not to, or argue against using it that way, you're in denial, plain and simple. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpLN8hSeYEOH.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Fri, Jul 18, 2008 at 10:34:41PM -0700, Dennis Lee Bieber wrote: > On Fri, 18 Jul 2008 19:14:43 -0400, Derek Martin <[EMAIL PROTECTED]> > declaimed the following in comp.lang.python: > > > On Fri, Jul 18, 2008 at 03:46:13PM -0700, Joel Teichroeb wrote: > > > Calling Windows PC seems to be something that Apple did so they would > > > not have to directly mention Windows. > > > > Actually it's something IBM did when they created the IBM PC. Of > > Bah... PC was short for Personal Computer... I'm well aware... congratulations on completely missing the point. I was describing how the term PC has become synonimous with Windows machines. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpbl4K02hAFc.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Change PC to Win or Windows
On Fri, Jul 18, 2008 at 03:46:13PM -0700, Joel Teichroeb wrote: > Calling Windows PC seems to be something that Apple did so they would > not have to directly mention Windows. Actually it's something IBM did when they created the IBM PC. Of course, all IBM PCs ran MS-DOS, since that's how IBM sold them... Then others started to build copies the IBM PC based on Intel hardware, and the resulting class of computers was called, collectively, "PC Clones" -- shortened to PCs -- by the industry and its market. Then companies like AMD and Cyrix started building Intel-compatible CPUs, and the term PC was extended to include systems built using those architectures. Eventually Windows was released, and PCs became Windows boxen running on Intel-compatible hardware, and I personally know no one who doesn't use the term that way... Much like the English word "bank" (and numerous others), the term "PC" has come to have several meanings, one of which is the above. You may not like it, but we're pretty much stuck with the term, so you may as well get used to it. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpGebEnJc6Ql.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Multiple variable control in for loops. Doable in Python?
On Fri, Jul 18, 2008 at 05:28:32PM -0400, Derek Martin wrote: > def control(i, j): > print i,j > if not (i < 5 or j < 10): Rather, if not (i < 5 and j < 10): > return > else: > control(some_increment_function(i), other_increment_function(j)) -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpizP6MkhvZ8.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Multiple variable control in for loops. Doable in Python?
On Fri, Jul 18, 2008 at 12:21:49PM -0700, mark floyd wrote: > I'm new to Python and have been doing work converting a few apps > from Perl to Python. I can not figure out the comparable Python > structures for multi-variable for loop control. [...] > I spent a good part of yesterday looking for a way to handle this > style for loop in Python and haven't been able to find an > appropriate way to handle this control style. One wonders why... :) > We have this style for loop all over the place and not being able to > find a similar structure in Python could be a problem. Any pointers > to a Python equivalent structure would be much appreciated Even if Python didn't offer a way to write a for loop in a similar fashion (someone else replied about that already), why should it be a problem? In general control structures can be rewritten as some other kind of control structure. For example, this does exactly what your for loop examples do: i = 0 j = 0 while i < 5 and j < 10: print i, j i += 1 j += 1 Though, this example is silly, as it will always terminate after the 5th iteration of the loop, and there is no need to have j being used as a control variable... it's termination condition will never be met. Though the example illustrates the techique, even if the example is bogus. Another way is to use functions to modify the values of i and j. Writing your loops this way, you can have as many control variables as you need, and your formula for incrementing those control variables can be as varied as complicated as you can imagine. def some_increment_function(i): # Do some complicated processing of i i = ... return i def other_incrjmental_function(j): # Do some complicated processing of j j = ... return j i = 0 j = 0 while i < 5 and j < 10: print i, j i = some_increment_function(i) j = other_increment_function(j) And of course, you could also replace the loop terminating conditions with functions that return a value which can be interpreted as a truth value. If you wanted to get really crazy, you could even code the control structure as a recursive function: def control(i, j): print i,j if not (i < 5 or j < 10): return else: control(some_increment_function(i), other_increment_function(j)) Should you really write control structures this way, generally? Absolutely not (unless you're writing LISP or Scheme :)). But the point is, even if a given language doesn't have a particular syntactic element that you're looking for, it's pretty much guaranteed to provide a way to do what you're trying to do. You just need to stop thinking about your problem in terms of a particular syntactic element, and start thinking about it in more general terms of what you are actually trying to accomplish, and apply whatever syntax (usually one of several) your language provides to do that. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpiKhYnuJoAw.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Using Python To Launch Python
On Mon, Jul 14, 2008 at 05:40:43PM -0400, Aquil H. Abdullah wrote: > You've hit the proverbial nail with the hammer. The problem is that my > application needs to run under both the Linux and Windows OSs, so while I > would love to use a nice sh, csh, or bash shell script. My hands are tied > because Windows does not provide such wonderful shells. *Provides*, no... neither does it provide Python, for what that's worth. But you can certainly get it (bash): http://win-bash.sourceforge.net/ I suppose it's not worth installing just for this purpose though... But you can provide with your application a DoS batch file that does exactly the same thing (in addition to a shell script). The user would quite intuitively use whichever were appropriate, or follow your provided directions otherwise. Or, the equivalent in (hopefully OS-agnostic) Python: import os, sys # I believe this gets the name of the root in all major OSes def root_dir(path): if os.path.dirname(path) == path: return path return (root_dir(os.path.dirname(path))) appname = root = root_dir(os.getcwd()) install_path = os.path.join(root, "usr") bin_path = os.path.join(install_path, "bin") os.environ["PATH"] = bin_path + os.pathsep + os.environ["PATH"] python_path = os.path.join(bin_path, "python") args = sys.argv[1:] args.insert(0, os.path.join(bin_path, appname)) args.insert(0, python_path) args.insert(0, python_path) os.execv(python_path, args) pgpQG92HCsITg.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Using Python To Launch Python
On Mon, Jul 14, 2008 at 02:01:04PM -0700, aha wrote: > Since my application has it's own version of Python installed with > it how should I use the system Python to launch the version of > Python that launches my Application. Yes, this is a convoluted > process, but not all Pythons are built the same :) /usr/local/bin/$APPNAME: #!/bin/sh INSTALLPATH= PATH=$INSTALLPATH/bin:$PATH exec $INSTALLPATH/bin/python $APPNAME "$@" Doesn't get much simpler than that. :) You can certainly do the equivalent in Python... there's not much difference. Slightly less typing in bourne/bash shell, I guess... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgplmkg6rt2dJ.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Does '!=' equivelent to 'is not'
Yaieee! On Wed, Jun 18, 2008 at 01:32:28AM -0400, Terry Reedy wrote: > > >Saying a flat "no" alone, without qualifying your statement is > > >generally interpreted as rude in English... > As a very much native English speaker I disagree that 'No' is > necessarily rude. I never said it was necessarily anything. Generalities generally have lots of exceptions. :D It definitely isn't *necessarily* rude, and I didn't interpret Gabriel's message as rude. I was merely pointing out that such statements are often interpreted as rude, whether or not they were intended that way. FWIW, my post wasn't intended to be a post at all, but instead a private message to Gabriel. I guess I zigged when I should have zagged... ;-) That said, what he did do, was to contradict a statement which was literally true, in an abrupt manner. Lots of people would interpret this as rude demeanor. His commentary was spot on, but the way he went about making it has a tendency to make some (perhaps many) responees defensive, if not belligerent. But, if I actually thought Gabriel was intentionally being rude, I wouldn't have bothered to say anything, and just deleted all his posts. :) I don't even think an apology was warranted... On Wed, Jun 18, 2008 at 07:01:23AM -0700, Paul McGuire wrote: > Geez, man, this is Usenet. If you want rude or condescending, the > answer would have been "No, you flatulent moron." Or maybe the > alarmist, "No! No! No!" Sure, those statements would generally be considered *blatantly* rude (but still sometimes may not be, in context). This does not mean that less blatant statements are not also rude. Geez indeed... > I see the unqualified "No." often on this list, I see it lots of places, and maybe as much as 1/3 of the time, I see it start flame wars. It seemed clear to me that Gabriel had no intention of being offensive... All I'm saying is that if you want to avoid offending some people unintentionally and needlessly, it's a good idea to avoid making curt statements, especially curt negative statements. If the intention is to signal that more is to come, a simple improvement is to add an elipsis, whose purpose is exactly that: "No..." But even more effective at avoiding the appearance of being rude are statements like "Not exactly..." "I don't think so..." etc. They're not even all that much extra typing. There are lots of times when a simple "no" is exactly what's called for. "Do you like dark Chocolate?" "No." "Are you watching the Celtics game?" "No." Or even, "Is the baby's new shirt blue?" "No, it's green." Being concise is not the same as being curt. Tone also plays a big role, but conveying the appropriate tone of a simple "no" is pretty much impossible in an e-mail. In written communication, it should be avoided like the plague. > Back in my college days, I would not be surprised for a professor to > respond "No." Sure, lots of professors are arrogant, insensitive jerks. Does that make it OK? But, depending on the context and the professor's tone, even the situation you describe isn't necessarily rude. It often isn't. The world is full of Jerks with a capital 'J'. Imagine if it weren't? How nice that would be... But, all I was offering here was a suggestion regarding how to not appear like a Jerk when one isn't intending to. > but as one of the most informed and careful posters on this list, > I'm inclined to give Gabriel a little slack. Sure. But not everyone here knows Gabriel. Not everyone here has seen his informed contributions. Not everyone here has been here more than a day... More than a few people have posted on this list complaining about the sort of responses people provide on this list, and many such complaints are quite reasonable (though sometimes the person doing the complaining is himself rather unreasonable, if not completely bonkers, I admit). I am somewhat incredulous that this required explanation... In the end what I thought would be a nice little, "hey, avoid this pot hole" kind of note seems to mostly have generated a lot of silly noise. I now retire from this discussion, and crawl back into my happy lurk-spot. :) Cheers -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpCV8qGT1EYK.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Does '!=' equivelent to 'is not'
On Tue, Jun 17, 2008 at 04:33:03AM -0300, Gabriel Genellina wrote: > > Basically 'a is b' and 'not(a is b)' is similar to 'id(a) == id(b)' > > and 'not(id(a) == id(b))' > > No. Sure it is... he said "similar"... not identical. They are not the same, but they are similar. Saying a flat "no" alone, without qualifying your statement is generally interpreted as rude in English... It's kind of like how you talk to children when they're too young to understand the explanation. Yucky. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpg79fnwMq5d.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: python confusion possibly related to pickle
On Sun, May 18, 2008 at 08:28:34PM +0100, Dennis wrote: > The problem that's got me annoyed is that after getting said error I > close the shell window, open a new one, run the python interpreter > and type "import pickle" and get the error that the script I'd run > earlier caused. Why is this ? Well, what's the error? Sounds like your system could be b0rked (or at least your python installation)... but depending on the error, there could be other explanations. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpkARlxW8Y91.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: RegEx for matching brackets
On Fri, May 02, 2008 at 03:51:16PM -0700, NevilleDNZ wrote: > Thanx for the link to these parsers. ANTLR looks interesting. > Yoyo: http://www-users.cs.york.ac.uk/~fisher/software/yoyovwg/readme > > I figured out a way to do it in python. [...] > > def check_open_close(str): > try: > eval("".join({"{":"[","}":"],"}[c] for c in re.findall( "([{}])|(?: > [^{}]+)", str) if c)) Ouchie... It may be short, but if I had to maintain this code, and I saw this, your name would be used in sentences with lots of curse words. ;-) That's one hard-to-read line of code... Also this may or may not do what you want it to do -- I think it doesn't... This problem is the classical example of when to use a stack (Last-In, First-Out) data structure. If all you want to do is make sure that the line has the same number of opens and closes in a line, your code does that. But if you actually want to verify the syntax (i.e. make sure that there are the same number of open brackets as close brackets, AND make sure that they occur in the correct order, opens first, closes last, AND that the closes come in the same (reverse) order as the opens), your code does not do that. I changed the tests in your code (specifically the brackets, and nothing else) to demonstrate this: DETECTED: { a test BAD DETECTED: { a test } OK # This should fail, because the closing ] comes before the open [ MISSED: { a test ] [ a test } BAD DETECTED: { a test } { this { a test } is a test } OK # this should fail, for the above reason, and because the order is wrong MISSED: { a test { this { a test ] is a test } missing close [}} BAD DETECTED: { a test { this { a test ] is a test } missing close } BAD # this should also fail for both reasons MISSED: { a test ] this { a test } is a test } missing close [ BAD DETECTED: a test } { this { a test } is a test } BAD DETECTED: { a test } this { a test } is a test } BAD It doesn't detect the brackets in the right order (opens before closes), nor does it detect that they occur in the correct sequence. Clever code isn't always so clever... I think there's something to be said for writing code that's a little bit more lengthy, but easier to understand. This version is only a few lines longer than yours (in total, not counting the comments), but it is a bit clearer and easier to follow. Note that I added angle brackets and mixed the bracket types in the tests. I also didn't use your referee... In my code, the test simply succeeds if the brackets match, and fails if they are unbalanced or out of order. #!/usr/bin/python # define the matching pairs bm = { '}': '{', ']': '[', ')': '(', '>': '<' } def bracket_balance(str): # initialize the stack to an empty list blist = [] for c in str: # If c is an open bracket of any type, place on stack if c in bm.values(): blist.append(c) # If it is a close bracket, pull one off the stack and # see if they are matching open-close pairs. If the stack # is empty, there was no matching open. Return false in that # case, or if they don't match. if c in bm.keys(): try: foo = blist.pop() except IndexError: return False if foo != bm[c]: return False # End of the line: if we still have brackets on the stack, we # didn't have enough close brackets. Return false. if blist != []: return False # If we got here, the stack is empty, and there are no brackets # left unmatched. we're good! return True tests=""" { this is a test BAD < this is a test > OK { this is a test } { this is a test } OK { this is a test } [ this { this is a test } is a test ] OK { this is a test { this { this is a test } is a test } missing close BAD """.splitlines()[1:] for test in tests: print "Testing %s:" % test if bracket_balance(test): print "-> OK" else: print "-> FAILED" Testing with your original set of tests: $ ./brackets.py Testing { this is a test BAD: -> FAILED Testing < this is a test > OK: -> OK Testing { this is a test } { this is a test } OK: -> OK Testing { this is a test } [ this { this is a test } is a test ] OK: -> OK Testing { this is a test { this { this is a test } is a test } missing close BAD: -> FAILED Testing with my modified set of tests: $ ./brackets.py Testing { a test BAD: -> FAILED Testing { a test } OK: -> OK Testing { a test ] [ a test } BAD: -> FAILED Testing { a test } { this { a test } is a test } OK: -> OK Testing { a test { this { a test ] is a test } missing close [}} BAD: -> FAILED Testing { a test { this { a test ] is a test } missing close } BAD: -> FAILED Testing { a test ] this { a test } is a test } missing close [ BAD: -> FAILED Testing a test } { this { a test } is a test } BAD: -> FAILED Testing { a test } this { a test } is a test
Re: Manipulate Large Binary Files
On Thu, Apr 03, 2008 at 02:36:02PM -0400, Derek Tracy wrote: > I am running it on a RAID(stiped raid 5 using fibre channel), but I > was expecting better performance. Don't forget that you're reading from and writing to the same spindles. Writes are slower on RAID 5, and you have to read the data before you can write it... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpGZVie2qSt5.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Manipulate Large Binary Files
On Wed, Apr 02, 2008 at 02:09:45PM -0400, Derek Tracy wrote: > Both are clocking in at the same time (1m 5sec for 2.6Gb), are there > any ways I can optimize either solution? Buy faster disks? How long do you expect it to take? At 65s, you're already reading/writing 2.6GB at a sustained transfer rate of about 42.6 MB/s. That's nothing to sneeze at... Your disks, and not your program, are almost certainly the real bottleneck. Unless you have reason to believe your hardware should be significantly faster... That said, due to normal I/O generally involving double-buffering, you might be able to speed things up noticably by using Memory-Mapped I/O (MMIO). It depends on whether or not the implementation of the Python things you're using already use MMIO under the hood, and whether or not MMIO happens to be broken in your OS. :) > Would turning off the read/write buff increase speed? No... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpbuOCRibbkY.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Manipulate Large Binary Files
On Wed, Apr 02, 2008 at 10:59:57AM -0400, Derek Tracy wrote: > I generated code that works wonderfully for files under 2Gb in size > but the majority of the files I am dealing with are over the 2Gb > limit > > ary = array.array('H', INPUT.read()) You're trying to read the file all at once. You need to break your reads up into smaller chunks, in a loop. You're essentially trying to store more data in memory than your OS can actually access in a single process... Something like this (off the top of my head, I may have overlooked some detail, but it should at least illustrate the idea): # read a meg at a time buffsize = 1048576 while true: buff = INPUT.read(buffsize) OUTPUT.write(buff) if len(buff) != buffsize: break -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgp80hee5vxgO.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Python 2.2.1 and select()
On Wed, Mar 26, 2008 at 07:11:15PM -0700, Noah Spurrier wrote: > >def set_nonblock(fd): > > flags = fcntl.fcntl(fd, fcntl.F_GETFL) > > fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) > > > >Then in the function, after calling popen: > > set_nonblock(io.fromchild.fileno()) > > set_nonblock(io.childerr.fileno()) > > > >Yay for smart people. > > You should still try Pexpect :-) As I recall there are also gotchas > on the non-blocking trick. Well, you need to remember to read ALL the file descriptors (objects) that select() returns, and if you don't, your program will hang and spin... It might also be the case that if the child is using stdio functions for output, you'll need to set the buffering mode explicitly (which you can theoretically do, see below). Aside from that, there are none, and actually the problem with my program had nothing to do with stdio buffering modes. > Pexpect is 100% pure Python. No extra libs to install. I looked at it, and (what I believe is) the very reason it manages to solve this particular problem is also the reason it won't work for me: it combines STDOUT and STDERR to one I/O stream. The reason I'm bothering with all this is because I need to keep them separate. Interestingly, were it not for that fact, I'm not sure that pexpect wouldn't still suffer from the same problem that plagued my original implementation. I had to drag out W. R. Stevens to remind myself of a few things before I continued with this discussion... Even though it forces the program to use line buffering, read() would still try to read until EOF, and if STDOUT and STDERR were separate files, it seems likely that it would eventually block reading from one file when the child program was sending its output to the other. The only way to prevent that problem, aside from non-blocking I/O, is to do a read(1) (i.e. read one character at a time), which will use silly amounts of CPU time. But mixing stdio and non-stdio functions is kind of funky, and I'm not completely sure what the behavior would be in that case, and couldn't quickly ind anything in Stevens to suggest one way or the other. Also, you could combine the streams yourself without using pexpect by having your subproc use the shell to redirect STDERR to STDOUT, or (if Python has it) using the dup() family of system calls to combine the two in Python [i.e. dup2(1,2)]. As far as I can tell, the whole pseudo terminal thing (though it definitely does have its uses) is a red herring for this particular problem... I also read (some of) the pexpect FAQ, and there are a number of incorrect statements in it, particularly in the section 'Why not just use a pipe (popen())?" - a pipe, if programmed correctly, is perfectly fine for controlling interactive programs, most of the time. You will almost certainly need to use non-blocking I/O, unless your communicating programs are perfectly synchronized, or else you'll have I/O deadlocks. The only time a pipe isn't OK is where the program tries to use terminal services (e.g. writing to /dev/tty), in which case you will need a pseudo-terminal device (as the FAQ correctly points out with regard to entering passwords in SSH). - Any application which contains "#include " does not necessarily make use of the stdio library (which isn't really a separate library at all, it's part of the standard C library). The file stdio.h is just a C header file which contains declarations of the prototypes for stdio-related functions, and various constants. It's often included in source files simply because it's so common to need it, or to make use of some constants defined there. You're only actually using stdio if you use stdio functions in your program, which are: printf, fopen, getc, getchar, putc, scanf, gets, puts, etc. In particular, open(), read() and write() are *not* stdio functions, and do *not* buffer I/O. They're Unix system calls, and the C functions by the same name are simply interfaces to those system calls. There is a kernel I/O buffer associated with all of the streams you will use them on, but this is not a stdio buffer. I have not checked Python's code, but based on its behavior, I assume that its read() function is a wrapper around the Unix read() system call, and as such it is not using stdio at all, and thus the stdio buffers are not relevant (though if the child is using stdio functions, that could be an issue). - The FAQ states: "The STDIO lib will use block buffering when talking to a block file descriptor such as a pipe." This is only true *by default* and indeed you can change the buffering mode of any stdio stream using the setbuf() and setvbuf() stdio functions (though I don't know if Python provides a way to do this, but I assume it does). Since the python program is the one opening the pipe, it controls the buffering mode, and you have only to change it in
Re: Python 2.2.1 and select()
On Wed, Mar 26, 2008 at 09:49:51AM -0700, Noah Spurrier wrote: > On 2008-03-24 22:03-0400, Derek Martin wrote: > >That's an interesting thought, but I guess I'd need you to elaborate > >on how the buffering mode would affect the operation of select(). I > >really don't see how your explanation can cover this, given the > >following: > > I might be completely off the mark here. I have not tested your code or even > closely examined it. I don't mean to waste your time. I'm only giving a > reflex response because your problem seems to exactly match a very common > situation where someone tries to use select with a pipe to a subprocess > created with popen and that subprocess uses C stdio. Yeah, you're right, more or less. I talked to someone much smarter than I here in the office, who pointed out that the behavior of Python's read() without a specified size is to attempt to read until EOF. This will definitely cause the read to block (if there's I/O waiting from STDERR), if you're allowing I/O to block... :( The solution is easy though... def set_nonblock(fd): flags = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) Then in the function, after calling popen: set_nonblock(io.fromchild.fileno()) set_nonblock(io.childerr.fileno()) Yay for smart people. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgptoUxGdeV6b.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Re: Python 2.2.1 and select()
On Mon, Mar 24, 2008 at 05:52:54PM -0700, Noah wrote: > On Mar 24, 2:58 pm, Derek Martin <[EMAIL PROTECTED]> wrote: > > If and only if the total amount of output is greater than the > > specified buffer size, then reading on this file hangs indefinitely. > I think this is more of a limitation with the underlying clib. > Subprocess buffering defaults to block buffering instead of > line buffering. That's an interesting thought, but I guess I'd need you to elaborate on how the buffering mode would affect the operation of select(). I really don't see how your explanation can cover this, given the following: 1. The subprocess used to test, in both the case where it worked, and the case where it did not, was the very same shell script -- not a compiled program (well, bash technically). As far as I'm aware, there haven't been any significant changes to the buffering mode defaults in glibc... But I could easily be mistaken. 2. By default, STDERR is always unbuffered, whether or not STDOUT is a terminal device or not. 3. The actual subproc I care about is a perl script. 4. Most importantly, the whole point of using select() is that it should only return a list of file objects which are ready for reading or writing. In this case, in both the working case (Python 2.4+ on Red Hat) and the non-working case (Python 2.2.1 on Debian 3.1), select() returns the file object corresponding to the subprocess's STDOUT, which *should* mean that there is data ready to be read on that file descriptor. However, the actual read blocks, and both the parent and the child go to sleep. This should be impossible. That is the very problem select() is designed to solve... Moreover, we've set the buffer size to 8k. If your scenario were correct, then at the very least, as soon as the process wrote 8k to STDOUT, there should be data ready to read. Assuming full buffering is enabled for the pipe that connects STDOUT of the subprocess to the parent, the call to select() should block until one of the following conditions occur: - 8k of data is written by the child into the pipe - any amount of data is written to STDERR - the child process terminates The last point is important; if the child process only has 4k of data to write to STDOUT, and never writes anything to STDERR, then the buffer will never fill. However, the program will terminate, at which point (assuming there was no explicit call to close() previously) the operating system will close all open file descriptors, and flush all of the child's I/O buffers. At that point, the parent process, which would be sleeping in select(), will wake up, read the 4k of data, and (eventually) close its end of the pipe (an additional iteration through the select() loop will be required, I believe). Should the program write output to STDERR before the 8k STDOUT buffer is full, then again, the parent, sleeping in select(), will awaken, and select will return the file object corresponding to the parent's end of the pipe connecting to the child's STDERR. Again, all of this is the essence of what select() does. It is supposed to guarantee that any file descriptors (or objects) it returns are in fact ready for data to be read or written. So, unless I'm missing something, I'm pretty certain that buffering mode has nothing to do with what's going on here. I think there are only a few possibilities: 1. My implementation of the select() loop is subtlely broken. This seems like the most likely case to me; however I've been over it a bunch of times, and I can't find anything wrong with it. It's undenyable that select is returning a file object, and that reads on that file object immediately after the call to select block. I can't see how this could be possible, barring a bug somewhere else. 2. select.select() is broken in the version of Python I'm using. 3. The select() system call is somehow broken in the Linux kernel I'm using. I tend to rule this out, because I'm reasonably certain someone would have noticed this before I did. The kernel in question is being used on thousands of machines (I'm not exaggerating) which run a variety of network-oriented programs. I can't imagine that none of them uses select() (though perhaps its possible that none use it in quite the manner I'm using it here). But it may be worth looking at... I could write an implementation of a select() loop in C and see how that works. If you can see any flaw in my analysis, by all means point it out! Thanks for your response. -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpzol0mPJUfy.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list
Python 2.2.1 and select()
Hi kids! I've got some code that uses select.select() to capture all the output of a subprocess (both stdout and stderr, see below). This code works as expected on a variety of Fedora systems running Python > 2.4.0, but on a Debian Sarge system running Python 2.2.1 it's a no-go. I'm thinking this is a bug in that particular version of Python, but I'd like to have confirmation if anyone can provide it. The behavior I see is this: the call to select() returns: [] [] [] If and only if the total amount of output is greater than the specified buffer size, then reading on this file hangs indefinitely. For what it's worth, the program whose output I need to capture with this generates about 17k of output to STDERR, and about 1k of output to STDOUT, at essentially random intervals. But I also ran it with a test shell script that generates roughly the same amount of output to each file object, alternating between STDOUT and STDERR, with the same results. Yes, I'm aware that this version of Python is quite old, but I don't have a great deal of control over that (though if this is indeed a python bug, as opposed to a problem with my implementation, it might provide some leverage to get it upgraded)... Thanks in advance for any help you can provide. The code in question (quite short) follows: def capture(cmd): buffsize = 8192 inlist = [] inbuf = "" errbuf = "" io = popen2.Popen3(cmd, True, buffsize) inlist.append(io.fromchild) inlist.append(io.childerr) while True: ins, outs, excepts = select.select(inlist, [], []) for i in ins: x = i.read() if not x: inlist.remove(i) else: if i == io.fromchild: inbuf += x if i == io.childerr: errbuf += x if not inlist: break if io.wait(): raise FailedExitStatus, errbuf return (inbuf, errbuf) If anyone would like, I could also provide a shell script and a main program one could use to test this function... -- Derek D. Martin http://www.pizzashack.org/ GPG Key ID: 0x81CFE75D pgpuxR0RACuHg.pgp Description: PGP signature -- http://mail.python.org/mailman/listinfo/python-list