Finding way around ABCs (was What for -- for? (was A bug?))
On Wednesday, October 29, 2014 11:49:27 AM UTC+5:30, Zachary Ware wrote: On Wed, Oct 29, 2014 at 1:11 AM, Rustom Mody wrote: On Wednesday, October 29, 2014 11:10:06 AM UTC+5:30, Zachary Ware wrote: Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) Not so. The charm of introspection is that the introspection itself can be introspected. For that to be convincing there needs to be a good combo of clarity and succinctness. In particular why not reduce the two functions to one? def get_abc_names(cls): return [abc.__name__ for abc in abcs if issubclass(cls,abc)] Well, it depends on what you actually want, the spec has been a bit fuzzy ;) Thanks for this much -- its helpful. Regarding ABCs -- is there a central documentation for them: What exactly is a sequence or iterable or etc protocol? This information seems to be strewn all over the place but systematically. -- https://mail.python.org/mailman/listinfo/python-list
Re: Finding way around ABCs (was What for -- for? (was A bug?))
On Thu, Oct 30, 2014 at 11:01 AM, Rustom Mody rustompm...@gmail.com wrote: On Wednesday, October 29, 2014 11:49:27 AM UTC+5:30, Zachary Ware wrote: On Wed, Oct 29, 2014 at 1:11 AM, Rustom Mody wrote: On Wednesday, October 29, 2014 11:10:06 AM UTC+5:30, Zachary Ware wrote: Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) Not so. The charm of introspection is that the introspection itself can be introspected. For that to be convincing there needs to be a good combo of clarity and succinctness. In particular why not reduce the two functions to one? def get_abc_names(cls): return [abc.__name__ for abc in abcs if issubclass(cls,abc)] Well, it depends on what you actually want, the spec has been a bit fuzzy ;) Thanks for this much -- its helpful. Regarding ABCs -- is there a central documentation for them: What exactly is a sequence or iterable or etc protocol? This information seems to be strewn all over the place but systematically. Maybe the glossary? https://docs.python.org/3/glossary.html -- https://mail.python.org/mailman/listinfo/python-list
Re: Finding way around ABCs (was What for -- for? (was A bug?))
On Thu, Oct 30, 2014 at 11:09 AM, Ian Kelly ian.g.ke...@gmail.com wrote: On Thu, Oct 30, 2014 at 11:01 AM, Rustom Mody rustompm...@gmail.com wrote: On Wednesday, October 29, 2014 11:49:27 AM UTC+5:30, Zachary Ware wrote: On Wed, Oct 29, 2014 at 1:11 AM, Rustom Mody wrote: On Wednesday, October 29, 2014 11:10:06 AM UTC+5:30, Zachary Ware wrote: Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) Not so. The charm of introspection is that the introspection itself can be introspected. For that to be convincing there needs to be a good combo of clarity and succinctness. In particular why not reduce the two functions to one? def get_abc_names(cls): return [abc.__name__ for abc in abcs if issubclass(cls,abc)] Well, it depends on what you actually want, the spec has been a bit fuzzy ;) Thanks for this much -- its helpful. Regarding ABCs -- is there a central documentation for them: What exactly is a sequence or iterable or etc protocol? This information seems to be strewn all over the place but systematically. Maybe the glossary? Also the documentation for the collections.abc and numbers modules: https://docs.python.org/3/library/collections.abc.html https://docs.python.org/3/library/numbers.html -- https://mail.python.org/mailman/listinfo/python-list
Re: Finding way around ABCs (was What for -- for? (was A bug?))
On Thursday, October 30, 2014 10:40:42 PM UTC+5:30, Ian wrote: On Thu, Oct 30, 2014 at 11:01 AM, Rustom Mody wrote: On Wednesday, October 29, 2014 11:49:27 AM UTC+5:30, Zachary Ware wrote: On Wed, Oct 29, 2014 at 1:11 AM, Rustom Mody wrote: On Wednesday, October 29, 2014 11:10:06 AM UTC+5:30, Zachary Ware wrote: Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) Not so. The charm of introspection is that the introspection itself can be introspected. For that to be convincing there needs to be a good combo of clarity and succinctness. In particular why not reduce the two functions to one? def get_abc_names(cls): return [abc.__name__ for abc in abcs if issubclass(cls,abc)] Well, it depends on what you actually want, the spec has been a bit fuzzy ;) Thanks for this much -- its helpful. Regarding ABCs -- is there a central documentation for them: What exactly is a sequence or iterable or etc protocol? This information seems to be strewn all over the place but systematically. Maybe the glossary? https://docs.python.org/3/glossary.html Ummm... I was looking for something more reference-ish, ie More prolix for ABCs And not containing random bits of unconnected data like - What is CPython - What is EAFP Maybe there's something in the bowels of the C(Python)-code? -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On 29 October 2014 03:22, Rustom Mody rustompm...@gmail.com wrote: Yesterday I was trying to introduce python to some senior computer scientists. Tried showing a comprehension-based dir-walker vs a for-loop based one: def dw(p): if isfile(p): return [p] else: return [p] + [c for f in listdir(p) for c in dw(p+'/'+f)] ... Comment to me : Well this is neat and compact, but it does not add anything fundamental (over usual index based for-loops) I tried to say that 'for' over general sequences is quite different and significantly more powerful than C/Pascal for over indexes + explicit indexing. If you really want to show the generality of iteration, I suggest you start with iterators: def walk(path): yield path if isdir(path): for name in iterdir(path): for file in walk(path + / + name): yield file This is fundementally inexpressable with indexes. It also lends itself to expressing delegation (eg. yield from walk(path + / + name)). -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Thursday, October 30, 2014 10:53:13 PM UTC+5:30, Joshua Landau wrote: On 29 October 2014 03:22, Rustom Mody wrote: Yesterday I was trying to introduce python to some senior computer scientists. Tried showing a comprehension-based dir-walker vs a for-loop based one: def dw(p): if isfile(p): return [p] else: return [p] + [c for f in listdir(p) for c in dw(p+'/'+f)] ... Comment to me : Well this is neat and compact, but it does not add anything fundamental (over usual index based for-loops) I tried to say that 'for' over general sequences is quite different and significantly more powerful than C/Pascal for over indexes + explicit indexing. If you really want to show the generality of iteration, I suggest you start with iterators: def walk(path): yield path if isdir(path): for name in iterdir(path): for file in walk(path + / + name): yield file heh! That was my next version -- almost word-for-word [Not on that laptop now; will check later] -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wednesday, October 29, 2014 11:14:14 AM UTC+5:30, Zachary Ware wrote: On Wed, Oct 29, 2014 at 12:27 AM, Ben Finney wrote: Zachary Ware writes: Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. Right, GMail is a poor choice for composing messages. You might get better results installing a proper mail client, and communicating via IMAP. Noted, but it works fine 99% of the time for me. I'm not really interested in trying to get a proper mail client set up on 5 different devices and 4 different platforms with settings shared between all just to avoid inconvenient line-wrapping (that I can avoid just by sticking to 80 column lines in the first place :). I was going to say the same: gmail is fine if you remember to press RET -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
Zachary Ware zachary.ware+pyl...@gmail.com writes: […] just to avoid inconvenient line-wrapping (that I can avoid just by sticking to 80 column lines in the first place :). That is a valid solution. If you have the discipline to stick to it, congratulations :-) -- \“If you ever drop your keys into a river of molten lava, let | `\ 'em go, because, man, they're gone.” —Jack Handey | _o__) | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wednesday, October 29, 2014 11:10:06 AM UTC+5:30, Zachary Ware wrote: On Wed, Oct 29, 2014 at 12:15 AM, Rustom Mody wrote: Maybe nicer to filter out the false's with a filter-false thus?? def ff(d): return [n for n in d if d[n]] Sure. Or, combining things: try: from collections import abc except ImportError: import collections as abc from abc import ABCMeta abcs = [o for o in vars(abc).values() if isinstance(o, ABCMeta)] def get_abcs(cls): return [abc for abc in abcs if issubclass(cls, abc)] def get_abc_names(cls): return [abc.__name__ for abc in get_abcs(cls)] Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) Not so. The charm of introspection is that the introspection itself can be introspected. For that to be convincing there needs to be a good combo of clarity and succinctness. In particular why not reduce the two functions to one? def get_abc_names(cls): return [abc.__name__ for abc in abcs if issubclass(cls,abc)] -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wed, Oct 29, 2014 at 1:11 AM, Rustom Mody rustompm...@gmail.com wrote: On Wednesday, October 29, 2014 11:10:06 AM UTC+5:30, Zachary Ware wrote: Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) Not so. The charm of introspection is that the introspection itself can be introspected. For that to be convincing there needs to be a good combo of clarity and succinctness. In particular why not reduce the two functions to one? def get_abc_names(cls): return [abc.__name__ for abc in abcs if issubclass(cls,abc)] Well, it depends on what you actually want, the spec has been a bit fuzzy ;) -- Zach -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On 10/29/2014 1:42 AM, Zachary Ware wrote: to avoid inconvenient line-wrapping (that I can avoid just by sticking to 80 column lines in the first place:). Try perhaps 65 for email. def get_abc_map(cls): return {n: issubclass(cls, getattr(abc, n)) for n in dir(abc) if n[0].isupper()} is less than 55 and should not get linewrapped on any sensible sender or reader. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
What for -- for? (was A bug?)
On Wednesday, October 29, 2014 7:47:47 AM UTC+5:30, Denis McMahon wrote: On Tue, 28 Oct 2014 01:29:28 +, Joshua Landau wrote: On 28 October 2014 00:36, Denis McMahon wrote: d = [[list(range(1,13))[i*3+j] for j in range(3)] for i in range(4)] A quick note. Ranges (even 2.7's xrange) are all indexable. The cast to a list isn't needed. Until you apply Chris' slicing trick, and then: [list(range(1,13))[i*3:i*3+3] for i in range(4)] [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] [range(1,13)[i*3:i*3+3] for i in range(4)] [range(1, 4), range(4, 7), range(7, 10), range(10, 13)] Depends how important it is that you get a list and not a range object ;) Heh! Strange that you say this in this context! Yesterday I was trying to introduce python to some senior computer scientists. Tried showing a comprehension-based dir-walker vs a for-loop based one: def dw(p): if isfile(p): return [p] else: return [p] + [c for f in listdir(p) for c in dw(p+'/'+f)] def dw(p): if isfile(p): return [p] else: ls = [p] for f in listdir(p): ls = ls+[f] for c in dw(p+'/'+f): ls = ls+[c] return ls Comment to me : Well this is neat and compact, but it does not add anything fundamental (over usual index based for-loops) I tried to say that 'for' over general sequences is quite different and significantly more powerful than C/Pascal for over indexes + explicit indexing. In particular the fact that in python-3: range(1,10) range(1, 10) and not like python2's range(1,10) [1, 2, 3, 4, 5, 6, 7, 8, 9] seemed to convincingly show that python's range is just 'notional' like Pascal's subrange types and not an actual sequence. That range(10)+range(10) works in python 2 but not 3 does not help my case at all! I'd be interested in thoughts on this -- is a range a 'real' or a 'notional' sequence? Related point: A range is a sequence How to prove this introspectively? ie if I do: type([]).__mro__ (class 'list', class 'object') type(range(10)).__mro__ (class 'range', class 'object') How to see that list and range are both sequences? Or more generally how to to introspectively discover (ie not by reading docs!!) the abstract base classes -- eg sequence, iterable etc -- for an arbitrary object? -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Tue, Oct 28, 2014 at 10:22 PM, Rustom Mody rustompm...@gmail.com wrote: How to see that list and range are both sequences? Or more generally how to to introspectively discover (ie not by reading docs!!) the abstract base classes -- eg sequence, iterable etc -- for an arbitrary object? # Python 2/3 compatible. Combine with pprint for nice interactive output try: from collections import abc except ImportError: import collections as abc def get_abc_map(cls): return {n: issubclass(cls, getattr(abc, n)) for n in dir(abc) if n[0].isupper()} -- Zach -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Tue, Oct 28, 2014 at 11:16 PM, Zachary Ware zachary.ware+pyl...@gmail.com wrote: def get_abc_map(cls): return {n: issubclass(cls, getattr(abc, n)) for n in dir(abc) if n[0].isupper()} Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. -- Zach -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wednesday, October 29, 2014 9:53:46 AM UTC+5:30, Zachary Ware wrote: On Tue, Oct 28, 2014 at 11:16 PM, Zachary Ware wrote: def get_abc_map(cls): return {n: issubclass(cls, getattr(abc, n)) for n in dir(abc) if n[0].isupper()} Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. Thanks Wrapping -- no problem. But the isupper looks like black-magic :-) And removing the ' ... if n[0].isupper()' breaks the code -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Tue, Oct 28, 2014 at 11:40 PM, Rustom Mody rustompm...@gmail.com wrote: On Wednesday, October 29, 2014 9:53:46 AM UTC+5:30, Zachary Ware wrote: On Tue, Oct 28, 2014 at 11:16 PM, Zachary Ware wrote: def get_abc_map(cls): return {n: issubclass(cls, getattr(abc, n)) for n in dir(abc) if n[0].isupper()} Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. Thanks Wrapping -- no problem. But the isupper looks like black-magic :-) And removing the ' ... if n[0].isupper()' breaks the code It's a terrible hack for 2/3 compatibility; in 3 I'd do if not n.startswith('__') since the Python 3 collections.abc module only contains ABCs (and the standard dunder names). Python 2 has all the ABCs mixed into the toplevel collections namespace with some other non-ABCs, but it happens that all the ABCs are capitalized, while the non-ABCs are not. The ABCs are imported into collections from _abcoll, but _abcoll also some uncapitalized non-ABCs as well. For somewhat greyer magic, do 'from abc import ABCMeta' and filter the collections.abc namespace with isinstance(obj, ABCMeta). I just used the above because it's short and sweet and keeps the name handy :) -- Zach -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wednesday, October 29, 2014 10:29:48 AM UTC+5:30, Zachary Ware wrote: On Tue, Oct 28, 2014 at 11:40 PM, Rustom Mody wrote: On Wednesday, October 29, 2014 9:53:46 AM UTC+5:30, Zachary Ware wrote: On Tue, Oct 28, 2014 at 11:16 PM, Zachary Ware wrote: def get_abc_map(cls): return {n: issubclass(cls, getattr(abc, n)) for n in dir(abc) if n[0].isupper()} Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. Thanks Wrapping -- no problem. But the isupper looks like black-magic :-) And removing the ' ... if n[0].isupper()' breaks the code It's a terrible hack for 2/3 compatibility; in 3 I'd do if not n.startswith('__') since the Python 3 collections.abc module only contains ABCs (and the standard dunder names). Python 2 has all the ABCs mixed into the toplevel collections namespace with some other non-ABCs, but it happens that all the ABCs are capitalized, while the non-ABCs are not. The ABCs are imported into collections from _abcoll, but _abcoll also some uncapitalized non-ABCs as well. For somewhat greyer magic, do 'from abc import ABCMeta' and filter the collections.abc namespace with isinstance(obj, ABCMeta). I just used the above because it's short and sweet and keeps the name handy :) Ha! Thanks Maybe nicer to filter out the false's with a filter-false thus?? def ff(d): return [n for n in d if d[n]] -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
Zachary Ware zachary.ware+pyl...@gmail.com writes: Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. Right, GMail is a poor choice for composing messages. You might get better results installing a proper mail client, and communicating via IMAP. -- \“Pinky, are you pondering what I'm pondering?” “Wuh, I think | `\ so, Brain, but how will we get three pink flamingos into one | _o__) pair of Capri pants?” —_Pinky and The Brain_ | Ben Finney -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wed, Oct 29, 2014 at 12:15 AM, Rustom Mody rustompm...@gmail.com wrote: Maybe nicer to filter out the false's with a filter-false thus?? def ff(d): return [n for n in d if d[n]] Sure. Or, combining things: try: from collections import abc except ImportError: import collections as abc from abc import ABCMeta abcs = [o for o in vars(abc).values() if isinstance(o, ABCMeta)] def get_abcs(cls): return [abc for abc in abcs if issubclass(cls, abc)] def get_abc_names(cls): return [abc.__name__ for abc in get_abcs(cls)] Of course, that's 3 (progressively shorter) loops to get the names of the ABCs of a class compared to 1 (fairly short in the first place) loop for a map of relationships to all available ABCs, but optimizing such a toy as this would just be an exercise in futility :) -- Zach -- https://mail.python.org/mailman/listinfo/python-list
Re: What for -- for? (was A bug?)
On Wed, Oct 29, 2014 at 12:27 AM, Ben Finney ben+pyt...@benfinney.id.au wrote: Zachary Ware zachary.ware+pyl...@gmail.com writes: Of course, Gmail decided to wrap my long line for me. In case it's not obvious, that should be a single line. Right, GMail is a poor choice for composing messages. You might get better results installing a proper mail client, and communicating via IMAP. Noted, but it works fine 99% of the time for me. I'm not really interested in trying to get a proper mail client set up on 5 different devices and 4 different platforms with settings shared between all just to avoid inconvenient line-wrapping (that I can avoid just by sticking to 80 column lines in the first place :). Although if you have a suggestion for that kind of setup, I'm all ears. -- Zach -- https://mail.python.org/mailman/listinfo/python-list