Re: Spam
> They are literally criminals, they use computer viruses and malware to > hijack people's computers to send their spam, and you want to trust them > and buy from them? this was probably a "Drive By" posy to get the original spam more attention & possibly bypass spam filters -- Come live with me, and be my love, And we will some new pleasures prove Of golden sands, and crystal brooks, With silken lines, and silver hooks. -- John Donne -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On Tue, 3 Oct 2017 06:51 am, Bill wrote: > Can you inspire me with a good decorator problem (standard homework > exercise-level will be fine)? Here is a nice even dozen problems for you. Please ask for clarification if any are unclear. (1) Write a decorator which simply prints a descriptive message and the name of the decorated function once, when the function is first decorated. E.g. if you write: @decorate def spam(x): return x + 1 # for example print(spam(1)) print(spam(2)) Python should print: Decorating function spam. 2 3 Note: "spam" must not be hard-coded, it must be taken from the function being decorated. (Hint: all functions have their name available as func.__name__.) (2) Modify the decorator from (1) so that calling the wrapped function also print a descriptive message such as "Calling function spam". The expected output will be: Decorating function spam. Calling function spam. 2 Calling function spam. 3 (3) Write a decorator that checks that the decorated function's first argument is a non-empty string, raising an appropriate exception if it is not, and lets through any other arguments unchanged. (4) Same as above, except the first argument is automatically stripped of leading and trailing whitespace and forced to uppercase. (5) Write a decorator which injects the argument 10 into the list of arguments received by the wrapped function. E.g. if you write: @inject def add(a, b): return a + b @inject def sub(a, b): return a - b print(add(5), sub(5)) Python should print "15 5". (And *not* "15 -5".) (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling it what value to inject into the list of arguments: @inject(99) def sub(a, b): return a - b print(sub(5)) will now print "94". (7) Write a decorator which checks the decorated function's two arguments are given smallest first, swapping them around if needed. (8) Write a decorator which prints the name of the wrapped function, its arguments, and the time, each time the wrapped function is called. (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the path to a file, and use the logging module to log the details to that file instead of printing them. (10) Write a decorator which adds an "cache" attribute initialised to an empty dictionary to the decorated function. (11) Write a decorator which wraps a class (not function!), and adds a "help" method to the class which prints a message as shown below. For example: @addhelp class Spam: pass @addhelp class Eggs: pass x = Spam() x.help() y = Eggs() y.help() will print: See http://example.com/Spam See http://example.com/Eggs (Hint: classes also have a __name__ attribute.) (12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator from (10) above to each non-dunder¹ method in the class. That is, after: @addcaches class MyClass: def foo(self): pass def bar(self): pass print(MyClass.foo.cache, MyClass.bar.cache) should print "{} {}". ¹ Remember that dunder methods are those that start with two leading and trailing underscores: "Double UNDERscore" methods. * * * Bruce Eckel has an excellent introduction to Python decorators, from way back when they were first introduced in 2008. His introduction is notable because: - he points out explicitly that Python decorators are not the same as the Decorator design pattern (I thought they were!); - he recommends using a class as the decorator, and building the extra functionality in object oriented fashion, rather than functional programming fashion (this may give an easier introduction to those who aren't familiar with functional idioms); - and he correctly predicted that the introduction of the @ syntactic sugar would have a big impact on the way people think about Python code. http://www.artima.com/weblogs/viewpost.jsp?thread=240808 Feel free to read his post before trying the problems I set. -- 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: INSTRUCTOR SOLUTIONS MANUAL Elementary Linear Algebra by Kuttler
Engineering Fluid Mechanics, 10th Edition by Crowe, Elger solution fuadnassa...@gmail.com -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
Steve D'Aprano writes: > (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying > the > path to a file, and use the logging module to log the details to that file > instead of printing them. This may suffer of excessive creativity, as usually the details of *where* a logger writes the messages are better left to a configuration done at another level :) ciao, lele. -- nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia. l...@metapensiero.it | -- Fortunato Depero, 1929. -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On Tue, 3 Oct 2017 10:01 pm, Lele Gaifax wrote: > Steve D'Aprano writes: > >> (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying >> the path to a file, and use the logging module to log the details to that >> file instead of printing them. > > This may suffer of excessive creativity, as usually the details of *where* a > logger writes the messages are better left to a configuration done at another > level :) Right. I didn't say the path has to be hard-coded in the source. @addlogging(config.logfile or default_logfile) def function(x, y, z): ... In production code, I'd probably pass a logger instance rather than a file name. But in any case, its only a programming exercise, not meant to be production-ready code. -- 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 Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano wrote: > On Tue, 3 Oct 2017 06:51 am, Bill wrote: > >> Can you inspire me with a good decorator problem (standard homework >> exercise-level will be fine)? > > > Here is a nice even dozen problems for you. Please ask for clarification if > any > are unclear. > > > > (1) Write a decorator which simply prints a descriptive message and the name > of > the decorated function once, when the function is first decorated. > > E.g. if you write: > > @decorate > def spam(x): > return x + 1 # for example > > print(spam(1)) > print(spam(2)) > > > Python should print: > > Decorating function spam. > 2 > 3 > > > Note: "spam" must not be hard-coded, it must be taken from the function being > decorated. (Hint: all functions have their name available as func.__name__.) > > > (2) Modify the decorator from (1) so that calling the wrapped function also > print a descriptive message such as "Calling function spam". The expected > output will be: > > Decorating function spam. > Calling function spam. > 2 > Calling function spam. > 3 > > > (3) Write a decorator that checks that the decorated function's first argument > is a non-empty string, raising an appropriate exception if it is not, and lets > through any other arguments unchanged. > > > (4) Same as above, except the first argument is automatically stripped of > leading and trailing whitespace and forced to uppercase. > > > (5) Write a decorator which injects the argument 10 into the list of arguments > received by the wrapped function. E.g. if you write: > > @inject > def add(a, b): > return a + b > > @inject > def sub(a, b): > return a - b > > print(add(5), sub(5)) > > Python should print "15 5". (And *not* "15 -5".) > > > (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument > telling > it what value to inject into the list of arguments: > > @inject(99) > def sub(a, b): > return a - b > > print(sub(5)) > > will now print "94". > > > (7) Write a decorator which checks the decorated function's two arguments are > given smallest first, swapping them around if needed. > > > (8) Write a decorator which prints the name of the wrapped function, its > arguments, and the time, each time the wrapped function is called. > > > (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying > the > path to a file, and use the logging module to log the details to that file > instead of printing them. > > > (10) Write a decorator which adds an "cache" attribute initialised to an empty > dictionary to the decorated function. > > > (11) Write a decorator which wraps a class (not function!), and adds a "help" > method to the class which prints a message as shown below. For example: > > @addhelp > class Spam: > pass > > @addhelp > class Eggs: > pass > > x = Spam() > x.help() > y = Eggs() > y.help() > > will print: > > See http://example.com/Spam > See http://example.com/Eggs > > (Hint: classes also have a __name__ attribute.) > > > (12) [ADVANCED] Write a decorator which wraps a class, and applies the > decorator > from (10) above to each non-dunder¹ method in the class. That is, after: > > @addcaches > class MyClass: > def foo(self): > pass > def bar(self): > pass > > print(MyClass.foo.cache, MyClass.bar.cache) > > should print "{} {}". > > > > ¹ Remember that dunder methods are those that start with two leading and > trailing underscores: "Double UNDERscore" methods. I also suggest: (13) Modify the decorator from (8) so that the wrapper has the same name and doc string as the wrapped function. (Hint: use functools.wraps) -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
On 03/10/2017 15:39, Ian Kelly wrote: On Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano wrote: On Tue, 3 Oct 2017 06:51 am, Bill wrote: Can you inspire me with a good decorator problem (standard homework exercise-level will be fine)? Here is a nice even dozen problems for you. Please ask for clarification if any are unclear. (1) Write a decorator which simply prints a descriptive message and the name of the decorated function once, when the function is first decorated. E.g. if you write: @decorate def spam(x): return x + 1 # for example print(spam(1)) print(spam(2)) Python should print: Decorating function spam. 2 3 Note: "spam" must not be hard-coded, it must be taken from the function being decorated. (Hint: all functions have their name available as func.__name__.) (2) Modify the decorator from (1) so that calling the wrapped function also print a descriptive message such as "Calling function spam". The expected output will be: Decorating function spam. Calling function spam. 2 Calling function spam. 3 (3) Write a decorator that checks that the decorated function's first argument is a non-empty string, raising an appropriate exception if it is not, and lets through any other arguments unchanged. (4) Same as above, except the first argument is automatically stripped of leading and trailing whitespace and forced to uppercase. (5) Write a decorator which injects the argument 10 into the list of arguments received by the wrapped function. E.g. if you write: @inject def add(a, b): return a + b @inject def sub(a, b): return a - b print(add(5), sub(5)) Python should print "15 5". (And *not* "15 -5".) (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling it what value to inject into the list of arguments: @inject(99) def sub(a, b): return a - b print(sub(5)) will now print "94". (7) Write a decorator which checks the decorated function's two arguments are given smallest first, swapping them around if needed. (8) Write a decorator which prints the name of the wrapped function, its arguments, and the time, each time the wrapped function is called. (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the path to a file, and use the logging module to log the details to that file instead of printing them. (10) Write a decorator which adds an "cache" attribute initialised to an empty dictionary to the decorated function. (11) Write a decorator which wraps a class (not function!), and adds a "help" method to the class which prints a message as shown below. For example: @addhelp class Spam: pass @addhelp class Eggs: pass x = Spam() x.help() y = Eggs() y.help() will print: See http://example.com/Spam See http://example.com/Eggs (Hint: classes also have a __name__ attribute.) (12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator from (10) above to each non-dunder¹ method in the class. That is, after: @addcaches class MyClass: def foo(self): pass def bar(self): pass print(MyClass.foo.cache, MyClass.bar.cache) should print "{} {}". ¹ Remember that dunder methods are those that start with two leading and trailing underscores: "Double UNDERscore" methods. [Sorry can't see Steve's original post.] 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? It seems to me the equivalent of an advanced driving course teaching you how to customise your car rather than involving any actual driving. -- bartc -- https://mail.python.org/mailman/listinfo/python-list
when is filter test applied?
In the following code (python3): for rb in filter (lambda b : b in some_seq, seq): ... some code that might modify some_seq I'm assuming that the test 'b in some_seq' is applied late, at the start of each iteration (but it doesn't seem to be working that way in my real code), so that if 'some_seq' is modified during a previous iteration the test is correctly performed on the latest version of 'some_seq' at the start of each iteration. Is this correct, and is this guaranteed? -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
No, I see this as teaching the skills involved to drive a car. Practicing a turn, scanning gauges, and checking blind spots are all a part of driving. When one is learning, it's easier to learn these in isolation so when the problem must be solved in real time, you know what to do. This is no different. You may never need to use a decorator ever in your development career, but the tool is there in case the problem you have can be elegantly solved using one. -Jorge On Tue, Oct 3, 2017 at 8:00 AM, bartc wrote: > On 03/10/2017 15:39, Ian Kelly wrote: > >> On Tue, Oct 3, 2017 at 4:41 AM, Steve D'Aprano >> wrote: >> >>> On Tue, 3 Oct 2017 06:51 am, Bill wrote: >>> >>> Can you inspire me with a good decorator problem (standard homework exercise-level will be fine)? >>> >>> >>> Here is a nice even dozen problems for you. Please ask for clarification >>> if any >>> are unclear. >>> >>> >>> >>> (1) Write a decorator which simply prints a descriptive message and the >>> name of >>> the decorated function once, when the function is first decorated. >>> >>> E.g. if you write: >>> >>> @decorate >>> def spam(x): >>> return x + 1 # for example >>> >>> print(spam(1)) >>> print(spam(2)) >>> >>> >>> Python should print: >>> >>> Decorating function spam. >>> 2 >>> 3 >>> >>> >>> Note: "spam" must not be hard-coded, it must be taken from the function >>> being >>> decorated. (Hint: all functions have their name available as >>> func.__name__.) >>> >>> >>> (2) Modify the decorator from (1) so that calling the wrapped function >>> also >>> print a descriptive message such as "Calling function spam". The expected >>> output will be: >>> >>> Decorating function spam. >>> Calling function spam. >>> 2 >>> Calling function spam. >>> 3 >>> >>> >>> (3) Write a decorator that checks that the decorated function's first >>> argument >>> is a non-empty string, raising an appropriate exception if it is not, >>> and lets >>> through any other arguments unchanged. >>> >>> >>> (4) Same as above, except the first argument is automatically stripped of >>> leading and trailing whitespace and forced to uppercase. >>> >>> >>> (5) Write a decorator which injects the argument 10 into the list of >>> arguments >>> received by the wrapped function. E.g. if you write: >>> >>> @inject >>> def add(a, b): >>> return a + b >>> >>> @inject >>> def sub(a, b): >>> return a - b >>> >>> print(add(5), sub(5)) >>> >>> Python should print "15 5". (And *not* "15 -5".) >>> >>> >>> (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument >>> telling >>> it what value to inject into the list of arguments: >>> >>> @inject(99) >>> def sub(a, b): >>> return a - b >>> >>> print(sub(5)) >>> >>> will now print "94". >>> >>> >>> (7) Write a decorator which checks the decorated function's two >>> arguments are >>> given smallest first, swapping them around if needed. >>> >>> >>> (8) Write a decorator which prints the name of the wrapped function, its >>> arguments, and the time, each time the wrapped function is called. >>> >>> >>> (9) [ADVANCED] Modify the decorator from (8) to take an argument >>> specifying the >>> path to a file, and use the logging module to log the details to that >>> file >>> instead of printing them. >>> >>> >>> (10) Write a decorator which adds an "cache" attribute initialised to an >>> empty >>> dictionary to the decorated function. >>> >>> >>> (11) Write a decorator which wraps a class (not function!), and adds a >>> "help" >>> method to the class which prints a message as shown below. For example: >>> >>> @addhelp >>> class Spam: >>> pass >>> >>> @addhelp >>> class Eggs: >>> pass >>> >>> x = Spam() >>> x.help() >>> y = Eggs() >>> y.help() >>> >>> will print: >>> >>> See http://example.com/Spam >>> See http://example.com/Eggs >>> >>> (Hint: classes also have a __name__ attribute.) >>> >>> >>> (12) [ADVANCED] Write a decorator which wraps a class, and applies the >>> decorator >>> from (10) above to each non-dunder¹ method in the class. That is, after: >>> >>> @addcaches >>> class MyClass: >>> def foo(self): >>> pass >>> def bar(self): >>> pass >>> >>> print(MyClass.foo.cache, MyClass.bar.cache) >>> >>> should print "{} {}". >>> >>> >>> >>> ¹ Remember that dunder methods are those that start with two leading and >>> trailing underscores: "Double UNDERscore" methods. >>> >> > [Sorry can't see Steve's original post.] > > 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? > > It seems to me the equivalent of an advanced driving course teaching you > how to customise your car rather than involving any actual driving. > > -- > bartc > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: when is filter test applied?
My intuition is that the lambda creates a closure that captures the value of some_seq. If that value is mutable, and "modify some_seq" means "mutate the value", then I'd expect each element of seq to be tested against the value of some_seq that is current at the time the test occurs, i.e. when the entry is generated from the filter. You say that doesn't happen, so my intuition (and yours) seems to be wrong. Can you provide a reproducible test case? I'd be inclined to run that through dis.dis to see what bytecode was produced. Paul On 3 October 2017 at 16:08, Neal Becker wrote: > In the following code (python3): > > for rb in filter (lambda b : b in some_seq, seq): > ... some code that might modify some_seq > > I'm assuming that the test 'b in some_seq' is applied late, at the start of > each iteration (but it doesn't seem to be working that way in my real code), > so that if 'some_seq' is modified during a previous iteration the test is > correctly performed on the latest version of 'some_seq' at the start of each > iteration. Is this correct, and is this guaranteed? > > > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: Research paper "Energy Efficiency across Programming Languages: How does energy, time, and memory relate?"
The page is fixed BTW >>>import this On Sun, Sep 17, 2017 at 6:13 AM, wrote: > Send Python-list mailing list submissions to > python-list@python.org > > To subscribe or unsubscribe via the World Wide Web, visit > https://mail.python.org/mailman/listinfo/python-list > or, via email, send a message with subject or body 'help' to > python-list-requ...@python.org > > You can reach the person managing the list at > python-list-ow...@python.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Python-list digest..." > > Today's Topics: > >1. Re: Old Man Yells At Cloud (Dennis Lee Bieber) >2. Re: Old Man Yells At Cloud (Stefan Ram) >3. Re: Which database system? (Stefan Ram) >4. CPython has hit 100,000 commits (breamore...@gmail.com) >5. [RELEASE] Python 2.7.14 (Benjamin Peterson) >6. Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" > (breamore...@gmail.com) >7. Re: Old Man Yells At Cloud (Steve D'Aprano) >8. Re: Old Man Yells At Cloud (John Pote) >9. Re: Old Man Yells At Cloud (Steve D'Aprano) > 10. Re: Old Man Yells At Cloud (MRAB) > 11. Re: Old Man Yells At Cloud (Chris Angelico) > 12. Re: Old Man Yells At Cloud (Chris Angelico) > 13. Re: Old Man Yells At Cloud (Dennis Lee Bieber) > 14. Re: Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" (Steve > D'Aprano) > 15. Re: Old Man Yells At Cloud (Stefan Ram) > 16. Re: Old Man Yells At Cloud (Paul Rubin) > 17. Re: Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" (Ian Kelly) > 18. Re: Old Man Yells At Cloud (Stefan Ram) > 19. Re: ttk.Notebook Tabs Question (Abdur-Rahmaan Janhangeer) > 20. Re: Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" (Terry Reedy) > 21. Re: Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" (Chris > Angelico) > 22. Re: Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" (Terry Reedy) > 23. Re: Old Man Yells At Cloud (Gregory Ewing) > 24. Re: Old Man Yells At Cloud (Gregory Ewing) > 25. Re: Old Man Yells At Cloud (mm0fmf) > 26. Re: Old Man Yells At Cloud (Steve D'Aprano) > 27. Re: Research paper "Energy Efficiency across Programming > Languages: How does energy, time, and memory relate?" (Steve > D'Aprano) > 28. Re: Which database system? (Amirouche Boubekki) > 29. Typo-squatting PyPi (Alain Ketterlin) > 30. Re: Old Man Yells At Cloud (Leam Hall) > 31. Re: Old Man Yells At Cloud (Abdur-Rahmaan Janhangeer) > 32. speech_to_text python command not working (pizza python) > 33. Re: Old Man Yells At Cloud (Leam Hall) > 34. Re: Old Man Yells At Cloud (Chris Angelico) > 35. Python built-ins versus Javascript [was Re: Old Man Yells At > Cloud] (Steve D'Aprano) > 36. Re: Old Man Yells At Cloud (Steve D'Aprano) > 37. Unicode (was: Old Man Yells At Cloud) (Leam Hall) > 38. Re: Unicode (was: Old Man Yells At Cloud) (Paul Moore) > 39. Re: Unicode (was: Old Man Yells At Cloud) (Chris Angelico) > 40. Re: Unicode (Leam Hall) > 41. Re: Old Man Yells At Cloud (Steve D'Aprano) > 42. Re: Unicode (Peter Otten) > > > -- Forwarded message -- > From: Dennis Lee Bieber > To: python-list@python.org > Cc: > Bcc: > Date: Sat, 16 Sep 2017 12:52:59 -0400 > Subject: Re: Old Man Yells At Cloud > On Sat, 16 Sep 2017 09:59:43 -0500, Tim Daneliuk > declaimed the following: > > > > >Well, the whole integer floor division thing years ago was the beginning > >of the end - Python was doomed ... > > Yes -- that would give me fits if I were using Python3 currently... > Since so many of the languages I've learned over the past years use the > concept integer / integer => integer_result > > Come to think of it -- wasn't there a post from someone (seems to > expired or been filtered from my client) asking for help with some sorting > program... I'm pretty sure the partitioning logic would croak on Python3 > due to floating point results in the slice indices: > > pA = part[:n/2] > pB = part[n/2:] > > -- > Wulfraed Dennis Lee Bieber AF6VN > wlfr...@ix.netcom.comHTTP://wlfraed.home.netcom.com/ > > > > > -- Forwarded message -- > From: Stefan Ram > To: python-list@python.org > Cc: > Bcc: > Date: 16 Sep 2017 18:00:00 GMT > Subject: Re: Old Man Yells At Cloud > Steve D'Aprano writes: > >"Hi, I've been programming in Python for what seems like days now, and > here's > >all the things that you guys are doing wrong. > > I never ever have written a line of Python 2. I started with > Python 3.6.0. Yet
Re: when is filter test applied?
I'm not certain that it isn't behaving as expected - my code is quite complicated. On Tue, Oct 3, 2017 at 11:35 AM Paul Moore wrote: > My intuition is that the lambda creates a closure that captures the > value of some_seq. If that value is mutable, and "modify some_seq" > means "mutate the value", then I'd expect each element of seq to be > tested against the value of some_seq that is current at the time the > test occurs, i.e. when the entry is generated from the filter. > > You say that doesn't happen, so my intuition (and yours) seems to be > wrong. Can you provide a reproducible test case? I'd be inclined to > run that through dis.dis to see what bytecode was produced. > > Paul > > On 3 October 2017 at 16:08, Neal Becker wrote: > > In the following code (python3): > > > > for rb in filter (lambda b : b in some_seq, seq): > > ... some code that might modify some_seq > > > > I'm assuming that the test 'b in some_seq' is applied late, at the start > of > > each iteration (but it doesn't seem to be working that way in my real > code), > > so that if 'some_seq' is modified during a previous iteration the test is > > correctly performed on the latest version of 'some_seq' at the start of > each > > iteration. Is this correct, and is this guaranteed? > > > > > > -- > > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list
Re: when is filter test applied?
Neal Becker wrote: > In the following code (python3): > > for rb in filter (lambda b : b in some_seq, seq): > ... some code that might modify some_seq > > I'm assuming that the test 'b in some_seq' is applied late, at the start > of each iteration (but it doesn't seem to be working that way in my real > code), so that if 'some_seq' is modified during a previous iteration the > test is correctly performed on the latest version of 'some_seq' at the > start of each > iteration. Is this correct, and is this guaranteed? Yes. filter() is lazy in Python 3, and otherwise the usual rules for binding, mutating, and lookup of some_seq apply. Example: >>> some_seq = set("abc") >>> for c in filter(lambda x: x in some_seq, "abbbcccCAAA"): ... some_seq.remove(c) ... >>> some_seq = set("abc") >>> for c in filter(lambda x: x in some_seq, "abbbcccCAAA"): ... print(c) ... some_seq.remove(c) ... if not some_seq: some_seq = set("ABC") ... a b c # at that point some_seq will be bound to a new set("ABC") C B A # as above A -- https://mail.python.org/mailman/listinfo/python-list
Re: when is filter test applied?
On 3 October 2017 at 16:38, Neal Becker wrote: > I'm not certain that it isn't behaving as expected - my code is quite > complicated. OK, so I'd say the filtering would follow any changes made to some_seq - not because it's a documented guarantee as such, but simply as a consequence of the behaviour of generators and closures. I'd tend to steer clear of code that relied on that behaviour in practice, as I think it's likely to be hard to understand/maintain, but I'm aware that reality's never quite that simple :-) Paul -- https://mail.python.org/mailman/listinfo/python-list
Re: optional int- and float arguments
On Wed, Oct 4, 2017 at 3:18 AM, Stefan Ram wrote: > »int« and »float« seem to behave quite similar: > > |>>> int( x = 8 ) > |8 > |>>> float( x = 8.0 ) > |8.0 > |>>> int() > |0 > |>>> float() > |0.0 > > . Yet the ways their parameters are being documented in > "The Python Library Reference, Release 3.6.0" seem to differ: > > |class float([x]) > |class int(x=0) > Huh. I just checked help() in Python 3.7, and it's the other way around. | float(x=0, /) | int([x]) -> integer > Would there be any error in describing »float« using > > |class float(x=0.0) > > ? I don't think so. This is a strange inconsistency in the docs, given that they behave the same way. Would be worth opening a tracker issue, mentioning all four things you found. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
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". x = 1 while x: x = int( input( "Number (enter 0 to terminate)? " )) if x: print( f'Square = { x**2 }' ) I'd usually write it as while True: x = tedious_function_call_with_sentinel() if x == 0: break do_something_with(x) ...or alternatively x = tedious_function_call_with_sentinel() while x != 0: do_something_with(x) x = tedious_function_call_with_sentinel() ...or some other refactoring. In a C-like language, one could write: while x = int( input( "Number (enter 0 to terminate)? " )) print( f'Square = { x**2 }' ) One could. One would richly deserve the compiler warnings one got as a result, but one could. -- Rhodri James *-* Kynesim Ltd -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Stefan Ram wrote: > Is this the best way to write a "loop and a half" in Python? > > x = 1 > while x: > x = int( input( "Number (enter 0 to terminate)? " )) > if x: > print( f'Square = { x**2 }' ) > > In a C-like language, one could write: > > while x = int( input( "Number (enter 0 to terminate)? " )) > print( f'Square = { x**2 }' ) Use iter() and a for loop: >>> def input_int(): ... return int(input("Enter number (0 to terminate): ")) ... >>> for x in iter(input_int, 0): ... print(f"Square = { x**2 }") ... Enter number (0 to terminate): 1 Square = 1 Enter number (0 to terminate): 2 Square = 4 Enter number (0 to terminate): 0 >>> -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 03/10/17 20:05, Dennis Lee Bieber wrote: > > while True: > x = input("Enter a number (blank to exit) => ") > if x: > try: > ix = int(x) > print("Square = %s" % (ix * ix) ) #why invoke > exponential > except checkTheDocsForException: The nice thing about how the stdlib does exceptions is that you can be pretty certain that this has simply got to be a ValueError. It's still best to check (or, in this case, try it out) - but you just know that there's nothing else it can be. > print(" '%s' is not a valid integer" % x ) > else: > break PS: I was weak. I tried it out before sending this mail. -- https://mail.python.org/mailman/listinfo/python-list
F5 not working?
Hello, I tried looking around the website, but didn't see a question about function keys. Somehow, I "turned off" the F5 function in the IDLE. It no longer "run module", but just does nothing. I have downloaded the newest version, 3.7, but that did not solve the problem. I admit to being clumsy, so I'm guessing I hit an odd key combination which disabled F5 for Python IDLE on this machine (windows 64 bit HP desk top). I tried to check the configuration, but it looks like the key is set up: [image: Inline image 1] Any suggestions? It was nice to have the key working. Thanks, Breta. -- https://mail.python.org/mailman/listinfo/python-list
Re: newb question about @property
Steve D'Aprano wrote: On Tue, 3 Oct 2017 06:51 am, Bill wrote: Can you inspire me with a good decorator problem (standard homework exercise-level will be fine)? Here is a nice even dozen problems for you. Please ask for clarification if any are unclear. Thank you for sharing the problems on decorators! I just finished reading Bruce Eckels' note on decorators (as well as some of the comments left by readers), which you shared a link to, and found the whole discussion very informative. If I was to point to two details, the analogy of decorator's with macros is helpful to bear in mind, as is the remark that "@Wrapper(def f..)" reassigns f to the composition. With the latter unstated, the matter can cause confusion! %-) Bill (1) Write a decorator which simply prints a descriptive message and the name of the decorated function once, when the function is first decorated. E.g. if you write: @decorate def spam(x): return x + 1 # for example print(spam(1)) print(spam(2)) Python should print: Decorating function spam. 2 3 Note: "spam" must not be hard-coded, it must be taken from the function being decorated. (Hint: all functions have their name available as func.__name__.) (2) Modify the decorator from (1) so that calling the wrapped function also print a descriptive message such as "Calling function spam". The expected output will be: Decorating function spam. Calling function spam. 2 Calling function spam. 3 (3) Write a decorator that checks that the decorated function's first argument is a non-empty string, raising an appropriate exception if it is not, and lets through any other arguments unchanged. (4) Same as above, except the first argument is automatically stripped of leading and trailing whitespace and forced to uppercase. (5) Write a decorator which injects the argument 10 into the list of arguments received by the wrapped function. E.g. if you write: @inject def add(a, b): return a + b @inject def sub(a, b): return a - b print(add(5), sub(5)) Python should print "15 5". (And *not* "15 -5".) (6) [ADVANCED] Modify the decorator in (5) so that it takes an argument telling it what value to inject into the list of arguments: @inject(99) def sub(a, b): return a - b print(sub(5)) will now print "94". (7) Write a decorator which checks the decorated function's two arguments are given smallest first, swapping them around if needed. (8) Write a decorator which prints the name of the wrapped function, its arguments, and the time, each time the wrapped function is called. (9) [ADVANCED] Modify the decorator from (8) to take an argument specifying the path to a file, and use the logging module to log the details to that file instead of printing them. (10) Write a decorator which adds an "cache" attribute initialised to an empty dictionary to the decorated function. (11) Write a decorator which wraps a class (not function!), and adds a "help" method to the class which prints a message as shown below. For example: @addhelp class Spam: pass @addhelp class Eggs: pass x = Spam() x.help() y = Eggs() y.help() will print: See http://example.com/Spam See http://example.com/Eggs (Hint: classes also have a __name__ attribute.) (12) [ADVANCED] Write a decorator which wraps a class, and applies the decorator from (10) above to each non-dunder¹ method in the class. That is, after: @addcaches class MyClass: def foo(self): pass def bar(self): pass print(MyClass.foo.cache, MyClass.bar.cache) should print "{} {}". ¹ Remember that dunder methods are those that start with two leading and trailing underscores: "Double UNDERscore" methods. * * * Bruce Eckel has an excellent introduction to Python decorators, from way back when they were first introduced in 2008. His introduction is notable because: - he points out explicitly that Python decorators are not the same as the Decorator design pattern (I thought they were!); - he recommends using a class as the decorator, and building the extra functionality in object oriented fashion, rather than functional programming fashion (this may give an easier introduction to those who aren't familiar with functional idioms); - and he correctly predicted that the introduction of the @ syntactic sugar would have a big impact on the way people think about Python code. http://www.artima.com/weblogs/viewpost.jsp?thread=240808 Feel free to read his post before trying the problems I set. -- https://mail.python.org/mailman/listinfo/python-list
Re: F5 not working?
On 10/3/2017 2:02 PM, Breta Skinner wrote: Hello, I tried looking around the website, but didn't see a question about function keys. Somehow, I "turned off" the F5 function in the IDLE. It no longer "run module", but just does nothing. I have downloaded the newest version, 3.7, but that did not solve the problem. I admit to being clumsy, so I'm guessing I hit an odd key combination which disabled F5 for Python IDLE on this machine (windows 64 bit HP desk top). I tried to check the configuration, but it looks like the key is set up: [image: Inline image 1] This is text only list; images are discarded. If you run IDLE, select Options => Preferences => Keys and scroll down to 'run-module', it will will say for a built-in keyset until you have changed idlelib/config-keys.def and should say for custom key sets until you changed it, in which case, you should be able to change it back. If it says F5, which is perhaps what you meant above, and F5 does not work, then you might have changed your keyboard, outside of IDLE, so that it does not generate the expected keycode. Have you rebooted? Any suggestions? It was nice to have the key working. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
Stefan Ram wrote: Is this the best way to write a "loop and a half" in Python? Is your goal brevity or clarity, or something else (for instance, what does the code written by the other members of your "team" look like--woudn't it be nice if it matched)? Bill x = 1 while x: x = int( input( "Number (enter 0 to terminate)? " )) if x: print( f'Square = { x**2 }' ) In a C-like language, one could write: while x = int( input( "Number (enter 0 to terminate)? " )) print( f'Square = { x**2 }' ) . -- https://mail.python.org/mailman/listinfo/python-list
Need some help with argparse
Hi, I am trying to figure out something with argparse. Here is a scenario: I have a group of arguments, say: (-a, -b, -c, -d, -e) [lets call it group1] I have another group, say: (-z, -y, -x, -w) [lets call it group2] Code: import argparse parser = argparse.ArgumentParser(description="Test this shiz") group1= parser.add_argument_group("Group 1") group2= parser.add_argument_group("Group 2") group1.add_argument('-a', '--extendA', action="store_true", help="HELP") group1.add_argument('-b', '--extendB', action="store_true", help="HELP") group1.add_argument('-c', '--extendC', action="store_true", help="HELP") group1.add_argument('-d', '--extendD', action="store_true", help="HELP") group1.add_argument('-e', '--extendE', action="store_true", help="HELP") # Similarly for group 2: group2.add_argument('-z', '--extendZ', action="store_true", help="HELP") group2.add_argument('-y', '--extendY', action="store_true", help="HELP") group2.add_argument('-x', '--extendX', action="store_true", help="HELP") group2.add_argument('-w', '--extendW', action="store_true", help="HELP") args = parser.parse_args() Now I want to get arguments of group1 and group2 separately. If I print(args) - I get arguments from both the groups. Also group1.parse_args() does not work (since ArgumentGroup does not have parse_args() method) How can I get all arguments of group 1 ONLY? Same goes for group 2? I tried subparsers too - but they require a mandatory `positional argument` - which is not application's requirement. Any kind of help is appreciated. Thank you! -- https://mail.python.org/mailman/listinfo/python-list
Re: Need some help with argparse
Kryptxy via Python-list writes: > I have a group of arguments, say: (-a, -b, -c, -d, -e) [lets call it group1] > I have another group, say: (-z, -y, -x, -w) [lets call it group2] Argument groups are a feature to control the help output from the parser: When an argument is added to the group, the parser treats it just like a normal argument, but displays the argument in a separate group for help messages. https://docs.python.org/3/library/argparse.html#argument-groups> > Now I want to get arguments of group1 and group2 separately. You don't want to use the “argument groups” feature for that, because that's not what it does. > How can I get all arguments of group 1 ONLY? Same goes for group 2? > I tried subparsers too - but they require a mandatory `positional > argument` - which is not application's requirement. I don't know of a way to have the argument parser know the separation you're talking about, without using a subparser. You will need to maintain that separation yourself, outside the parser. One simple way (I have not tried this):: argument_names_by_group = { 'foo': {'lorem', 'donec', 'fusce'}, 'bar': {'aliquam', 'nunc'}, } args = parser.parse_args() args_by_group = { group_name: { getattr(arg_name) for arg_name in argument_names_by_group[group_name] } for group_name in argument_names_by_group } -- \ “I believe our future depends powerfully on how well we | `\ understand this cosmos, in which we float like a mote of dust | _o__) in the morning sky.” —Carl Sagan, _Cosmos_, 1980 | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
[RELEASE] Python 3.6.3 is now available
On behalf of the Python development community and the Python 3.6 release team, I am happy to announce the availability of Python 3.6.3, the third maintenance release of Python 3.6. Detailed information about the changes made in 3.6.3 can be found in the change log here: https://docs.python.org/3.6/whatsnew/changelog.html#python-3-6-3-final Please see "What’s New In Python 3.6" for more information about the new features in Python 3.6: https://docs.python.org/3.6/whatsnew/3.6.html You can download Python 3.6.3 here: https://www.python.org/downloads/release/python-363/ The next maintenance release of Python 3.6 is expected to follow in about 3 months, around the end of 2017-12. More information about the 3.6 release schedule can be found here: https://www.python.org/dev/peps/pep-0494/ Enjoy! -- Ned Deily n...@python.org -- [] -- https://mail.python.org/mailman/listinfo/python-list
Re: when is the filter test applied?
On Tue, Oct 3, 2017 15:38:42, Neal Becker wrote: > I'm not certain that it isn't behaving as expected - my code is quite >complicated. > >On Tue, Oct 3, 2017 at 11:35 AM Paul Moore wrote: > >> My intuition is that the lambda creates a closure that captures the >> value of some_seq. If that value is mutable, and "modify some_seq" >> means "mutate the value", then I'd expect each element of seq to be >> tested against the value of some_seq that is current at the time the >> test occurs, i.e. when the entry is generated from the filter. >> >> You say that doesn't happen, so my intuition (and yours) seems to be >> wrong. Can you provide a reproducible test case? I'd be inclined to >> run that through dis.dis to see what bytecode was produced. >> >> Paul >> >> On 3 October 2017 at 16:08, Neal Becker wrote: >> > In the following code (python3): >> > >> > for rb in filter (lambda b : b in some_seq, seq): >> > ... some code that might modify some_seq >> > >> > I'm assuming that the test 'b in some_seq' is applied late, at the start of >> > each iteration (but it doesn't seem to be working that way in my real code), >> > so that if 'some_seq' is modified during a previous iteration the test is >> > correctly performed on the latest version of 'some_seq' at the start of each >> > iteration. Is this correct, and is this guaranteed? > > I think one must always be very careful about modifying anything that you are iterating across -- if not avoiding that sort of thing entirely. In particular, avoid anything that might add or remove elements in the middle of the sequence. YMMV, but you can imagine the iterator behaving like some of these (all naturally implementation-dependent) Traversing an indexable sequence (such as a list or string) might maintain an internal counter that increments for each iteration. Traversing a linked sequence (such as a linked list) might maintain an internal reference that advances down the chain. If you were to remove the element that you were currently visiting (such was done in "for c in x: x.remove(c)")) you may end up missing items. For example, if you remove element 10 from a list or string, element 11 moves forward to position 10, but the internal counter mentioned above would still advance to 11 -- skipping over the item that followed what you removed. Similarly, if you to remove the linked list node that contained the data you tried to remove, you might have an unspecified behavior of where the linked list advancement would take you. It would be safer to make a deep copy of the data iterable data and iterate down the copy, so you can be sure that all your intended changes to the original data do not interfere with your iteration. Here is an illustration of something going awry: ('.'s added in case my mailer destroys indents) x = list('aaabcadaae') for c in x: ... if c == 'a': ... x.remove('a') ''.join(x) 'bcaadaae' Of the original 18 a's, 10 were removed. The test for (c == 'a') only applied to every other a, because the deletions removed some a's forward, while the iterator kept advancing. (And of course, it always deleted the first a in the list, even if that is not where my iterator was looking) And yes, I would expect the filter to be a lazy application to the iterable you are filtering, so anything that removes from your iterable is going to cause you filter so skip something. That can also be fixed by copying the iterable first. Or alternatively, you can go more functional and instead create a new iterable set of data from the old, instead of mutating what you have. Roger Christman Pennsylvania State University -- https://mail.python.org/mailman/listinfo/python-list
Re: when is the filter test applied?
On Wed, Oct 4, 2017 at 7:31 AM, ROGER GRAYDON CHRISTMAN wrote: >>> > for rb in filter (lambda b : b in some_seq, seq): >>> > ... some code that might modify some_seq > I think one must always be very careful about modifying anything > that you are iterating across -- if not avoiding that sort of thing entirely. > In particular, avoid anything that might add or remove elements > in the middle of the sequence. It isn't, though. That's iterating over seq, and possibly modifying some_seq. So it's safe. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
testbank
do you have testbank for Small Business Management: Launching & Growing Entrepreneurial Ventures, 18th Edition by Justin G. LongeneckerJ. William Petty -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
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". -- 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 10/3/2017 2:10 PM, Peter Otten wrote: Stefan Ram wrote: Is this the best way to write a "loop and a half" in Python? [snip while loop] Use iter() and a for loop: def input_int(): ... return int(input("Enter number (0 to terminate): ")) ... for x in iter(input_int, 0): ... print(f"Square = { x**2 }") ... Enter number (0 to terminate): 1 Square = 1 Enter number (0 to terminate): 2 Square = 4 Enter number (0 to terminate): 0 I think this is the best answer. Using a for loop cleanly separates the source of a sequence of objects from processing the objects. While loop raret in Python as they are only needed for other patterns, such as 'while mutable object is not in the state we want: modify some more', and the number of modifications needed is not necessarity known ahead of time. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: optional int- and float arguments
On Wed, 4 Oct 2017 03:18 am, Stefan Ram wrote: > »int« and »float« seem to behave quite similar: > > |>>> int( x = 8 ) > |8 > |>>> float( x = 8.0 ) > |8.0 I expect that these functions taking a *named* parameter "x" is an accident that shouldn't be relied on. -- 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 Tue, Oct 3, 2017 at 9:16 AM, Jorge Gimeno wrote: > No, I see this as teaching the skills involved to drive a car. Practicing a > turn, scanning gauges, and checking blind spots are all a part of driving. > When one is learning, it's easier to learn these in isolation so when the > problem must be solved in real time, you know what to do. This is no > different. You may never need to use a decorator ever in your development > career, but the tool is there in case the problem you have can be elegantly > solved using one. I have to agree. Learning the language without taking the time to learn all of its features is like learning to drive without bothering to learn how to use the tachometer or the hand brake. Sure you can drive without those things, but that doesn't make them not useful. -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On 10/03/2017 10:29 AM, Stefan Ram wrote: Is this the best way to write a "loop and a half" in Python? x = 1 while x: x = int( input( "Number (enter 0 to terminate)? " )) if x: print( f'Square = { x**2 }' ) In a C-like language, one could write: while x = int( input( "Number (enter 0 to terminate)? " )) print( f'Square = { x**2 }' ) This does not answer your question and is only somewhat related. Here is a generic number input function that I wrote for my own (hobby-programmer) use. The docstring explains it. def get_num(prmt, lo=None, hi=None, dflt=None, flt=False, abrt=False): """Get a number from the console Parameters: prmt: The prompt to be used with the input function, required. lo: The minimum permissible value, or None if no minimum (the default) hi: The maximum permissible value, or None if no maximum (the default) dflt: Default value to return with empty input, None is no default value flt:If True, accepts and returns floats If False, accepts and returns integers (the default) abrt: If True empty input aborts and returns None If False (the default) empty input is handled as invalid data Invalid input or out-of-range values are not accepted and a warning message is displayed. It will then repeat the input prompt for a new value. Note: If the dflt parameter is given, its data type is not checked and could be anything, and could also be used as an abort signal. """ while True: val = input(prmt).strip() if not val: if abrt: return None if dflt is not None: return dflt try: num = float(val) if flt else int(val) except ValueError: print('Invalid input, try again') continue # We have a valid number here, check for in-range if (lo is None or num >= lo) and (hi is None or num <= hi): return num print('Number is out of range') -- FWIW, as to your question, my preference is for the pseudo-do loop using 'while True' with a break as described in other answers here. Using this function, your loop could be: while True: x = get_num('Number (enter ) to terminate: ') if x == 0: # Or if not x: break print(f'Square = { x**2 }') OR my preference: Use empty input to terminate by making the input and test: x = get_num('Number ( to terminate: ', abrt=True) if x is None: break -- -=- Larry -=- -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Wed, Oct 4, 2017 at 1:17 PM, Larry Hudson via Python-list wrote: > def get_num(prmt, lo=None, hi=None, dflt=None, flt=False, abrt=False): > """Get a number from the console > > Parameters: > prmt: The prompt to be used with the input function, required. > lo: The minimum permissible value, or None if no minimum (the > default) > hi: The maximum permissible value, or None if no maximum (the > default) > dflt: Default value to return with empty input, None is no default > value > flt:If True, accepts and returns floats > If False, accepts and returns integers (the default) > abrt: If True empty input aborts and returns None > If False (the default) empty input is handled as invalid > data > > Invalid input or out-of-range values are not accepted and a warning > message > is displayed. It will then repeat the input prompt for a new value. > Note: If the dflt parameter is given, its data type is not checked and > could be anything, and could also be used as an abort signal. > """ > > while True: > val = input(prmt).strip() > if not val: > if abrt: > return None > if dflt is not None: > return dflt > try: > num = float(val) if flt else int(val) > except ValueError: > print('Invalid input, try again') > continue > # We have a valid number here, check for in-range > if (lo is None or num >= lo) and (hi is None or num <= hi): > return num > print('Number is out of range') 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. I'd whitewash the bikeshed a slightly different colour, personally. _SENTINEL = object() def get_number(prompt, *, min=None, max=None, default=_SENTINEL, type=int): Broadly the same as you have (modulo variable names), but there's no need for the boolean 'abrt', since setting default to None will have the same effect - hence the dedicated sentinel object to represent "no default". (I also mandated keyword args, since that's how you're using them anyway.) The one real change I'd make is to replace the boolean flag "flt" with a type, so you now say: x = get_number("Number (enter to terminate): ", type=float) It reads more cleanly than "flt=True", and you don't have to look up any docs to grok it; plus, if you ever need to, you can use "type=Decimal" or something. It's simpler inside the code too - "num = type(val)". If you don't like shadowing the built-in name 'type', feel free to call this something else, but IMO it's okay to shadow here. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: The "loop and a half"
On Wed, 4 Oct 2017 09:08 am, 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 might got Sahami wrong, but it took it to mean this kind > of loop (in pseudo code, which is not necessarily Python): > > while condition >... >... >... >if condition > ... >end if > end while > > The two »condition«s above are the same condition. Hmmm. To me, that appears to be just one case of an unlimited number of different possibilities, none more special or general than any of the others: while condition ... if condition ... else ... end if ... if condition ... else ... end if ... if not condition ... end if ... ... # etc end while I don't see why your version is any more special, or deserving of a name, than any other variety: while condition ... while condition ... end while ... if not condition ... end if while not condition ... if not condition ... else ... end if ... end while ... while condition ... end while ... end while There is literally an infinite number of possibilities for what can go inside a while loop. More while loops, if...else, for loops, any structure you like. What is so special about "if condition..." that it deserves a special name or syntax? > Initially, one loops through this loop an integral > number of times. > > But eventually the conditions is made false by the > upper half of the loop, so then the lower half is > skipped. Or the middle third is skipped. Of the second and third parts of five. Or the fifth, eighth and eleventh parts of twelve. > But at this point in the class, I only have > shown »while« and »if« so far, iterators and for-loops > will only be introduced later. Why? Teaching while loops before for-each loops is backwards. That's one of the bigger problems with "Learn Python the Hard Way", and I see people struggle, really really struggle, so solve problems using a while loop which are *trivial* using a for loop. For-each loops are MUCH easier to understand, and should be taught first. "Do something to each of these items" is a very natural, almost instinctive operation. While loops are harder to write correctly, harder to reason about, and harder to learn. Just because for-each loops are, in some sense, derived from while loops, doesn't mean you should teach them first. -- 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: optional int- and float arguments
On Wed, 4 Oct 2017 12:17 pm, Stefan Ram wrote: > |>>> str(object='abc') > |'abc' That's probably also a bug. -- 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 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. -- 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, 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.) ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: on a very slow function
On Tue, 3 Oct 2017 04:23 am, Ian Kelly wrote: >> py> (2**75 + 7) % 12 # Expected value. >> 3 >> py> ((2**75) % 12 + (7 % 12)) % 12 # Correct. >> 3 >> py> (2**75) % 12 + (7 % 12) # Incorrect. >> 15 > > No, only the final one is necessary. Modding the result of the > exponentiation might be useful for performance, but if c is expected > to be small then it may be pointless to mod that as well. > > py> ((2**75) % 12 + 7) % 12 # Still correct. > 3 Its been years since I've had to tackle modulo arithmetic, but the more I think about it, the more I think you are right. -- 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 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 > It seems to me the equivalent of an advanced driving course teaching you > how to customise your car rather than involving any actual driving. 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? My examples didn't include a full-blown cache, just the beginnings of one, but the principle still stands. Program smart, not hard: don't do things by hand if you can write a function to do them. 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. -- 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