Re: The "loop and a half"
Steve D'Aprano wrote: On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote: You know, you don't HAVE to economize on letters. It's okay to call your parameters "prompt" instead of "prmt". Remember, that's part of your API. Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of vwel wth nt nuff 4 vrybdy. I blame the Dutch. They're clearly using more than their fair share of the world's vowels. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Wed, 04 Oct 2017 20:16:29 +1300, Gregory Ewing wrote: > Steve D'Aprano wrote: >> On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote: >> >>>You know, you don't HAVE to economize on letters. It's okay to call >>>your parameters "prompt" instead of "prmt". Remember, that's part of >>>your API. >> >> Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of >> vwel wth nt nuff 4 vrybdy. > > I blame the Dutch. They're clearly using more than their fair share of > the world's vowels. but that is compensated for by the welsh which don't seem to use any -- Never trust an operating system. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Given the prevalence of the loop and a half idea in python I wonder why we don't have a "do" or "loop" statement to start loops without a test. C:\Python27\Lib>grep "while True" *.py | wc -l 99 C:\Python27\Lib>grep "while 1" *.py | wc -l 117 C:\Python36\Lib>grep "while True" *.py | wc -l 131 C:\Python36\Lib>grep "while 1" *.py | wc -l 44 How much does the while True actually cost compared to nothing? -- Robin Becker -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Steve D'Aprano writes: > On Wed, 4 Oct 2017 04:45 am, Rhodri James wrote: > >> On 03/10/17 18:29, Stefan Ram wrote: >>>Is this the best way to write a "loop and a half" in Python? >> >> Define "best". > > I'd start with "define loop and a half". What it means to me is this pattern: while True: ... statements that don't exit the loop ... if condition: break ... more statements that don't exit the loop ... When the first set of statements is null, it's just a while loop. When the second is null, it's just a do ... while (in languages that have it). Where both sets are present some languages encourage putting the first set into the condition of the loop. For example, in Algol 68 an expression can be replaced by a statement sequence that ends in an expression. C encourages the same, provided the first set of statements is very simple. The classic example being while ((some_var = some_input_function()) != some_error_value) { ... process some_var ... } In Pascal, you sometimes had to duplicate the first set of statements: ... statements that don't exit the loop ... while condition begin ... more statements that don't exit the loop ... ... statements that don't exit the loop ... end -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Multithreaded compression/decompression library with python bindings?
Hello, I was wondering if anyone here knew of any python libraries with interfaces similar to the bzip2 module which is also multithreaded in (de)compression? Something along the lines of (say) the pbip2 program but with bindings for python? Obviously the multi-threaded part will need to be handled by the underlying library code and not the python code itself. If that's too much to ask (I haven't found anything myself after all), if anyone here happens to have any experience using similar C++ (or possibly C) libraries I am certainly open for any recommendations. :) Thanks in advance! Thomas -- https://mail.python.org/mailman/listinfo/python-list
Good virtualenv and packaging tutorials for beginner?
Folks on IRC have suggested using virtualenv to test code under different python versions. Sadly, I've not found a virtualenv tutorial I understand. Anyone have a link to a good one? The next step will be to figure out how to package a project; a good tutorial URL would be appreciated on that, too. Thanks! Leam -- https://mail.python.org/mailman/listinfo/python-list
Python community "welcoming" feedback
A while back I pointed out some challenges for the Python community's intake of new coders. Mostly focusing on IRC and the Python e-mail list. Several people have stepped up their "welcome" game and I've been very impressed with the way things are going. Great job! Leam -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 04/10/2017 06:32, Steve D'Aprano wrote: On Wed, 4 Oct 2017 02:00 am, bartc wrote: Does all this advanced stuff (which I don't understand and which doesn't look very appealing either; hopefully I will never come across such code) still count as programming? I could not have hoped to see a more perfect example of the Blub effect in action if I had invented it myself. As long as our hypothetical Blub programmer is looking down the power continuum, he knows he's looking down. Languages less powerful than Blub are obviously less powerful, because they're missing some feature he's used to. But when our hypothetical Blub programmer looks in the other direction, up the power continuum, he doesn't realize he's looking up. What he sees are merely weird languages. He probably considers them about equivalent in power to Blub, but with all this other hairy stuff thrown in as well. Blub is good enough for him, because he thinks in Blub. http://www.paulgraham.com/avg.html I've seen that example brought up before. It still doesn't cut any ice. You might as well be condescending of someone who finds Joyce or Proust unreadable, and prefers McBain, Simenon or Chandler. (Sorry, can't think of any modern pulp novelists). It is just being elitist. I have a preference for keeping things simple and avoiding unnecessary complexity. But with programming languages many do have a penchant for the latter. As an example, a recent discussion on comp.lang.c was about implementing named constants. I proposed one very simple way of doing it, other people were talking about using #define, enum, const, static const, or importing constexpr and special rules for 'const' from C++. All unsatisfactory and each having their own problems. For that matter, I don't think Python has such a feature either. So that you write for example: const C = 123345 and then whenever C appears within the code, it's implemented as: LOAD_CONST (123345) I'm pretty sure that there are very complicated ways of achieving something similar, maybe with all your decorators, or using PyMacro or whatever. But not doing it straightforwardly. [Python's design makes a simple implementation harder.] Anyway, what I'm saying is that languages sometimes neglect the basics in favour of all this other stuff. You don't think that adding a cache for an expensive function is programming? If you had ten expensive functions, and you wanted to add a cache to each of them, would you write out ten separate caches (probably copying and pasting the code each time)? Or would you write a function that builds a cache and adds it to the expensive function *once*, then call it ten times, once for each function being wrapped? I'm trying to think of a real example where I've had to add a cache to to a function, whatever that even means (memoisation?). Is it looking to see if a certain combination of parameters has been used before and retrieving the return value that resulted on that occasion without having to redo the calculation? In my sort of coding that would need be done on a per-function basis because there would be other considerations. It does still sound like adding a turbo-charger to your engine, rather than actually going anywhere. That at least might be useful, but it's still not driving. But if the ultimate purpose is more speed, then piling on yet more code and more layers may be counter-productive! That you think that this is not programming is an indictment off your programming skills. These sorts of functional programming techniques go back to the 1950s, Lisp is literally the second oldest high-level language ever (only Fortran is older). You may or may not have been a hotshot in your little corner of the programming world, but there's an entire world out there. What other languages apart from Python have equivalent features to decorators and, what's the other one, descriptors? Apart from Lisp. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Good virtualenv and packaging tutorials for beginner?
Leam Hall writes: > Folks on IRC have suggested using virtualenv to test code under > different python versions. Sadly, I've not found a virtualenv tutorial > I understand. Anyone have a link to a good one? The Python Packaging Authority has a guide https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments> which seems good to me. The standard library documentation for the ‘venv’ library https://docs.python.org/3/library/venv.html> is essential. > The next step will be to figure out how to package a project; a good > tutorial URL would be appreciated on that, too. Follow the documentation maintained by the Python Packaging Authority https://packaging.python.org/>. -- \ “Courage is not the absence of fear, but the decision that | `\ something else is more important than fear.” —Ambrose Redmoon | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
"Stefan Ram" wrote in message news:vba-loops-20171004114...@ram.dialup.fu-berlin.de... Robin Becker writes: >Given the prevalence of the loop and a half idea in python I wonder why >we don't >have a "do" or "loop" statement to start loops without a test. VBA has quite an orthogonal way to build loop control: pre-checked positive: Do While ... ... Loop post-checked positive: Do ... Loop While ... pre-checked negative: Do Until ... ... Loop post-checked negative Do ... Loop Until ... "endless": Do ... Loop There is a language called Pick Basic (which most of you have never heard of) which has a single syntax covering all possibilities - LOOP {optional statements} WHILE {condition} or UNTIL {condition} DO {optional statements} REPEAT The DO and the REPEAT are necessary because it does not use indentation or braces to terminate blocks, it uses keywords. Frank Millman -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 04/10/2017 11:42, Stefan Ram wrote: Robin Becker writes: Given the prevalence of the loop and a half idea in python I wonder why we don't have a "do" or "loop" statement to start loops without a test. VBA has quite an orthogonal way to build loop control: pre-checked positive: Do While ... ... Loop post-checked positive: Do ... Loop While ... pre-checked negative: Do Until ... ... Loop post-checked negative Do ... Loop Until ... "endless": Do ... Loop None of them appear to be loop-and-a-halves. (Note that your reverse-indentation style is confusing! Imagine that Python was written like this: for i in R: print (i) ) Anyway I think what is needed in Python for a proper loop-and-a-half is this: while: s1 s2 do cond: s3 s4 s1, s2, s3, s4 are executed in sequence while cond is true. When cond is false, only s1, s2 are executed in that iteration, and the loop terminates. (A few syntactical details to be worked out such as whether while, do and else line up or not.) This is equivalent I think to the current: while 1: s1 s2 if cond: s3 s4 else: break But this would be a less satisfactory, ad-hoc approach. For example, there can be several such if-blocks within the same loop. They could be nested. There might not be any, so can't at a glance distinguish an endless loop from a loop-and-a-half. My proposed while-do has a less chaotic structure. It wouldn't preclude 'break' from still being used, but there would be less need. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 04/10/17 10:01, Robin Becker wrote: Given the prevalence of the loop and a half idea in python I wonder why we don't have a "do" or "loop" statement to start loops without a test. See PEP 315. Guido's rejection note is here: https://mail.python.org/pipermail/python-ideas/2013-June/021610.html -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list
Re: Good virtualenv and packaging tutorials for beginner?
On Wed, Oct 4, 2017 at 7:15 AM, Ben Finney wrote: > Leam Hall writes: > > > Folks on IRC have suggested using virtualenv to test code under > > different python versions. Sadly, I've not found a virtualenv tutorial > > I understand. Anyone have a link to a good one? > > The Python Packaging Authority has a guide > https://packaging.python.org/tutorials/installing- > packages/#creating-virtual-environments> > which seems good to me. > > The standard library documentation for the ‘venv’ library > https://docs.python.org/3/library/venv.html> is essential. > > > The next step will be to figure out how to package a project; a good > > tutorial URL would be appreciated on that, too. > > Follow the documentation maintained by the Python Packaging Authority > https://packaging.python.org/>. > > Ben, thanks! I'm off to print and study... Leam -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 2017-10-04, Stefan Ram wrote: > r...@zedat.fu-berlin.de (Stefan Ram) writes: >>Maybe this way: Use a while-loop and try-catch to get values >>from an iterator until exhausted, and then introduce the >>for-loop as an abbreviation for that. > > # while-loop > > iterable = range( 3 ) > > iterator = iter( iterable ) > try: > while True: > i = next( iterator ) > print( i ) > except StopIteration: > pass > > iterator = iter( iterable ) > try: > while True: > i = next( iterator ) > print( i ) > except StopIteration: > pass > > # for-loop as-an-abbreviation > > iterable = range( 3 ) > > for i in iterable: > print( i ) > > for i in iterable: > print( i ) That looks the opposite of an excellent way to teach iterators. If you insist they understand the iterator protocol and exception handling first they're bound to think iteration is a hovercraft full of eels. -- Neil Cerutti -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
r...@zedat.fu-berlin.de (Stefan Ram) writes: > Steve D'Aprano writes: >>For-each loops are MUCH easier to understand, and should be taught first. > > I prefer a bottom-up approach. > > For loops are based on iterators. > > So, "bottom-up" in this case means: iterators should be > taught before for-loops. > > But iterators are too abstract to be taught very early. I think this may be a problem with your style. From your other postings, I think you value precision and exactness over broad understanding, and maybe you teach like that. I my view, it's possible to explain enough about iterators to understand a huge range of for loops without having to go into the gory details. I find the image of a conjurer pulling knotted hankies out of a hat a good one -- they may go on forever and you don't know if there is rabbit in there knotting them and deciding which colour comes next. > But I will teach iterators and for loops not much later than > while-loop. > > Maybe this way: Use a while-loop and try-catch to get values > from an iterator until exhausted, and then introduce the > for-loop as an abbreviation for that. That sounds very complicated, but I think I favour the other extreme to you. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 04/10/2017 11:57, Rhodri James wrote: On 04/10/17 10:01, Robin Becker wrote: Given the prevalence of the loop and a half idea in python I wonder why we don't have a "do" or "loop" statement to start loops without a test. See PEP 315. Guido's rejection note is here: https://mail.python.org/pipermail/python-ideas/2013-June/021610.html Oh, OK, similar to what I proposed earlier. That it was rejected is not a surprise. Programming languages seem to hate special forms for basic constructs such as looping, even though they can express more directly exactly what the coder intended. But this is what it says about it: "Please reject the PEP. More variations along these lines won't make the language more elegant or easier to learn. They'd just save a few hasty folks some typing while making others who have to read/maintain their code wonder what it means." Exactly the same could be said of pretty much any of the advanced features that /have/ been added. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
r...@zedat.fu-berlin.de (Stefan Ram) writes: > bartc writes: >>Note that your reverse-indentation style is confusing! > > In Python, indentation can be significant. > > Sometimes, some lines in Python must be indented by 0. > > This dictates that Python code cannot be indented > in posts to differentiate it from the natural-language > body of the post. Therefore, it's rather the > natural-language body that has to be indented. It does not /dictate/ it. It just makes it convenient for people with certain news readers. If you posted def f(x): return x*x I can select the block starting in column 2 and paste it into a python REPL quite easily. I prefer software that copes with existing conventions rather than have the conventions change to make it easy for the software. But if I felt I should not indent my python code, I would certainly not indent my text commentary. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 04/10/2017 11:57, Rhodri James wrote: On 04/10/17 10:01, Robin Becker wrote: Given the prevalence of the loop and a half idea in python I wonder why we don't have a "do" or "loop" statement to start loops without a test. See PEP 315. Guido's rejection note is here: https://mail.python.org/pipermail/python-ideas/2013-June/021610.html seems fair enough; I suppose the cost is negligible or perhaps there's peephole optimization for this common case. -- Robin Becker -- https://mail.python.org/mailman/listinfo/python-list
How best to initialize in unit tests?
Suppose you want to test a package (in the general sense of the word, not necessarily a Python package). You probably have specific unit tests, maybe some doctests scattered around in doc strings. Further, suppose that package requires you call an initialize function of some sort. Where does that go? I know about setUp and setUpClass methods in unittest.TestCase. Is order of execution of doctests deterministic across modules (say, when tests are run through nosetests)? In my case, I didn't know what order things would be called, so I added a call to initialize() at the start of every doctest and added a setUpClass class method to all my TestCase subclasses. Just in case. It worked okay because my initialize function can be called multiple times. What about situations where it can only be called once? Do you have to define some sort of super_initialize() function for your tests which guarantees that your initialize function is called precisely once? This all seems rather messy. I'm open to better ways to do this, but as I've only had one cup of coffee this morning, no spark of insight has zapped my frontal cortex as yet. Thx, Skip -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 04/10/2017 14:02, Robin Becker wrote: On 04/10/2017 11:57, Rhodri James wrote: On 04/10/17 10:01, Robin Becker wrote: Given the prevalence of the loop and a half idea in python I wonder why we don't have a "do" or "loop" statement to start loops without a test. See PEP 315. Guido's rejection note is here: https://mail.python.org/pipermail/python-ideas/2013-June/021610.html seems fair enough; I suppose the cost is negligible or perhaps there's peephole optimization for this common case. Read the thread. Not having a dedicated feature means I counted at least half a dozen different ideas for implementing what the OP really wanted to do, which was expressed using C-like syntax. None of which were as obvious. And that C-like one worked because it could use an assignment within a while-condition. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 04/10/17 12:07, bartc wrote: I've seen that example brought up before. It still doesn't cut any ice. You might as well be condescending of someone who finds Joyce or Proust unreadable, and prefers McBain, Simenon or Chandler. (Sorry, can't think of any modern pulp novelists). I don't think your comparison is appropriate. Joyce and Proust strike me as the literary equivalent of Perl or APL; very clever but nearly unreadable even for experts. No, think rather of Terry Pratchett. (Almost) anyone can read a Pratchett novel and enjoy it. Most people will not even notice maybe half the jokes. This is most obvious with The Colour of Magic and The Light Fantastic, where long-time Fantasy readers will spot Fafhrd and the Grey Mouser, recognise the tropes that are cheerfully being exploded, and so on. You can write decent Python without using decorators, properties, metaclasses or comprehensions in much the same way that you can enjoy Pratchett without ever having heard of Fritz Lieber. For a straightforward enough problem, writing your Python as if it was C won't even cause you any trouble. But if you think using these extra tools isn't programming, you are as flat out wrong as if you think Small Gods is just about a deity having to work on being believed in. -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On Wed, Oct 4, 2017 at 5:07 AM, bartc wrote: > It is just being elitist. I have a preference for keeping things simple and > avoiding unnecessary complexity. But with programming languages many do have > a penchant for the latter. > > As an example, a recent discussion on comp.lang.c was about implementing > named constants. I proposed one very simple way of doing it, other people > were talking about using #define, enum, const, static const, or importing > constexpr and special rules for 'const' from C++. All unsatisfactory and > each having their own problems. > > For that matter, I don't think Python has such a feature either. So that you > write for example: > > const C = 123345 > > and then whenever C appears within the code, it's implemented as: > > LOAD_CONST (123345) > > I'm pretty sure that there are very complicated ways of achieving something > similar, maybe with all your decorators, or using PyMacro or whatever. But > not doing it straightforwardly. [Python's design makes a simple > implementation harder.] Python has the simplest named constants of all: C = 12345 As long as you don't subsequently change it, it's a constant. And it's very simple because it works just like any other variable. Python also has a particularly flexible Enum implementation, but if you don't want it then don't use it. >> You don't think that adding a cache for an expensive function is >> programming? >> >> If you had ten expensive functions, and you wanted to add a cache to each >> of >> them, would you write out ten separate caches (probably copying and >> pasting >> the code each time)? >> >> Or would you write a function that builds a cache and adds it to the >> expensive >> function *once*, then call it ten times, once for each function being >> wrapped? > > > I'm trying to think of a real example where I've had to add a cache to to a > function, whatever that even means (memoisation?). You've never used a dynamic programming algorithm? >> That you think that this is not programming is an indictment off your >> programming skills. These sorts of functional programming techniques go >> back >> to the 1950s, Lisp is literally the second oldest high-level language ever >> (only Fortran is older). You may or may not have been a hotshot in your >> little corner of the programming world, but there's an entire world out >> there. > > > What other languages apart from Python have equivalent features to > decorators and, what's the other one, descriptors? Apart from Lisp. Literally any language with first-class function types, whether they have the @decorator-style syntactic sugar for it or not. Descriptors are a bit unique to Python, I'll grant, but mostly they're just used in the form of properties. Here's a list of languages that support properties: https://en.wikipedia.org/wiki/Property_(programming)#Example_syntax -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 10/3/2017 5:08 PM, Stefan Ram wrote: Steve D'Aprano writes: On Wed, 4 Oct 2017 04:45 am, Rhodri James wrote: On 03/10/17 18:29, Stefan Ram wrote: Is this the best way to write a "loop and a half" in Python? Define "best". I'd start with "define loop and a half". I encountered this phenomenon decades ago. But only some years ago, I heard someone using a special word for it! Let me try to find it ... Yes, it was Mehran Sahami who used it, possibly in one of his lectures of the course "Programming Methodology" (CS 106A) at "Stanford Engineering". ... The history of this problem goes way back into the past. In the 1950s (and possibly still inthe 1960s), such mundane loops were research topics, and Knuth and others wrote research articles about how to write such a loop in such a way that no test or statement has to be repeated. (I sometimes liked to read old magazines from those years.) Thanks for all the answers so far! I'm adding to what Stefan wrote, simply to point out how a newb like me came across this issue formally, besides actually dealing with this in my practice. In Python Programming Fundamentals 2nd ed., the author, Kent D. Lee, brings up loop and a half in ch. 3, Repetitive Tasks (p. 82). He wrote: "Whether you are writing code in Python or some other language, this Reading Records From a File pattern comes up over and over again. It is sometimes called the loop and a half problem. The idea is that you must attempt to read a line from the file before you know whether you are at the end of file or not. This can also be done if a boolean variable is introduced to help with the while loop. This boolean variable is the condition that gets you out of the while loop and the first time through it must be set to get your code to execute the while loop at least one." best, John -- https://mail.python.org/mailman/listinfo/python-list
Re: Good virtualenv and packaging tutorials for beginner?
On 4 October 2017 at 13:30, leam hall wrote: > On Wed, Oct 4, 2017 at 7:15 AM, Ben Finney > wrote: > >> Leam Hall writes: >> >> > Folks on IRC have suggested using virtualenv to test code under >> > different python versions. Sadly, I've not found a virtualenv tutorial >> > I understand. Anyone have a link to a good one? >> >> The Python Packaging Authority has a guide >> https://packaging.python.org/tutorials/installing- >> packages/#creating-virtual-environments> >> which seems good to me. >> >> The standard library documentation for the ‘venv’ library >> https://docs.python.org/3/library/venv.html> is essential. >> >> > The next step will be to figure out how to package a project; a good >> > tutorial URL would be appreciated on that, too. >> >> Follow the documentation maintained by the Python Packaging Authority >> https://packaging.python.org/>. >> >> > Ben, thanks! I'm off to print and study... Leam - if the guide is difficult to follow, feel free to ask here, or raise issues on the project tracker at https://github.com/pypa/python-packaging-user-guide/. Most of us working on packaging are way too involved in the details to know how it really feels to a newcomer to be faced with all this stuff, so if you have any comments (or even better, suggestions as to how we could improve things) that would be immensely valuable. Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: How best to initialize in unit tests?
I've not had this problem myself, but py.test has the idea of "autouse fixtures" which would work for this situation. Define your setup call in a function, declare it with the pytest.fixture decorator with autouse=True, and it'll be run before every test. The declaration goes in a conftest.py file alongside your test files. I don't know if unittest or doctest has anything similar, but I suspect not (or at least not something as simple). Whether you're comfortable with the level of magic behaviour pytest has is probably something you'll have to decide for yourself (although I believe it does discover unittest and doctest tests, so you don't need to change all your tests over). There's an example of an autouse fixture in pip's test suite, although it's massively more complex than what you're describing, so don't be put off by the size of it :-) Paul On 4 October 2017 at 14:07, Skip Montanaro wrote: > Suppose you want to test a package (in the general sense of the word, > not necessarily a Python package). You probably have specific unit > tests, maybe some doctests scattered around in doc strings. Further, > suppose that package requires you call an initialize function of some > sort. Where does that go? I know about setUp and setUpClass methods in > unittest.TestCase. Is order of execution of doctests deterministic > across modules (say, when tests are run through nosetests)? > > In my case, I didn't know what order things would be called, so I > added a call to initialize() at the start of every doctest and added a > setUpClass class method to all my TestCase subclasses. Just in case. > It worked okay because my initialize function can be called multiple > times. What about situations where it can only be called once? Do you > have to define some sort of super_initialize() function for your tests > which guarantees that your initialize function is called precisely > once? > > This all seems rather messy. I'm open to better ways to do this, but > as I've only had one cup of coffee this morning, no spark of insight > has zapped my frontal cortex as yet. > > Thx, > > Skip > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 4 October 2017 at 14:02, Robin Becker wrote: > On 04/10/2017 11:57, Rhodri James wrote: >> >> On 04/10/17 10:01, Robin Becker wrote: >>> >>> Given the prevalence of the loop and a half idea in python I wonder why >>> we don't have a "do" or "loop" statement to start loops without a test. >> >> >> See PEP 315. Guido's rejection note is here: >> https://mail.python.org/pipermail/python-ideas/2013-June/021610.html >> > seems fair enough; I suppose the cost is negligible or perhaps there's > peephole optimization for this common case. There is: >>> def f(): ... while True: ... pass ... >>> import dis >>> dis.dis(f) 2 0 SETUP_LOOP 4 (to 6) 3 >>2 JUMP_ABSOLUTE2 4 POP_BLOCK >>6 LOAD_CONST 0 (None) 8 RETURN_VALUE Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: How best to initialize in unit tests?
> I've not had this problem myself, but py.test has the idea of "autouse > fixtures" which would work for this situation. Define your setup call > in a function, declare it with the pytest.fixture decorator with > autouse=True, and it'll be run before every test. The declaration goes > in a conftest.py file alongside your test files. Thanks. I'm not a py.test user, but it turns out that nose (which I do use) appears to have something similar: https://nose.readthedocs.io/en/latest/doc_tests/test_init_plugin/init_plugin.html Thanks for the nudge in the right direction. Skip -- https://mail.python.org/mailman/listinfo/python-list
Re: How best to initialize in unit tests?
On Oct 4, 2017, at 6:07 AM, Skip Montanaro wrote: > > Suppose you want to test a package (in the general sense of the word, > not necessarily a Python package). You probably have specific unit > tests, maybe some doctests scattered around in doc strings. Further, > suppose that package requires you call an initialize function of some > sort. Where does that go? I know about setUp and setUpClass methods in > unittest.TestCase. Is order of execution of doctests deterministic > across modules (say, when tests are run through nosetests)? > > In my case, I didn't know what order things would be called, so I > added a call to initialize() at the start of every doctest and added a > setUpClass class method to all my TestCase subclasses. Just in case. > It worked okay because my initialize function can be called multiple > times. What about situations where it can only be called once? Do you > have to define some sort of super_initialize() function for your tests > which guarantees that your initialize function is called precisely > once? > > This all seems rather messy. I'm open to better ways to do this, but > as I've only had one cup of coffee this morning, no spark of insight > has zapped my frontal cortex as yet. > > Thx, > > Skip > -- > https://mail.python.org/mailman/listinfo/python-list Seems like you’re overthinking this. You should be able to unit test any part of your code in isolation. If not, you need to refactor your code. I generally don’t use test classes in pytest. Chris R. -- https://mail.python.org/mailman/listinfo/python-list
Re: Python-list Digest, Vol 169, Issue 5
On Wed, Oct 4, 2017 14:54, Chris Angelico wrote: > On Wed, Oct 4, 2017 at 2:48 PM, Steve D'Aprano > wrote: >> On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote: >> >> You know, you don't HAVE to economize on letters. It's okay to call >> your parameters "prompt" instead of "prmt". Remember, that's part of >> your API. >> >> >> Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of vwel wth >> nt nuff 4 vrybdy. >> > >And then English will turn into an abjad like Arabic. Yes, I see how >it is. Python is a sneaky plan by Islamic extremists to make us use up >all our vowels. > >(I'd end the post there, except that I've learned from past experience >that there is no statement so ridiculous that people will know for >sure that you're joking. So for the humour-impaired: THIS POST WAS A >JOKE. Okay? Good.) > > Gotta watch out for all those Islamic extremists. Somewhere along the line when I wasn't paying attention, they got us all using Arabic numerals. Roger Christman Pennsylvania State University -- https://mail.python.org/mailman/listinfo/python-list
Re: How best to initialize in unit tests?
On Thu, 5 Oct 2017 12:07 am, Skip Montanaro wrote: > Suppose you want to test a package (in the general sense of the word, > not necessarily a Python package). I'm... not sure I understand. Given that we're discussing Python, in a Python group, what are senses are relevant? > You probably have specific unit > tests, maybe some doctests scattered around in doc strings. Further, > suppose that package requires you call an initialize function of some > sort. Where does that go? Ew. Sounds like a badly designed package. Importing the package should initialise it. We write: import math x = math.sin(1) not: import math math.initialise() # I actually do want to use the module I just imported x = math.sin(1) # fails mysteriously if we forget to initialise first If you see a code unit (a package, a module, a class, or even a function) that requires a manual call to something called "initialise" or equivalent, you probably have a poorly designed code unit. (I suppose there may be -- hopefully rare -- cases where that's unavoidable, or less bad than the alternative.) But given that you have to test the code you have, not the code you wish you had... Where are the doc tests? (1) If they are in the module you are testing itself, you will probably need to call initialise() at the start of each doc string before running any tests. That's because doctest makes a shallow copy of the module's globals before running the tests, so any global state initialised in one doc string will be lost when the next is called. https://docs.python.org/2/library/doctest.html#what-s-the-execution-context (2) If the doc tests are in a separate file, the entire file will be run in a single context. You probably already start the file by importing the module you are testing: >>> import Module so just add the initalise call after that. In unit tests, you import the module, so just call initialise immediately: import Module Module.initialise() and then you don't have to worry about it in the test cases themselves. > I know about setUp and setUpClass methods in > unittest.TestCase. Is order of execution of doctests deterministic > across modules (say, when tests are run through nosetests)? I can't speak for nose, but doctest runs the tests in undocumented, and therefore arbitrary, order. > In my case, I didn't know what order things would be called, so I > added a call to initialize() at the start of every doctest and added a > setUpClass class method to all my TestCase subclasses. Just in case. > It worked okay because my initialize function can be called multiple > times. What about situations where it can only be called once? If the initialise function isn't idempotent, there may be subtle problems with doctest if making a shallow copy of the module globals isn't enough to reset all the initialised state. > Do you > have to define some sort of super_initialize() function for your tests > which guarantees that your initialize function is called precisely > once? No. > This all seems rather messy. Indeed. And now you know why importing a module/package should be sufficient to initialise it. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 04/10/2017 14:41, Ian Kelly wrote: On Wed, Oct 4, 2017 at 5:07 AM, bartc wrote: For that matter, I don't think Python has such a feature either. So that you write for example: const C = 123345 and then whenever C appears within the code, it's implemented as: LOAD_CONST (123345) Python has the simplest named constants of all: C = 12345 As long as you don't subsequently change it, it's a constant. And it's very simple because it works just like any other variable. Yes, but you don't want it to work like other variables! In other languages, a known compile-time constant is essential in certain contexts, but even in Python there are advantages to such a feature, for example in more opportunities for optimisation. Even if it's just so it can use LOAD_CONST instead of LOAD_GLOBAL (as such constants often are global). The problems with doing this in current CPython are first, that all such identifiers are dynamic: you can assign anything to them at any time. Also that some may be inside imported files, which the byte-code compiler will not know about until its too late. (There are ways around those but it would be an impossible sell when most people are not convinced that lightweight named constants are useful.) I'm trying to think of a real example where I've had to add a cache to to a function, whatever that even means (memoisation?). You've never used a dynamic programming algorithm? I had to look up what it means, but I still didn't see any practical examples. Probably I've done such coding, but I didn't give it a fancy name, and more likely just considered it data caching. > Descriptors are a bit unique to Python, I'll grant, but mostly they're > just used in the form of properties. Here's a list of languages that > support properties: > https://en.wikipedia.org/wiki/Property_(programming)#Example_syntax "A property, in some object-oriented programming languages, is a special sort of class member, intermediate in functionality between a field (or data member) and a method." But Python has some problems just in using fields. If you wanted say a data type with two fields called x and y, then AFAIK you just create any suitable class, but you don't need to specifically declare those two fields: class any(): pass p=any() p.x=10 p.y=20 But you also do this: p.z=30 and it magically acquires a third field! Or you want to modify p.x, but accidentally type: p.c=40 No error. Some would perceive all this as an advantage, but it means you can't just declare a lightweight struct or record 'Point' with exactly two fields x and y. You have to use other solutions ('namedtuples' or whatever, which probably are immutable so that don't work the same way). This is another example of neglecting the basics, but going for more advanced, perhaps more sexy features instead. Result? You can't just look at my 'any' class and see what fields it uses. You can't even just look at the static source code. You have to run the program to find out. And it might be different each time. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: Multithreaded compression/decompression library with python bindings?
On Wed, 4 Oct 2017 08:19 pm, Thomas Nyberg wrote: > Hello, > > I was wondering if anyone here knew of any python libraries with > interfaces similar to the bzip2 module which is also multithreaded in > (de)compression? Something along the lines of (say) the pbip2 program > but with bindings for python? pbip2? Never heard of it, and googling comes up with nothing relevant. Got a link? > Obviously the multi-threaded part will > need to be handled by the underlying library code and not the python > code itself. Why obviously? > > If that's too much to ask (I haven't found anything myself after all), > if anyone here happens to have any experience using similar C++ (or > possibly C) libraries I am certainly open for any recommendations. :) > > Thanks in advance! > Thomas -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Constants [was Re: newb question about @property]
On Thu, 5 Oct 2017 12:41 am, Ian Kelly wrote: > Python has the simplest named constants of all: > > C = 12345 > > As long as you don't subsequently change it, it's a constant. And it's > very simple because it works just like any other variable. I do feel that the lack of constants[1] is a (mild) weakness of Python. In small projects, if you want a constant: pi = 3.1415 and you don't want to change it, it is easy enough to remember to just not change it. Especially if you follow a naming convention like using ALLCAPS for constants. But in large projects, especially those where you cannot trust every module in the project to obey the naming convention, I can see that this lack might contribute to the perception, if not the fact, of Python being a bit too unsafe for big projects. We have read-only attributes in classes, but not read-only names in modules. That makes me a little bit sad. Back in the day when I used Pascal regularly, I recall having the compiler complain when I accidentally tried to assign a new value to a constant. But I was a much less experienced coder back then. In all honesty, I can't remember the last time I accidentally reassigned to something intended as a constant. Nevertheless, constants are a safety net I would appreciate. [1] By which I mean names which can only be bound once, but not rebound. This is not about mutability, it is about whether or not the name can be rebound. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Wed, 4 Oct 2017 11:50 pm, bartc wrote: > But this is what it says about it: > > "Please reject the PEP. More variations along these lines won't make the > language more elegant or easier to learn. They'd just save a few hasty > folks some typing while making others who have to read/maintain their > code wonder what it means." > > Exactly the same could be said of pretty much any of the advanced > features that have been added. People can say any old rubbish they like, and frequently do. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: How best to initialize in unit tests?
On Wed, Oct 4, 2017 at 9:53 AM, Steve D'Aprano wrote: > On Thu, 5 Oct 2017 12:07 am, Skip Montanaro wrote: > >> Suppose you want to test a package (in the general sense of the word, >> not necessarily a Python package). > > I'm... not sure I understand. Given that we're discussing Python, in a Python > group, what are senses are relevant? I have to test an entire application, which involves at least one package, unit tests and doctests. I suppose I should have used the word "application." My apology. > >> You probably have specific unit >> tests, maybe some doctests scattered around in doc strings. Further, >> suppose that package requires you call an initialize function of some >> sort. Where does that go? > > Ew. Sounds like a badly designed package. I will refer interested readers to the nose documentation: https://nose.readthedocs.io/en/latest/doc_tests/test_init_plugin/init_plugin.html where the author writes, "Many applications, especially those using web frameworks like Pylons or Django, can’t be tested without first being configured or otherwise initialized." My system, while not a web framework, does still require the caller of the client libraries (both Python and R, as it happens) to tell the system what server to contact. In the case of my test scenario, that is a Flask server on the local host with a SQLite database behind it, as opposed to a Flask server somewhere out on the network. (I actually attempt to test both client and server at the same time.) Skip -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Wed, 4 Oct 2017 09:35 pm, Stefan Ram wrote: > Steve D'Aprano writes: >>For-each loops are MUCH easier to understand, and should be taught first. > > I prefer a bottom-up approach. I prefer an effective approach that starts with the simplest concepts first, not the most complex. > For loops are based on iterators. That's an implementation detail that is not necessary to understand in order to use for-loops. Python had for-loops for many years before it gained iterators, and even today in Python 3 you can iterate over non-iterators. py> class X: # not an iterator! ... def __getitem__(self, i): ... if i < 3: ... return str(i)*2 ... raise IndexError ... py> for obj in X(): ... print(obj) ... 00 11 22 X instances have no __iter__ or __next__ methods and are not iterators. > So, "bottom-up" in this case means: iterators should be > taught before for-loops. Why? As an educator, you should care about teaching topics in whatever order makes learning easier, not according to some theoretically pure order. Do you really think that it is hard to teach a simple "do this three times" example: for i in range(3): print("do this") example until you've covered iterators, exceptions, try...except StopIteration, and while loops? > But iterators are too abstract to be taught very early. I agree with that. So don't teach them. You don't need to care about the implementation of iteration in order to teach iteration. Most beginners probably won't write their own iterators for many years. > But I will teach iterators and for loops not much later than > while-loop. > > Maybe this way: Use a while-loop and try-catch to get values > from an iterator until exhausted, and then introduce the > for-loop as an abbreviation for that. Ah, I get it now... this is a cunning plan to make Python seem like a confusing, difficult language, so your students will learn Javascript instead. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 4 October 2017 at 16:03, bartc wrote: > No error. Some would perceive all this as an advantage, but it means you > can't just declare a lightweight struct or record 'Point' with exactly two > fields x and y. You have to use other solutions ('namedtuples' or whatever, > which probably are immutable so that don't work the same way). > > This is another example of neglecting the basics, but going for more > advanced, perhaps more sexy features instead. It's another example of a consistent design philosophy (highly dynamic classes) that you might not like - possibly even enough that Python isn't the best language for you. It's not an advantage or a disadvantage, just an approach. Many people like it, you may not. Specifically, yes you can't "just declare a lightweight struct or record with exactly two fields". Python doesn't enforce things like that, but leaves it to the programmer(s) to agree on (and follow) conventions in the code. This means that certain classes of error (e.g. mistyping an attribute name) can go unnoticed until later than in other languages, but conversely it means that things like monkeypatching of 3rd party code are possible. The popularity of Python is evidence that the flexibility this allows is useful to many people. Expecting Python to have the same design as other languages does a disservice to both Python and those other languages. There are trade-offs in these things, and Python's choices won't be the best in all circumstances. All we can really say is that they have turned out to be pretty useful and popular in many situations... Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Multithreaded compression/decompression library with python bindings?
On 4 October 2017 at 16:08, Steve D'Aprano wrote: > On Wed, 4 Oct 2017 08:19 pm, Thomas Nyberg wrote: > >> Hello, >> >> I was wondering if anyone here knew of any python libraries with >> interfaces similar to the bzip2 module which is also multithreaded in >> (de)compression? Something along the lines of (say) the pbip2 program >> but with bindings for python? > > pbip2? Never heard of it, and googling comes up with nothing relevant. > > Got a link? It's a typo. pbzip2 - a search found http://compression.ca/pbzip2/ but I don't know anything about it. Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, 5 Oct 2017 12:44 am, john polo wrote: > I'm adding to what Stefan wrote, simply to point out how a newb like me > came across this issue formally, besides actually dealing with this in > my practice. > > In Python Programming Fundamentals 2nd ed., the author, Kent D. Lee, > brings up loop and a half in ch. 3, Repetitive Tasks (p. 82). He wrote: > > "Whether you are writing code in Python or some other language, this Reading > Records From a File pattern comes up over and over again. No it doesn't. Who is this Kent Lee, and is he actually fluent in Python? Because the following problem doesn't seem like it: > It is sometimes called > the loop and a half problem. The idea is that you must attempt to read a > line from the > file before you know whether you are at the end of file or not. Utter nonsense. There's no "must" here. I'll accept the remote possibility that maybe one time in a million you have to do what he says, but the other 99 times you just read from the file in a for-loop: for line in file: process(line) > This can also be done > if a boolean variable is introduced to help with the while loop. This > boolean variable > is the condition that gets you out of the while loop and the first time > through it must > be set to get your code to execute the while loop at least one." I've been programming in Python for twenty years, and I don't think I have ever once read from a file using a while loop. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Wednesday, October 4, 2017 at 9:34:09 AM UTC+1, alister wrote: > On Wed, 04 Oct 2017 20:16:29 +1300, Gregory Ewing wrote: > > > Steve D'Aprano wrote: > >> On Wed, 4 Oct 2017 01:40 pm, Chris Angelico wrote: > >> > >>>You know, you don't HAVE to economize on letters. It's okay to call > >>>your parameters "prompt" instead of "prmt". Remember, that's part of > >>>your API. > >> > >> Whn u wste vwels lik that, dn't b srprsd whn u run ot n hav shrtg of > >> vwel wth nt nuff 4 vrybdy. > > > > I blame the Dutch. They're clearly using more than their fair share of > > the world's vowels. > > but that is compensated for by the welsh which don't seem to use any > Careful lad, that's my late mum's nation you're talking about. Of course I take it that you know the definition of a Welshman? It's an Irishman who couldn't swim. That is also a joke. > -- > Never trust an operating system. -- Kindest regards. Mark Lawrence. -- https://mail.python.org/mailman/listinfo/python-list
Re: How best to initialize in unit tests?
On Thu, 5 Oct 2017 02:23 am, Skip Montanaro wrote: [...] >> Ew. Sounds like a badly designed package. > > I will refer interested readers to the nose documentation: > > https://nose.readthedocs.io/en/latest/doc_tests/test_init_plugin/init_plugin.html > > where the author writes, "Many applications, especially those using > web frameworks like Pylons or Django, can’t be tested without first > being configured or otherwise initialized." I haven't used Pylons or Django, but frameworks are a different story to libraries, which is what I understood you to be discussing. In any case, I would expect any decent framework to automatically read from a configuration file, so that importing the framework automatically initialises it as well (provided it can find a configuration file, and if not, it should noisily complain unless explicitly silenced). > My system, while not a web framework, does still require the caller of > the client libraries (both Python and R, as it happens) to tell the > system what server to contact. And you do that globally? What if you want to talk to two servers? Anyway, whatever your reasons (good, bad or indifferent) for designing the system the way it is, you have to deal with it as it exists, not the way I would prefer it. Did you read my suggestion to just put the initialise call immediately after the import? import system system.initialise(server='foo') You can certainly do that with unittest; doing so in doctest requires a bit more nuance and care, but is still possible. If this doesn't solve your problem, I'm afraid I don't understand your problem. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 4 October 2017 at 16:35, Steve D'Aprano wrote: > I've been programming in Python for twenty years, and I don't think I have > ever once read from a file using a while loop. Twenty years isn't long enough :-) The pattern the OP is talking about was common in "Jackson Structured Programming" from back in the 1980s. At the time (from what I recall, it *was* 35+ years ago after all!), it was a reasonably elegant way of handling reading of data that's structured as header subheader body body subheader body body while maintaining per-section style subtotals (I believe this is referred to as a "break report" in certain business contexts). Nowadays, I wouldn't code such a report like that. Like you say, I'd use a custom iterator or something similar. Although getting the details and edge cases right of such a pattern is still a surprisingly tricky problem. So I guess it's a good "learning to program" exercise, but the "while loop with break part way through" pattern for solving it is not really what I'd want to see taught to beginning Python programmers... Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 04/10/17 16:33, Paul Moore wrote: On 4 October 2017 at 16:03, bartc wrote: No error. Some would perceive all this as an advantage, but it means you can't just declare a lightweight struct or record 'Point' with exactly two fields x and y. You have to use other solutions ('namedtuples' or whatever, which probably are immutable so that don't work the same way). This is another example of neglecting the basics, but going for more advanced, perhaps more sexy features instead. It's another example of a consistent design philosophy (highly dynamic classes) that you might not like - possibly even enough that Python isn't the best language for you. It's not an advantage or a disadvantage, just an approach. Many people like it, you may not. Specifically, yes you can't "just declare a lightweight struct or record with exactly two fields". Actually you can: >>> class Point: ... __slots__ = ("x", "y") ... def __init__(self, x, y): ... self.x = x ... self.y = y ... def __str__(self): ... return "({0},{1})".format(self.x, self.y) ... >>> p = Point(3,4) >>> print(p) (3,4) >>> print(p.x) 3 >>> p.x = 7 >>> print(p) (7,4) >>> p.z = 2 Traceback (most recent call last): File "", line 1, in AttributeError: 'Point' object has no attribute 'z' I pretty much never bother to do this because (bart to the contrary) it isn't useful if you're thinking in Pythonic terms, but it can be done pretty easily. -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list
Re: Constants [was Re: newb question about @property]
On Wed, Oct 4, 2017 at 9:08 AM, Steve D'Aprano wrote: > But in large projects, especially those where you cannot trust every module in > the project to obey the naming convention, I can see that this lack might > contribute to the perception, if not the fact, of Python being a bit too > unsafe for big projects. We have read-only attributes in classes, but not > read-only names in modules. That makes me a little bit sad. Which brings up the point that you can hack it in if you want it. $ cat demo.py import sys class DemoModule: @property def foo(self): return 42 sys.modules['demo'] = DemoModule() $ python3 -c 'import demo; print(demo.foo); demo.foo = 14' 42 Traceback (most recent call last): File "", line 1, in AttributeError: can't set attribute -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 4 October 2017 at 17:02, Rhodri James wrote: > Actually you can: > class Point: > ... __slots__ = ("x", "y") > ... def __init__(self, x, y): > ... self.x = x > ... self.y = y > ... def __str__(self): > ... return "({0},{1})".format(self.x, self.y) > ... p = Point(3,4) print(p) > (3,4) print(p.x) > 3 p.x = 7 print(p) > (7,4) p.z = 2 > Traceback (most recent call last): > File "", line 1, in > AttributeError: 'Point' object has no attribute 'z' > > I pretty much never bother to do this because (bart to the contrary) it > isn't useful if you're thinking in Pythonic terms, but it can be done pretty > easily. Good point. I'd forgotten that - like you say, it's not common to want to constrain things to this level in idiomatic Python code. Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: Constants [was Re: newb question about @property]
On 4 October 2017 at 17:15, Ian Kelly wrote: > On Wed, Oct 4, 2017 at 9:08 AM, Steve D'Aprano > wrote: >> But in large projects, especially those where you cannot trust every module >> in >> the project to obey the naming convention, I can see that this lack might >> contribute to the perception, if not the fact, of Python being a bit too >> unsafe for big projects. We have read-only attributes in classes, but not >> read-only names in modules. That makes me a little bit sad. > > Which brings up the point that you can hack it in if you want it. > > $ cat demo.py > import sys > > class DemoModule: > @property > def foo(self): > return 42 > > sys.modules['demo'] = DemoModule() > > $ python3 -c 'import demo; print(demo.foo); demo.foo = 14' > 42 > Traceback (most recent call last): > File "", line 1, in > AttributeError: can't set attribute I wonder - would the people who want "real constants" find the following confusing: >>> from demo import foo >>> foo = 14 >>> foo 14 It's fundamental to the way the import function works, and how names in Python behave, but I can see someone with a background in other languages with "real" constants thinking "but foo is a constant, and importing it stops it being a constant!" Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 2017-10-04, Steve D'Aprano wrote: >> It is sometimes called the loop and a half problem. The idea is >> that you must attempt to read a line from the file before you know >> whether you are at the end of file or not. > > Utter nonsense. There's no "must" here. I'll accept the remote > possibility that maybe one time in a million you have to do what he > says, but the other 99 times you just read from the file in a > for-loop: > > for line in file: > process(line) > >> This can also be done if a boolean variable is introduced to help >> with the while loop. This boolean variable is the condition that >> gets you out of the while loop and the first time through it must be >> set to get your code to execute the while loop at least one." > > I've been programming in Python for twenty years, and I don't think I have > ever once read from a file using a while loop. You're right, that construct isn't used for reading from files in Python. It _is_ commonly used for reading from things like sockets: mysock.connect(...) while True: data = mysock.recv() if not data: break do_something_with(data) mysock.close() -- Grant Edwards grant.b.edwardsYow! Now I am depressed ... at gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Easier way to do this?
Looking for advice for what looks to me like clumsy code. I have a large csv (effectively garbage) dump. I have to pull out sales information per employee and count them by price range. I've got my code working, but I'm thinking there must be a more refined way of doing this. ---snippet of what I have--- EMP1 = [0,0] EMP2 = [0,0] EMP3 = [0,0] for line in (inputfile): content = line.split(",") if content[18] == "EMP1": if float(content[24]) < 99.75: EMP1[0] += 1 elif float(content[24]) > 99.74: EMP1[1] += 1 if content[18] == "EMP2": if float(content[24]) < 99.75: EMP2[0] += 1 elif float(content[24]) > 99.74: EMP2[1] += 1 if content[18] == "EMP3": if float(content[24]) < 99.75: EMP3[0] += 1 elif float(content[24]) > 99.74: EMP3[1] += 1 and repeat if statements for the rest of 25+ employees. I can make a list of the employees, but I'd prefer to pull them from the csv, as our turnover is rather high (however this is not important). I'm thinking another "for employee in content[18]" should be there, but when I tried, my numbers were incorrect. Any help / advice is appreciated, Matt -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On Wednesday, October 4, 2017 at 8:29:26 PM UTC+1, 20/20 Lab wrote: > Looking for advice for what looks to me like clumsy code. > > I have a large csv (effectively garbage) dump. I have to pull out sales > information per employee and count them by price range. I've got my code > working, but I'm thinking there must be a more refined way of doing this. > > ---snippet of what I have--- > > EMP1 = [0,0] > EMP2 = [0,0] > EMP3 = [0,0] > > for line in (inputfile): > content = line.split(",") > if content[18] == "EMP1": > if float(content[24]) < 99.75: > EMP1[0] += 1 > elif float(content[24]) > 99.74: > EMP1[1] += 1 > if content[18] == "EMP2": > if float(content[24]) < 99.75: > EMP2[0] += 1 > elif float(content[24]) > 99.74: > EMP2[1] += 1 > if content[18] == "EMP3": > if float(content[24]) < 99.75: > EMP3[0] += 1 > elif float(content[24]) > 99.74: > EMP3[1] += 1 > > and repeat if statements for the rest of 25+ employees. I can make a > list of the employees, but I'd prefer to pull them from the csv, as our > turnover is rather high (however this is not important). I'm thinking > another "for employee in content[18]" should be there, but when I tried, > my numbers were incorrect. > > Any help / advice is appreciated, > > Matt Use the csv module https://docs.python.org/3/library/csv.html to read the file with a Counter https://docs.python.org/3/library/collections.html#collections.Counter. I'm sorry but I'm too knackered to try writing the code for you :-( -- Kindest regards. Mark Lawrence. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 04/10/2017 14:44, john polo wrote: In Python Programming Fundamentals 2nd ed., the author, Kent D. Lee, brings up loop and a half in ch. 3, Repetitive Tasks (p. 82). He wrote: "Whether you are writing code in Python or some other language, this Reading Records From a File pattern comes up over and over again. It is sometimes called the loop and a half problem. The idea is that you must attempt to read a line from the file before you know whether you are at the end of file or not. This can also be done if a boolean variable is introduced to help with the while loop. This boolean variable is the condition that gets you out of the while loop and the first time through it must be set to get your code to execute the while loop at least one." while not eof(f): # read next bit of the file But you need an eof(f) function that tells you if you are at the end of the file. Some people might be concerned that the status could change between checking for eof, and doing a subsequent read (but I've never had such problems). This is suitable for reading perhaps binary files in uneven chunks, which are dependent on the last bit read, so iterating over the file by line or by byte won't work. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
I teach a course in programming to students who have no plans to be programmers, scientists, or engineers.And I deliberately lied today about the for loop. In my lecture slide, I said that the for loop could only be used if you had a collection of values (e.g. list, tuple, dict, string, or range) where all the data was in hand, and should only be used when truly planning to visit the entire collection. The slide essentially claimed, you could not use the for loop to input a series of values from the keyboard, until seeing a blank line or zero. or to search a list until you found the first even value, and stopping when you get there. If you want to stop repeating for an arbitrary reason, you must use a while loop. Deliberate lie. Verbally I said it was actually a fib, and that there was a way to do these cleanly with a for loop, but it's a method that I postpone until halfway through the second course for students in the major, not the sort of thing I would teach to this particular audience this early. But yes, we can use yield, and iter(), and itertools to do both of these examples very clearly with a for loop (and without an explicit break statement), but I'd rather keep my course content small and simple. Roger Christman Pennsylvania State University > > -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On 04/10/17 18:42, 20/20 Lab wrote: > Looking for advice for what looks to me like clumsy code. > > I have a large csv (effectively garbage) dump. I have to pull out > sales information per employee and count them by price range. I've got > my code working, but I'm thinking there must be a more refined way of > doing this. > > ---snippet of what I have--- > > EMP1 = [0,0] > EMP2 = [0,0] > EMP3 = [0,0] > > for line in (inputfile): > content = line.split(",") First of all, you don't want to make a habit of parsing common file formats by hand. CSV is simple enough, but there are some edge cases that might come up when you're least expecting them. The stdlib has a csv module: https://docs.python.org/3/library/csv.html > if content[18] == "EMP1": > if float(content[24]) < 99.75: > EMP1[0] += 1 > elif float(content[24]) > 99.74: > EMP1[1] += 1 > if content[18] == "EMP2": > if float(content[24]) < 99.75: > EMP2[0] += 1 > elif float(content[24]) > 99.74: > EMP2[1] += 1 > if content[18] == "EMP3": > if float(content[24]) < 99.75: > EMP3[0] += 1 > elif float(content[24]) > 99.74: > EMP3[1] += 1 This just cries out for something like pandas (everyone's favourite data analysis library) Be warned, pandas is part of the scientific python stack, which is immensely powerful and popular, but it does have a distinctive style that may appear cryptic if you're used to the way the rest of the world writes Python. Your code could end up looking something like this: import pandas as pd employee_data = pd.read_csv(csv_filename) employee_data['is_great'] = employee_data['cryptic_number'] > 99.74 employee_data['is_fantastic'] = employee_data['cryptic_number'] < 99.75 by_employee = employee_data.groupby('employee').sum() greatness_dict = dict(by_employee['is_great']) fantasy_dict = dict(by_employee['is_fantastic']) > > and repeat if statements for the rest of 25+ employees. I can make a > list of the employees, but I'd prefer to pull them from the csv, as > our turnover is rather high (however this is not important). I'm > thinking another "for employee in content[18]" should be there, but > when I tried, my numbers were incorrect. > > Any help / advice is appreciated, > > Matt > -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Am 04.10.17 um 14:34 schrieb Ben Bacarisse: r...@zedat.fu-berlin.de (Stefan Ram) writes: Steve D'Aprano writes: For-each loops are MUCH easier to understand, and should be taught first. I prefer a bottom-up approach. For loops are based on iterators. So, "bottom-up" in this case means: iterators should be taught before for-loops. But iterators are too abstract to be taught very early. I think this may be a problem with your style. From your other postings, I think you value precision and exactness over broad understanding, and maybe you teach like that. To understand Stefan's way of teaching, take a look at his other courses, for example the C++ course: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/c++-kurs He defends the opinion that you learn a programming language best by studying syntax diagrams. He even writes in his FAQ about the language courses: http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/faq_programmieren "Neuere Forschungen haben gezeigt, daß es erfolgreicher ist, formale Systeme (wie Programmiersprachen oder Mathematik) zu unterrichten, wenn dabei kein künstlicher „Praxisbezug“ durch “real-world examples” (Beispiele aus dem „wahren Leben“) hergestellt wird!" which means "Recent research results show that it is more successful, to teach formal systems (like programming language or maths), if no artificial practical use-case is demonstrated by "real-world examples" with a reference: "They said students who were taught abstract math concepts fared better in experiments than those taught with real-world examples, such as story problems. Adding extraneous details makes it hard for students to extract the basic mathematical concepts and apply them to new problems, they said. "We're really making it difficult for students because we are distracting them from the underlying math," said Jennifer Kaminski, a research scientist at Ohio State University, whose study appears in the journal Science.Reuters, 25. April 2008" Christian -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On Wed, Oct 4, 2017 14:03 PM, bartc wrote > "A property, in some object-oriented programming languages, is a special >sort of class member, intermediate in functionality between a field (or >data member) and a method." > >But Python has some problems just in using fields. If you wanted say a >data type with two fields called x and y, then AFAIK you just create any >suitable class, but you don't need to specifically declare those two fields: > > class any(): > pass > > p=any() > p.x=10 > p.y=20 > >But you also do this: > > p.z=30 > >and it magically acquires a third field! Or you want to modify p.x, but >accidentally type: > > p.c=40 > >No error. Some would perceive all this as an advantage, but it means you >can't just declare a lightweight struct or record 'Point' with exactly >two fields x and y. You have to use other solutions ('namedtuples' or >whatever, which probably are immutable so that don't work the same way). > >This is another example of neglecting the basics, but going for more >advanced, perhaps more sexy features instead. > >Result? You can't just look at my 'any' class and see what fields it >uses. You can't even just look at the static source code. You have to >run the program to find out. And it might be different each time. > > I think you might be missing a small feature buried in the language: class any():.. __slots__ = ["x","y"] >>> p = any() >>> p.x = 10 >>> p.y = 20 >>> p.z = 30 Traceback (most recent call last): File "", line 1, in p.z = 30 AttributeError: 'any' object has no attribute 'z' >>> p.c = 40 Traceback (most recent call last): File "", line 1, in p.c = 40 AttributeError: 'any' object has no attribute 'c' >>> p.__slots__ ['x', 'y'] So, you can prevent new fields from being added without forcing yourself into an immutable named tuple. And if you really need to know what is in there, it tells you! Oh, and as regards to it being different each time: >>> p.__slots__ = ['x','y','z'] Traceback (most recent call last): File "", line 1, in p.__slots__ = ['x','y','z'] AttributeError: 'any' object attribute '__slots__' is read-only Oh, and here's a little thing from the Python 3.6.2 Glossary: __slots__ A declaration inside a class that saves memory by pre-declaring space for instance attributes and eliminating instance dictionaries. Though popular, the technique is somewhat tricky to get right and is best reserved for rare cases where there are large numbers of instances in a memory-critical application. Roger Christman Pennsylvania State University -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On 10/04/2017 10:11 PM, Thomas Jollans wrote: Be warned, pandas is part of the scientific python stack, which is immensely powerful and popular, but it does have a distinctive style that may appear cryptic if you're used to the way the rest of the world writes Python. Can you elaborate on this one? As a scientist, I am curious ;-) -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
20/20 Lab writes: > Looking for advice for what looks to me like clumsy code. > > I have a large csv (effectively garbage) dump. I have to pull out > sales information per employee and count them by price range. I've got > my code working, but I'm thinking there must be a more refined way of > doing this. I second the suggestion to use the CSV module. It's very simple to use. > ---snippet of what I have--- > > EMP1 = [0,0] > EMP2 = [0,0] > EMP3 = [0,0] > > for line in (inputfile): > content = line.split(",") > if content[18] == "EMP1": > if float(content[24]) < 99.75: > EMP1[0] += 1 > elif float(content[24]) > 99.74: > EMP1[1] += 1 > if content[18] == "EMP2": > if float(content[24]) < 99.75: > EMP2[0] += 1 > elif float(content[24]) > 99.74: > EMP2[1] += 1 > if content[18] == "EMP3": > if float(content[24]) < 99.75: > EMP3[0] += 1 > elif float(content[24]) > 99.74: > EMP3[1] += 1 > > and repeat if statements for the rest of 25+ employees. Eek! When you have named objects selected using a string that is the object's name you know you want a dict. You'd have a single dict for all employees, keyed by the tag in field 18 of the file. Does that help? I'm deliberately not saying more because this looks like a learning exercise and you probably want to do most of it yourself. -- Ben. -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On 10/04/2017 12:47 PM, breamore...@gmail.com wrote: On Wednesday, October 4, 2017 at 8:29:26 PM UTC+1, 20/20 Lab wrote: Any help / advice is appreciated, Matt Use the csv module https://docs.python.org/3/library/csv.html to read the file with a Counter https://docs.python.org/3/library/collections.html#collections.Counter. I'm sorry but I'm too knackered to try writing the code for you :-( -- Kindest regards. Mark Lawrence. This looks to be exactly what I want. I'll get to reading. Thank you very much. Matt -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On 10/04/2017 01:55 PM, Ben Bacarisse wrote: 20/20 Lab writes: Looking for advice for what looks to me like clumsy code. I have a large csv (effectively garbage) dump. I have to pull out sales information per employee and count them by price range. I've got my code working, but I'm thinking there must be a more refined way of doing this. I second the suggestion to use the CSV module. It's very simple to use. ---snippet of what I have--- EMP1 = [0,0] EMP2 = [0,0] EMP3 = [0,0] for line in (inputfile): content = line.split(",") if content[18] == "EMP1": if float(content[24]) < 99.75: EMP1[0] += 1 elif float(content[24]) > 99.74: EMP1[1] += 1 if content[18] == "EMP2": if float(content[24]) < 99.75: EMP2[0] += 1 elif float(content[24]) > 99.74: EMP2[1] += 1 if content[18] == "EMP3": if float(content[24]) < 99.75: EMP3[0] += 1 elif float(content[24]) > 99.74: EMP3[1] += 1 and repeat if statements for the rest of 25+ employees. Eek! When you have named objects selected using a string that is the object's name you know you want a dict. You'd have a single dict for all employees, keyed by the tag in field 18 of the file. Does that help? I'm deliberately not saying more because this looks like a learning exercise and you probably want to do most of it yourself. Looks like I'll be going with the CSV module. Should trim it up nicely. It's not quite a 'learning exercise', but I learn on my own if I treat it as such. This is just to cut down a few hours of time for me every week filtering the file by hand for the office manager. Thanks for the pointers, Matt -- https://mail.python.org/mailman/listinfo/python-list
Re: Python community "welcoming" feedback
Leam Hall wrote: A while back I pointed out some challenges for the Python community's intake of new coders. Mostly focusing on IRC and the Python e-mail list. What is the Python e-mail list? Thanks, Bill Several people have stepped up their "welcome" game and I've been very impressed with the way things are going. Great job! Leam -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On 04/10/17 22:47, Fabien wrote: > On 10/04/2017 10:11 PM, Thomas Jollans wrote: >> Be warned, pandas is part of the scientific python stack, which is >> immensely powerful and popular, but it does have a distinctive style >> that may appear cryptic if you're used to the way the rest of the world >> writes Python. > > Can you elaborate on this one? As a scientist, I am curious ;-) Sure. Python is GREAT at iterating. Generators are everywhere. Everyone loves for loops. List comprehensions and generator expressions are star features. filter and map are builtins. reduce used be a builtin, even though almost nobody really understood what it did. In [1]: import numpy as np In the world of numpy (and the greater scientific stack), you don't iterate. You don't write for loops. You have a million floats in memory that you want to do math on - you don't want to wait for ten million calls to __class__.__dict__['__getattr__']('__add__').__call__() or whatever to run. In numpy land, numpy writes your loops for you. In FORTRAN. (well ... probably C) As I see it the main cultural difference between "traditional" Python and numpy-Python is that numpy implicitly iterates over arrays all the time. Python never implicitly iterates. Python is not MATLAB. In [2]: np.array([1, 2, 3]) + np.array([-3, -2, -1]) Out[2]: array([-2, 0, 2]) In [3]: [1, 2, 3] + [-3, -2, -1] Out[3]: [1, 2, 3, -3, -2, -1] In numpy, operators don't mean what you think they mean. In [4]: a = (np.random.rand(30) * 10).astype(np.int64) In [5]: a Out[5]: array([6, 1, 6, 9, 1, 0, 3, 5, 8, 5, 2, 6, 1, 1, 2, 2, 4, 2, 4, 2, 5, 3, 7, 8, 2, 5, 8, 1, 0, 8]) In [6]: a > 5 Out[6]: array([ True, False, True, True, False, False, False, False, True, False, False, True, False, False, False, False, False, False, False, False, False, False, True, True, False, False, True, False, False, True], dtype=bool) In [7]: list(a) > 5 --- TypeError Traceback (most recent call last) in () > 1 list(a) > 5 TypeError: unorderable types: list() > int() Suddenly, you can even compare sequences and scalars! And > no longer gives you a bool! Madness! Now, none of this, so far, has been ALL THAT cryptic as far as I can tell. It's when you do more complicated things, and start combining different parts of the numpy toolbox, that it becomes clear that numpy-Python is kind of a different language. In [8]: a[(np.sqrt(a).astype(int)**2 == a) & (a < 5)] Out[8]: array([1, 1, 0, 1, 1, 4, 4, 1, 0]) In [9]: import math In [10]: [i for i in a if int(math.sqrt(i))**2 == i and i < 5] Out[10]: [1, 1, 0, 1, 1, 4, 4, 1, 0] Look at my pandas example from my previous post. If you're a Python-using scientist, even if you're not very familiar with pandas, you'll probably be able to see more or less how it works. I imagine that there are plenty of experienced Pythonistas on this list who never need to deal with large amounts of numeric data that are completely nonplussed by it, and I wouldn't blame them. The style and the idiosyncrasies of array-heavy scientific Python and stream or iterator-heavy scripting and networking Python are just sometimes rather different. Cheers Thomas -- https://mail.python.org/mailman/listinfo/python-list
Re: Python community "welcoming" feedback
On 04/10/17 23:39, Bill wrote: > Leam Hall wrote: >> A while back I pointed out some challenges for the Python community's >> intake of new coders. Mostly focusing on IRC and the Python e-mail list. > > What is the Python e-mail list? You're on it right now! There is a two-way mirror between comp.lang.python and python-list@python.org https://mail.python.org/mailman/listinfo/python-list There are a bunch of other Python mailing lists as well (https://mail.python.org/mailman/listinfo) - the most important ones, apart from regional and language-specific ones, are probably tutor, python-dev and python-ideas. -- Thomas > > Thanks, > Bill > > >> >> Several people have stepped up their "welcome" game and I've been >> very impressed with the way things are going. >> >> Great job! >> >> Leam > -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 04/10/2017 17:02, Rhodri James wrote: On 04/10/17 16:33, Paul Moore wrote: It's not an advantage or a disadvantage, just an approach. Many people like it, you may not. Specifically, yes you can't "just declare a lightweight struct or record with exactly two fields". Actually you can: >>> class Point: ... __slots__ = ("x", "y") ... def __init__(self, x, y): ... self.x = x ... self.y = y ... def __str__(self): ... return "({0},{1})".format(self.x, self.y) ... >>> p = Point(3,4) >>> print(p) (3,4) >>> print(p.x) 3 >>> p.x = 7 >>> print(p) (7,4) >>> p.z = 2 Traceback (most recent call last): File "", line 1, in AttributeError: 'Point' object has no attribute 'z' I pretty much never bother to do this because (bart to the contrary) But it's something you'd have to explicitly do (unless perhaps you make use of those decorators, which AFAICS can do magic). And when I tried, it didn't really work in Python 2 (extra attributes could still be created, and .__slots__ wasn't readonly); only Py3. it isn't useful if you're thinking in Pythonic terms, I clearly don't. When I do this in my non-Python language it would be just: record any = (var x,y) p := any(10,20) println p # (10,20) println p.y, p.x # 20 10 println p.len # 2 println p[2] # 20 println p = any(10,20) # 1 (compares fields) No __slots__, __init__ or __str__ need to be defined; it just works. If I needed a version suitable for foreign function interfacing, a little different: type point = struct (real64 x,y) p := point(10,20) println p # (10.,20.) println p.bytes# 16 It's not Pythonic, but it is pretty handy (I know Python can also do structs like this but it appeared to be quite a slog last time I looked.) I guess my kind of coding is somewhat less esoteric than the kind of thing I typically see in Python here. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 05/10/17 00:42, Stefan Ram wrote: > Steve D'Aprano writes: >>> So, "bottom-up" in this case means: iterators should be >>> taught before for-loops. >> Why? > The syntax for is (from memory): > > for in : > > . As an example, I might show: > > for i in range( 3 ): ... > > . This raises the question: > > "What is the value of »range( 3 )«?". > > "Bottom up" means that the simple and constituent parts > are taught before the complex and compound parts. I.e., > »range( 3 )« is explained before »for i in range( 3 ):«. If you apply that kind of thinking consistently with Python you'll get caught in an infinite loop trying to explain attribute access before even teaching print(). To call print, you need to access print.__call_. To access that attribute, you need to check print.__dict__ (and some other things), which is itself an attribute of print. To access that, (...) >>> print.__class__.__dict__['__call__'].__call__(print, "hello world") hello world >>> Of course that's not actually what happens when you call the builtin print(). You can delve into the constituent parts of your favourite Python implementation or the language reference to prove it, but that's no longer simple. "simple and constituent parts" is, quite often, not well-defined. Iterators are pretty simple, and, while they have constituent parts, pretty fundamental to Python, at least in spirit. -- Thomas > -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 10/4/2017 1:24 PM, Grant Edwards wrote: On 2017-10-04, Steve D'Aprano wrote: It is sometimes called the loop and a half problem. The idea is that you must attempt to read a line from the file before you know whether you are at the end of file or not. Utter nonsense. There's no "must" here. I'll accept the remote possibility that maybe one time in a million you have to do what he says, but the other 99 times you just read from the file in a for-loop: for line in file: process(line) This can also be done if a boolean variable is introduced to help with the while loop. This boolean variable is the condition that gets you out of the while loop and the first time through it must be set to get your code to execute the while loop at least one." I've been programming in Python for twenty years, and I don't think I have ever once read from a file using a while loop. You're right, that construct isn't used for reading from files in Python. It _is_ commonly used for reading from things like socket mysock.connect(...) while True: data = mysock.recv() if not data: break do_something_with(data) mysock.close() I contend that it would be better in this case also to separate data access from data processing. def sockreader(socket, size): while True: data = socket.recv(size) if data: yield data else: break for data in socketreader(mysock, ): do_something_with(data) Perhaps the socket module needs an update to make the boilerplate generator function a method, such as 'iterread'. The separation lets one write source-agnostic processing functions. def do_something(source): for data in source: One can now 'do_something' with data from pipe, file, socket, or list. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
I'm assuming from your posts that you are not a student. If that is the case, look at my solution below. > On Oct 4, 2017, at 9:42 AM, 20/20 Lab wrote: > > Looking for advice for what looks to me like clumsy code. > > I have a large csv (effectively garbage) dump. I have to pull out sales > information per employee and count them by price range. I've got my code > working, but I'm thinking there must be a more refined way of doing this. > > ---snippet of what I have--- > > EMP1 = [0,0] > EMP2 = [0,0] > EMP3 = [0,0] > > for line in (inputfile): > content = line.split(",") > if content[18] == "EMP1": > if float(content[24]) < 99.75: > EMP1[0] += 1 > elif float(content[24]) > 99.74: > EMP1[1] += 1 > if content[18] == "EMP2": > if float(content[24]) < 99.75: > EMP2[0] += 1 > elif float(content[24]) > 99.74: > EMP2[1] += 1 > if content[18] == "EMP3": > if float(content[24]) < 99.75: > EMP3[0] += 1 > elif float(content[24]) > 99.74: > EMP3[1] += 1 > > and repeat if statements for the rest of 25+ employees. I can make a list of > the employees, but I'd prefer to pull them from the csv, as our turnover is > rather high (however this is not important). I'm thinking another "for > employee in content[18]" should be there, but when I tried, my numbers were > incorrect. > > Any help / advice is appreciated, > > Matt > You could certainly use the csv module if you want, but this builds on your start of dealing with the data line by line. Completely untested, but this approach works by building a dictionary on the fly from your data. Each key is an employee name. The data associated with each key is a two item list of counts. # Constants NAME_INDEX = 18 SALES_INDEX = 24 THRESHHOLD = 99.75 salesCountDict = {} # start with an empty dict for line in (inputfile): content = line.split(",") # split the line into a list name = content[NAME_INDEX] # extract the name from the content list # If we have not seen this employee name before, add it to the dictionary # like key value pair: '': [0, 0] if not(name in employeeDataDict): salesCountDict[name] = [0, 0] price = float(content[SALES_INDEX]) # extract the price # If the price is under some threshhold, increment one value in the associated sales list # otherwise increment the other if price < THRESHHOLD: salesCountDict[name][0] += 1 else: salesCountDict[name][1] += 1 # Now you should have a dictionary. Do what you want with it. For example: for name in salesCountDict: salesList = salesCountDict[name] print(name, salesList)# Assuming Python 3 -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, 5 Oct 2017 02:56 am, Paul Moore wrote: > On 4 October 2017 at 16:35, Steve D'Aprano > wrote: >> I've been programming in Python for twenty years, and I don't think I have >> ever once read from a file using a while loop. > > Twenty years isn't long enough :-) The pattern the OP is talking about > was common in "Jackson Structured Programming" from back in the 1980s. In context, I was replying to a quoted author who claims this pattern is universal in Python code. I don't doubt that pattern exists *at all*, only that it is common in Python. That pattern wasn't even universal in the 80s. In Pascal, for example, you read from a file using something very close to this: reset(infile); while not eof(indeck) do begin read(indeck, buffer); {now process the buffer} end; I recall that the Pascal compiler had to do some clever behind the scenes jiggery-pokery to get eof() to work, but that's what compilers are supposed to do: make common tasks easy for the programmer. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Creating a MIDI file
What would be the best library to use for creating MIDI files that I could import into a DAW like Reaper? Thanks, Tobiah -- https://mail.python.org/mailman/listinfo/python-list
Lies in education [was Re: The "loop and a half"]
On Thu, 5 Oct 2017 07:17 am, ROGER GRAYDON CHRISTMAN wrote: > I teach a course in programming to students who have no plans to be > programmers, scientists, or engineers.And I deliberately lied today > about the for loop. Well done! (I'm not being sarcastic.) This is entirely appropriate: all education is best understood as a series of "lies to children" asymptotically approaching reality, where "children" should be read figuratively not literally. https://en.wikipedia.org/wiki/Lie-to-children (If you prefer a more academic, philosophical term, Wittgenstein's Ladder is often used for more or less the same concept.) The term is provocative and evocative, but it is also slightly unfortunate in that some people (who should know better!) take issue with it due to an entirely avoidable misunderstanding of what is meant by "lie". E.g. the quote from Mishra in the above Wikipedia article *completely* misses the point; Kharem and Collura's lament that it is "stupidification". What are these people thinking? Is it stupidification to teach music students scales before atonal music? Do they honestly think that we should start teaching science with quantum mechanics and general relativity? (And even if we did, it would still be a lie: at *best*, QM and GR are themselves incomplete descriptions of the universe and therefore any description of reality in terms of QM or GR must be strictly false.) Strictly speaking, everything we human beings are capable of understanding about the universe falls short of reality and is therefore, in some sense, a lie. But lies-to-children are simplifications and half-truths which lead to better understanding, not outright porkies: "The pedagogical point is to avoid unnecessary burdens on the student’s first encounter with the concept." (Jeffrey and Corless, 2011, quoted in Wikipedia above.) Despite Mishra's opinion, "babies are delivered by the stork" is not a lie-to- children in this sense. Its just a dishonest untruth told by parents too embarrassed (or not smart enough) to explain where babies come from in a simplified, honest way to their children. Lies-to-children are not dishonest untruths. At various stages of education, we teach many lies-to-children, including: - supply and demand curves; - human beings make rational economic choices; - well, on average, human beings collectively make rational economic choices; - "AEIOU" are the English vowels; - the pyramids were built by slaves; - you cannot subtract a larger number from a smaller; - or take the square root of a negative number; - if the discriminant is negative, the quadratic equation cannot be factorized; - mass is conserved; - water is incompressible; - the gas laws; - Germany was the aggressor in World War 2; - well, Germany and Japan; - *surely* it must be Germany, Italy and Japan; - Hookes' Law for springs; - any table of values, or graph, used in engineering; - Newton's laws of motion; - Ampere's Law and Ohm's Law; - Special and General Relativity; - matter is made of indivisible atoms; - transformation of elements (such as lead to gold) is impossible; - there are three forms of radioactive decay: alpha, beta and gamma; - and two forms of carbon, graphite and diamond; - people and animals come in exactly two distinct sexes; - tides are caused by the moon; - well, the moon and the sun; Every one of these have to eventually be followed with: "Well, yes, that's kind of true *but* ..." > In my lecture slide, I said that the for loop could only be used if you had > a collection of values (e.g. list, tuple, dict, string, or range) > where all the data was in hand, and should only be used when > truly planning to visit the entire collection. Kastens & Chayes (2011) give some recommendations for effective use of the lies-to-children as a pedagogical technique. Since it is unavoidable to "lie" to your students, how can you make sure the lies help their education rather than hinder it? https://web.archive.org/web/20160205090900/http://serc.carleton.edu/earthandmind/posts/lies_children.html > The slide essentially claimed, you could not use the for loop to > input a series of values from the keyboard, until seeing a blank line or > zero. or to search a list until you found the first even value, and stopping > when you get there. > If you want to stop repeating for an arbitrary reason, you must use a while > loop. > > Deliberate lie. > > Verbally I said it was actually a fib, and that there was a way to > do these cleanly with a for loop, but it's a method that I postpone until > halfway through the second course for students in the major, > not the sort of thing I would teach to this particular audience this early. > > But yes, we can use yield, and iter(), and itertools to do both of these > examples very clearly with a for loop (and without an explicit break > statement), but I'd rather keep my course content small and simple. > > > Roger Christman > Pennsylvania State Un
Re: Creating a Dictionary
Stefan Ram wrote: One might wish to implement a small language with these commands: Explain why. What is the advantage? F - move forward B - move backward L - larger stepsize S - smaller stepsize . One could start with the following pseudocode for a dictionary: { 'F': lambda: myturtle.forward( s ), 'B': lambda: myturtle.backward( s ), 'L': lambda: global s; s *= 2, 'S': lambda: global s; s /= 2 } . But lambda-expressions cannot contain statements. In real Python one could write something like (untested): def f(): myturtle.forward( s ) def b(): myturtle.backward( s ) def l(): global siz size *= 2 def s(): global siz size /= 2 { 'F': f, 'B': b, 'L': l, 'S': s } . Is this more readable or less readable? Any other suggestions? -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 10/4/17 7:37 AM, Stefan Ram wrote: bartc writes: Note that your reverse-indentation style is confusing! In Python, indentation can be significant. Sometimes, some lines in Python must be indented by 0. This dictates that Python code cannot be indented in posts to differentiate it from the natural-language body of the post. Therefore, it's rather the natural-language body that has to be indented. FWIW, I also find your posts hard to read because of the inverted indentation. We don't have difficulty understanding the meaning of block-indented chunks of Python code. --Ned. -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On Thu, 5 Oct 2017 09:08 am, bartc wrote: [...] > And when I tried, it didn't really work in Python 2 (extra attributes > could still be created, and .__slots__ wasn't readonly); only Py3. Not quite, but I don't blame you for the mistake. Its an easy one to make. __slots__ only works in "new style classes", not "classic classes" in Python 2. And yes, it is a wart in Python 2 that there are two subtly different kinds of class. This is due to historical reasons, and its fixed in Python 3. In Python 2, "classic classes" are declared like this: class MyClass: ... (or by inheriting from another classic class). New-style classes, or "types", inherit from object: class MyClass(object): ... (or some other new-style type, like int, dict, list, etc.) Yes yes yes, I completely agree that this is a suboptimal situation. It is a language wart and a trap for the beginner, or even the experienced coder. Use Python 3, where it is fixed. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
How to determine lowest version of Python 3 to run?
Greetings, I've always installed the latest and greatest version of Python 3 to develop my own programs. I'm planning to release a program to the public. I could toss in a note that the program runs on the latest version of Python 3.6 but I haven't tested on earlier versions (i.e., 3.4 and 3.5). AFAIK, I haven't written any version-specific code. How do I determine the lowest version of Python to run? I'm leaning towards installing the latest minor version of each available major version, running tox to run the unit tests against each one, and seeing what blows up. Thank you, Chris R. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, 5 Oct 2017 09:42 am, Stefan Ram wrote: > Steve D'Aprano writes: >>>So, "bottom-up" in this case means: iterators should be >>>taught before for-loops. >>Why? > > The syntax for is (from memory): > > for in : > > . As an example, I might show: > > for i in range( 3 ): ... > > . This raises the question: > > "What is the value of »range( 3 )«?". That's easy: in Python 2, it is a list [0, 1, 2]. In Python 3, it is a range object, a lazily calculated list-like object. > "Bottom up" means that the simple and constituent parts > are taught before the complex and compound parts. I.e., > »range( 3 )« is explained before »for i in range( 3 ):«. This is reductionist thinking. Which is sometimes useful, but not here. If you were teaching people to drive a car, would you insist on teaching them how to pull out and rebuild the engine before sitting them in the drivers seat? If you were teaching people to swim, would you teach them the laws of hydrodynamics and the chemistry of water before going near a swimming pool? If you were teaching people to ride a horse, would you start by having them dissect a dead horse and learn the biomechanics of the horse skeletal and muscular systems? -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Creating a Dictionary
On Thu, Oct 5, 2017 at 12:24 PM, Stefan Ram wrote: > One might wish to implement a small language with these commands: > > F - move forward > B - move backward > L - larger stepsize > S - smaller stepsize > > . One could start with the following pseudocode for a dictionary: > > { 'F': lambda: myturtle.forward( s ), > 'B': lambda: myturtle.backward( s ), > 'L': lambda: global s; s *= 2, > 'S': lambda: global s; s /= 2 } > > . But lambda-expressions cannot contain statements. > > Any other suggestions? There are a few options here. One is to make use of a simple "collector decorator": commands = {} def cmd(f): commands[f.__name__.upper()] = f return f @cmd def f(): myturtle.forward( s ) @cmd def b(): myturtle.backward( s ) @cmd def l(): global siz size *= 2 @cmd def s(): global siz size //= 2 (Also untested, but the pattern is one I've used many times.) Another is to deploy the whole thing as a class, with no globals: class Turtle: def __init__(self): self.size = ... self.turtle = ... def cmd_F(self): self.turtle.forward(self.size) def cmd_B(self): self.turtle.backward(self.size) def cmd_L(self): self.size *= 2 def cmd_S(self): self.size //= 2 Note that I've added "cmd_" in front of the names, which means you can safely getattr(turtle, "cmd_" + letter) and be confident you won't accidentally grab something that isn't a command. (Note also that I used // for division. If your size is actually a float, then change those back to single slashes.) Either of these patterns would work fairly well. There are others, too, but I'd be inclined to use one of these. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, 5 Oct 2017 10:56 am, Terry Reedy wrote: >> You're right, that construct isn't used for reading from files in >> Python. It _is_ commonly used for reading from things like socket > >> mysock.connect(...) >> while True: >> data = mysock.recv() >> if not data: >> break >> do_something_with(data) >> mysock.close() > > I contend that it would be better in this case also to separate data > access from data processing. [...] > Perhaps the socket module needs an update to make the boilerplate > generator function a method, such as 'iterread'. I was thinking the same thing as Terry. Obviously we need the low-level socket module for those (hopefully rare) times we need to interface with a socket at a low level. But I was thinking, why isn't there an equivalent high-level socket interface, like for files, so we can simply write something like: with Socket(spam) as mysock: for block in mysock(blocksize): ... I haven't done enough [read: any] socket programming to tell how useful and practical this is, but it seems like an obvious enhancement. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, 5 Oct 2017 10:15 am, Thomas Jollans wrote: > If you apply that kind of thinking consistently with Python you'll get > caught in an infinite loop trying to explain attribute access before > even teaching print(). > > To call print, you need to access print.__call_. To access that > attribute, you need to check print.__dict__ (and some other things), > which is itself an attribute of print. To access that, (...) > print.__class__.__dict__['__call__'].__call__(print, "hello world") > hello world Its worse than that. Conceptually, you are calling type(print).__call__, not print.__call__. But how do you call type? With type.__call__(print), except that it is actually type(type).__call__(type, print) which is recursive... Obviously the real interpreter doesn't do that. Doing attribute access on the type is magic, and built into the interpreter: there's no infinite regress. > "simple and constituent parts" is, quite often, not well-defined. Indeed. > Iterators are pretty simple, and, while they have constituent parts, > pretty fundamental to Python, at least in spirit. But you don't need to know the slightest thing about iterators in order to learn how to iterate over lists, strings, tuples, dicts etc. In fact, iterators are merely a subset of a more fundamental "kind" of object, iterables: anything which can be iterated over. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, Oct 5, 2017 at 1:20 PM, Steve D'Aprano wrote: > On Thu, 5 Oct 2017 09:42 am, Stefan Ram wrote: > >> Steve D'Aprano writes: So, "bottom-up" in this case means: iterators should be taught before for-loops. >>>Why? >> >> The syntax for is (from memory): >> >> for in : >> >> . As an example, I might show: >> >> for i in range( 3 ): ... >> >> . This raises the question: >> >> "What is the value of »range( 3 )«?". > > That's easy: in Python 2, it is a list [0, 1, 2]. In Python 3, it is a range > object, a lazily calculated list-like object. Even easier: in any version of Python, it is the series of numbers 0, 1, 2. You can go a rather long way without worrying about what "series" actually means at the concrete level. It's a thing you can iterate over, and that's all that matters to 99%+ of range() usage. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: How to determine lowest version of Python 3 to run?
On Thu, Oct 5, 2017 at 1:23 PM, Christopher Reimer wrote: > Greetings, > > I've always installed the latest and greatest version of Python 3 to develop > my own programs. I'm planning to release a program to the public. I could > toss in a note that the program runs on the latest version of Python 3.6 but > I haven't tested on earlier versions (i.e., 3.4 and 3.5). AFAIK, I haven't > written any version-specific code. > > How do I determine the lowest version of Python to run? > > I'm leaning towards installing the latest minor version of each available > major version, running tox to run the unit tests against each one, and seeing > what blows up. > By "major" and "minor", do you mean that you're testing on the latest "3.5" (currently 3.5.4)? Usually a three-part version number is described as "Major.Minor.Revision" [1], so you're working with the single major version "3". My recommendation is to quote only two-part version numbers. Test on the last few, then say "Requires Python 3.4 or greater" if that's how far back you tested. Generally, you won't have to test on multiple revisions of the same minor version; if it runs on 3.5.2, it should run on 3.5.3 and 3.5.1, unless you depend on some specific bug that got fixed. And how many versions back should you test? If you want to be thorough, look at which versions are still in support - either with your OS repositories or at Python.org - and test on all of those. If you're like me, though, just test on whichever ones you happen to have around, and then quote that :) You can shortcut this whole process, though, if you know for certain that you've used a newly-added feature. For example, if your code depends on the order of arguments in **kwargs, don't bother testing on 3.5 and getting flaky results - that changed in 3.6, so just quote that you need 3.6+. If you use the matrix multiplication operator "@", test on 3.5 and 3.6 and that's it. Obviously this only helps if you KNOW about a new feature, but I've had a number of projects where I get all excited about a flashy new feature and immediately start using it... :) Hope that helps! ChrisA [1] The music nerd in me wants "minor" to be lower-cased, but I told me to shut up. -- https://mail.python.org/mailman/listinfo/python-list
Re: Easier way to do this?
On Thu, Oct 5, 2017 at 11:11 AM, Irv Kalb wrote: > # If we have not seen this employee name before, add it to the dictionary > # like key value pair: '': [0, 0] > if not(name in employeeDataDict): > salesCountDict[name] = [0, 0] Python provides a "not in" operator, which is far superior to parenthesizing the expression. But, even better, you can use a defaultdict to create this automatically - and you could even, with a slight tweak, make use of collections.Counter to do all the work for you. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, Oct 5, 2017 at 1:21 PM, Stefan Ram wrote: > Steve D'Aprano writes: >>At various stages of education, we teach many lies-to-children, including: > > Many of those lies can be perfectly true in some sense. > I pick some examples: > >>- "AEIOU" are the English vowels; > > One is free to define this term this way. This is just > a definition. Definitions cannot be false. The definition > use by phoneticians is not "more correct" than the > definition used in everyday life. One is free to be factually wrong, like claiming that Australia is not a continent. (I've seen that, in a quiz game.) Definitions can most certainly be incorrect. >>- you cannot subtract a larger number from a smaller; > > In a certain theory one cannot, indeed. In another, one can. Until negative numbers have been taught, you cannot. Once they have, you can. >>- mass is conserved; > > This also depends on the theory. > > (Ok, the theory where it is /not/ conserved better > describes our world. [But the theory where it /is/ > conserved might be more useful in everyday life.]) You can get through a lot of life believing that mass is conserved, but technically it is not, as can be proven. Ergo it is a lie to claim that it is, which fits into Steven's post. >>- Germany was the aggressor in World War 2; >>- well, Germany and Japan; >>- *surely* it must be Germany, Italy and Japan; > > This listing style reminds me of of a listing style used in > »Falsehoods Programmers Believe About Names«: > > |32. People's names are assigned at birth. > |33. OK, maybe not at birth, but at least pretty close to birth. > |34. Alright, alright, within a year or so of birth. > |35. Five years? > |36. You're kidding me, right? There are a lot of those kinds of posts now, and I like the style. (That's why I made my own take on it, about PEP 8.) Yes, okay, that last one "You're kidding me, right?" doesn't technically fit into the concept, but seriously, if nobody had told you that some people are nameless for 5+ years, would you have guessed that that's the case? ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Asking help about Python
Hi Everyone, I now do need to re-compile the Python 2.7 with VisualStudio 2012. Can anyone here kindly give me any help? I appreciate any kind of help: hints, learning sources, or ideally show me some instructions :(. Thank you. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to determine lowest version of Python 3 to run?
On 2017-10-05 03:23, Christopher Reimer wrote: Greetings, I've always installed the latest and greatest version of Python 3 to develop my own programs. I'm planning to release a program to the public. I could toss in a note that the program runs on the latest version of Python 3.6 but I haven't tested on earlier versions (i.e., 3.4 and 3.5). AFAIK, I haven't written any version-specific code. How do I determine the lowest version of Python to run? I'm leaning towards installing the latest minor version of each available major version, running tox to run the unit tests against each one, and seeing what blows up. Thank you, If you want to know whether it'll run on 3.4, just run it on 3.4. There may not be much point in running it on 3.5 because if it's OK on 3.4, then it should also be OK on 3.5. Of course, if you're talking about stuff that needs to be compiled, such as an extension written in C, then you'll need to test it on every version that you're willing to support. -- https://mail.python.org/mailman/listinfo/python-list
Re: Asking help about Python
On Thu, Oct 5, 2017 at 1:48 PM, wrote: > Hi Everyone, > > I now do need to re-compile the Python 2.7 with VisualStudio 2012. > Can anyone here kindly give me any help? I appreciate any kind of help: > hints, learning sources, or ideally show me some instructions :(. > > Thank you. This is not going to be easy. Why do you want to? Are you trying to make a patched version of Python, or are you simply looking to get the latest? Python 2.7 is not intended to be compiled with VS 2012. The official Windows builds use VS 2008. Trying to change compilers - even versions of the same compiler - is going to be a hairy job. Unless you are EXTREMELY comfortable with building large applications from source, I do not recommend this. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, 5 Oct 2017 01:21 pm, Stefan Ram wrote: > Steve D'Aprano writes: >>At various stages of education, we teach many lies-to-children, including: > > Many of those lies can be perfectly true in some sense. Well of course, that's the whole point of them being "lies-to-children". In fact, only one of them (to the best of my knowledge) is an outright untruth that should be wiped from the education syllabus: the myth that the Egyptian pyramids were built by slave labour. And even that has a tiny kernel of fact. Of course there were some slaves who would have worked on the pyramids, probably on medial jobs, but the bulk of the work was done by free labourers and craftsmen, who were not only well-paid but were organised enough to go on strike when their pay was late. > I pick some examples: > >>- "AEIOU" are the English vowels; > > One is free to define this term this way. This is just > a definition. Definitions cannot be false. Yes they can. I can define the letter M as a vowel, but the meaning of the word "vowel" and the sound of the letter "M" are in contradiction. One or the other can be correct, but not both. > The definition > use by phoneticians is not "more correct" than the > definition used in everyday life. Yes it is. Even in everyday life, there are clear, simple and obvious counter-examples to the claimed "AEIOU" vowel rule. In fact, mY mind boogles at the mYsterY of whY people insist that AEIOU are the onlY vowels. It is, I think, an example of a stupid English language folklore that people repeat unthinkingly, even though the counter-examples are obvious and common. Like "I before E except after C", which is utter rubbish. It gets worse: sometimes W is a vowel too (although mostly only in archaic spelling, or in loan words like "cwm", from Welsh, pronounced "coom"), or at least *part* of a vowel. But vowels and constonants represent types of *sounds*, not letters, so we shouldn't even be talking about letters being vowels at all. (Nevertheless, the practice is probably too ingrained to ever completely stamp out.) The A and E in the word "are" are not vowels, since they are silent. The U in "unicorn" and "university" are not vowels either, and if you write "an unicorn" you are making a mistake. >>- you cannot subtract a larger number from a smaller; > > In a certain theory one cannot, indeed. In another, one can. > >>- mass is conserved; > > This also depends on the theory. Forget theory, in *reality* mass is not conserved. > (Ok, the theory where it is /not/ conserved better > describes our world. [But the theory where it /is/ > conserved might be more useful in everyday life.]) Of course it is useful. Its just not true. That's the whole point of calling it "lies to children". >>- Germany was the aggressor in World War 2; >>- well, Germany and Japan; >>- *surely* it must be Germany, Italy and Japan; > > This listing style reminds me of of a listing style used in > »Falsehoods Programmers Believe About Names«: Yes. For the record: The USSR and Germany invaded Poland simultaneously, and the two countries divided Poland between them. Churchill himself wrote about having difficulty convincing people to care, since Poland had earlier invaded Czechoslovakia (opportunistically while the Germans were seizing the Sudetenland) and many people in England thought that Poland deserved their fate. Likewise the USSR had invaded Finland. The UK invaded and occupied neutral Iceland in 1940, handing over control to the USA in 1941. Despite signing an agreement in 1948 to leave within 6 months, US military forces actually did not finally leave Iceland, and return full sovereignty to the Icelander government, until 2006. In the East, while Japan did take the first overtly military action against the US, the US had (in some sense) first engaged in hostile behaviour against Japan by unilaterally imposing, and enforcing, sanctions on Japan. (I make no comment on whether such sanctions were justified or not, only that they can be seen as a form of aggressive economic warfare.) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Thu, 5 Oct 2017 01:36 pm, Stefan Ram wrote: > Steve D'Aprano writes: >>If you were teaching people to drive a car, would you insist on teaching >>them how to pull out and rebuild the engine before sitting them in the >>drivers seat? > > If I would have to teach people to drive a car, I would > exercise with them how to move the steering wheel to control > the direction, how to change gears, how to look over the > shoulder to check the blind spot, and I would first exercise > each of these actions /in isolation/ at a quiet training > area, before the people then possible have to do several of > these actions at the same time in real road traffic. My very first driving lesson had the instructor sit me in his car in my drive way, show me how to start the car, where the gear, accelerator and brake pedals were, and have me drive straight out onto a moderately busy road. That certainly made sure I was paying attention. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, Oct 5, 2017 at 2:22 PM, Steve D'Aprano wrote: > It is, I think, an example of a stupid English language folklore that people > repeat unthinkingly, even though the counter-examples are obvious and common. > Like "I before E except after C", which is utter rubbish. That's because it's only half the rule. I before E except after C, when the sound is "aye" or the sound is "ee". If the sound isn't one of those, the rule doesn't apply. So yeah, in that form, it's utter rubbish. (There are exceptions even to the longer form of the rule, but only a handful. English isn't a tidy language.) > But vowels and constonants represent types of *sounds*, not letters, so we > shouldn't even be talking about letters being vowels at all. (Nevertheless, > the practice is probably too ingrained to ever completely stamp out.) > > The A and E in the word "are" are not vowels, since they are silent. The U > in "unicorn" and "university" are not vowels either, and if you write "an > unicorn" you are making a mistake. In explaining how spelling works, it's better to talk in terms of *phonograms*, not letters. In Turkish, they correspond almost perfectly - each letter makes a sound on its own - but in English, there are a good number of two-letter phonograms, and a few longer ones. I'm sure nobody here will be surprised to think of "th" as a phonogram, but of course it isn't always so; in the word "courthouse", the two letters happen to abut, but are in separate syllables. In your example, "are" has two phonograms: "ar", and a silent "e". That said, though, none of this matters in contexts like game shows. If you'd like to buy a vowel, people are going to look VERY strangely at you when you ask for "w". And you can't choose the letter þ ("thorn") and expect to get both the "t" and the "h" given to you. No, you work with the basic 26 ASCII Latin letters in most contexts, and the only uncertain one is "Y". > The UK invaded and occupied neutral Iceland in 1940, handing over control to > the USA in 1941. Despite signing an agreement in 1948 to leave within 6 > months, US military forces actually did not finally leave Iceland, and return > full sovereignty to the Icelander government, until 2006. Huh. I didn't know that part. > In the East, while Japan did take the first overtly military action against > the US, the US had (in some sense) first engaged in hostile behaviour against > Japan by unilaterally imposing, and enforcing, sanctions on Japan. > > (I make no comment on whether such sanctions were justified or not, only that > they can be seen as a form of aggressive economic warfare.) Economic warfare is different from military action, though. Economic sanctions may be a precursor to war but they are not the first blow in warfare. However, that's off topic for this list. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Suggestions on storing, caching, querying json
HI Looking for suggestions around json libraries. with Python. I am looking for suggestions around a long term solution to store and query json documents across many files. I will be accessing an api and downloading approx 20 json files from an api a week. Having downloaded this year I have over 200 files already. So it will grow at a reasonable rate. What I have initially done is store them into a mongo db. Now I am wondering if this is useful or prudent since other than querying the json I wont have much use of other mongo features. When querying the json files though queries will utilise multiple json files at once, not just retrieving a single record. The usage is for data analysis. Is there a good json storage option, with caching and optimal querying etc. Regarding querying I did find a library for json searching called ObjectPath written in Python http://objectpath.org/reference.html Looking to leverage your experience. Cheers Sayth -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, 5 Oct 2017 02:14 pm, Stefan Ram wrote: > Chris Angelico writes: >>You can get through a lot of life believing that mass is conserved, >>but technically it is not, as can be proven. > > Well, in fact, it is conserved. It certainly is not. The whole point of Einstein's equation E = mc² is that energy and mass are freely convertible. Neither energy nor mass alone are conserved. > When an electron and a positron annihilate to give a gas of > two photons, this gas as a whole still has the same mass as > the electron before. And its center of gravity moves with > less than c. That doesn't sound like any description of matter/anti-matter annihilation I've every seen before. I think you may be conflating the concepts of clouds of virtual electron/positron particles with actual annihilation events between real electron/positron particles. In actual annihilation events, there is (as far as I know) generally a single real photon produced, with momentum equal to the sum of the momentum vectors of the original electron and positron. That moves away from the point of production at the speed of light. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
OT aggression [was Re: Lies in education [was Re: The "loop and a half"]]
On Thu, 5 Oct 2017 02:54 pm, Chris Angelico wrote: > On Thu, Oct 5, 2017 at 2:22 PM, Steve D'Aprano > wrote: [...] >> In the East, while Japan did take the first overtly military action against >> the US, the US had (in some sense) first engaged in hostile behaviour >> against Japan by unilaterally imposing, and enforcing, sanctions on Japan. >> >> (I make no comment on whether such sanctions were justified or not, only >> that they can be seen as a form of aggressive economic warfare.) > > Economic warfare is different from military action, though. Economic > sanctions may be a precursor to war but they are not the first blow in > warfare. I carefully choose my words: I spoke of *the aggressor*, not the first country to fire shots. Nor is the aggressor necessarily in the wrong. There are many ways to be aggressive. On a personal level, you don't have to throw the first punch to be the aggressor -- if you crowd somebody, getting right in their face, blocking their exit and forcing them to back up into a corner, you are the aggressor even if they are the first to throw a punch. The US of course is a military superpower, with enormous sea and land borders and control over its airspace. Nobody could successfully blockade them. But if somebody choose to enforce a blockade of (lets say) Iceland, forcing back all planes and ships, that would rightly be seen as an act of aggression. Likewise, if (say) North Korea were to flood the US with billions of counterfeit $100 notes, I don't think anyone would fail to consider that an act of war. Its a sign of just how dysfunctional US politics has become that the revelations of just how much Russia manipulated the last federal election, and how deeply the current administration is under Russia's influence, has failed to make any practical difference to US federal politics. Had the USSR done in 1976 what Russia did in 2016, at the very least the government would have fallen and the replacement government threaten reprisals. > However, that's off topic for this list. Since when does that stop us? :-) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Constants [was Re: newb question about @property]
On Thu, 5 Oct 2017 04:00 am, Paul Moore wrote: > I wonder - would the people who want "real constants" find the > following confusing: > from demo import foo foo = 14 foo > 14 > > It's fundamental to the way the import function works, and how names > in Python behave, but I can see someone with a background in other > languages with "real" constants thinking "but foo is a constant, and > importing it stops it being a constant!" Of course it would be confusing. Just as "from module import foo" can be confusing today, without constants. People are surprised by at least two things: - if foo is mutable, they may be surprised that importing it doesn't make a copy; mutating the "imported copy" will show up everywhere; - they may be surprised that the local name "foo" isn't an alias to the qualified name "demo.foo": if demo.foo changes, foo does not. So is early binding of function defaults. And in other contexts, so is late binding of function defaults. Scoping and name binding rules are something one has to learn. When I first learned Python, they caused me trouble, and I'm sure they will cause any beginner to programming trouble. Adding constants to the language won't change that. Besides, if we had constants: const foo = 1234 then we could have: from demo import const foo -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
OT I before E [was Re: Lies in education [was Re: The "loop and a half"]]
On Thu, 5 Oct 2017 02:54 pm, Chris Angelico wrote: > On Thu, Oct 5, 2017 at 2:22 PM, Steve D'Aprano > wrote: >> It is, I think, an example of a stupid English language folklore that >> people repeat unthinkingly, even though the counter-examples are obvious >> and common. Like "I before E except after C", which is utter rubbish. > > That's because it's only half the rule. I before E except after C, > when the sound is "aye" or the sound is "ee". If the sound isn't one > of those, the rule doesn't apply. So yeah, in that form, it's utter > rubbish. Even when the sound is "A" or "EE", there are still exceptions. (As you say.) http://www.worldwidewords.org/articles/ar-ibe1.htm The best version of the rule I ever heard was: "I before E, EXCEPT after C, AND when sounding like A, as in neighbor, and weigh, and on weekends, and holidays, and all throughout May, and you'll always be wrong NO MATTER WHAT YOU SAY!" https://en.wikiquote.org/wiki/Brian_Regan > (There are exceptions even to the longer form of the rule, but only a > handful. English isn't a tidy language.) Even with the longer version of the rule, there are so few applicable cases, and enough difficulty in applying the rule correctly, that the rule is not worth the breath it takes to say it. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Good virtualenv and packaging tutorials for beginner?
On Oct 4, 2017, at 3:49 AM, Leam Hall wrote: > > Folks on IRC have suggested using virtualenv to test code under different > python versions. Sadly, I've not found a virtualenv tutorial I understand. > Anyone have a link to a good one? > > The next step will be to figure out how to package a project; a good tutorial > URL would be appreciated on that, too. > > Thanks! > > Leam > -- > https://mail.python.org/mailman/listinfo/python-list I'm looking at tox that will automatically set up virtualenv for running unit tests under different versions of Python. https://tox.readthedocs.io/en/latest/ Chris R. -- https://mail.python.org/mailman/listinfo/python-list
Re: How to determine lowest version of Python 3 to run?
Christopher Reimer writes: > How do I determine the lowest version of Python to [declare that my > code supports]? You can determine that by installing all the Python versions you want to try, and running your code's unit test suite on each of them. Those versions where the unit test suite fails, you can know that your code does not run on that version of Python. do this each time you make a significant change to the code; certainly before you release any changes to the world. Automate this procedure with an automated testing tool such as Tox https://tox.readthedocs.org/>. > I'm leaning towards installing the latest minor version of each > available major version, running tox to run the unit tests against > each one, and seeing what blows up. That sounds to me like a good approach. -- \ “Working out the social politics of who you can trust and why | `\ is, quite literally, what a very large part of our brain has | _o__) evolved to do.” —Douglas Adams | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: How to determine lowest version of Python 3 to run?
Op 2017-10-05, Ben Finney schreef : > Christopher Reimer writes: > >> How do I determine the lowest version of Python to [declare that my >> code supports]? > > You can determine that by installing all the Python versions you want to > try, and running your code's unit test suite on each of them. An easy way to get a bunch of different Python versions is to just pull the various Docker containers for them. https://hub.docker.com/r/_/python/ Then run your unit tests in each of them. Note that Python 3.3 support officially ended on 2017-09-29, so at the moment I wouldn't bother to support anything lower than 3.4. That means testing 3.4, 3.5 and 3.6 (and 3.7 prerelease if you want to be thorough). Stephan -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On 5 October 2017 at 14:22, Steve D'Aprano wrote: > The A and E in the word "are" are not vowels, since they are silent. The U > in "unicorn" and "university" are not vowels either, and if you write "an > unicorn" you are making a mistake. > There are dialects of English where the "u" in unicorn or university would be pronounced "oo" (e.g. where heavily influenced by Spanish or Portuguese), in which case writing "an unicorn" would not necessarily be a mistake. For a similar example, I and most Australians would say that writing "an herb" is a mistake since we pronounce the "h", but millions of people elsewhere would disagree with us. Tim Delaney -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On Wed, 4 Oct 2017 11:46 pm, Rhodri James wrote: > On 04/10/17 12:07, bartc wrote: >> I've seen that example brought up before. It still doesn't cut any ice. >> >> You might as well be condescending of someone who finds Joyce or Proust >> unreadable, and prefers McBain, Simenon or Chandler. (Sorry, can't think >> of any modern pulp novelists). > > I don't think your comparison is appropriate. Joyce and Proust strike > me as the literary equivalent of Perl or APL; very clever but nearly > unreadable even for experts. No, think rather of Terry Pratchett. +1 for mentioning Sir PTerry! And an extra bonus for it actually being relevant :-) -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thursday, October 5, 2017 at 4:22:26 AM UTC+1, Steve D'Aprano wrote: > On Thu, 5 Oct 2017 01:21 pm, Stefan Ram wrote: > > >>- Germany was the aggressor in World War 2; > >>- well, Germany and Japan; > >>- *surely* it must be Germany, Italy and Japan; > > > > This listing style reminds me of of a listing style used in > > »Falsehoods Programmers Believe About Names«: > > Yes. > > For the record: > > The USSR and Germany invaded Poland simultaneously, and the two countries > divided Poland between them. Churchill himself wrote about having difficulty > convincing people to care, since Poland had earlier invaded Czechoslovakia > (opportunistically while the Germans were seizing the Sudetenland) and many > people in England thought that Poland deserved their fate. Likewise the USSR > had invaded Finland. Germany had all ready grabbed Austria and pretty much all of Czechoslovakia. The USSR invaded Poland 16 days after Germany did. You've missed out Rumania and Hungary grabbing bits of central Europe while they had a chance. > > The UK invaded and occupied neutral Iceland in 1940, handing over control to > the USA in 1941. Despite signing an agreement in 1948 to leave within 6 > months, US military forces actually did not finally leave Iceland, and return > full sovereignty to the Icelander government, until 2006. The Icelandic government quite happily worked with the UK government as their ruler, the King of Denmark, was preoccupied with the state of affairs at home. The USA has a habit of hanging around but they disliked European colonialists. Pot, kettle, black? > > In the East, while Japan did take the first overtly military action against > the US, the US had (in some sense) first engaged in hostile behaviour against > Japan by unilaterally imposing, and enforcing, sanctions on Japan. > > (I make no comment on whether such sanctions were justified or not, only that > they can be seen as a form of aggressive economic warfare.) Japan had been in control of Korea since 1905, had been involved in China from 1931 and been in all out war with the Chinese from 1937. As the USA had a strong relationship with China it does not surprise me that they took such action. > -- > Steve > “Cheer up,” they said, “things could be worse.” So I cheered up, and sure > enough, things got worse. -- Kindest regards. Mark Lawrence. -- https://mail.python.org/mailman/listinfo/python-list
Re: Multithreaded compression/decompression library with python bindings?
Op 2017-10-04, Paul Moore schreef : > On 4 October 2017 at 16:08, Steve D'Aprano wrote: >> On Wed, 4 Oct 2017 08:19 pm, Thomas Nyberg wrote: >> >>> Hello, >>> >>> I was wondering if anyone here knew of any python libraries with >>> interfaces similar to the bzip2 module which is also multithreaded in >>> (de)compression? Something along the lines of (say) the pbip2 program >>> but with bindings for python? In a pinch: with open("myoutfile.gz", "wb") as f: sp = subprocess.Popen(("gzip",), stdin=subprocess.PIPE, stdout=f) sp.stdin.write(b"Hello, world\n") sp.stdin.close() Does compression in a separate process ;-) Stephan -- https://mail.python.org/mailman/listinfo/python-list
Re: Lies in education [was Re: The "loop and a half"]
On Thu, 5 Oct 2017 03:54 pm, Stefan Ram wrote: > Steve D'Aprano writes: >>In actual annihilation events, there is (as far as I know) >>generally a single real photon produced > > »There are only a very limited set of possibilities for > the final state. The most probable is the creation of > two or more gamma ray photons« > > en.wikipedia.org/wiki/Electron%E2%80%93positron_annihilation. > > "two or more" Ah, that makes sense: as you say: > (Conservation of momentum requires that two particles whose > center of gravity is at rest cannot annihilate to a single > photon with a non-zero momentum.) Of course it can't. In hindsight it is obvious. But that demonstrates exactly the sort of thing I'm talking about. I'm not an expert at quantum mechanics. I've seen (or at least, I remember seeing) diagrams of matter/antimatter annihilation with the two particles coming together and a single photon coming out: a simplified and strictly wrong view of the physics. e+ \ \ /-\ /-\ /\-/ \-/ / e- It turns out that's half the Feynman diagram for Bhabha scattering, not annihilation. I cannot say for sure whether I have ever been explicitly taught (in a book, say) that there is one photon, but I'm sure I've seen equations like: e+ + e- -> γ Writing the equation as: e+ + e- -> 2γ would be equally wrong, since there may not be two photons -- that's just the most likely case. So thank you, today I learned something. -- Steve “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list