Re: Side-effects [was Re: I am out of trial and error again Lists]
On Sun, Oct 26, 2014 at 5:12 PM, Steven D'Aprano wrote: > However, mutator methods on a class don't change global state, they change > the state of an instance. Even random.random and friends don't change > global state, they change a (hidden) instance, and you can create your own > instances when needed. That gives you the convenience of pseudo-global > state while still allowing the flexibility of having separate instances. > Even global variables in Python are global to the module, not global to the > entire application. True, but they do still change state; I oversimplified a bit, but certainly there are plenty of functions that change state in some way, and are not frowned upon. Module level variables really are global, though. You can't easily and conveniently reinstantiate a module in Python; if you "import random; random.seed(1234)", you can confidently expect that some other module that uses random.random will be affected. Sure, there are ways around that, but that's true of any form of global state - for a start, it's usually "process level" state, in that spawning a new process will isolate one from another. The only thing that isn't truly global is the namespace; I can write "x = {}" and you can write "x = []" and they don't collide. They're still global (process-level), it's just that they're "foo.x" and "bar.x" and are thus distinct. > I would say that Python is a pragmatic > language which uses whatever idiom seems best at the time, but over all it > prefers mutable state for compound objects, prefers immutable state for > scalar objects (like numbers), and discourages the unnecessary use of > global mutable state. It's not really compound vs scalar, but yes, I agree. Practicality beats purity, on so many levels. Functions with side effects aren't considered some sort of weird beast that we have to permit for the sake of I/O; they're a fundamental part of the language. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Side-effects [was Re: I am out of trial and error again Lists]
Chris Angelico wrote: > On Sat, Oct 25, 2014 at 4:40 PM, Rustom Mody > wrote: >> Its generally accepted that side-effecting functions are not a good idea >> -- typically a function that returns something and changes global state. > > Only in certain circles. Not in Python. There are large numbers of > functions with side effects (mutator methods like list.append, > anything that needs lots of state like random.random, everything with > external effect like I/O, heaps of stuff), and it is most definitely > not frowned upon. Hmmm. You might be overstating it a tad. You are absolutely correct that Python is not a strict functional language with no side-effects. However, mutator methods on a class don't change global state, they change the state of an instance. Even random.random and friends don't change global state, they change a (hidden) instance, and you can create your own instances when needed. That gives you the convenience of pseudo-global state while still allowing the flexibility of having separate instances. Even global variables in Python are global to the module, not global to the entire application. So although Python code isn't entirely side-effect free, the general advice to avoid writing code that relies on global state and operates via side-effect still applies. To take an extreme example, we do this: print(len(something)) not this: LEN_ARGUMENT = something len() print(LEN_RESULT) We *could* write code like that in Python, but as a general rule we don't. If we did, it would be frowned upon. I would say that Python is a pragmatic language which uses whatever idiom seems best at the time, but over all it prefers mutable state for compound objects, prefers immutable state for scalar objects (like numbers), and discourages the unnecessary use of global mutable state. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sun, Oct 26, 2014 at 3:15 PM, Steven D'Aprano wrote: > Since the list items exist only to be counted, the actual item used makes no > difference. You could use any value at all, or even a different value each > time: > > len([random.random() for line in lines if not line.strip()]) > > What is your reason for the choice of True as the tally marker? It doesn't > clarify your intent, or make it more obvious that you're counting the > number of non-empty lines. Personally, I'd use the original value. When you're counting something, it's common to count that thing, rather than some stand-in. len([line for line in lines if not line.strip()]) But that's no better than anything else. The only significance is that it feels more like counting a filtered portion of the list. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
Ben Finney wrote: > Steven D'Aprano writes: > >> I suspect that Guido and the core developers disagree with you, since >> they had the opportunity to fix that in Python 3 and didn't. > > That doesn't follow; there are numerous warts in Python 2 that were not > fixed in Python 3. As I understand it, the preservation of bool–int > equality has more to do with preserving backward compatibility. On reviewing PEP 285, I think it is safe to say that Guido *explicitly* wants bools to be ints, not just for backwards compatibility: 4) Should we strive to eliminate non-Boolean operations on bools in the future, through suitable warnings, so that for example True+1 would eventually (in Python 3000) be illegal? => No. There's a small but vocal minority that would prefer to see "textbook" bools that don't support arithmetic operations at all, but most reviewers agree with me that bools should always allow arithmetic operations. http://legacy.python.org/dev/peps/pep-0285/ > I agree with the decision, because this isn't an issue which often leads > to *incorrect* code. But I maintain that it's an unfortunate and > needlessly confusing wart of the language. That puts you in the small but vocal minority :-) >> One example of where treating True and False as 1 and 0 is useful is >> that it makes counting operations very simple, e.g. counting the >> number of blank lines: >> >> sum(not line.strip() for line in lines) >> sum(1 if not line.strip() else 0 for line in lines) >> sum({'': 0}.get(line.strip(), 1) for line in lines) > > These all look ludicrous and explain nothing about intent, to my > reading. [...] > I'm left wondering why > the coder chose something so obfuscatory to their intent. "Ludicrous" and "obfuscatory". They're awfully strong words. Do you really not see the connection between counting and summing? If so, that would put you in a truly small minority. The connection between adding and counting has been known to Western mathematics since at least the ancient Greeks, if not even earlier, and we teach it to school children. If you have three apples, and I have two apples, then in total we have (count the apples: one two three, four five) five apples. Pre-schoolers learn this. I'm sure it's not too difficult for programmers. > This is short and clear and needs no leaking of the underlying bool > implementation:: > > len(True for line in lines if line.strip()) I see that in a later email you discovered your unfortunate bug in this, and corrected it to this: len([True for line in lines if line.strip()]) Alas, you missed the bigger bug: I'm counting *blank lines*, not non-blank lines. You need a `not` in there. You mentioned intent before. I wonder what your intention is, to needlessly build a potentially gigantic list of identical values, only to then throw the list away. Could be worse; you might have written [True for line in lines if not line.strip()].count(True) Since the list items exist only to be counted, the actual item used makes no difference. You could use any value at all, or even a different value each time: len([random.random() for line in lines if not line.strip()]) What is your reason for the choice of True as the tally marker? It doesn't clarify your intent, or make it more obvious that you're counting the number of non-empty lines. If you wanted to suggest a tally: len(['/' for line in lines if not line.strip()]) at least looks like a tally: makes four. Using a bool doesn't make this any clearer, and you don't even have the excuse that it's efficient, because it isn't. Let's get rid of the list comp and write a straightforward translation: temp = [] for line in lines: if not line.strip(): temp.append(True) result = len(temp) del temp I don't consider that sensible code at all. Why waste time building the temporary list when all we want is a counter? result = 0 for line in lines: if not line.strip(): result += 1 which can be simplified to: result = 0 for line in lines: result += not line.strip() I agree with you that this breaks the abstraction "bools are abstract enumerations, not ints", but that abstraction is not part of Python. If I objected to code like this: types = [int, str, list, dict] for t in types: do_something_with(t) on the basis that we shouldn't treat types as values, because that breaks the abstraction that "types are not values, they're a different kind of thing known only to the compiler" (as in Java), I expect that you would have no hesitation in telling me that my objection was invalid. Making types be non-values may, or may not, be a reasonable programming model, but it's not Python's programming model. In Python, types are themselves objects and first-class values. Objecting to Python code because it violates a norm from some other language is, frankly, silly. The abstraction "bools are abstract enumerations diff
Re: (test) ? a:b
On 10/25/2014 07:20 PM, Chris Angelico wrote: > So don't use Python idioms in BASIC. :) Back when I used to write > BASIC code, I'd do explicit comparisons with zero for this sort of > thing... these days, I'd use Python idioms, but I'd also write Python > code :) > > I think it's indicative that the BASIC code I'm most proud of was > consciously getting around language limitations (I wrote a mess of > code in assembly language and Q-BASIC to allow my programs to use the > mouse), but the Python code I'm most proud of is using the language's > strengths. Hey I did the same thing in Turbo and then later Power BASIC. I have a soft spot for BASIC, and now with FreeBASIC releasing their 1.0 release (object-oriented capabilities and the works), I revisited a bit of my BASIC past. Translated a few programs from Turbo and Power BASIC into the more modern FreeBASIC dialect. But now that that's done, it's back to Python, where I'm going to stay! Python reminds me of the best BASIC had to offer plus a whole lot more. -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sun, Oct 26, 2014 at 12:04 PM, Michael Torrie wrote: > But you can run > into trouble if you tried to use a common python idiom like this: > > x = read_some_lines() 'returns number of lines read, or zero if none are > if not x: > print ("I couldn't read any lines") > exit(1) > > Basically any value other than -1 for x would cause the not x to be > true. So don't use Python idioms in BASIC. :) Back when I used to write BASIC code, I'd do explicit comparisons with zero for this sort of thing... these days, I'd use Python idioms, but I'd also write Python code :) I think it's indicative that the BASIC code I'm most proud of was consciously getting around language limitations (I wrote a mess of code in assembly language and Q-BASIC to allow my programs to use the mouse), but the Python code I'm most proud of is using the language's strengths. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
Ben Finney writes: > This is short and clear and needs no leaking of the underlying bool > implementation:: > > len(True for line in lines if line.strip()) Correction:: len([True for line in lines if line.strip()]) -- \ “Our task must be to free ourselves from our prison by widening | `\our circle of compassion to embrace all humanity and the whole | _o__) of nature in its beauty.” —Albert Einstein | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On 10/22/2014 09:46 PM, Gregory Ewing wrote: > Chris Angelico wrote: >> I've seen much MUCH worse... where multiple conditional >> expressions get combined arithmetically, and then the result used >> somewhere... > > In the days of old-school BASIC it was common to > exploit the fact that boolean expressions evaluated > to 0 or 1 (or -1, depending on your dialect :) to > achieve conditional expressions or other tricks. As far as I can tell, no BASIC dialect I've looked at (DOS and Linux worlds only), has ever had any logical operators like AND (&&), OR (||), and NOT (!). They only appear to have bitwise operators (&,|,~ C equivalent). The fact that comparison operators returned 0 and -1 made the bitwise operators function the same as logical. But you can run into trouble if you tried to use a common python idiom like this: x = read_some_lines() 'returns number of lines read, or zero if none are if not x: print ("I couldn't read any lines") exit(1) Basically any value other than -1 for x would cause the not x to be true. Off topic, and no matter to python programmers. But for BASIC you need to watch out for this. One BASIC dialect introduced a set of functions, istrue() and isfalse() to convert a non-zero truth value to -1, and any falsish value to zero (like maybe an empty string). That way the bitwise operators would always function as logical operators in a conditional expression. -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
Steven D'Aprano writes: > I suspect that Guido and the core developers disagree with you, since > they had the opportunity to fix that in Python 3 and didn't. That doesn't follow; there are numerous warts in Python 2 that were not fixed in Python 3. As I understand it, the preservation of bool–int equality has more to do with preserving backward compatibility. I agree with the decision, because this isn't an issue which often leads to *incorrect* code. But I maintain that it's an unfortunate and needlessly confusing wart of the language. > One example of where treating True and False as 1 and 0 is useful is > that it makes counting operations very simple, e.g. counting the > number of blank lines: > > sum(not line.strip() for line in lines) > sum(1 if not line.strip() else 0 for line in lines) > sum({'': 0}.get(line.strip(), 1) for line in lines) These all look ludicrous and explain nothing about intent, to my reading. The ‘bool’ type exists precisely because there is a concept to be represented which is distinct from integers. Using a sum on non-numeric values just cracks the abstraction open needlessly. Once I figure out what is going on, I'm left wondering why the coder chose something so obfuscatory to their intent. This is short and clear and needs no leaking of the underlying bool implementation:: len(True for line in lines if line.strip()) > which I consider far less obvious than the straightforward summation > of True values. Why sum them at all? You aren't interested in them as numbers, you're just asking how many objects meet a criterion. That calls not for ‘sum’, but ‘len’. There's no need to rely on an underlying ‘int’ operation just to count objects. The fact that summing them gives the same answer as simply asking how many there are, demonstrates that nothing is gained by peeking into the implementation. The example I give above works exactly as well with no ‘int’ underlying the ‘bool’ type at all. -- \ “The way to build large Python applications is to componentize | `\ and loosely-couple the hell out of everything.” —Aahz | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
Ben Finney wrote: > Steven D'Aprano writes: > >> Of course it won't be clear to *everyone* but it should be clear >> enough to people who are familiar with standard Python idioms. A >> concrete example should be more obvious than the fake example: >> >> title = ('Mr', 'Ms')[person.sex == 'F'] >> >> which should be clear to anyone who understands indexing in Python and >> that True == 1 and False == 0. > > I consider it an accident of history, and one which should not be > necessary to understand Python code. > > In other words, I consider code which exploits the equality of True with > 1, or False with 0, is code with a leaky abstraction and should be > fixed. I suspect that Guido and the core developers disagree with you, since they had the opportunity to fix that in Python 3 and didn't. Equating True with 1 and False with 0 is fundamental to many programming languages, but more importantly Boolean Algebra itself normally identifies True with 1 and False with 0. https://en.wikipedia.org/wiki/Boolean_algebra http://mathworld.wolfram.com/BooleanAlgebra.html Admittedly this is only a convention, and you're welcome to invent your own convention, but when doing so you should be aware that Python's convention is mathematically sound and, well, conventional. One example of where treating True and False as 1 and 0 is useful is that it makes counting operations very simple, e.g. counting the number of blank lines: sum(not line.strip() for line in lines) If you reject implicit or explicit bool-to-int conversions: sum(1 if not line.strip() else 0 for line in lines) or for compatibility with Python 2.4: sum({'': 0}.get(line.strip(), 1) for line in lines) which I consider far less obvious than the straightforward summation of True values. Sometimes making things *too* abstract is worse than allowing an abstraction to leak. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sun, Oct 26, 2014 at 11:09 AM, Mark Lawrence wrote: > Horrible IMHO, it just doesn't fit in my mind set. Still each to their own. Yeah, the comprehension version is way more explicit (though it probably ought to be a set and a set comp, not a tuple and a list comp), and not as good, IMO. But it explains and justifies the original. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On 26/10/2014 01:01, Chris Angelico wrote: On Sun, Oct 26, 2014 at 10:53 AM, Ben Finney wrote: Dan Stromberg writes: EG, if I have 3 mutually exclusive command line options, I'll do something like: if option_a + option_b + option_c != 1: sys.stderr.write('{}: -a, -b and -c are mutually exclusive\n'.format(sys.argv[0])) That is an excellent illustration of why exploiting this accidental property of True and False leads to obfuscated code. The above test gives me no clue that we're operating on boolean values, nor that we're testing for exclusive options. Would it be more readable thus? if len([opt for opt in (option_a, option_b, option_c) if opt]) != 1: Because that's what it's doing. I think treating bools as numbers is fine. Matter of opinion I guess. ChrisA Horrible IMHO, it just doesn't fit in my mind set. Still each to their own. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sun, Oct 26, 2014 at 10:53 AM, Ben Finney wrote: > Dan Stromberg writes: > >> EG, if I have 3 mutually exclusive command line options, I'll do >> something like: >> >> if option_a + option_b + option_c != 1: >>sys.stderr.write('{}: -a, -b and -c are mutually >> exclusive\n'.format(sys.argv[0])) > > That is an excellent illustration of why exploiting this accidental > property of True and False leads to obfuscated code. The above test > gives me no clue that we're operating on boolean values, nor that we're > testing for exclusive options. Would it be more readable thus? if len([opt for opt in (option_a, option_b, option_c) if opt]) != 1: Because that's what it's doing. I think treating bools as numbers is fine. Matter of opinion I guess. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
Dan Stromberg writes: > EG, if I have 3 mutually exclusive command line options, I'll do > something like: > > if option_a + option_b + option_c != 1: >sys.stderr.write('{}: -a, -b and -c are mutually > exclusive\n'.format(sys.argv[0])) That is an excellent illustration of why exploiting this accidental property of True and False leads to obfuscated code. The above test gives me no clue that we're operating on boolean values, nor that we're testing for exclusive options. The error message bears no obvious relation to the test, and if I was tracking down that error message I'd have no hint from the code why the test is written that way. An explanatory comment would be needed, but that's a strong sign IMO that instead the test should be re-written to be much more obvious. -- \ “Never express yourself more clearly than you are able to | `\ think.” —Niels Bohr | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On 25/10/2014 23:48, Terry Reedy wrote: On 10/25/2014 2:23 PM, Dennis Lee Bieber wrote: On Fri, 24 Oct 2014 10:38:31 -0400, Seymore4Head declaimed the following: I do get the difference. I don't actually use Python 2. I use CodeSkulptor. I do have Python 3 installed. Actually I have Python 2 installed but IDLE defaults to Python 3. This is wrong. Pythonx.y runs Idlex.y, not vice versa. Seymore installed some version of Python 3 as default, as he should have, and 'Edit with Idle' opens the default version of Python, with its version of Idle. >> So it is a pain to actually load Python 2. Not really, neither on linux or Windows. So don't use Idle... Since Seymore analysis is wrong, this advice in not the answer. If he is running on Windows, it is dubious in that the Windows console interpreter is a pain to use. > Open up a Windows command shell and invoke Python without giving a script file to execute. C:\Users\Wulfraed\Documents>python python -m idlelib will open the corresponding Idle. So will the Start menu entry or an icon pinned to the taskbar. C:\Users\Wulfraed\Documents>python3 You must have done something extra to make this work on Windows. The Python launcher for Windows should be taken into account here http://legacy.python.org/dev/peps/pep-0397/ -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence -- https://mail.python.org/mailman/listinfo/python-list
Re: Status of side-effecting functions in python
On 10/25/2014 6:22 PM, Dan Sommers wrote: On Sat, 25 Oct 2014 23:41:52 +0200, Wolfgang Maier wrote: ... It may be rare to use an expression both for its side-effects and its return value ... A lot of concurrency-related operations work that way. In the old days, it was CPU-level Test and Set (or Compare and Set) instructions. These days, we have Python's threading.Lock.acquire. list.pop and and related set and dict methods. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On 10/25/2014 2:23 PM, Dennis Lee Bieber wrote: On Fri, 24 Oct 2014 10:38:31 -0400, Seymore4Head declaimed the following: I do get the difference. I don't actually use Python 2. I use CodeSkulptor. I do have Python 3 installed. Actually I have Python 2 installed but IDLE defaults to Python 3. This is wrong. Pythonx.y runs Idlex.y, not vice versa. Seymore installed some version of Python 3 as default, as he should have, and 'Edit with Idle' opens the default version of Python, with its version of Idle. >> So it is a pain to actually load Python 2. Not really, neither on linux or Windows. So don't use Idle... Since Seymore analysis is wrong, this advice in not the answer. If he is running on Windows, it is dubious in that the Windows console interpreter is a pain to use. > Open up a Windows command shell and invoke Python without giving a script file to execute. C:\Users\Wulfraed\Documents>python python -m idlelib will open the corresponding Idle. So will the Start menu entry or an icon pinned to the taskbar. C:\Users\Wulfraed\Documents>python3 You must have done something extra to make this work on Windows. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sat, Oct 25, 2014 at 1:45 PM, Ben Finney wrote: > Steven D'Aprano writes: >> title = ('Mr', 'Ms')[person.sex == 'F'] >> >> which should be clear to anyone who understands indexing in Python and >> that True == 1 and False == 0. > > I consider it an accident of history, and one which should not be > necessary to understand Python code. > > In other words, I consider code which exploits the equality of True with > 1, or False with 0, is code with a leaky abstraction and should be > fixed. I don't like the (a, b)[True] thing, but I use the fact that True is 1 and False is 0 sometimes. EG, if I have 3 mutually exclusive command line options, I'll do something like: if option_a + option_b + option_c != 1: sys.stderr.write('{}: -a, -b and -c are mutually exclusive\n'.format(sys.argv[0])) -- https://mail.python.org/mailman/listinfo/python-list
Re: Status of side-effecting functions in python
On Sat, 25 Oct 2014 23:41:52 +0200, Wolfgang Maier wrote: > ... It may be rare to use an expression both for its side-effects and > its return value ... A lot of concurrency-related operations work that way. In the old days, it was CPU-level Test and Set (or Compare and Set) instructions. These days, we have Python's threading.Lock.acquire. Dan -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On Fri, 24 Oct 2014 20:15:02 -0400, Seymore4Head wrote: > On Wed, 22 Oct 2014 16:30:37 -0400, Seymore4Head > wrote: > > name="012" name is a string of 3 characters > b=list(range(3)) b is a list of 3 numbers > print (name[1]) name[1] is the string "1" > print (b[1]) b[1] is the number 1 > if name[1] == b[1]: > print ("Eureka!") This didn't happen > else: > print ("OK, I get it") This happened -- Denis McMahon, denismfmcma...@gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: Status of side-effecting functions in python
On 25.10.2014 19:27, Rustom Mody wrote: Moved from other (Seymore's) thread where this is perhaps not relevant On Saturday, October 25, 2014 1:15:09 PM UTC+5:30, Steven D'Aprano wrote: Rustom Mody wrote: On Saturday, October 25, 2014 11:20:03 AM UTC+5:30, Chris Angelico wrote: On Sat, Oct 25, 2014 at 4:40 PM, Rustom Mody wrote: Its generally accepted that side-effecting functions are not a good idea -- typically a function that returns something and changes global state. Only in certain circles. Not in Python. There are large numbers of functions with side effects (mutator methods like list.append, anything that needs lots of state like random.random, everything with external effect like I/O, heaps of stuff), and it is most definitely not frowned upon. In Python 3 (or Python 2 with the future directive), print is a function, print() an expression. It's not "semantically a statement". Ok So give me a valid (ie useful) use where instead of the usual l=[1,2,3] l.append(4) we have foo(l.append(4)) Your question seems to be non-sequitor. To me, it doesn't appear to have any relationship to Chris' comments. | Languages like Pascal (many others)... distinguish function which return | results and procedure which do not... | Extract from https://en.wikipedia.org/wiki/Subroutine#Language_support So my point: Whether the language supports it strongly (Pascal' procedures) weakly (C's void functions) more weakly (Python's None returning functions), the beginning programmer needs this concept as a core thinking tool. Pascal makes this easy -- teach the syntax and the concept will get across Python is harder because the concept does not correlate with any specific syntax But its not all that hard unless the teacher is stuck in correlating core concepts and language syntax. A teacher who is so stuck is cheating the student. My version: "print may (3) or may not (2) be an expression. Just always consider it as a statement" Chris version: print() is an expression. Technically Chris is correct. Is it methodologically/pedagogically it is sound? Consider: From my explanation this: [print(x) for x in [1,2,3]] 1 2 3 [None, None, None] is in "Dont Do!" category whether python (3) allows it or python 2 doesn't. And you "Dont do" because print(x) is a statement -- literally in python 2; morally in python 3 And from here its only a small step to why l.append(4) should never be used except as a statement. Python may not literally have Pascal's procedures; they are morally there if you choose to 'believe' in them. How would Chris inculcate avoidance of code-smells like - foo(l.append(4)) - [print(x) for x in [1,2,3]] As Chris and Steven have pointed out, picking print() as an example does not make too much sense since it returns None. It may be rare to use an expression both for its side-effects and its return value, but, provided you document the intention appropriately, I do not see what would generally be wrong with it. A quick example that's not quite as silly as all your print() ones: >>> with open('longnumber.txt', 'w') as out: print(sum(out.write(str(x)) for x in range(100)), 'characters written.') 190 characters written. -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On Sat, 25 Oct 2014 15:01:54 +, Grant Edwards wrote: > On 2014-10-24, Denis McMahon wrote: >> On Fri, 24 Oct 2014 10:38:31 -0400, Seymore4Head wrote: >> >>> Thanks everyone for your suggestions. >> >> Try loading the following in codeskulptor: >> >> http://www.codeskulptor.org/#user38_j6kGKgeOMr_0.py > No. I wasn't replying to you, I was replying to S4H. > We[1] aren't intested in whatever Python-like language is implemented in > codeskulptor. However S4H may be, and one thing I can be sure is that if I give him a cs url, he will at least be running the exact same python code I typed in the same python environment, and hence I know what results he should see, namely the same ones I saw. -- Denis McMahon, denismfmcma...@gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
Steven D'Aprano writes: > Of course it won't be clear to *everyone* but it should be clear > enough to people who are familiar with standard Python idioms. A > concrete example should be more obvious than the fake example: > > title = ('Mr', 'Ms')[person.sex == 'F'] > > which should be clear to anyone who understands indexing in Python and > that True == 1 and False == 0. I consider it an accident of history, and one which should not be necessary to understand Python code. In other words, I consider code which exploits the equality of True with 1, or False with 0, is code with a leaky abstraction and should be fixed. > Although that's probably better written as a dict lookup: > > title = {'M': 'Mr', 'F': 'Ms'}[person.sex] > > which is then more easily extended to support intersex and > non-traditional[1] gender identities. It's true that gender is not a binary, but even if it were, this would be a bad idea. A schema which blurs the distinction between boolean versus integer is a code smell: it speaks to the high likelihood that the “flag” really represents an entity which will soon have more than two states, and should never have been represented as a boolean. -- \ “As scarce as truth is, the supply has always been in excess of | `\ the demand.” —Josh Billings | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sat, 25 Oct 2014 16:03:16 +1100, Steven D'Aprano wrote: > [Alister] >> I had to mentally step through this before it became apparent what it >> was doing, can see places where it could be usefull (a switch >> replacement) but it is not instantly obvious > > Very little code is instantly obvious. Even when you know what the > syntax means, you still have to understand the semantics, and sometimes > that's far from obvious. > > >> a = if else >> >> is instantly obvious (at least to a native English speaker anyway) > > Ha! And yet people have, and continue to, complain *bitterly* about the > non-standard ordering of Python's ternary if, compared to C, standard > if...else syntax, and English. Not Me, I don't program i C & I don't want to it is too low level fro my liking (& I used to program in assembler for a living) -- "You need tender loving care once a week - so that I can slap you into shape." - Ellyn Mustard -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On Sat, 25 Oct 2014 14:23:44 -0400, Dennis Lee Bieber wrote: >On Fri, 24 Oct 2014 10:38:31 -0400, Seymore4Head > declaimed the following: > >> >>I do get the difference. I don't actually use Python 2. I use >>CodeSkulptor. I do have Python 3 installed. Actually I have Python 2 >>installed but IDLE defaults to Python 3. So it is a pain to actually >>load Python 2. >> > > So don't use Idle... Open up a Windows command shell and invoke Python >without giving a script file to execute. > >C:\Users\Wulfraed\Documents>python >ActivePython 2.7.5.6 (ActiveState Software Inc.) based on >Python 2.7.5 (default, Sep 16 2013, 23:11:01) [MSC v.1500 64 bit (AMD64)] >on win32 >Type "help", "copyright", "credits" or "license" for more information. exit() > >C:\Users\Wulfraed\Documents>python3 >ActivePython 3.3.2.0 (ActiveState Software Inc.) based on >Python 3.3.2 (default, Sep 16 2013, 23:11:39) [MSC v.1600 64 bit (AMD64)] >on win32 >Type "help", "copyright", "credits" or "license" for more information. exit() > >C:\Users\Wulfraed\Documents> > > Note that my default Python is still 2.7, but I also have Python 3.3 >installed, and can access it using "python3" (I can also ensure Python 2.7 >by using "python2") > > >> >>I tried list(range(10) I thought that would work in Python 3. It >>didn't. I spent quite a bit of time last night trying to come up with > > Really? what did it do? SHOW US! > >C:\Users\Wulfraed\Documents>python3 >ActivePython 3.3.2.0 (ActiveState Software Inc.) based on >Python 3.3.2 (default, Sep 16 2013, 23:11:39) [MSC v.1600 64 bit (AMD64)] >on win32 >Type "help", "copyright", "credits" or "license" for more information. list(range(10)) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(list(range(10))) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] repr(list(range(10))) >'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' > > Recall that "print" is a function in Python 3, so the extra layer of () >are required. > >C:\Users\Wulfraed\Documents>python >ActivePython 2.7.5.6 (ActiveState Software Inc.) based on >Python 2.7.5 (default, Sep 16 2013, 23:11:01) [MSC v.1500 64 bit (AMD64)] >on win32 >Type "help", "copyright", "credits" or "license" for more information. list(range(10)) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print list(range(10)) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(list(range(10))) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] repr(list(range(10))) >'[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' > > "Print" doesn't need the (), but they also don't hurt it in Python 2. >(still in Py2) > range(10) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] xrange(10) >xrange(10) print range(10) >[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print xrange(10) >xrange(10) exit >Use exit() or Ctrl-Z plus Return to exit exit() > > Now Py3 > >C:\Users\Wulfraed\Documents>python3 >ActivePython 3.3.2.0 (ActiveState Software Inc.) based on >Python 3.3.2 (default, Sep 16 2013, 23:11:39) [MSC v.1600 64 bit (AMD64)] >on win32 >Type "help", "copyright", "credits" or "license" for more information. range(10) >range(0, 10) xrange(10) >Traceback (most recent call last): > File "", line 1, in >NameError: name 'xrange' is not defined print(range(10)) >range(0, 10) I am not working on that any more. I have my assignment for this week so I am done with busy work. Thanks for all your help -- https://mail.python.org/mailman/listinfo/python-list
Status of side-effecting functions in python
Moved from other (Seymore's) thread where this is perhaps not relevant On Saturday, October 25, 2014 1:15:09 PM UTC+5:30, Steven D'Aprano wrote: > Rustom Mody wrote: > > > On Saturday, October 25, 2014 11:20:03 AM UTC+5:30, Chris Angelico wrote: > >> On Sat, Oct 25, 2014 at 4:40 PM, Rustom Mody wrote: > >> > Its generally accepted that side-effecting functions are not a good > >> > idea -- typically a function that returns something and changes global > >> > state. > >> > >> Only in certain circles. Not in Python. There are large numbers of > >> functions with side effects (mutator methods like list.append, > >> anything that needs lots of state like random.random, everything with > >> external effect like I/O, heaps of stuff), and it is most definitely > >> not frowned upon. > >> > >> In Python 3 (or Python 2 with the future directive), print is a > >> function, print() an expression. It's not "semantically a statement". > > > > Ok > > So give me a valid (ie useful) use where instead of the usual > > l=[1,2,3] > > l.append(4) > > > > we have > > > > foo(l.append(4)) > > Your question seems to be non-sequitor. To me, it doesn't appear to have any > relationship to Chris' comments. | Languages like Pascal (many others)... distinguish function which return | results and procedure which do not... | Extract from https://en.wikipedia.org/wiki/Subroutine#Language_support So my point: Whether the language supports it strongly (Pascal' procedures) weakly (C's void functions) more weakly (Python's None returning functions), the beginning programmer needs this concept as a core thinking tool. Pascal makes this easy -- teach the syntax and the concept will get across Python is harder because the concept does not correlate with any specific syntax But its not all that hard unless the teacher is stuck in correlating core concepts and language syntax. A teacher who is so stuck is cheating the student. My version: "print may (3) or may not (2) be an expression. Just always consider it as a statement" Chris version: print() is an expression. Technically Chris is correct. Is it methodologically/pedagogically it is sound? Consider: >From my explanation this: >>> [print(x) for x in [1,2,3]] 1 2 3 [None, None, None] >>> is in "Dont Do!" category whether python (3) allows it or python 2 doesn't. And you "Dont do" because print(x) is a statement -- literally in python 2; morally in python 3 And from here its only a small step to why l.append(4) should never be used except as a statement. Python may not literally have Pascal's procedures; they are morally there if you choose to 'believe' in them. How would Chris inculcate avoidance of code-smells like - foo(l.append(4)) - [print(x) for x in [1,2,3]] ? No idea! I dare say: about print I dont know but [foo(x) for x in lst] and foo is used for effect not return-value is a rather common code-smell in my experience -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On Saturday, October 25, 2014 1:15:09 PM UTC+5:30, Steven D'Aprano wrote: > Rustom Mody wrote: > > > On Saturday, October 25, 2014 11:20:03 AM UTC+5:30, Chris Angelico wrote: > >> On Sat, Oct 25, 2014 at 4:40 PM, Rustom Mody wrote: > >> > Its generally accepted that side-effecting functions are not a good > >> > idea -- typically a function that returns something and changes global > >> > state. > >> > >> Only in certain circles. Not in Python. There are large numbers of > >> functions with side effects (mutator methods like list.append, > >> anything that needs lots of state like random.random, everything with > >> external effect like I/O, heaps of stuff), and it is most definitely > >> not frowned upon. > >> > >> In Python 3 (or Python 2 with the future directive), print is a > >> function, print() an expression. It's not "semantically a statement". > > > > Ok > > So give me a valid (ie useful) use where instead of the usual > > l=[1,2,3] > > l.append(4) > > > > we have > > > > foo(l.append(4)) > > Your question seems to be non-sequitor. To me, it doesn't appear to have any > relationship to Chris' comments. I am going to leave undisturbed Seymore's thread for whom these nit-picks are unlikely to be helpful Answer in another one -- https://mail.python.org/mailman/listinfo/python-list
Re: Meetup in NYC?
There's a metope group for Python in NYC and they have project nights/study groups. You should check them out. http://www.meetup.com/nycpython/ On Saturday, October 25, 2014 11:08:31 AM UTC-5, ryguy7272 wrote: > Are there any Python professionals in or around NYC who can meetup for an > hour or two to help me with a few things? I've been trying to run various > Python scripts for a few months now, and I'm not having any success with this > stuff at all. Basically, everything built into Python works perfectly fine > for me. However, whenever I try to run something like numpy or beautifulsoup, > or anything like that, I have all kinds of errors. > > If anyone could meet for an hour or two, in a Starbucks, and go through a few > examples of Python code, it would be great!! I can take you out for a few > beers afterwards. -- https://mail.python.org/mailman/listinfo/python-list
Meetup in NYC?
Are there any Python professionals in or around NYC who can meetup for an hour or two to help me with a few things? I've been trying to run various Python scripts for a few months now, and I'm not having any success with this stuff at all. Basically, everything built into Python works perfectly fine for me. However, whenever I try to run something like numpy or beautifulsoup, or anything like that, I have all kinds of errors. If anyone could meet for an hour or two, in a Starbucks, and go through a few examples of Python code, it would be great!! I can take you out for a few beers afterwards. -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On 2014-10-24, Denis McMahon wrote: > On Fri, 24 Oct 2014 10:38:31 -0400, Seymore4Head wrote: > >> Thanks everyone for your suggestions. > > Try loading the following in codeskulptor: > > http://www.codeskulptor.org/#user38_j6kGKgeOMr_0.py No. We[1] aren't intested in whatever Python-like language is implemented in codeskulptor. [1] I know I'm being a bit presumptuous writing the the plural first person rather than the signular. If you _are_ interested in codeskulptor "python" then jump in... -- Grant -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On Sat, Oct 25, 2014 at 12:46 AM, Larry Hudson wrote: >> name="123-xyz-abc" >> for x in name: >> if x in range(10): > > x is a character (a one-element string). range(10) is a list of ints. A > string will never match an int. BTW, as it is used here, range(10) is for > Py2, for Py3 it needs to be list(range(10)). The last comment is incorrect. You can do membership tests on a Python 3 range object: >>> range(2, 4) range(2, 4) >>> for i in range(5): ... print(i, i in range(2, 4)) ... 0 False 1 False 2 True 3 True 4 False You can also index them: >>> range(50, 100)[37] 87 slice them: >>> range(0, 100, 2)[:25] range(0, 50, 2) get their length: >>> len(range(25, 75)) 50 search them: >>> range(25, 75).index(45) 20 and generally do most operations that you would expect to be able to do with an immutable sequence type, with the exceptions of concatenation and multiplication. And as I observed elsewhere in the thread, such operations are often more efficient on range objects than by constructing and operating on the equivalent lists. -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On Sat, Oct 25, 2014 at 5:58 AM, Ned Batchelder wrote: > You mention "standard Python idioms." I think this style of > conditional-via-indexing is becoming quite uncommon, and is no longer one of > the standard Python idioms. This is now in the category of "outdated hack." I think that's probably true. And even in code written for versions of Python than predate the ternary, I think I've seen the idiom "(cond and [if_true] or [if_false])[0]" more often than the one being discussed -- perhaps because it more closely resembles the format of the C ternary -- https://mail.python.org/mailman/listinfo/python-list
Re: Weird connection problem
It’s a special HTTPS url and searching further it seems to be a SNI problem talked about here: http://stackoverflow.com/questions/18578439/using-requests-with-tls-doesnt-give-sni-support > 25 okt 2014 kl. 08:48 skrev Joel Goldstick : > > On Sat, Oct 25, 2014 at 9:40 AM, Roland Hedberg wrote: >> When I try to access a URL using requests I always get: >> socket.error: [Errno 104] Connection reset by peer >> >> If I try to access the same URL using curl I get no error message instead I >> get the page. >> The same result if I use a web browser like Safari. >> >> But, if I use python httplib I also get Errno 104. >> >> What gives ? >> >> Oh, by the way it’s a HTTPS url. >> >> — Roland > > Is this for any url or a specific one? >> -- >> https://mail.python.org/mailman/listinfo/python-list > > > > -- > Joel Goldstick > http://joelgoldstick.com > -- > https://mail.python.org/mailman/listinfo/python-list — Roland ”Being able to think like a child is an important attribute of being an adult” - Eddie Izzard -- https://mail.python.org/mailman/listinfo/python-list
Re: Weird connection problem
On Sat, Oct 25, 2014 at 9:40 AM, Roland Hedberg wrote: > When I try to access a URL using requests I always get: > socket.error: [Errno 104] Connection reset by peer > > If I try to access the same URL using curl I get no error message instead I > get the page. > The same result if I use a web browser like Safari. > > But, if I use python httplib I also get Errno 104. > > What gives ? > > Oh, by the way it’s a HTTPS url. > > — Roland Is this for any url or a specific one? > -- > https://mail.python.org/mailman/listinfo/python-list -- Joel Goldstick http://joelgoldstick.com -- https://mail.python.org/mailman/listinfo/python-list
Re: Weird connection problem
Oh, by the way! To make this more interesting :-/ I saw this behavior on a Linux machine (Ubuntu 14.04 LTS) using Python 2.7.6 if I do the same exercise on a Mac OS X machine also with Python 2.7.6 - no problem what so ever. > 25 okt 2014 kl. 08:40 skrev Roland Hedberg : > > When I try to access a URL using requests I always get: > socket.error: [Errno 104] Connection reset by peer > > If I try to access the same URL using curl I get no error message instead I > get the page. > The same result if I use a web browser like Safari. > > But, if I use python httplib I also get Errno 104. > > What gives ? > > Oh, by the way it’s a HTTPS url. > > — Roland > > ”Being able to think like a child is an important attribute of being an > adult” - Eddie Izzard > > -- > https://mail.python.org/mailman/listinfo/python-list — Roland ”Being able to think like a child is an important attribute of being an adult” - Eddie Izzard -- https://mail.python.org/mailman/listinfo/python-list
Weird connection problem
When I try to access a URL using requests I always get: socket.error: [Errno 104] Connection reset by peer If I try to access the same URL using curl I get no error message instead I get the page. The same result if I use a web browser like Safari. But, if I use python httplib I also get Errno 104. What gives ? Oh, by the way it’s a HTTPS url. — Roland ”Being able to think like a child is an important attribute of being an adult” - Eddie Izzard -- https://mail.python.org/mailman/listinfo/python-list
Re: (test) ? a:b
On 10/25/14 1:03 AM, Steven D'Aprano wrote: alister wrote: >On Fri, 24 Oct 2014 10:20:30 -0700, Dan Stromberg wrote: > >>On Fri, Oct 24, 2014 at 1:38 AM, Steven D'Aprano >> wrote: >>>I don't get why that's considered hard to read. >> >>>So why is it hard to read when the index is a flag? >>> >>>value = [f, g][cond]() >> [Dan] >>It's clear to you, it's clear to me, but is it clear to everyone? I >>very much doubt it. Of course it won't be clear to*everyone* but it should be clear enough to people who are familiar with standard Python idioms. A concrete example should be more obvious than the fake example: title = ('Mr', 'Ms')[person.sex == 'F'] which should be clear to anyone who understands indexing in Python and that True == 1 and False == 0. You mention "standard Python idioms." I think this style of conditional-via-indexing is becoming quite uncommon, and is no longer one of the standard Python idioms. This is now in the category of "outdated hack." Yes, its meaning is well-defined by the language. But no, its meaning is not immediately apparent to most of today's Python programmers. Of course, opinions obviously differ. -- Ned Batchelder, http://nedbatchelder.com -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
Rustom Mody wrote: > On Saturday, October 25, 2014 11:20:03 AM UTC+5:30, Chris Angelico wrote: >> On Sat, Oct 25, 2014 at 4:40 PM, Rustom Mody wrote: >> > Its generally accepted that side-effecting functions are not a good >> > idea -- typically a function that returns something and changes global >> > state. >> >> Only in certain circles. Not in Python. There are large numbers of >> functions with side effects (mutator methods like list.append, >> anything that needs lots of state like random.random, everything with >> external effect like I/O, heaps of stuff), and it is most definitely >> not frowned upon. >> >> In Python 3 (or Python 2 with the future directive), print is a >> function, print() an expression. It's not "semantically a statement". > > Ok > So give me a valid (ie useful) use where instead of the usual > l=[1,2,3] > l.append(4) > > we have > > foo(l.append(4)) Your question seems to be non-sequitor. To me, it doesn't appear to have any relationship to Chris' comments. But to answer your question, Ruby has mutator methods like list.append return the list being mutated, to make it easy to chain multiple calls: l.append(4).reverse().sort() That would make it easy and convenient to modify a list immediately pass the modified list to a function and embed it in an expression: # Python's way l.append(4) values = [1, 2, foo(l), 3] # Pseudo-Ruby way values = [1, 2, foo(l.append(4)), 3] Languages where all values are immutable *by definition* have to return a new list, since you can't modify the original, hence they too can easily be embedded in an expression. Many people try to write something like this: old_lists = [a, b, c, d] new_lists = [thelist.append(x) for thelist in old_lists if len(thelist) < 5] only to be unpleasantly surprised to discover than new_lists now contains None instead of the lists. Having methods return a result rather than behave like a procedure is a valid (i.e. useful) design choice. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: I am out of trial and error again Lists
On 25/10/2014 03:41, Seymore4Head wrote: On Fri, 24 Oct 2014 19:16:21 -0700, Larry Hudson wrote: On 10/24/2014 07:38 AM, Seymore4Head wrote: I do get the difference. I don't actually use Python 2. I use CodeSkulptor. I do have Python 3 installed. Actually I have Python 2 installed but IDLE defaults to Python 3. So it is a pain to actually load Python 2. Exactly HOW are you trying to run Idle? A default install of Py2 and Py3 in Windows should have also installed Idle for each version. In my Win7 system, they are BOTH in the standard menu, you should be able to call up either one. OT: Side comment: I rarely use Windows these days, maybe once every two or three months -- I MUCH prefer Linux. Among other reasons its a far better environment for programming. I only have one (active) system with Windows installed, and two others with Linux only. Actually make that three, if you count my Raspberry Pi. :-) -=- Larry -=- I have a directory of my py files. I right click on one of the py files and "open with IDLE" Windows XP If I try to open a py file I have for Python 2 it still opens using IDLE 3. I don't have many py 2 files anyway. How about running your Python 2 version of IDLE and opening your files using File->Open or CTRL-O? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence -- https://mail.python.org/mailman/listinfo/python-list