Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #87953 > unrolled thread
| Started by | Manuel Graune <manuel.graune@koeln.de> |
|---|---|
| First post | 2015-03-25 18:29 +0100 |
| Last post | 2015-03-28 08:58 +0000 |
| Articles | 20 on this page of 41 — 15 participants |
Back to article view | Back to comp.lang.python
Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-25 18:29 +0100
Re: Supply condition in function call Joel Goldstick <joel.goldstick@gmail.com> - 2015-03-25 13:41 -0400
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-25 18:51 +0100
Re: Supply condition in function call Joel Goldstick <joel.goldstick@gmail.com> - 2015-03-25 14:17 -0400
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-25 12:22 -0600
Re: Supply condition in function call Joel Goldstick <joel.goldstick@gmail.com> - 2015-03-25 14:42 -0400
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-25 11:44 -0600
Re: Supply condition in function call Grant Edwards <invalid@invalid.invalid> - 2015-03-25 19:53 +0000
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-25 14:49 -0600
Re: Supply condition in function call Grant Edwards <invalid@invalid.invalid> - 2015-03-26 15:41 +0000
Re: Supply condition in function call Terry Reedy <tjreedy@udel.edu> - 2015-03-25 14:50 -0400
Re: Supply condition in function call Gary Herron <gherron@digipen.edu> - 2015-03-25 12:13 -0700
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-25 21:02 -0700
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-26 17:00 +1100
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-26 18:41 -0700
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-27 12:56 +1100
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-26 19:21 -0700
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-27 15:34 +1100
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-27 06:48 -0700
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-28 01:17 +1100
Re: Supply condition in function call Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-03-27 16:00 +0000
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-28 18:32 +1100
Re: Supply condition in function call Chris Angelico <rosuav@gmail.com> - 2015-03-28 18:45 +1100
Re: Supply condition in function call Larry Hudson <orgnut@yahoo.com> - 2015-03-27 17:26 -0700
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-27 18:27 -0700
Re: Supply condition in function call Marko Rauhamaa <marko@pacujo.net> - 2015-03-28 09:50 +0200
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-28 20:17 +1100
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-28 03:19 -0600
Re: Supply condition in function call Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-28 20:57 +1100
Re: Supply condition in function call Cameron Simpson <cs@zip.com.au> - 2015-03-30 09:35 +1100
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-30 00:46 +0200
Re: Supply condition in function call Ian Kelly <ian.g.kelly@gmail.com> - 2015-03-26 20:25 -0600
Re: Supply condition in function call Rustom Mody <rustompmody@gmail.com> - 2015-03-26 19:46 -0700
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-26 07:27 +0100
Re: Supply condition in function call Cameron Simpson <cs@zip.com.au> - 2015-03-26 18:06 +1100
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-27 21:02 +0100
Re: Supply condition in function call Cameron Simpson <cs@zip.com.au> - 2015-03-28 09:55 +1100
Re: Supply condition in function call Peter Otten <__peter__@web.de> - 2015-03-26 10:03 +0100
Re: Supply condition in function call Manuel Graune <manuel.graune@koeln.de> - 2015-03-27 20:46 +0100
Re: Supply condition in function call Peter Otten <__peter__@web.de> - 2015-03-27 21:38 +0100
Re: Supply condition in function call smap <askme.first@thankyouverymuch.invalid> - 2015-03-28 08:58 +0000
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-03-27 16:00 +0000 |
| Message-ID | <mailman.270.1427472028.10327.python-list@python.org> |
| In reply to | #88157 |
On 27/03/2015 13:48, Rustom Mody wrote: > On Friday, March 27, 2015 at 10:05:21 AM UTC+5:30, Steven D'Aprano wrote: >> On Fri, 27 Mar 2015 01:21 pm, Rustom Mody wrote: >> >>> Anyway my point is that in python (after 2.2??) saying something is an >>> object is a bit of a tautology -- ie verbiage without information. >> >> >> Er, it's *always* been a tautology. Every value in Python is an object, >> including classes, and that has been always the case. >> >> However, just because it's a tautology doesn't mean it isn't useful to know. >> (Tautologies are also known as *facts* and knowing facts is usually a good >> thing.) For the majority of programming languages, it is not the case that >> all values are objects, and not all people reading the documentation should >> be expected to know that this applies to Python. > > I am making a point of pedagogy not semantics. > This is help(filter) for python 2 and 3. > > Python2: > Help on built-in function filter in module __builtin__: > > filter(...) > filter(function or None, sequence) -> list, tuple, or string > > Return those items of sequence for which function(item) is true. If > function is None, return the items that are true. If sequence is a tuple > or string, return the same type, else return a list. > -------------------------- > > Python 3 > Help on class filter in module builtins: > > class filter(object) > | filter(function or None, iterable) --> filter object > | > | Return an iterator yielding those items of iterable for which function(item) > | is true. If function is None, return the items that are true. > | > | Methods defined here: > | > | __getattribute__(self, name, /) > | Return getattr(self, name). > | > | __iter__(self, /) > | Implement iter(self). > | > | __new__(*args, **kwargs) from builtins.type > | Create and return a new object. See help(type) for accurate signature. > | > | __next__(self, /) > | Implement next(self). > | > | __reduce__(...) > | Return state information for pickling. > ------------------------ > > Try and put yourself in the place of a noob: > > Knows some C, not much else. > Starts studying python. > Good until a point. > Then suddenly hit... map, filter, and the worst of all lambda. > More he reads less he understands. > Tries help... Gets the above. > > So which do you think helps him more python 2 or 3? > Can't say it bothers me personally as I never use Python 2 any more. What does bother me is the stream of complaints you make about the docs or docstrings but there are very few if any tracker issues to get these things sorted. -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-28 18:32 +1100 |
| Message-ID | <5516591d$0$13013$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88157 |
By the way, you're not alone in recognising that Python 3 may be a little harder to teach to beginners than Python 2. Raymond Hettinger, one of the most respected Pythonistas around, has pointed out the same thing. More below. On Sat, 28 Mar 2015 12:48 am, Rustom Mody wrote: > On Friday, March 27, 2015 at 10:05:21 AM UTC+5:30, Steven D'Aprano wrote: >> On Fri, 27 Mar 2015 01:21 pm, Rustom Mody wrote: >> >> > Anyway my point is that in python (after 2.2??) saying something is an >> > object is a bit of a tautology -- ie verbiage without information. >> >> >> Er, it's *always* been a tautology. Every value in Python is an object, >> including classes, and that has been always the case. >> >> However, just because it's a tautology doesn't mean it isn't useful to >> know. (Tautologies are also known as *facts* and knowing facts is usually >> a good thing.) For the majority of programming languages, it is not the >> case that all values are objects, and not all people reading the >> documentation should be expected to know that this applies to Python. > > I am making a point of pedagogy not semantics. I'm also making a point of pedagogy. You cannot possibly understand Python without understanding the words Python programmers use to discuss Python code, and that includes "object", a word with multiple meanings. How can you talk about teaching people to use filter without discussing the semantics of filter? What are you teaching them then, the way the word looks when written down using calligraphy? Any meaningful discussion about pedagogy cannot avoid semantics. You cannot teach people about filter without expressing what filter is and does and what sort of thing it returns. This is all semantics. In my opinion, once somebody is reduced to dismissing an argument as "that's just semantics", they've already lost, they just don't know it. > This is help(filter) for python 2 and 3. > > Python2: > Help on built-in function filter in module __builtin__: > > filter(...) > filter(function or None, sequence) -> list, tuple, or string > > Return those items of sequence for which function(item) is true. If > function is None, return the items that are true. If sequence is a > tuple or string, return the same type, else return a list. Right. filter is Python 2 is a function, and it returns a list, tuple or string. > Python 3 > Help on class filter in module builtins: > > class filter(object) > | filter(function or None, iterable) --> filter object > | > | Return an iterator yielding those items of iterable for which > | function(item) is true. If function is None, return the items that are > | true. Right. filter in Python 3 is a class (a.k.a. a type). Calling a type normally returns an instance of that type, in this case a "filter object" in the same way that calling str(x) returns a str object or list(x) returns a list object. Are we learning yet? :-) filter is *more powerful* in Python 3, because it is no longer eager. It is lazy, and returns an iterator. What sort of iterator? A *filter instance*. We have to call it something, and Python wouldn't be improved if filter was a function which returned a "pimwit instance". That helps neither beginners nor experts. > | Methods defined here: This is the usual guff that help() prints when you pass it a class or type. Occasionally it is useful. Often it is not, especially the dunder methods. Unfortunately help's UI is rather primitive. It would be nice if it provided a menu of commands whereby you could hide/show dunders (hidden by default, perhaps), but that's an order of magnitude more complexity. It might make a nice third-party tool though. > Try and put yourself in the place of a noob: > > Knows some C, not much else. Why C? Why not somebody who knows Java and not much else, or PHP, or Ruby, or no other programming language at all? People can come to Python from all sorts of backgrounds. C is not and never has been a prerequisite for learning Python. Not every programmer, or programming beginner, knows C. Coming to Python from C is possibly the worst place to start from. Coming from another OOP language like Ruby or Java is better, since the basic concepts will be more familiar, although you will have to unlearn many of the idioms and details. Having no preconceptions is even better. Instead of a C programmer, how about a Scheme or Lisp programmer reading help(filter) in Python 2: "I know what Python lists, tuples and strings are, this sounds just like the filter I know from Scheme. Easy! By the way, why is there no car and cdr function for processing lists?" The point being that preconceptions often need to be unlearned. If the C programmer needs to learn what an object is, the Scheme programmer needs to unlearn what a list is. Should we therefore decide that Python's use of the word "list" is harmful? (I'm hoping that you will agree that it is not, but if you wish to debate it, I'm game.) It's 2015, not 1990, and our imaginary student would have to have been especially isolated to have experience in programming and yet not have any idea of what "object" means. OOP has been the dominant programming paradigm for a quarter of a century, anyone with even a modicum of exposure to programming should have some concept of objects. Even C programmers will have heard of the term, even if they think of it as a fancy word for a struct with some fields being pointers-to-functions. > Starts studying python. > Good until a point. > Then suddenly hit... map, filter, and the worst of all lambda. > More he reads less he understands. > Tries help... Gets the above. > > So which do you think helps him more python 2 or 3? That depends. You're glossing over an awful lot. Where precisely is this "point" they reach? Have they learned what lists and tuples are yet? If not, then the Python 2 docs will give them no insight. "What's a list?" Have they learned what an object is, and understand about iterators and lazy processing? If so, then the Python 3 docs will give them no pause. "Ah, filter is a type, and its instances are iterators. Simple." Obviously there are degrees of knowledge between those two points on the learning curve[1], and for *some* of those degrees a beginner will find the Python 2 version of filter easier to understand than the Python 3 version. Oh well. That's the usual trade-off between power and simplicity. It seems to me that your complaint about the filter docs in Python 3 is based on the supposition that filter should be learned *early* in the process, presumably after list but before iterators and the idea of lazy processing. But why should filter (and map) be necessarily more fundamental than lazy processing? Why not teach them the other way around? Although Python is intended to be easy to learn, it is not intended to be a purely pedagogical language. It is meant to be a practical language, and that may mean including features which are hard to teach but useful, like first-class functions, iterators, coroutines, asynchronous processing, exceptions, and so forth. Trading off some simplicity for power is a good thing. [1] "The" learning curve would imply that there is one and only one order in which people can learn Python concepts, which is nonsense of course. But we can fairly assume that *most* people will learn about lists and strings before they learn about iterators. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-28 18:45 +1100 |
| Message-ID | <mailman.288.1427528744.10327.python-list@python.org> |
| In reply to | #88206 |
On Sat, Mar 28, 2015 at 6:32 PM, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: >> | Methods defined here: > > This is the usual guff that help() prints when you pass it a class or type. > Occasionally it is useful. Often it is not, especially the dunder methods. > > Unfortunately help's UI is rather primitive. It would be nice if it provided > a menu of commands whereby you could hide/show dunders (hidden by default, > perhaps), but that's an order of magnitude more complexity. It might make a > nice third-party tool though. This is why I would never point someone to help() as a means of primary learning. It's great for quickly checking a function's parameters (especially their order) when you already know what it does. Otherwise, how do you know what to call help() on? Much more useful to start with the online module docs, which are searchable (unlike help(modulename), broadly speaking), and which omit all the dunders. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Larry Hudson <orgnut@yahoo.com> |
|---|---|
| Date | 2015-03-27 17:26 -0700 |
| Message-ID | <atednU_7D9DdaIjInZ2dnUU7-cmdnZ2d@giganews.com> |
| In reply to | #88121 |
On 03/26/2015 06:56 PM, Chris Angelico wrote:
> On Fri, Mar 27, 2015 at 12:41 PM, Rustom Mody <rustompmody@gmail.com> wrote:
[snip]
>> After selecting the line above [inside python inside help(filter) ]for
>> cut-pasting here, by mistake I pressed Ctrl-C rather than Ctrl-Shift-C
>> An exception was thrown and the terminal remained in some sort of raw mode
>> even after exiting python
>
> Yes, confirmed. It'll be something to do with what happens when you
> have 'less' and readline working together, probably.
>
> Tip: Use Ctrl-Insert rather than Ctrl-Shift-C. It's the more standard
> keystroke anyway.
>
> ChrisA
>
It seems that many people are not aware of the standard Unix/Linux middle-click copy method.
Highlight the selection you want copied, move the mouse cursor to the location you want it
copied to and middle-click with the mouse. Works between programs as well as within a single
program. And it copies directly without going through the clipboard.
I use this all the time, VERY handy. It's been standard in Unix/Linux since forever... :-)
-=- Larry -=-
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-03-27 18:27 -0700 |
| Message-ID | <c73141b6-fe99-4ad8-bbb2-5b8f099779f6@googlegroups.com> |
| In reply to | #88191 |
On Saturday, March 28, 2015 at 5:57:08 AM UTC+5:30, Larry Hudson wrote: > On 03/26/2015 06:56 PM, Chris Angelico wrote: > > On Fri, Mar 27, 2015 at 12:41 PM, Rustom Mody wrote: > [snip] > >> After selecting the line above [inside python inside help(filter) ]for > >> cut-pasting here, by mistake I pressed Ctrl-C rather than Ctrl-Shift-C > >> An exception was thrown and the terminal remained in some sort of raw mode > >> even after exiting python > > > > Yes, confirmed. It'll be something to do with what happens when you > > have 'less' and readline working together, probably. > > > > Tip: Use Ctrl-Insert rather than Ctrl-Shift-C. It's the more standard > > keystroke anyway. > > > > ChrisA > > > It seems that many people are not aware of the standard Unix/Linux middle-click copy method. > > Highlight the selection you want copied, move the mouse cursor to the location you want it > copied to and middle-click with the mouse. Works between programs as well as within a single > program. And it copies directly without going through the clipboard. > > I use this all the time, VERY handy. It's been standard in Unix/Linux since forever... :-) Neat Thanks
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-03-28 09:50 +0200 |
| Message-ID | <87bnjd8ss3.fsf@elektro.pacujo.net> |
| In reply to | #88191 |
Larry Hudson <orgnut@yahoo.com>: > Highlight the selection you want copied, move the mouse cursor to the > location you want it copied to and middle-click with the mouse. Works > between programs as well as within a single program. And it copies > directly without going through the clipboard. Unfortunately, Linux nowadays employs both schemes. They just couldn't resist the lure of the clipboard. Marko
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-28 20:17 +1100 |
| Message-ID | <551671aa$0$13006$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88208 |
On Sat, 28 Mar 2015 06:50 pm, Marko Rauhamaa wrote: > Larry Hudson <orgnut@yahoo.com>: > >> Highlight the selection you want copied, move the mouse cursor to the >> location you want it copied to and middle-click with the mouse. Works >> between programs as well as within a single program. And it copies >> directly without going through the clipboard. > > Unfortunately, Linux nowadays employs both schemes. They just couldn't > resist the lure of the clipboard. "Unfortunately"? The only "unfortunately" I have with two copy/paste schemes are: - When I am forced to use a Windows application, middle-click *never* pastes :-( - Certain Linux applications like OpenOffice seem to have buggy implementations of middle-click, and sometimes fail to recognise when you've copied something in another application. But only sometimes. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-03-28 03:19 -0600 |
| Message-ID | <mailman.290.1427534422.10327.python-list@python.org> |
| In reply to | #88208 |
On Sat, Mar 28, 2015 at 1:50 AM, Marko Rauhamaa <marko@pacujo.net> wrote: > Larry Hudson <orgnut@yahoo.com>: > >> Highlight the selection you want copied, move the mouse cursor to the >> location you want it copied to and middle-click with the mouse. Works >> between programs as well as within a single program. And it copies >> directly without going through the clipboard. As I understand it, the primary selection and the clipboard selection both work the same way under the hood: a client that wishes to paste the selection requests it from the client that owns it. The clipboard selection may be called "the clipboard" but it does not refer to an OS-level buffer as in Windows. > Unfortunately, Linux nowadays employs both schemes. They just couldn't > resist the lure of the clipboard. For good reason. Anything that can only be done with a mouse is not accessible. I've never been a fan of the primary selection style anyway. Copying text is conceptually an action. Selecting text is how one indicates the target of an action; conceptually it is not an action itself and shouldn't cause an action to be performed. It leads to muddled processes like "highlight this text, paste it there, highlight that text, delete it, paste in the replacement text from before -- oops, I accidentally pasted back in the text that I just deleted instead."
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-28 20:57 +1100 |
| Message-ID | <55167b09$0$13013$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88215 |
On Sat, 28 Mar 2015 08:19 pm, Ian Kelly wrote: > I've never been a fan of the primary selection style anyway. Copying > text is conceptually an action. Selecting text is how one indicates > the target of an action; conceptually it is not an action itself and > shouldn't cause an action to be performed. It leads to muddled > processes like "highlight this text, paste it there, highlight that > text, delete it, paste in the replacement text from before -- oops, I > accidentally pasted back in the text that I just deleted instead." Everything you say is absolutely correct. And yet middle-click paste is so convenient when it works that I all but cry from frustration when I find an application that doesn't support it. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2015-03-30 09:35 +1100 |
| Message-ID | <mailman.318.1427668529.10327.python-list@python.org> |
| In reply to | #88217 |
On 28Mar2015 20:57, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: >On Sat, 28 Mar 2015 08:19 pm, Ian Kelly wrote: >> I've never been a fan of the primary selection style anyway. Copying >> text is conceptually an action. Selecting text is how one indicates >> the target of an action; conceptually it is not an action itself and >> shouldn't cause an action to be performed. It leads to muddled >> processes like "highlight this text, paste it there, highlight that >> text, delete it, paste in the replacement text from before -- oops, I >> accidentally pasted back in the text that I just deleted instead." > >Everything you say is absolutely correct. And yet middle-click paste is so >convenient when it works that I all but cry from frustration when I find an >application that doesn't support it. In xterm and I think several other X11 terminals, Shift-Insert pastes. I found that _way_ more convenient than middle click. The mouse is not your friend. Cheers, Cameron Simpson <cs@zip.com.au> Unix is user-friendly. It's just picky about who its friends are.
[toc] | [prev] | [next] | [standalone]
| From | Manuel Graune <manuel.graune@koeln.de> |
|---|---|
| Date | 2015-03-30 00:46 +0200 |
| Message-ID | <87iodjifqq.fsf@uriel.graune.org> |
| In reply to | #88290 |
Cameron Simpson <cs@zip.com.au> writes: > > In xterm and I think several other X11 terminals, Shift-Insert > pastes. I found that _way_ more convenient than middle click. The > mouse is not your friend. > This information might prove as useful as your answer to my original question. ;-) Thanks for both! -- A hundred men did the rational thing. The sum of those rational choices was called panic. Neal Stephenson -- System of the world http://www.graune.org/GnuPG_pubkey.asc Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A 5828 5476 7E92 2DB4 3C99
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-03-26 20:25 -0600 |
| Message-ID | <mailman.231.1427423166.10327.python-list@python.org> |
| In reply to | #88116 |
On Thu, Mar 26, 2015 at 7:56 PM, Chris Angelico <rosuav@gmail.com> wrote: >> On a more specific note, its the 1st line: >> >> class filter(object) >> >> which knocks me off. >> If a more restricted type from the ABC was shown which exactly captures all >> the iterator-specific stuff like __iter__, __next__ it would sure help (me) > > But there's no point in subclassing for everything. In this case, > filter doesn't subclass anything but object, so there's no value in > stating anything else. You want to know if it's iterable? Check for an > __iter__ method. Etcetera. Also, filter is a builtin, while collections.abc.Iterable is in a library module written in Python, so there's a bootstrapping problem with having the one inherit from the other.
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2015-03-26 19:46 -0700 |
| Message-ID | <d5de648a-0ef1-4eb2-b0a6-decf5fbbfa1f@googlegroups.com> |
| In reply to | #88129 |
On Friday, March 27, 2015 at 7:56:16 AM UTC+5:30, Ian wrote: > On Thu, Mar 26, 2015 at 7:56 PM, Chris Angelico wrote: > >> On a more specific note, its the 1st line: > >> > >> class filter(object) > >> > >> which knocks me off. > >> If a more restricted type from the ABC was shown which exactly captures all > >> the iterator-specific stuff like __iter__, __next__ it would sure help (me) > > > > But there's no point in subclassing for everything. In this case, > > filter doesn't subclass anything but object, so there's no value in > > stating anything else. You want to know if it's iterable? Check for an > > __iter__ method. Etcetera. > > Also, filter is a builtin, while collections.abc.Iterable is in a > library module written in Python, so there's a bootstrapping problem > with having the one inherit from the other. As I said to Chris, I am not talking of the facts but of the docs
[toc] | [prev] | [next] | [standalone]
| From | Manuel Graune <manuel.graune@koeln.de> |
|---|---|
| Date | 2015-03-26 07:27 +0100 |
| Message-ID | <87r3sc9stg.fsf@uriel.graune.org> |
| In reply to | #87967 |
Gary Herron <gherron@digipen.edu> writes:
> On 03/25/2015 10:29 AM, Manuel Graune wrote:
>>
>> def test1(a, b, condition="True"):
>> for i,j in zip(a,b):
>> c=i+j
>> if eval(condition):
>> print("Foo")
>>
>> test1([0,1,2,3],[1,2,3,4],"i+j >4")
>> print("Bar")
>> test1([0,1,2,3],[1,2,3,4],"c >4")
>> print("Bar")
>> test1([0,1,2,3],[1,2,3,4],"a[i] >2")
>>
>
> This is nicely done with lambda expressions:
>
> To pass in a condition as a function:
> test1([0,1,2,3],[1,2,3,4], lambda i,j: i+j<4)
>
> To check the condition in the function:
> if condition(i,j):
This seems to be the right direction and a good solution for simple
cases. Unfortunately this:
> To get the full range of conditions, you will need to include all the variables needed by any condition you can imagine. So the above suggestions may need to be expanded to:
> ... lambda i,j,a,b: ... or whatever
>
> and
> ... condition(i,j,a,b) ... or whatever
>
is not as concise as I had hoped for. Is there a possibility to do
(maybe with a helper function inside the main function's body) solve
this more elegantly? I'm thinking of some combination of e. g. **kwargs,
dir() and introspection.
Regards,
Manuel
--
A hundred men did the rational thing. The sum of those rational choices was
called panic. Neal Stephenson -- System of the world
http://www.graune.org/GnuPG_pubkey.asc
Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A 5828 5476 7E92 2DB4 3C99
[toc] | [prev] | [next] | [standalone]
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2015-03-26 18:06 +1100 |
| Message-ID | <mailman.184.1427353571.10327.python-list@python.org> |
| In reply to | #88029 |
On 26Mar2015 07:27, Manuel Graune <manuel.graune@koeln.de> wrote:
>Gary Herron <gherron@digipen.edu> writes:
>> On 03/25/2015 10:29 AM, Manuel Graune wrote:
>>> def test1(a, b, condition="True"):
>>> for i,j in zip(a,b):
>>> c=i+j
>>> if eval(condition):
>>> print("Foo")
>>>
>>> test1([0,1,2,3],[1,2,3,4],"i+j >4")
>>> print("Bar")
>>> test1([0,1,2,3],[1,2,3,4],"c >4")
>>> print("Bar")
>>> test1([0,1,2,3],[1,2,3,4],"a[i] >2")
>>
>> This is nicely done with lambda expressions:
>>
>> To pass in a condition as a function:
>> test1([0,1,2,3],[1,2,3,4], lambda i,j: i+j<4)
>>
>> To check the condition in the function:
>> if condition(i,j):
>
>This seems to be the right direction and a good solution for simple
>cases. Unfortunately this:
>
>> To get the full range of conditions, you will need to include all the variables needed by any condition you can imagine. So the above suggestions may need to be expanded to:
>> ... lambda i,j,a,b: ... or whatever
>>
>> and
>> ... condition(i,j,a,b) ... or whatever
>>
>
>is not as concise as I had hoped for. Is there a possibility to do
>(maybe with a helper function inside the main function's body) solve
>this more elegantly? I'm thinking of some combination of e. g. **kwargs,
>dir() and introspection.
Yes.
Consider locals():
https://docs.python.org/3/library/functions.html#locals
which is a built in function returning a copy of the current local variables in
a dict. Example:
condition_test = lambda vars: vars['i'] + vars[j'] > 4
def test1(a, b, condition):
for i, j in zip(a,b):
c = i + j
if condition(locals()):
print("Foo")
test1([0,1,2,3], [1,2,3,4], condition_test)
This passes the local variables inside test1() to "condition" as a single
parameter. Now, I grant that vars['i'] is a miracle of tediousness. So consider
this elaboration:
from collections import namedtuple
condition_test = lambda vars: vars.i + vars.j > 4
def test1(a, b, condition):
for i, j in zip(a,b):
c = i + j
vars = locals()
varnames = list(vars.keys())
varstupletype = namedtuple("locals", varnames)
varstuple = varstupletype(*[ vars[k] for k in varnames ])
if condition(varstuple):
print("Foo")
Here, the condition_test function/lambda uses "vars.i" and "vars.j", which i
think you'll agree is easier to read and write. The price is the construction
of a "namedtuple" to hold the variable name values. See:
https://docs.python.org/3/library/collections.html#collections.namedtuple
So the (untested) code above:
- get the locals() as before
- get the names of the variables; it is important to have this in a array because we need to access the values in the same order when we make the tuple
- make a new namedtuple class "varstupletype", which is used to make the named tuple
- make the named tuple itself with the values of the variables in order
If you're writing a lot of test functions like test1 you can push the
namedtuple stuff off into a helper function:
def vartuple(vars):
varnames = list(vars.keys())
varstupletype = namedtuple("locals", varnames)
varstuple = varstupletype(*[ vars[k] for k in varnames ])
return varstuple
and then "test1()" can look like this:
def test1(a, b, condition):
for i, j in zip(a,b):
c = i + j
if condition(vartuple(locals())):
print("Foo")
which makes it much easier to write test2 and so on later.
Does this help?
Cheers,
Cameron Simpson <cs@zip.com.au>
Your reality is lies and balderdash, and I'm glad to say that I have no grasp
of it. - Baron Munchausen
[toc] | [prev] | [next] | [standalone]
| From | Manuel Graune <manuel.graune@koeln.de> |
|---|---|
| Date | 2015-03-27 21:02 +0100 |
| Message-ID | <87twx6qkdz.fsf@uriel.graune.org> |
| In reply to | #88030 |
Cameron Simpson <cs@zip.com.au> writes:
> This passes the local variables inside test1() to "condition" as a
> single parameter. Now, I grant that vars['i'] is a miracle of
> tediousness. So consider this elaboration:
>
> from collections import namedtuple
>
> condition_test = lambda vars: vars.i + vars.j > 4
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> vars = locals()
> varnames = list(vars.keys())
> varstupletype = namedtuple("locals", varnames)
> varstuple = varstupletype(*[ vars[k] for k in varnames ])
> if condition(varstuple):
> print("Foo")
>
> Here, the condition_test function/lambda uses "vars.i" and "vars.j",
> which i think you'll agree is easier to read and write. The price is
> the construction of a "namedtuple" to hold the variable name
> values. See:
>
> https://docs.python.org/3/library/collections.html#collections.namedtuple
>
This is probably getting off topic, but is there any relevant difference
or benefit to using namedtuple instead of something like types.SimpleNamespace?
https://docs.python.org/3/library/types.html#additional-utility-classes-and-functions
--
A hundred men did the rational thing. The sum of those rational choices was
called panic. Neal Stephenson -- System of the world
http://www.graune.org/GnuPG_pubkey.asc
Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A 5828 5476 7E92 2DB4 3C99
[toc] | [prev] | [next] | [standalone]
| From | Cameron Simpson <cs@zip.com.au> |
|---|---|
| Date | 2015-03-28 09:55 +1100 |
| Message-ID | <mailman.281.1427496970.10327.python-list@python.org> |
| In reply to | #88179 |
On 27Mar2015 21:02, Manuel Graune <manuel.graune@koeln.de> wrote:
>Cameron Simpson <cs@zip.com.au> writes:
>
>> This passes the local variables inside test1() to "condition" as a
>> single parameter. Now, I grant that vars['i'] is a miracle of
>> tediousness. So consider this elaboration:
>>
>> from collections import namedtuple
>>
>> condition_test = lambda vars: vars.i + vars.j > 4
>>
>> def test1(a, b, condition):
>> for i, j in zip(a,b):
>> c = i + j
>> vars = locals()
>> varnames = list(vars.keys())
>> varstupletype = namedtuple("locals", varnames)
>> varstuple = varstupletype(*[ vars[k] for k in varnames ])
>> if condition(varstuple):
>> print("Foo")
>>
>> Here, the condition_test function/lambda uses "vars.i" and "vars.j",
>> which i think you'll agree is easier to read and write. The price is
>> the construction of a "namedtuple" to hold the variable name
>> values. See:
>>
>> https://docs.python.org/3/library/collections.html#collections.namedtuple
>>
>
>This is probably getting off topic,
I think it is on topic.
>but is there any relevant difference
>or benefit to using namedtuple instead of something like types.SimpleNamespace?
>
>https://docs.python.org/3/library/types.html#additional-utility-classes-and-functions
Probably not. SimpleNamespace is much easier to construct; I hadn't thought of
it. As the doc remarks, a namedtuple is probably better for fixed records (eg
mapping out rows of a CSV file) because it will prevent you using the wrong
name. But for a comparison function SimpleNamespace is probably better.
Cheers,
Cameron Simpson <cs@zip.com.au>
The Horn of Vengeance: When he pushes the horn button, the device produces
the sound of fingernails scraping on a blackboard, amplified beyond pain
threshold. If that doesn't work, the horn then plays the Pina Colada song.
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-03-26 10:03 +0100 |
| Message-ID | <mailman.190.1427360650.10327.python-list@python.org> |
| In reply to | #88029 |
Cameron Simpson wrote:
> On 26Mar2015 07:27, Manuel Graune <manuel.graune@koeln.de> wrote:
>>Gary Herron <gherron@digipen.edu> writes:
>>> On 03/25/2015 10:29 AM, Manuel Graune wrote:
>>>> def test1(a, b, condition="True"):
>>>> for i,j in zip(a,b):
>>>> c=i+j
>>>> if eval(condition):
>>>> print("Foo")
>>>>
>>>> test1([0,1,2,3],[1,2,3,4],"i+j >4")
>>>> print("Bar")
>>>> test1([0,1,2,3],[1,2,3,4],"c >4")
>>>> print("Bar")
>>>> test1([0,1,2,3],[1,2,3,4],"a[i] >2")
>>>
>>> This is nicely done with lambda expressions:
>>>
>>> To pass in a condition as a function:
>>> test1([0,1,2,3],[1,2,3,4], lambda i,j: i+j<4)
>>>
>>> To check the condition in the function:
>>> if condition(i,j):
>>
>>This seems to be the right direction and a good solution for simple
>>cases. Unfortunately this:
>>
>>> To get the full range of conditions, you will need to include all the
>>> variables needed by any condition you can imagine. So the above
>>> suggestions may need to be expanded to:
>>> ... lambda i,j,a,b: ... or whatever
>>>
>>> and
>>> ... condition(i,j,a,b) ... or whatever
>>>
>>
>>is not as concise as I had hoped for. Is there a possibility to do
>>(maybe with a helper function inside the main function's body) solve
>>this more elegantly? I'm thinking of some combination of e. g. **kwargs,
>>dir() and introspection.
>
> Yes.
>
> Consider locals():
>
> https://docs.python.org/3/library/functions.html#locals
>
> which is a built in function returning a copy of the current local
> variables in a dict. Example:
>
> condition_test = lambda vars: vars['i'] + vars[j'] > 4
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> if condition(locals()):
> print("Foo")
>
> test1([0,1,2,3], [1,2,3,4], condition_test)
>
> This passes the local variables inside test1() to "condition" as a single
> parameter. Now, I grant that vars['i'] is a miracle of tediousness. So
> consider this elaboration:
>
> from collections import namedtuple
>
> condition_test = lambda vars: vars.i + vars.j > 4
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> vars = locals()
> varnames = list(vars.keys())
That leaves varnames in undefined order. Consider
varnames = sorted(vars)
instead or pass the list of arguments explicitly, optionally with some
inspect fallback:
$ cat pass_condition_inspect.py
import inspect
def test3(a, b, condition, args=None):
if args is None:
args = inspect.getargspec(condition).args
for i, j in zip(a,b):
c = i + j
_locals = locals()
if condition(*[_locals[name] for name in args]):
print("Foo", i, j)
def condition(c, i):
return i * i > c
test3([1, 2, 3], [2, 3, 4], condition)
print("---")
# note reverse order of argument names
test3([1, 2, 3], [2, 3, 4], condition, ["i", "c"])
$ python3 pass_condition_inspect.py
Foo 3 4
---
Foo 1 2
Foo 2 3
Foo 3 4
A simpler alternative is changing the signature of condition() and passing
keyword arguments:
$ cat pass_condition.py
def test2(a, b, condition):
for i, j in zip(a,b):
c = i + j
if condition(**locals()):
print("Foo", i, j)
def condition(c, i, **unused):
return i * i > c
test2([1, 2, 3], [2, 3, 4], condition)
$ python3 pass_condition.py
Foo 3 4
Creating a locals() dict on every iteration is still costly, and personally
I would prefer the tighter interface where you pass a limited set of
arguments explicitly.
> varstupletype = namedtuple("locals", varnames)
> varstuple = varstupletype(*[ vars[k] for k in varnames ])
> if condition(varstuple):
> print("Foo")
>
> Here, the condition_test function/lambda uses "vars.i" and "vars.j", which
> i think you'll agree is easier to read and write. The price is the
> construction of a "namedtuple" to hold the variable name values. See:
>
>
https://docs.python.org/3/library/collections.html#collections.namedtuple
>
> So the (untested) code above:
>
> - get the locals() as before
> - get the names of the variables; it is important to have this in a
> array because we need to access the values in the same order when we
> make the tuple - make a new namedtuple class "varstupletype", which is
> used to make the named tuple - make the named tuple itself with the
> values of the variables in order
>
> If you're writing a lot of test functions like test1 you can push the
> namedtuple stuff off into a helper function:
>
> def vartuple(vars):
> varnames = list(vars.keys())
> varstupletype = namedtuple("locals", varnames)
> varstuple = varstupletype(*[ vars[k] for k in varnames ])
> return varstuple
>
> and then "test1()" can look like this:
>
> def test1(a, b, condition):
> for i, j in zip(a,b):
> c = i + j
> if condition(vartuple(locals())):
> print("Foo")
>
> which makes it much easier to write test2 and so on later.
[toc] | [prev] | [next] | [standalone]
| From | Manuel Graune <manuel.graune@koeln.de> |
|---|---|
| Date | 2015-03-27 20:46 +0100 |
| Message-ID | <87y4miql4h.fsf@uriel.graune.org> |
| In reply to | #88035 |
Peter Otten <__peter__@web.de> writes:
> Cameron Simpson wrote:
>
>> test1([0,1,2,3], [1,2,3,4], condition_test)
>>
>> This passes the local variables inside test1() to "condition" as a single
>> parameter. Now, I grant that vars['i'] is a miracle of tediousness. So
>> consider this elaboration:
>>
>> from collections import namedtuple
>>
>> condition_test = lambda vars: vars.i + vars.j > 4
>>
>> def test1(a, b, condition):
>> for i, j in zip(a,b):
>> c = i + j
>> vars = locals()
>> varnames = list(vars.keys())
>
> instead or pass the list of arguments explicitly, optionally with some
> inspect fallback:
>
> $ cat pass_condition_inspect.py
> import inspect
>
> def test3(a, b, condition, args=None):
> if args is None:
> args = inspect.getargspec(condition).args
>
> for i, j in zip(a,b):
> c = i + j
> _locals = locals()
> if condition(*[_locals[name] for name in args]):
> print("Foo", i, j)
>
> def condition(c, i):
> return i * i > c
>
> test3([1, 2, 3], [2, 3, 4], condition)
> print("---")
> # note reverse order of argument names
> test3([1, 2, 3], [2, 3, 4], condition, ["i", "c"])
> $ python3 pass_condition_inspect.py
> Foo 3 4
> ---
> Foo 1 2
> Foo 2 3
> Foo 3 4
>
I'm just comparing the different solutions. For most of them, the
logic and the costs/benefits are pretty clear to me. Can you
elaborate on your code? I'm not clear what you are achieving with
explicitly passing the arguments instead of simply passing some
variant of the complete locals()-dictionary.
--
A hundred men did the rational thing. The sum of those rational choices was
called panic. Neal Stephenson -- System of the world
http://www.graune.org/GnuPG_pubkey.asc
Key fingerprint = 1E44 9CBD DEE4 9E07 5E0A 5828 5476 7E92 2DB4 3C99
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2015-03-27 21:38 +0100 |
| Message-ID | <mailman.276.1427488778.10327.python-list@python.org> |
| In reply to | #88178 |
Manuel Graune wrote:
> Peter Otten <__peter__@web.de> writes:
>
>> Cameron Simpson wrote:
>>
>>> test1([0,1,2,3], [1,2,3,4], condition_test)
>>>
>>> This passes the local variables inside test1() to "condition" as a
>>> single parameter. Now, I grant that vars['i'] is a miracle of
>>> tediousness. So consider this elaboration:
>>>
>>> from collections import namedtuple
>>>
>>> condition_test = lambda vars: vars.i + vars.j > 4
>>>
>>> def test1(a, b, condition):
>>> for i, j in zip(a,b):
>>> c = i + j
>>> vars = locals()
>>> varnames = list(vars.keys())
>>
>> instead or pass the list of arguments explicitly, optionally with some
>> inspect fallback:
>>
>> $ cat pass_condition_inspect.py
>> import inspect
>>
>> def test3(a, b, condition, args=None):
>> if args is None:
>> args = inspect.getargspec(condition).args
>>
>> for i, j in zip(a,b):
>> c = i + j
>> _locals = locals()
>> if condition(*[_locals[name] for name in args]):
>> print("Foo", i, j)
>>
>> def condition(c, i):
>> return i * i > c
>>
>> test3([1, 2, 3], [2, 3, 4], condition)
>> print("---")
>> # note reverse order of argument names
>> test3([1, 2, 3], [2, 3, 4], condition, ["i", "c"])
>> $ python3 pass_condition_inspect.py
>> Foo 3 4
>> ---
>> Foo 1 2
>> Foo 2 3
>> Foo 3 4
>>
>
> I'm just comparing the different solutions. For most of them, the
> logic and the costs/benefits are pretty clear to me. Can you
> elaborate on your code? I'm not clear what you are achieving with
> explicitly passing the arguments instead of simply passing some
> variant of the complete locals()-dictionary.
Positional arguments are the most common calling convention, and the
resulting condition() function
def condition(c, i):
return i * i > c
looks more natural to my eye than the
def condition(d):
return d["i"] * d["i"] > d["c"]
or
def condition(s):
return d.i * d.i > d.c
variants that you have to write when you follow Cameron's suggestions. You
are basically trading cleaner condition() client functions for messier
testX() calling code.
You might also be able to reuse functions not written specifically for that
interface. Example using the sum() builtin:
test3([1, 2, 3], [10, 20, 30], sum, ("a", "j"))
Not that sum() makes much sense here, but I hope you get the idea...
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.python
csiph-web