From no.email at nospam.invalid Tue Aug 1 02:45:18 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 31 Jul 2017 23:45:18 -0700 Subject: YAML in std lib? References: <61f95827-1fc9-4fad-a962-3df282bf317f@gmail.com> <597d7abd$0$1591$c3e8da3$5496439d@news.astraweb.com> <85mv7l2vq9.fsf@benfinney.id.au> Message-ID: <874ltrg51d.fsf@nightsong.com> Ben Finney writes: > I don't know of any PEP yet which specifies exactly what to add to the > standard library for YAML YAML is more of a Ruby thing, so there might not be much constituency for putting it in Python. From m at funkyhat.org Tue Aug 1 07:06:06 2017 From: m at funkyhat.org (Matt Wheeler) Date: Tue, 01 Aug 2017 11:06:06 +0000 (UTC) Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On Tue, 1 Aug 2017 at 02:32 Terry Reedy wrote: > On 7/31/2017 7:31 PM, tom at tomforb.es wrote: > > As part of the Python 3 cleanup in Django there are a fair few uses of > @functools.lru_cache on functions that take no arguments. > > This makes no sense to me. If the function is being called for > side-effects, then it should not be cached. If the function is being > called for a result, different for each call, calculated from a changing > environment, then it should not be cached. (Input from disk is an > example.) If the function returns a random number, or a non-constant > value from an oracle (such as a person), it should not be cached. If > the function returns a constant (possible calculated once), then the > constant should just be bound to a name (which is a form of caching) > rather than using the overkill of an lru cache. What possibility am I > missing? > A function which is moderately expensive to run, that will always return the same result if run again in the same process, and which will not be needed in every session. Also particularly in the context of a large framework it may be neater & easier to expose a constant-like thing as a function to be called rather than directly bound to a name; if there are several implementations of a particular function, to be chosen based on configuration, and *some* of them are pure functions while others may change depending on the environment during a single run, maintaining the interface would trump simplicity for the simple case). I've not investigated the Django codebase, so I don't know if my guesses line up with it exactly, but it should be quite easy to construct a grep or sed script to scan the source to find out :) -- -- Matt Wheeler http://funkyh.at From tomuxiong at gmx.com Tue Aug 1 07:53:56 2017 From: tomuxiong at gmx.com (Thomas Nyberg) Date: Tue, 1 Aug 2017 13:53:56 +0200 Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On 08/01/2017 01:06 PM, Matt Wheeler wrote: > A function which is moderately expensive to run, that will always return > the same result if run again in the same process, and which will not be > needed in every session. > What about just using a lazy getter property? E.g.: https://pypi.python.org/pypi/lazy-property Cheers, Thomas From tom at tomforb.es Tue Aug 1 08:50:41 2017 From: tom at tomforb.es (tom at tomforb.es) Date: Tue, 1 Aug 2017 05:50:41 -0700 (PDT) Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: Hello all, Thank you for the replies! So, here is the context: 1. The functions Django wants to cache require Django to be initialized and the settings loaded. This means the return values are not available at definition time. (Matt Wheeler hits it on the head). 2. Django has a long-standing no-dependencies rule, which may change in the near future but for now it is stdlib only. We can't add a dependency on `lazy-property`. This is all a bit off-topic anyway. I was merely asking about the tradeoffs for using maxsize=None vs maxsize=default in `lru_cache`. On my Ubuntu machine I am getting some interesting benchmark results. If you disable the LRU cache C extension, so it uses the following implementations: 1. maxsize is not none: https://github.com/python/cpython/blob/master/Lib/functools.py#L526-L581 2. maxsize is none: https://github.com/python/cpython/blob/master/Lib/functools.py#L509-L522 And you have a simple function: def test(): return object() I get the following numbers without much variance: 1. lru_cache(maxsize=None) - 870ns 2. lru_cache() - 1300ns 3. no cache - 100ns So, in the best case, without the C extension lru_cache is 8x as slow as the function itself. I get that it's not a great comparison as few functions are as simple as that, but a 700ns overhead is quite a bit, and if you're putting it around simple functions and expecting them to be faster, that may not be true. With the C extension I get 50ns for both. So obviously a lot faster. Maybe it doesn't matter... From rosuav at gmail.com Tue Aug 1 09:01:12 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 1 Aug 2017 23:01:12 +1000 Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On Tue, Aug 1, 2017 at 10:50 PM, wrote: > And you have a simple function: > > def test(): > return object() > > I get the following numbers without much variance: > > 1. lru_cache(maxsize=None) - 870ns > > 2. lru_cache() - 1300ns > > 3. no cache - 100ns > > So, in the best case, without the C extension lru_cache is 8x as slow as the function itself. I get that it's not a great comparison as few functions are as simple as that, but a 700ns overhead is quite a bit, and if you're putting it around simple functions and expecting them to be faster, that may not be true. > > With the C extension I get 50ns for both. So obviously a lot faster. Maybe it doesn't matter... There's a drastic semantic difference here, though. Without a cache, you're constructing a new, unique object every time you call it; with a cache, you return the same one every time. A better comparison would be: _sentinel = object() def test(): return _sentinel Not that it changes your point about timings, but if you're slapping a cache onto functions to try to make them faster, you want to be sure you're not breaking their semantics. ChrisA From tomuxiong at gmx.com Tue Aug 1 09:10:45 2017 From: tomuxiong at gmx.com (Thomas Nyberg) Date: Tue, 1 Aug 2017 15:10:45 +0200 Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On 08/01/2017 02:50 PM, tom at tomforb.es wrote: > 2. Django has a long-standing no-dependencies rule, which may change in the near future but for now it is stdlib only. We can't add a dependency on `lazy-property`. Apologies for continuing going off-topic, but the actual code in that package I linked appears to be about 40 lines. It's MIT-licensed, so you could just embed it in your code. In fact, I only linked that because it was easily accessible by pip. I personally have used similar versions in the past that were much shorter (presumably missing some features in the package I linked though). For example, I know at some point I used some variation of this (~11 lines): https://github.com/columbia-applied-data-science/rosetta/blob/master/rosetta/common.py#L24-L35 But I do respect the distaste for adding a dependency on something so small. :) Cheers, Thomas From m at funkyhat.org Tue Aug 1 09:14:35 2017 From: m at funkyhat.org (Matt Wheeler) Date: Tue, 01 Aug 2017 13:14:35 +0000 (UTC) Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On Tue, 1 Aug 2017 at 12:53 Thomas Nyberg wrote: > On 08/01/2017 01:06 PM, Matt Wheeler wrote: > > A function which is moderately expensive to run, that will always return > > the same result if run again in the same process, and which will not be > > needed in every session. > > > > What about just using a lazy getter property? E.g.: > > https://pypi.python.org/pypi/lazy-property That doesn't necessarily solve any problems (Tom has already answered why this won't work for Django, but also...) - the methods then can't be passed around before being called, which will make your lazy evaluation greedy again if that's why you're using the lru_cache. - this requires the functions to be methods of an instance of some class (no, you can't use properties on a class, see below). That may be much more overhead than the current solution (the object+class lookups plus @property method call might add up to more overhead to a single object lookup & lru_cache call as a rule anyway. I haven't investigated): Python 3.6.0 (default, Mar 13 2017, 00:53:03) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> class A: ... @property ... @classmethod ... def test(cls): ... return 'a' ... >>> A.test -- -- Matt Wheeler http://funkyh.at From p.f.moore at gmail.com Tue Aug 1 09:48:38 2017 From: p.f.moore at gmail.com (Paul Moore) Date: Tue, 1 Aug 2017 06:48:38 -0700 (PDT) Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On Tuesday, 1 August 2017 00:31:52 UTC+1, t... at tomforb.es wrote: > Am I right in thinking that using `maxsize=None` is best for functions that accept no arguments? Should we even be using a `lru_cache` in such situations, or write our own simple cache decorator instead? It seems like overkill to use lru_cache for this case - it's designed to map arguments to results, so it makes little sense when there are no arguments. It's also got LRU arglist management and thread safety overheads, so there's a lot of unneeded overhead for this usage. _sentinel = object() _val = _sentinel def val(): if _val is _sentinel: # Calculate _val return _val seems entirely sufficient for this case. Write a custom decorator if you use the idiom often enough to make it worth the effort. Paul From christian at python.org Tue Aug 1 09:57:47 2017 From: christian at python.org (Christian Heimes) Date: Tue, 1 Aug 2017 15:57:47 +0200 Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On 2017-08-01 01:31, tom at tomforb.es wrote: > As part of the Python 3 cleanup in Django there are a fair few uses of @functools.lru_cache on functions that take no arguments. A lru_cache isn't strictly needed here, but it's convenient to just cache the result. Some examples are here: https://github.com/django/django/pull/8825/files > > I did some profiling and I found that using `@lru_cache(maxsize=None)` on such functions is twice as fast as a standard `@lru_cache()`, apparently because with a `maxsize` the lru_cache code requires a lock acquisition and a fair bit more state to track. > > Am I right in thinking that using `maxsize=None` is best for functions that accept no arguments? Should we even be using a `lru_cache` in such situations, or write our own simple cache decorator instead? There is a more elegant and faster approach if you use a non-data descriptor instead of a property or a lru_cache. If you use a non-data descriptor property, you can even get rid of subsequent function calls. I dumped some example code in a gist, https://gist.github.com/tiran/da7d4c43d493c5aa7d7abc4d8a0678a6 Christian From tom at tomforb.es Tue Aug 1 10:52:30 2017 From: tom at tomforb.es (tom at tomforb.es) Date: Tue, 1 Aug 2017 07:52:30 -0700 (PDT) Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> > _sentinel = object() > _val = _sentinel > def val(): > if _val is _sentinel: > # Calculate _val > return _val > > seems entirely sufficient for this case. Write a custom decorator if you use the idiom often enough to make it worth the effort. I did some timings with this as part of my timings above and found it to be significantly slower than lru_cache with the C extension. I had to add `nonlocal` to get `_val` to resolve, which I think kills performance a bit. I agree with the premise though, it might be worth exploring. > There is a more elegant and faster approach if you use a non-data > descriptor instead of a property or a lru_cache. If you use a non-data > descriptor property, you can even get rid of subsequent function calls. > I dumped some example code in a gist, > https://gist.github.com/tiran/da7d4c43d493c5aa7d7abc4d8a0678a6 Thank you! That's an interesting and great idea. It's faster, but not faster than lru-cache with the C extension. I'll investigate further. From tjreedy at udel.edu Tue Aug 1 11:05:38 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 1 Aug 2017 11:05:38 -0400 Subject: @lru_cache on functions with no arguments In-Reply-To: References: Message-ID: On 8/1/2017 7:06 AM, Matt Wheeler wrote: > On Tue, 1 Aug 2017 at 02:32 Terry Reedy wrote: > >> On 7/31/2017 7:31 PM, tom at tomforb.es wrote: >>> As part of the Python 3 cleanup in Django there are a fair few uses of >> @functools.lru_cache on functions that take no arguments. >> >> This makes no sense to me. If the function is being called for >> side-effects, then it should not be cached. If the function is being >> called for a result, different for each call, calculated from a changing >> environment, then it should not be cached. (Input from disk is an >> example.) If the function returns a random number, or a non-constant >> value from an oracle (such as a person), it should not be cached. If >> the function returns a constant (possible calculated once), then the >> constant should just be bound to a name (which is a form of caching) >> rather than using the overkill of an lru cache. What possibility am I >> missing? >> > > A function which is moderately expensive to run, that will always return > the same result if run again in the same process, and which will not be > needed in every session. In initialization section: answer = None Somewhere else: answer = expensive_calculaton() if answer is None else answer The conditional has to be cheaper than accessing lru cache. There can be more than one of these. -- Terry Jan Reedy From jobmattcon at gmail.com Tue Aug 1 15:50:23 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Tue, 1 Aug 2017 12:50:23 -0700 (PDT) Subject: how to sort a list of tuples with custom function Message-ID: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> def isneighborlocation(lo1, lo2): if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: return 1 elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: return 1 elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: return 1 else: return 0 sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) return something like [(1,2),(3,3),(2,5)] From jobmattcon at gmail.com Tue Aug 1 16:01:10 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Tue, 1 Aug 2017 13:01:10 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> Message-ID: <7b8e0f12-04e5-4ebc-bd64-1006af03e977@googlegroups.com> i tried with testing1.sort(key=lambda x: x[0]) but only first element of tuple are grouped then i expect to sort with custom function if difference between first element of tuple and another first element of tuple is less than some value and do for second element too, goal to segmentation of black words from photo from PIL import Image from functools import partial ma = Image.open("roster.png") color1 = ma.load() print ma.size print color1[1,1] color1 = ma.load() print ma.size print color1[1,1] colortolocation = {} def addtogroupkey(keyandmemory, key1, memorycontent): k = key1 if k in keyandmemory: keyandmemory[k].append(memorycontent) else: keyandmemory[k] = [memorycontent] return keyandmemory for ii in range(0, ma.size[0]): for jj in range(0, ma.size[1]): colortolocation = addtogroupkey(colortolocation, color1[ii,jj], (ii,jj)) def isneighborlocation(lo1, lo2): if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: return 1 elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: return 1 elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: return 1 else: return 0 for eachcolor in colortolocation: testing1 = list(colortolocation[eachcolor]) #testing1.sort(key=lambda x: x[1]) #custom_list_indices = {v: i for i, v in enumerate(custom_list)} testing1.sort(key=lambda x: x[0]-x[1]) locations = testing1 locationsgroup = {} continueconnect = 0 for ii in range(0,len(locations)-1): if isneighborlocation(locations[ii], locations[ii+1]) == 1: if continueconnect == 0: keyone = len(locationsgroup)+1 if keyone in locationsgroup: if locations[ii] not in locationsgroup[keyone]: locationsgroup = addtogroupkey(locationsgroup, keyone, locations[ii]) if locations[ii+1] not in locationsgroup[keyone]: locationsgroup = addtogroupkey(locationsgroup, keyone, locations[ii+1]) else: locationsgroup = addtogroupkey(locationsgroup, keyone, locations[ii]) locationsgroup = addtogroupkey(locationsgroup, keyone, locations[ii+1]) continueconnect = 1 else: if len(locationsgroup) > 0: if locations[ii] not in locationsgroup[len(locationsgroup)]: locationsgroup = addtogroupkey(locationsgroup, len(locationsgroup)+1, locations[ii]) else: locationsgroup = addtogroupkey(locationsgroup, len(locationsgroup)+1, locations[ii]) continueconnect = 0 colortolocation[eachcolor] = locationsgroup for kk in colortolocation[(0,0,0)]: if len(colortolocation[(0,0,0)][kk]) > 7: print kk print colortolocation[(0,0,0)][kk] On Wednesday, August 2, 2017 at 3:50:52 AM UTC+8, Ho Yeung Lee wrote: > def isneighborlocation(lo1, lo2): > if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > return 1 > elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > return 1 > elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > return 1 > else: > return 0 > > > sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > > return something like > [(1,2),(3,3),(2,5)] From piet-l at vanoostrum.org Tue Aug 1 17:10:06 2017 From: piet-l at vanoostrum.org (Piet van Oostrum) Date: Tue, 01 Aug 2017 23:10:06 +0200 Subject: how to sort a list of tuples with custom function References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> Message-ID: Ho Yeung Lee writes: > def isneighborlocation(lo1, lo2): > if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > return 1 > elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > return 1 > elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > return 1 > else: > return 0 > > > sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > > return something like > [(1,2),(3,3),(2,5)] I think you are trying to sort a list of two-dimensional points into a one-dimensiqonal list in such a way thet points that are close together in the two-dimensional sense will also be close together in the one-dimensional list. But that is impossible. -- Piet van Oostrum WWW: http://piet.vanoostrum.org/ PGP key: [8DAE142BE17999C4] From piet-l at vanoostrum.org Tue Aug 1 17:24:53 2017 From: piet-l at vanoostrum.org (Piet van Oostrum) Date: Tue, 01 Aug 2017 23:24:53 +0200 Subject: how to group by function if one of the group has relationship with another one in the group? References: <1d6f7a4f-86f7-4827-8eb4-b74fa6c8ba40@googlegroups.com> Message-ID: Ho Yeung Lee writes: > which function should be used for this problem? > I think it is a kind if clustering, or a connectivity problem. There are special algorithms for that, not just a simple function. Maybe scikit-learn has a suitable algorithm for it. -- Piet van Oostrum WWW: http://piet.vanoostrum.org/ PGP key: [8DAE142BE17999C4] From v+python at g.nevcal.com Tue Aug 1 18:02:27 2017 From: v+python at g.nevcal.com (Glenn Linderman) Date: Tue, 1 Aug 2017 15:02:27 -0700 Subject: how to sort a list of tuples with custom function In-Reply-To: References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> Message-ID: <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > Ho Yeung Lee writes: > >> def isneighborlocation(lo1, lo2): >> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: >> return 1 >> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: >> return 1 >> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: >> return 1 >> else: >> return 0 >> >> >> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) >> >> return something like >> [(1,2),(3,3),(2,5)] > I think you are trying to sort a list of two-dimensional points into a > one-dimensiqonal list in such a way thet points that are close together > in the two-dimensional sense will also be close together in the > one-dimensional list. But that is impossible. It's not impossible, it just requires an appropriate distance function used in the sort. From jobmattcon at gmail.com Tue Aug 1 19:26:57 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Tue, 1 Aug 2017 16:26:57 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> Message-ID: <77e8c6e7-689c-48d0-be5c-045ef9c653f6@googlegroups.com> how to write this distance function in sort there are the syntax error On Wednesday, August 2, 2017 at 6:03:13 AM UTC+8, Glenn Linderman wrote: > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > > Ho Yeung Lee writes: > > > >> def isneighborlocation(lo1, lo2): > >> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > >> return 1 > >> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > >> return 1 > >> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > >> return 1 > >> else: > >> return 0 > >> > >> > >> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > >> > >> return something like > >> [(1,2),(3,3),(2,5)] > > I think you are trying to sort a list of two-dimensional points into a > > one-dimensiqonal list in such a way thet points that are close together > > in the two-dimensional sense will also be close together in the > > one-dimensional list. But that is impossible. > It's not impossible, it just requires an appropriate distance function > used in the sort. From __peter__ at web.de Wed Aug 2 03:05:56 2017 From: __peter__ at web.de (Peter Otten) Date: Wed, 02 Aug 2017 09:05:56 +0200 Subject: how to sort a list of tuples with custom function References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> Message-ID: Glenn Linderman wrote: > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: >> Ho Yeung Lee writes: >> >>> def isneighborlocation(lo1, lo2): >>> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: >>> return 1 >>> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: >>> return 1 >>> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: >>> return 1 >>> else: >>> return 0 >>> >>> >>> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) >>> >>> return something like >>> [(1,2),(3,3),(2,5)] >> I think you are trying to sort a list of two-dimensional points into a >> one-dimensiqonal list in such a way thet points that are close together >> in the two-dimensional sense will also be close together in the >> one-dimensional list. But that is impossible. > It's not impossible, it just requires an appropriate distance function > used in the sort. That's a grossly misleading addition. Once you have an appropriate clustering algorithm clusters = split_into_clusters(items) # needs access to all items you can devise a key function def get_cluster(item, clusters=split_into_clusters(items)): return next( index for index, cluster in enumerate(clusters) if item in cluster ) such that grouped_items = sorted(items, key=get_cluster) but that's a roundabout way to write grouped_items = sum(split_into_clusters(items), []) In other words: sorting is useless, what you really need is a suitable approach to split the data into groups. One well-known algorithm is k-means clustering: https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.vq.kmeans.html Here is an example with pictures: https://dzone.com/articles/k-means-clustering-scipy From robin at reportlab.com Wed Aug 2 04:13:54 2017 From: robin at reportlab.com (Robin Becker) Date: Wed, 2 Aug 2017 09:13:54 +0100 Subject: cgiapp versus apache & nginx+fcgiwrap Message-ID: <0d01c273-8c12-f6dd-c294-b51211b61424@chamonix.reportlab.co.uk> A client is using servicenow to direct requests to a cgi application. The servicenow mechanism seems to create a whole file json request. For testing purposes the cgi application tries to respond to standard posts as well. The connection part is handled like this F = cgi.FieldStorage(keep_blank_values=False) D = dict( json='', SCRIPT_NAME=os.environ.get('SCRIPT_NAME','app.cgi'), ) try: K = F.keys() except TypeError: K = None if K is not None: for k in K: D[k] = xmlEscape(F.getvalue(k)) json = D['json'] else: try: #assume json is everything D['json'] = F.file.read() except: log_error() so if we don't see any normal cgi arguments we try to read json from the cgi input file. With nginx+fcgiwrap this seems to work well for both normal post/get and the whole file mechanism, but with apache the split never worked; we always seem to get keys in K even if it is an empty list. Looking at the envirnment that the cgi script sees I cannot see anything obvious except the expected differences for the two frontend servers. I assume apache (2.4) is doing something different. The client would feel more comfortable with apache. Does anyone know how to properly distinguish the two mechanisms ie standard POST and a POST with no structure? -- Robin Becker From steve+comp.lang.python at pearwood.info Wed Aug 2 05:00:56 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 02 Aug 2017 09:00:56 GMT Subject: @lru_cache on functions with no arguments References: Message-ID: <598194c7$0$2878$c3e8da3$76491128@news.astraweb.com> On Tue, 01 Aug 2017 11:05:38 -0400, Terry Reedy wrote: > On 8/1/2017 7:06 AM, Matt Wheeler wrote: >> On Tue, 1 Aug 2017 at 02:32 Terry Reedy wrote: >> >>> On 7/31/2017 7:31 PM, tom at tomforb.es wrote: >>>> As part of the Python 3 cleanup in Django there are a fair few uses >>>> of >>> @functools.lru_cache on functions that take no arguments. >>> >>> This makes no sense to me. If the function is being called for >>> side-effects, then it should not be cached. If the function is being >>> called for a result, different for each call, calculated from a >>> changing environment, then it should not be cached. (Input from disk >>> is an example.) If the function returns a random number, or a >>> non-constant value from an oracle (such as a person), it should not be >>> cached. If the function returns a constant (possible calculated >>> once), then the constant should just be bound to a name (which is a >>> form of caching) rather than using the overkill of an lru cache. What >>> possibility am I missing? >>> >>> >> A function which is moderately expensive to run, that will always >> return the same result if run again in the same process, and which will >> not be needed in every session. > > In initialization section: > answer = None > > Somewhere else: > answer = expensive_calculaton() if answer is None else answer > > The conditional has to be cheaper than accessing lru cache. There can > be more than one of these. One conditional has to be cheaper than accessing lru cache. Debugging the errors from forgetting to wrap every single reference to "answer" in a "if answer is None" test is not so cheap. Maintaining twice as much state (one function plus one global variable, instead of just one function) is not so cheap. Sometimes paying a small cost to avoid having to occasionally pay a large cost is worth it. This is effectively the "Only Once" decorator pattern, which guarantees a function only executes once no matter how often you call it. -- ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From seoservices714 at gmail.com Wed Aug 2 05:30:33 2017 From: seoservices714 at gmail.com (Seo Services) Date: Wed, 2 Aug 2017 02:30:33 -0700 (PDT) Subject: Event Ticket | Ticket Printing Malaysia | Fifty Percent Print Message-ID: Event Ticket Fifty percent print is providing services of voucher printing, Event Ticket Printing in Malaysia. Customers can choose size firstly; select the finishing secondly, a variety of supplement for your options, which can satisfy your needs absolutely. Our journals, organizers, or business organizers give you a Chance to advance your service or product as well as to create a year-round bond with your customers. Available in variety materials, sizes and contents, rest assured you will receive the very best value and quality diaries, organizers or business planners. From tritium-list at sdamon.com Wed Aug 2 10:21:23 2017 From: tritium-list at sdamon.com (Alex Walters) Date: Wed, 2 Aug 2017 10:21:23 -0400 Subject: concurrent-log-handler 0.9.6 released In-Reply-To: References: Message-ID: <016701d30b9a$9eef2c20$dccd8460$@sdamon.com> Pypiwin32 exists to allow pywin32 to be installed through pip (thanks to Glyph and the Twisted project for supporting that) > -----Original Message----- > From: Python-announce-list [mailto:python-announce-list-bounces+tritium- > list=sdamon.com at python.org] On Behalf Of Preston Landers > Sent: Sunday, July 30, 2017 11:24 AM > To: python-announce-list at python.org > Subject: concurrent-log-handler 0.9.6 released > > concurrent-log-handler > ====================== > > RotatingFileHandler replacement with concurrency, gzip and Windows > support > -------------------------------------------------------------------------- > > This package provides an additional log handler for Python's standard logging > package (PEP 282). This handler will write log events to a log file which is > rotated when the log file reaches a certain size. Multiple processes can > safely write to the same log file concurrently. Rotated logs can be gzipped > if desired. Windows and POSIX systems are supported. An optional threaded > queue logging handler is provided to perform logging in the background. > > This is a fork of Lowell Alleman's ConcurrentLogHandler 0.9.1 with additional > enhancements: > > * Renamed package to `concurrent_log_handler` > * Provide `use_gzip` option to compress rotated logs > * Support for Windows > * Note: PyWin32 is required on Windows, but can't be installed as an > automatic dependency because it's not currently installable through pip. > * Fix deadlocking problem with ConcurrentLogHandler under newer Python > * More secure generation of random numbers for temporary filenames > * Change the name of the lockfile to have .__ in front of it (hide it on Posix) > * Provide a QueueListener / QueueHandler implementation for > handling log events in a background thread. Optional: requires Python 3. > > > Download > ======== > > `pip install concurrent-log-handler` > > https://github.com/Preston-Landers/concurrent-log-handler > > https://pypi.python.org/pypi/concurrent-log-handler > > > > News / Changes > ============== > > - 0.9.7/0.9.6: Fix platform specifier for PyPi > > - 0.9.5: Add `use_gzip` option to compress rotated logs. Add an > optional threaded > logging queue handler based on the standard library's > `logging.QueueHandler`. > > - 0.9.4: Fix setup.py to not include tests in distribution. > > - 0.9.3: Refactoring release > * For publishing fork on pypi as `concurrent-log-handler` under new > package name. > * NOTE: PyWin32 is required on Windows but is not an explicit > dependency because > the PyWin32 package is not currently installable through pip. > * Fix lock behavior / race condition > > - 0.9.2: Initial release of fork by Preston Landers based on a fork of > Lowell Alleman's > ConcurrentLogHandler 0.9.1 > * Fixes deadlocking issue with recent versions of Python > * Puts `.__` prefix in front of lock file name > * Use `secrets` or `SystemRandom` if available. > * Add/fix Windows support > > > > thanks, > Preston > -- > https://mail.python.org/mailman/listinfo/python-announce-list > > Support the Python Software Foundation: > http://www.python.org/psf/donations/ From daiyueweng at gmail.com Wed Aug 2 11:05:24 2017 From: daiyueweng at gmail.com (Daiyue Weng) Date: Wed, 2 Aug 2017 16:05:24 +0100 Subject: how to fast processing one million strings to remove quotes Message-ID: Hi, I am trying to removing extra quotes from a large set of strings (a list of strings), so for each original string, it looks like, """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" I like to remove the start and end quotes and extra pairs of quotes on each string value, so the result will look like, "str_value1","str_value2","str_value3",1,"str_value4" and then join each string by a new line. I have tried the following code, for line in str_lines[1:]: strip_start_end_quotes = line[1:-1] splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', '"') str_lines[str_lines.index(line)] = splited_line_rem_quotes for_pandas_new_headers_str = '\n'.join(splited_lines) but it is really slow (running for ages) if the list contains over 1 million string lines. I am thinking about a fast way to do that. I also tried to multiprocessing this task by def preprocess_data_str_line(data_str_lines): """ :param data_str_lines: :return: """ for line in data_str_lines: strip_start_end_quotes = line[1:-1] splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', '"') data_str_lines[data_str_lines.index(line)] = splited_line_rem_quotes return data_str_lines def multi_process_prepcocess_data_str(data_str_lines): """ :param data_str_lines: :return: """ # if cpu load < 25% and 4GB of ram free use 3 cores # if cpu load < 70% and 4GB of ram free use 2 cores cores_to_use = how_many_core() data_str_blocks = slice_list(data_str_lines, cores_to_use) for block in data_str_blocks: # spawn processes for each data string block assigned to every cpu core p = multiprocessing.Process(target=preprocess_data_str_line, args=(block,)) p.start() but I don't know how to concatenate the results back into the list so that I can join the strings in the list by new lines. So, ideally, I am thinking about using multiprocessing + a fast function to preprocessing each line to speed up the whole process. cheers From python at mrabarnett.plus.com Wed Aug 2 13:05:52 2017 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 2 Aug 2017 18:05:52 +0100 Subject: how to fast processing one million strings to remove quotes In-Reply-To: References: Message-ID: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> On 2017-08-02 16:05, Daiyue Weng wrote: > Hi, I am trying to removing extra quotes from a large set of strings (a > list of strings), so for each original string, it looks like, > > """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" > > > I like to remove the start and end quotes and extra pairs of quotes on each > string value, so the result will look like, > > "str_value1","str_value2","str_value3",1,"str_value4" > > > and then join each string by a new line. > > I have tried the following code, > > for line in str_lines[1:]: > strip_start_end_quotes = line[1:-1] > splited_line_rem_quotes = > strip_start_end_quotes.replace('\"\"', '"') > str_lines[str_lines.index(line)] = splited_line_rem_quotes > > for_pandas_new_headers_str = '\n'.join(splited_lines) > > but it is really slow (running for ages) if the list contains over 1 > million string lines. I am thinking about a fast way to do that. > [snip] The problem is the line: str_lines[str_lines.index(line)] It does a linear search through str_lines until time finds a match for the line. To find the 10th line it must search through the first 10 lines. To find the 100th line it must search through the first 100 lines. To find the 1000th line it must search through the first 1000 lines. And so on. In Big-O notation, the performance is O(n**2). The Pythonic way of doing it is to put the results into a new list: new_str_lines = str_lines[:1] for line in str_lines[1:]: strip_start_end_quotes = line[1:-1] splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', '"') new_str_lines.append(splited_line_rem_quotes) In Big-O notation, the performance is O(n). From arequipeno at gmail.com Wed Aug 2 13:21:56 2017 From: arequipeno at gmail.com (Ian Pilcher) Date: Wed, 2 Aug 2017 12:21:56 -0500 Subject: Get list of attributes from list of objects? Message-ID: Given a list of objects that all have a particular attribute, is there a simple way to get a list of those attributes? In other words: class Foo(object): def __init__(self, name): self.name = name foolist = [ Foo('a'), Foo('b'), Foo('c') ] namelist = [] for foo in foolist: namelist.append(foo.name) Is there a way to avoid the for loop and create 'namelist' with a single expression? -- ======================================================================== Ian Pilcher arequipeno at gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ======================================================================== From daiyueweng at gmail.com Wed Aug 2 13:48:20 2017 From: daiyueweng at gmail.com (Daiyue Weng) Date: Wed, 2 Aug 2017 18:48:20 +0100 Subject: how to fast processing one million strings to remove quotes In-Reply-To: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> References: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> Message-ID: that works superbly! any idea about how to multi process the task and concatenate results from each process back into a list? On 2 August 2017 at 18:05, MRAB wrote: > On 2017-08-02 16:05, Daiyue Weng wrote: > >> Hi, I am trying to removing extra quotes from a large set of strings (a >> list of strings), so for each original string, it looks like, >> >> """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" >> >> >> I like to remove the start and end quotes and extra pairs of quotes on >> each >> string value, so the result will look like, >> >> "str_value1","str_value2","str_value3",1,"str_value4" >> >> >> and then join each string by a new line. >> >> I have tried the following code, >> >> for line in str_lines[1:]: >> strip_start_end_quotes = line[1:-1] >> splited_line_rem_quotes = >> strip_start_end_quotes.replace('\"\"', '"') >> str_lines[str_lines.index(line)] = splited_line_rem_quotes >> >> for_pandas_new_headers_str = '\n'.join(splited_lines) >> >> but it is really slow (running for ages) if the list contains over 1 >> million string lines. I am thinking about a fast way to do that. >> >> [snip] > > The problem is the line: > > str_lines[str_lines.index(line)] > > It does a linear search through str_lines until time finds a match for the > line. > > To find the 10th line it must search through the first 10 lines. > > To find the 100th line it must search through the first 100 lines. > > To find the 1000th line it must search through the first 1000 lines. > > And so on. > > In Big-O notation, the performance is O(n**2). > > The Pythonic way of doing it is to put the results into a new list: > > > new_str_lines = str_lines[:1] > > for line in str_lines[1:]: > strip_start_end_quotes = line[1:-1] > splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', '"') > new_str_lines.append(splited_line_rem_quotes) > > > In Big-O notation, the performance is O(n). > -- > https://mail.python.org/mailman/listinfo/python-list > From rosuav at gmail.com Wed Aug 2 13:49:59 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 3 Aug 2017 03:49:59 +1000 Subject: Get list of attributes from list of objects? In-Reply-To: References: Message-ID: On Thu, Aug 3, 2017 at 3:21 AM, Ian Pilcher wrote: > Given a list of objects that all have a particular attribute, is there > a simple way to get a list of those attributes? > > In other words: > > class Foo(object): > def __init__(self, name): > self.name = name > > foolist = [ Foo('a'), Foo('b'), Foo('c') ] > > namelist = [] > for foo in foolist: > namelist.append(foo.name) > > Is there a way to avoid the for loop and create 'namelist' with a single > expression? You can't eliminate the loop, but you can compact it into a single logical operation: namelist = [foo.name for foo in foolist] That's a "list comprehension", and is an elegant way to process a list in various ways. ChrisA From tjreedy at udel.edu Wed Aug 2 14:00:12 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 2 Aug 2017 14:00:12 -0400 Subject: how to fast processing one million strings to remove quotes In-Reply-To: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> References: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> Message-ID: On 8/2/2017 1:05 PM, MRAB wrote: > On 2017-08-02 16:05, Daiyue Weng wrote: >> Hi, I am trying to removing extra quotes from a large set of strings (a >> list of strings), so for each original string, it looks like, >> >> """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" >> >> >> I like to remove the start and end quotes and extra pairs of quotes on >> each >> string value, so the result will look like, >> >> "str_value1","str_value2","str_value3",1,"str_value4" >> >> >> and then join each string by a new line. >> >> I have tried the following code, >> >> for line in str_lines[1:]: >> strip_start_end_quotes = line[1:-1] >> splited_line_rem_quotes = >> strip_start_end_quotes.replace('\"\"', '"') >> str_lines[str_lines.index(line)] = splited_line_rem_quotes >> >> for_pandas_new_headers_str = '\n'.join(splited_lines) Do you actually need the list of strings joined up like that into one string, or will the one string just be split again into multiple strings? >> but it is really slow (running for ages) if the list contains over 1 >> million string lines. I am thinking about a fast way to do that. >> > [snip] > > The problem is the line: > > str_lines[str_lines.index(line)] > > It does a linear search through str_lines until time finds a match for > the line. > > To find the 10th line it must search through the first 10 lines. > > To find the 100th line it must search through the first 100 lines. > > To find the 1000th line it must search through the first 1000 lines. > > And so on. > > In Big-O notation, the performance is O(n**2). > > The Pythonic way of doing it is to put the results into a new list: > > > new_str_lines = str_lines[:1] > > for line in str_lines[1:]: > strip_start_end_quotes = line[1:-1] > splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', '"') > new_str_lines.append(splited_line_rem_quotes) > > > In Big-O notation, the performance is O(n). Making a slice copy of all but the first member of the list is also unnecessary. Use an iterator instead. lineit = iter(str_lines) new_str_lines = [next(lineit)] for line in lineit: ... -- Terry Jan Reedy From tjreedy at udel.edu Wed Aug 2 14:01:14 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 2 Aug 2017 14:01:14 -0400 Subject: Get list of attributes from list of objects? In-Reply-To: References: Message-ID: On 8/2/2017 1:21 PM, Ian Pilcher wrote: > Given a list of objects that all have a particular attribute, is there > a simple way to get a list of those attributes? > > In other words: > > class Foo(object): > def __init__(self, name): > self.name = name > > foolist = [ Foo('a'), Foo('b'), Foo('c') ] > > namelist = [] > for foo in foolist: > namelist.append(foo.name) > > Is there a way to avoid the for loop and create 'namelist' with a single > expression? namelist = [foo.name for foo in foolist] -- Terry Jan Reedy From __peter__ at web.de Wed Aug 2 14:13:59 2017 From: __peter__ at web.de (Peter Otten) Date: Wed, 02 Aug 2017 20:13:59 +0200 Subject: how to fast processing one million strings to remove quotes References: Message-ID: Daiyue Weng wrote: > Hi, I am trying to removing extra quotes from a large set of strings (a > list of strings), so for each original string, it looks like, > > """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" Where did you get that strange list from in the first place? If it is read from a file it is likely that you can parse the data into the desired format directly, e. g. by using the csv module. From daiyueweng at gmail.com Wed Aug 2 14:18:02 2017 From: daiyueweng at gmail.com (Daiyue Weng) Date: Wed, 2 Aug 2017 19:18:02 +0100 Subject: how to fast processing one million strings to remove quotes In-Reply-To: References: Message-ID: it is getting from an encrypted and snappy file On 2 August 2017 at 19:13, Peter Otten <__peter__ at web.de> wrote: > Daiyue Weng wrote: > > > Hi, I am trying to removing extra quotes from a large set of strings (a > > list of strings), so for each original string, it looks like, > > > > """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" > > Where did you get that strange list from in the first place? > > If it is read from a file it is likely that you can parse the data into the > desired format directly, e. g. by using the csv module. > > > -- > https://mail.python.org/mailman/listinfo/python-list > From arequipeno at gmail.com Wed Aug 2 14:41:09 2017 From: arequipeno at gmail.com (Ian Pilcher) Date: Wed, 2 Aug 2017 13:41:09 -0500 Subject: Get list of attributes from list of objects? In-Reply-To: References: Message-ID: On 08/02/2017 12:49 PM, Chris Angelico wrote: > On Thu, Aug 3, 2017 at 3:21 AM, Ian Pilcher wrote: > You can't eliminate the loop, but you can compact it into a single > logical operation: > > namelist = [foo.name for foo in foolist] > > That's a "list comprehension", and is an elegant way to process a list > in various ways. Very nice! Thank you! -- ======================================================================== Ian Pilcher arequipeno at gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ======================================================================== From __peter__ at web.de Wed Aug 2 14:42:56 2017 From: __peter__ at web.de (Peter Otten) Date: Wed, 02 Aug 2017 20:42:56 +0200 Subject: how to fast processing one million strings to remove quotes References: Message-ID: Daiyue Weng wrote: > On 2 August 2017 at 19:13, Peter Otten <__peter__ at web.de> wrote: > >> Daiyue Weng wrote: >> >> > Hi, I am trying to removing extra quotes from a large set of strings (a >> > list of strings), so for each original string, it looks like, >> > >> > """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" >> >> Where did you get that strange list from in the first place? >> >> If it is read from a file it is likely that you can parse the data into >> the desired format directly, e. g. by using the csv module. > it is getting from an encrypted and snappy file Provided it is only a few lines it might be helpful if you could post the code to create the list ;) From attend at home.srv Wed Aug 2 14:50:00 2017 From: attend at home.srv (attend) Date: Wed, 02 Aug 2017 18:50:00 GMT Subject: python in chromebook References: Message-ID: On Thu, 27 Jul 2017 10:03:29 +0900, Byung-Hee HWANG (???, ???) wrote: > my computer is chromebook. how can i install python in chromebook? > barely i did meet develop mode of chromebook. also i'm new to python. > > INDEED, i want to make python code on my chromebook. > > thanks in avance!!! google crouton chromebook From ian.g.kelly at gmail.com Wed Aug 2 14:50:31 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 2 Aug 2017 12:50:31 -0600 Subject: Get list of attributes from list of objects? In-Reply-To: References: Message-ID: On Wed, Aug 2, 2017 at 11:49 AM, Chris Angelico wrote: > On Thu, Aug 3, 2017 at 3:21 AM, Ian Pilcher wrote: >> Given a list of objects that all have a particular attribute, is there >> a simple way to get a list of those attributes? >> >> In other words: >> >> class Foo(object): >> def __init__(self, name): >> self.name = name >> >> foolist = [ Foo('a'), Foo('b'), Foo('c') ] >> >> namelist = [] >> for foo in foolist: >> namelist.append(foo.name) >> >> Is there a way to avoid the for loop and create 'namelist' with a single >> expression? > > You can't eliminate the loop Well, you can do this: namelist = list(map(operator.attrgetter('name'), foolist)) But use what Chris and Terry suggested; it's cleaner. From no_reply at vedu.org Wed Aug 2 15:05:00 2017 From: no_reply at vedu.org (Vedarth Sharma) Date: Wed, 2 Aug 2017 19:05:00 +0000 (UTC) Subject: Will my project be accepted in pypi? References: Message-ID: There are lots of cool things on PyPI. For instance, check out pytube as well. It's similar to youtube-dl. Cheers, Vedu From v+python at g.nevcal.com Wed Aug 2 15:34:24 2017 From: v+python at g.nevcal.com (Glenn Linderman) Date: Wed, 2 Aug 2017 12:34:24 -0700 Subject: cgiapp versus apache & nginx+fcgiwrap In-Reply-To: <0d01c273-8c12-f6dd-c294-b51211b61424@chamonix.reportlab.co.uk> References: <0d01c273-8c12-f6dd-c294-b51211b61424@chamonix.reportlab.co.uk> Message-ID: On 8/2/2017 1:13 AM, Robin Becker wrote: > we always seem to get keys in K even if it is an empty list. Can you treat None and empty list the same? > > Looking at the envirnment that the cgi script sees I cannot see > anything obvious except the expected differences for the two frontend > servers. Might be more enlightening to look at the input data stream, if the environment is the same. From breezy at bestweb.net Wed Aug 2 17:36:36 2017 From: breezy at bestweb.net (breezy at bestweb.net) Date: Wed, 2 Aug 2017 17:36:36 -0400 (EDT) Subject: first code attempt Message-ID: <1903b32dd2c537baea984b96f128b1c4.squirrel@webmail2.bestweb.net> Hello, I am using the workbook Computer Coding by Jon Woodcock, published by DK WORKBOOKS, to try to learn computer coding. I only get to pages 10 and 11 in Robot Programs when round robots appear in squares to manipulate them. Where in the world do I find robots and squares? I would appreciate your help. Thank you. George Wilson From arequipeno at gmail.com Wed Aug 2 18:26:59 2017 From: arequipeno at gmail.com (Ian Pilcher) Date: Wed, 2 Aug 2017 17:26:59 -0500 Subject: Subclassing dict to modify values Message-ID: YANQ (Yet Another Newbie Question) ... I would like to create a subclass of dict that modifies values as they are inserted. (Effectively I want to do the equivalent of "interning" the values, although they aren't strings.) Do I need to implement any methods other than __setitem__? (I.e. will any other methods/operators that add values to the dictionary call my __setitem__ method?) -- ======================================================================== Ian Pilcher arequipeno at gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ======================================================================== From rantingrickjohnson at gmail.com Wed Aug 2 19:30:37 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Wed, 2 Aug 2017 16:30:37 -0700 (PDT) Subject: first code attempt In-Reply-To: References: <1903b32dd2c537baea984b96f128b1c4.squirrel@webmail2.bestweb.net> Message-ID: <063e04b6-a772-49bd-a737-5a5d741885d7@googlegroups.com> On Wednesday, August 2, 2017 at 5:34:18 PM UTC-5, bre... at bestweb.net wrote: > Hello, > I am using the workbook Computer Coding by Jon Woodcock, > published by DK WORKBOOKS, to try to learn computer coding. > I only get to pages 10 and 11 in Robot Programs when round > robots appear in squares to manipulate them. Where in the > world do I find robots and squares? As for squares, you came to right place! Not quite bottom of the barrel "okee from muskogee" squares, but somewhere along a graduated scale, for sure. As for robots, i'm sure a few of the "malevolent type" are still running around in Elon Musks' nightmares. But seriously. ;-) If you need help with a coding question, then you should post the code along with any error messages you may have received. Asking vague questions typically does not produce a desirable result. Of course, asking vague questions about a random Python beginners' guide that few here have ever heard of, would produce even less desirable results. The key to eliciting good answers is to be specific, articulate and explicit. Try again. From m at funkyhat.org Wed Aug 2 20:02:29 2017 From: m at funkyhat.org (Matt Wheeler) Date: Thu, 03 Aug 2017 00:02:29 +0000 (UTC) Subject: Subclassing dict to modify values In-Reply-To: References: Message-ID: On Wed, 2 Aug 2017 at 23:26 Ian Pilcher wrote: > YANQ (Yet Another Newbie Question) ... > > I would like to create a subclass of dict that modifies values as they > are inserted. (Effectively I want to do the equivalent of "interning" > the values, although they aren't strings.) > > Do I need to implement any methods other than __setitem__? (I.e. will > any other methods/operators that add values to the dictionary call my > __setitem__ method?) > Yes. At least update and setdefault will also need to be overridden. You will probably be better off creating a class which inherits from collections.MutableMapping . A MutableMapping subclass behaves like a dict (i.e. is a mapping type) as long as the minimum required methods are defined. See the table for the required methods at https://docs.python.org/3/library/collections.abc.html#collections-abstract-base-classes All of the mixin methods (the ones defined for you) will call the abstract methods you override. -- -- Matt Wheeler http://funkyh.at From robertvstepp at gmail.com Wed Aug 2 20:22:20 2017 From: robertvstepp at gmail.com (boB Stepp) Date: Wed, 2 Aug 2017 19:22:20 -0500 Subject: first code attempt In-Reply-To: <1903b32dd2c537baea984b96f128b1c4.squirrel@webmail2.bestweb.net> References: <1903b32dd2c537baea984b96f128b1c4.squirrel@webmail2.bestweb.net> Message-ID: On Wed, Aug 2, 2017 at 4:36 PM, wrote: > Hello, > I am using the workbook Computer Coding by Jon Woodcock, published by DK > WORKBOOKS, to try to learn computer coding. I only get to pages 10 and 11 > in Robot Programs when round robots appear in squares to manipulate them. > Where in the world do I find robots and squares? I happened to find preview pages for pages 10-11 on the publisher's website: https://www.dk.com/us/9781465426857-dk-workbooks-computer-coding/ I suggest you reread page 10 very carefully. This is a paper and pencil set of exercises; nothing is typed into the computer. You have a "programming language" for your paper and pencil robot with just three instructions: (1) "F": This instruction moves your robot forward one square. (2) "R": Rotate your robot in place 90 degrees (a quarter-turn) to the right. (3) "L": Rotate your robot in place 90 degrees (a quarter-turn) to the left. The author wants you to figure out what sequence of these three instructions ("F", "R", and "L") are needed to navigate the paper robot through the printed mazes provided in the book. In each problem the robot starts out on the green circle of each printed diagram and your task is to get the robot to the square with the checkered flag. The actual problems are on page 11. The instructions say that the robot cannot go through pink walls, so you will have to write down the correct instructions to get around such obstacles. Look closely at the example on page 10. This shows how to write down the instructions to get through that simple maze. Again, this is a paper and pencil exercise with a very simple 3 instruction programming language. The author is trying to get you to understand how detailed and simple the steps need to be to program a computer. You have to be very specific! And programming languages have a very limited vocabulary compared to a natural human language. Programming language "words" mean very specific things, normally one such "thing" per word. English words, for instance, may mean a variety of things depending on the context where they are being used. I hope this helps! Later in the book they will get to how to do things in the Python programming language (Or so the book description says.). You might want to consider joining the Python Tutor list (https://mail.python.org/mailman/listinfo/tutor). This is meant for newcomers to Python who have a lot of basic questions. This list is more oriented towards already competent Python programmers who tend to go off on interesting technical tangents. ~(:>)) -- boB From rantingrickjohnson at gmail.com Wed Aug 2 21:17:38 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Wed, 2 Aug 2017 18:17:38 -0700 (PDT) Subject: first code attempt In-Reply-To: References: <1903b32dd2c537baea984b96f128b1c4.squirrel@webmail2.bestweb.net> Message-ID: <4f2007bf-0b4c-44cc-abf3-89e419381a17@googlegroups.com> On Wednesday, August 2, 2017 at 7:22:56 PM UTC-5, boB Stepp wrote: > You might want to consider joining the Python Tutor list > (https://mail.python.org/mailman/listinfo/tutor). This is meant for > newcomers to Python who have a lot of basic questions. I would second that advice. However, i would also urge the OP to lurk, listen and participate in this group as much as possible. Simply asking questions is not the path to enlightenment, no, one must learn to swim with sharks and run with wolves is one is become competent in any field of expertise. Self confidence and communication skills are just as important as technical skills and library/interface memorization. > This list is more oriented towards already competent Python > programmers who tend to go off on interesting technical > tangents. ~(:>)) Not _always_ interesting (unless i'm participating ;-)[1], but most of the time, yes. And such a diverse range of ideas and topics can only be fostered in a forum that maintains a deep respect for the freedom of speech. Which is why this open forum is so vital to the Python community. Exposure to diverse forms of knowledge is the _key_ to becoming a proficient problem solver. [1] As per Rick's "Theory of Subjectivity"[2] [2] But let's not go off on that tangent...[3] [3] At least, not today O:-) From jobmattcon at gmail.com Wed Aug 2 22:01:34 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Wed, 2 Aug 2017 19:01:34 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> Message-ID: <2125bf76-229d-4ffb-a921-c8c859f62022@googlegroups.com> https://gist.github.com/hoyeunglee/f371f66d55f90dda043f7e7fea38ffa2 I am near succeed in another way, please run above code when so much black words, it will be very slow so I only open notepad and maximum it without any content then capture screen and save as roster.png and run it, but I discover it can not circle all words with red rectangle and only part of words On Wednesday, August 2, 2017 at 3:06:40 PM UTC+8, Peter Otten wrote: > Glenn Linderman wrote: > > > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > >> Ho Yeung Lee writes: > >> > >>> def isneighborlocation(lo1, lo2): > >>> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > >>> return 1 > >>> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > >>> return 1 > >>> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > >>> return 1 > >>> else: > >>> return 0 > >>> > >>> > >>> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > >>> > >>> return something like > >>> [(1,2),(3,3),(2,5)] > > >> I think you are trying to sort a list of two-dimensional points into a > >> one-dimensiqonal list in such a way thet points that are close together > >> in the two-dimensional sense will also be close together in the > >> one-dimensional list. But that is impossible. > > > It's not impossible, it just requires an appropriate distance function > > used in the sort. > > That's a grossly misleading addition. > > Once you have an appropriate clustering algorithm > > clusters = split_into_clusters(items) # needs access to all items > > you can devise a key function > > def get_cluster(item, clusters=split_into_clusters(items)): > return next( > index for index, cluster in enumerate(clusters) if item in cluster > ) > > such that > > grouped_items = sorted(items, key=get_cluster) > > but that's a roundabout way to write > > grouped_items = sum(split_into_clusters(items), []) > > In other words: sorting is useless, what you really need is a suitable > approach to split the data into groups. > > One well-known algorithm is k-means clustering: > > https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.vq.kmeans.html > > Here is an example with pictures: > > https://dzone.com/articles/k-means-clustering-scipy From kryptxy at protonmail.com Wed Aug 2 23:00:47 2017 From: kryptxy at protonmail.com (Kryptxy) Date: Wed, 02 Aug 2017 23:00:47 -0400 Subject: Command-line torrent search tool (windows/linux) Message-ID: Torrench - A Command-line torrent search tool - For windows and Linux OS The tool fetches torrents from existing torrent-hosting sites. Websites supported: 1. linuxtracker.org - Get linux distros ISO torrents 2. ThePirateBay - Do read usage instructions. Project is in python3, and is completely open-source. Project link: https://github.com/kryptxy/torrench I plan on hosting it on pypi as well as AUR (Arch User repository) :) Hope you like this tool, and find it useful. Feedback/suggestions are highly appreciated. From thebalancepro at gmail.com Wed Aug 2 23:16:02 2017 From: thebalancepro at gmail.com (Nick Mellor) Date: Wed, 2 Aug 2017 20:16:02 -0700 (PDT) Subject: how to fast processing one million strings to remove quotes In-Reply-To: References: Message-ID: On Thursday, 3 August 2017 01:05:57 UTC+10, Daiyue Weng wrote: > Hi, I am trying to removing extra quotes from a large set of strings (a > list of strings), so for each original string, it looks like, > > """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" > > > I like to remove the start and end quotes and extra pairs of quotes on each > string value, so the result will look like, > > "str_value1","str_value2","str_value3",1,"str_value4" > > > and then join each string by a new line. > > I have tried the following code, > > for line in str_lines[1:]: > strip_start_end_quotes = line[1:-1] > splited_line_rem_quotes = > strip_start_end_quotes.replace('\"\"', '"') > str_lines[str_lines.index(line)] = splited_line_rem_quotes > > for_pandas_new_headers_str = '\n'.join(splited_lines) > > but it is really slow (running for ages) if the list contains over 1 > million string lines. I am thinking about a fast way to do that. > > I also tried to multiprocessing this task by > > def preprocess_data_str_line(data_str_lines): > """ > > :param data_str_lines: > :return: > """ > for line in data_str_lines: > strip_start_end_quotes = line[1:-1] > splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', > '"') > data_str_lines[data_str_lines.index(line)] = splited_line_rem_quotes > > return data_str_lines > > > def multi_process_prepcocess_data_str(data_str_lines): > """ > > :param data_str_lines: > :return: > """ > # if cpu load < 25% and 4GB of ram free use 3 cores > # if cpu load < 70% and 4GB of ram free use 2 cores > cores_to_use = how_many_core() > > data_str_blocks = slice_list(data_str_lines, cores_to_use) > > for block in data_str_blocks: > # spawn processes for each data string block assigned to every cpu > core > p = multiprocessing.Process(target=preprocess_data_str_line, > args=(block,)) > p.start() > > but I don't know how to concatenate the results back into the list so that > I can join the strings in the list by new lines. > > So, ideally, I am thinking about using multiprocessing + a fast function to > preprocessing each line to speed up the whole process. > > cheers Hi MRAB, My first thought is to use split/join to solve this problem, but you would need to decide what to do with the non-strings in your 1,000,000 element list. You also need to be sure that the pipe character | is in none of your strings. split_on_dbl_dbl_quote = original_list.join('|').split('""') remove_dbl_dbl_quotes_and_outer_quotes = split_on_dbl_dbl_quote[::2].join('').split('|') You need to be sure of your data: [::2] (return just even-numbered elements) relies on all double-double-quotes both opening and closing within the same string. This runs in under a second for a million strings but does affect *all* elements, not just strings. The non-strings would become strings after the second statement. As to multi-processing: I would be looking at well-optimised single-thread solutions like split/join before I consider MP. If you can fit the problem to a split-join it'll be much simpler and more "pythonic". Cheers, Nick From robin at reportlab.com Thu Aug 3 03:53:10 2017 From: robin at reportlab.com (Robin Becker) Date: Thu, 3 Aug 2017 08:53:10 +0100 Subject: cgiapp versus apache & nginx+fcgiwrap In-Reply-To: References: <0d01c273-8c12-f6dd-c294-b51211b61424@chamonix.reportlab.co.uk> Message-ID: On 02/08/2017 20:34, Glenn Linderman wrote: > On 8/2/2017 1:13 AM, Robin Becker wrote: > >> we always seem to get keys in K even if it is an empty list. > > Can you treat None and empty list the same? > >> >> Looking at the envirnment that the cgi script sees I cannot see anything >> obvious except the expected differences for the two frontend servers. > > Might be more enlightening to look at the input data stream, if the environment > is the same. Seems for the servicenow requests that with apache no CONTENT_TYPE is set in the environment, but nginx+fcgiwrap has CONTENT_TYPE=''. That makes cgi.FieldStorage behave differently as when not available it sets a default content-type of "application/x-www-form-urlencoded" which then forces a parse and creates an empty list attribute. I think the way forward would be to force an empty CONTENT_TYPE into the environment if it is not already set. -- Robin Becker From nomail at com.invalid Thu Aug 3 03:53:43 2017 From: nomail at com.invalid (ast) Date: Thu, 3 Aug 2017 09:53:43 +0200 Subject: coroutines Message-ID: <5982d68b$0$4817$426a74cc@news.free.fr> Hello Here a code for a simple demultiplexer coroutine def demultiplexer(target1, target2): while True: data = yield target1.send(data) target2.send(data) When data is sent to target1, what Cpython do immediately after ? 1- Go on execute demultiplexer, so send a data to target2 then pause demultiplexer when it reach line data=yied, then execute coroutine target1, then execute coroutine target2 or 2- Go and execute target1 coroutine, then resume demultiplexer, so send a data to target2, go to target2, then resume demultiplexer and stops From jobmattcon at gmail.com Thu Aug 3 03:54:01 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Thu, 3 Aug 2017 00:54:01 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: <2125bf76-229d-4ffb-a921-c8c859f62022@googlegroups.com> References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> <2125bf76-229d-4ffb-a921-c8c859f62022@googlegroups.com> Message-ID: <6c682f07-3f13-4393-b004-9c182616e64e@googlegroups.com> https://gist.github.com/hoyeunglee/3d340ab4e9a3e2b7ad7307322055b550 I updated again how to do better because some words are stored in different files On Thursday, August 3, 2017 at 10:02:01 AM UTC+8, Ho Yeung Lee wrote: > https://gist.github.com/hoyeunglee/f371f66d55f90dda043f7e7fea38ffa2 > > I am near succeed in another way, please run above code > > when so much black words, it will be very slow > so I only open notepad and maximum it without any content > then capture screen and save as roster.png > > and run it, but I discover it can not circle all words with red rectangle > and only part of words > > > On Wednesday, August 2, 2017 at 3:06:40 PM UTC+8, Peter Otten wrote: > > Glenn Linderman wrote: > > > > > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > > >> Ho Yeung Lee writes: > > >> > > >>> def isneighborlocation(lo1, lo2): > > >>> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > > >>> return 1 > > >>> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > > >>> return 1 > > >>> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > > >>> return 1 > > >>> else: > > >>> return 0 > > >>> > > >>> > > >>> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > > >>> > > >>> return something like > > >>> [(1,2),(3,3),(2,5)] > > > > >> I think you are trying to sort a list of two-dimensional points into a > > >> one-dimensiqonal list in such a way thet points that are close together > > >> in the two-dimensional sense will also be close together in the > > >> one-dimensional list. But that is impossible. > > > > > It's not impossible, it just requires an appropriate distance function > > > used in the sort. > > > > That's a grossly misleading addition. > > > > Once you have an appropriate clustering algorithm > > > > clusters = split_into_clusters(items) # needs access to all items > > > > you can devise a key function > > > > def get_cluster(item, clusters=split_into_clusters(items)): > > return next( > > index for index, cluster in enumerate(clusters) if item in cluster > > ) > > > > such that > > > > grouped_items = sorted(items, key=get_cluster) > > > > but that's a roundabout way to write > > > > grouped_items = sum(split_into_clusters(items), []) > > > > In other words: sorting is useless, what you really need is a suitable > > approach to split the data into groups. > > > > One well-known algorithm is k-means clustering: > > > > https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.vq.kmeans.html > > > > Here is an example with pictures: > > > > https://dzone.com/articles/k-means-clustering-scipy From jobmattcon at gmail.com Thu Aug 3 04:03:06 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Thu, 3 Aug 2017 01:03:06 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: <6c682f07-3f13-4393-b004-9c182616e64e@googlegroups.com> References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> <2125bf76-229d-4ffb-a921-c8c859f62022@googlegroups.com> <6c682f07-3f13-4393-b004-9c182616e64e@googlegroups.com> Message-ID: <1a2f83c4-5352-44e7-95bf-6b4fd230c742@googlegroups.com> I remove red line and capture another version https://gist.github.com/hoyeunglee/99bbe7999bc489a79ffdf0277e80ecb6 it can capture words in windows, but since window words some are black and some gray, some are not exactly black, so I only choose notepad , since it is using black words but some words are splitted, I have already sorted by x[0] and x[1] can it improver to a consecutively a few words "??" <- File is succeed but "????" failed since words are splitted On Thursday, August 3, 2017 at 3:54:13 PM UTC+8, Ho Yeung Lee wrote: > https://gist.github.com/hoyeunglee/3d340ab4e9a3e2b7ad7307322055b550 > > I updated again > > how to do better because some words are stored in different files > > On Thursday, August 3, 2017 at 10:02:01 AM UTC+8, Ho Yeung Lee wrote: > > https://gist.github.com/hoyeunglee/f371f66d55f90dda043f7e7fea38ffa2 > > > > I am near succeed in another way, please run above code > > > > when so much black words, it will be very slow > > so I only open notepad and maximum it without any content > > then capture screen and save as roster.png > > > > and run it, but I discover it can not circle all words with red rectangle > > and only part of words > > > > > > On Wednesday, August 2, 2017 at 3:06:40 PM UTC+8, Peter Otten wrote: > > > Glenn Linderman wrote: > > > > > > > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > > > >> Ho Yeung Lee writes: > > > >> > > > >>> def isneighborlocation(lo1, lo2): > > > >>> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > > > >>> return 1 > > > >>> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > > > >>> return 1 > > > >>> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > > > >>> return 1 > > > >>> else: > > > >>> return 0 > > > >>> > > > >>> > > > >>> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > > > >>> > > > >>> return something like > > > >>> [(1,2),(3,3),(2,5)] > > > > > > >> I think you are trying to sort a list of two-dimensional points into a > > > >> one-dimensiqonal list in such a way thet points that are close together > > > >> in the two-dimensional sense will also be close together in the > > > >> one-dimensional list. But that is impossible. > > > > > > > It's not impossible, it just requires an appropriate distance function > > > > used in the sort. > > > > > > That's a grossly misleading addition. > > > > > > Once you have an appropriate clustering algorithm > > > > > > clusters = split_into_clusters(items) # needs access to all items > > > > > > you can devise a key function > > > > > > def get_cluster(item, clusters=split_into_clusters(items)): > > > return next( > > > index for index, cluster in enumerate(clusters) if item in cluster > > > ) > > > > > > such that > > > > > > grouped_items = sorted(items, key=get_cluster) > > > > > > but that's a roundabout way to write > > > > > > grouped_items = sum(split_into_clusters(items), []) > > > > > > In other words: sorting is useless, what you really need is a suitable > > > approach to split the data into groups. > > > > > > One well-known algorithm is k-means clustering: > > > > > > https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.vq.kmeans.html > > > > > > Here is an example with pictures: > > > > > > https://dzone.com/articles/k-means-clustering-scipy From tjol at tjol.eu Thu Aug 3 04:06:07 2017 From: tjol at tjol.eu (Thomas Jollans) Date: Thu, 3 Aug 2017 10:06:07 +0200 Subject: how to fast processing one million strings to remove quotes In-Reply-To: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> References: <08914252-4ea6-e6d3-04be-6be1e57c6a25@mrabarnett.plus.com> Message-ID: <220eddd3-c16c-98c1-6a6c-cb0ac8e03d8e@tjol.eu> On 2017-08-02 19:05, MRAB wrote: > On 2017-08-02 16:05, Daiyue Weng wrote: >> Hi, I am trying to removing extra quotes from a large set of strings (a >> list of strings), so for each original string, it looks like, >> >> """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" >> >> >> I like to remove the start and end quotes and extra pairs of quotes on >> each >> string value, so the result will look like, >> >> "str_value1","str_value2","str_value3",1,"str_value4" >> >> >> and then join each string by a new line. >> >> I have tried the following code, >> >> for line in str_lines[1:]: >> strip_start_end_quotes = line[1:-1] >> splited_line_rem_quotes = >> strip_start_end_quotes.replace('\"\"', '"') >> str_lines[str_lines.index(line)] = splited_line_rem_quotes >> >> for_pandas_new_headers_str = '\n'.join(splited_lines) >> >> but it is really slow (running for ages) if the list contains over 1 >> million string lines. I am thinking about a fast way to do that. >> > [snip] > > The problem is the line: > > str_lines[str_lines.index(line)] > > It does a linear search through str_lines until time finds a match for > the line. > > To find the 10th line it must search through the first 10 lines. > > To find the 100th line it must search through the first 100 lines. > > To find the 1000th line it must search through the first 1000 lines. > > And so on. > > In Big-O notation, the performance is O(n**2). > > The Pythonic way of doing it is to put the results into a new list: > > > new_str_lines = str_lines[:1] > > for line in str_lines[1:]: > strip_start_end_quotes = line[1:-1] > splited_line_rem_quotes = strip_start_end_quotes.replace('\"\"', '"') > new_str_lines.append(splited_line_rem_quotes) > > > In Big-O notation, the performance is O(n). Sometimes it's desirable to modify the list in-place (such as in this case, where you don't really want to double the memory use: for idx, line in enumerate(str_lines): str_lines[idx] = fixed(line) The most Pythonic way to process a large "list" of data is often to not use a list at all, but to use iterators. Whether it's feasible to access the strings one-by-one will depend on where they come from and where they're going. Something like this may or may not be useful: def remove_quotes_from_all(lines): for line in lines: yield line[1:-1].replace('""', '"') with open('weird_file.txt', 'r') as input: with open('not_so_weird_file.txt', 'w') as output: for fixed_line in remove_quotes_from_all(input): output.write(f'{fixed_line}\n') -- Thomas From soyeomul at doraji.xyz Thu Aug 3 07:41:29 2017 From: soyeomul at doraji.xyz (Byung-Hee HWANG =?utf-8?B?KO2Zqeuzke2drCwg6buD?= =?utf-8?B?54Kz54aZKQ==?=) Date: Thu, 03 Aug 2017 20:41:29 +0900 Subject: python in chromebook References: Message-ID: attend ?? ???, ??? ?? ???: > On Thu, 27 Jul 2017 10:03:29 +0900, Byung-Hee HWANG (???, ???) wrote: > >> my computer is chromebook. how can i install python in chromebook? >> barely i did meet develop mode of chromebook. also i'm new to python. >> >> INDEED, i want to make python code on my chromebook. >> >> thanks in avance!!! > > google crouton chromebook Possibly i would like to install python under Chrome OS. Anyway thanks! -- ^????? _????_ ?????_^))// From p.f.moore at gmail.com Thu Aug 3 10:35:28 2017 From: p.f.moore at gmail.com (Paul Moore) Date: Thu, 3 Aug 2017 07:35:28 -0700 (PDT) Subject: @lru_cache on functions with no arguments In-Reply-To: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Tuesday, 1 August 2017 15:54:42 UTC+1, t... at tomforb.es wrote: > > _sentinel = object() > > _val = _sentinel > > def val(): > > if _val is _sentinel: > > # Calculate _val > > return _val > > > > seems entirely sufficient for this case. Write a custom decorator if you use the idiom often enough to make it worth the effort. > > I did some timings with this as part of my timings above and found it to be significantly slower than lru_cache with the C extension. I had to add `nonlocal` to get `_val` to resolve, which I think kills performance a bit. > > I agree with the premise though, it might be worth exploring. It's worth pointing out that there's nothing *wrong* with using lru_cache with maxsize=None. You're going to find it hard to get a pure-Python equivalent that's faster (after all, even maintaining a single variable is still a dict lookup, which is all the cache does when LRU functionality is disabled). Certainly if you only ever call with no arguments there's little point in an LRU cache, so maxsize=None ("the LRU feature is disabled") is logical. Whether that approach clearly expresses your intent is maybe a little less obvious, but you could always write a custom decorator to make your intent clear: >>> from functools import lru_cache >>> def only_call_once(fn): ... return lru_cache(maxsize=None)(fn) ... >>> @only_call_once ... def f(): ... print("Called!") ... return 1 ... >>> f() Called! 1 >>> f() 1 Paul From ian.g.kelly at gmail.com Thu Aug 3 11:36:00 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 09:36:00 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 8:35 AM, Paul Moore wrote: > On Tuesday, 1 August 2017 15:54:42 UTC+1, t... at tomforb.es wrote: >> > _sentinel = object() >> > _val = _sentinel >> > def val(): >> > if _val is _sentinel: >> > # Calculate _val >> > return _val >> > >> > seems entirely sufficient for this case. Write a custom decorator if you use the idiom often enough to make it worth the effort. >> >> I did some timings with this as part of my timings above and found it to be significantly slower than lru_cache with the C extension. I had to add `nonlocal` to get `_val` to resolve, which I think kills performance a bit. >> >> I agree with the premise though, it might be worth exploring. > > It's worth pointing out that there's nothing *wrong* with using lru_cache with maxsize=None. You're going to find it hard to get a pure-Python equivalent that's faster (after all, even maintaining a single variable is still a dict lookup, which is all the cache does when LRU functionality is disabled). The single variable is only a dict lookup if it's a global. Locals and closures are faster. def simple_cache(function): sentinel = object() cached = sentinel @functools.wraps(function) def wrapper(*args, **kwargs): nonlocal cached if args or kwargs: return function(*args, **kwargs) # No caching with args if cached is sentinel: cached = function() return cached return wrapper *Zero* dict lookups at call-time. If that's not (marginally) faster than lru_cache with maxsize=None I'll eat my socks. From ian.g.kelly at gmail.com Thu Aug 3 11:41:47 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 09:41:47 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 9:36 AM, Ian Kelly wrote: > On Thu, Aug 3, 2017 at 8:35 AM, Paul Moore wrote: >> On Tuesday, 1 August 2017 15:54:42 UTC+1, t... at tomforb.es wrote: >>> > _sentinel = object() >>> > _val = _sentinel >>> > def val(): >>> > if _val is _sentinel: >>> > # Calculate _val >>> > return _val >>> > >>> > seems entirely sufficient for this case. Write a custom decorator if you use the idiom often enough to make it worth the effort. >>> >>> I did some timings with this as part of my timings above and found it to be significantly slower than lru_cache with the C extension. I had to add `nonlocal` to get `_val` to resolve, which I think kills performance a bit. >>> >>> I agree with the premise though, it might be worth exploring. >> >> It's worth pointing out that there's nothing *wrong* with using lru_cache with maxsize=None. You're going to find it hard to get a pure-Python equivalent that's faster (after all, even maintaining a single variable is still a dict lookup, which is all the cache does when LRU functionality is disabled). > > The single variable is only a dict lookup if it's a global. Locals and > closures are faster. > > def simple_cache(function): > sentinel = object() > cached = sentinel > > @functools.wraps(function) > def wrapper(*args, **kwargs): > nonlocal cached > if args or kwargs: > return function(*args, **kwargs) # No caching with args > if cached is sentinel: > cached = function() > return cached > return wrapper > > *Zero* dict lookups at call-time. If that's not (marginally) faster > than lru_cache with maxsize=None I'll eat my socks. Reading above, I now realize you were referring to the C extension version of lru_cache. Yes, I'm sure that's faster. I still maintain that this has to be faster than the pure-Python version however. From tom at tomforb.es Thu Aug 3 11:44:24 2017 From: tom at tomforb.es (tom at tomforb.es) Date: Thu, 3 Aug 2017 08:44:24 -0700 (PDT) Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: <3fc75c94-4627-4151-b4fa-8ef3e361319f@googlegroups.com> On Thursday, 3 August 2017 16:37:22 UTC+1, Ian wrote: > On Thu, Aug 3, 2017 at 8:35 AM, Paul Moore ... at gmail.com> wrote: > > On Tuesday, 1 August 2017 15:54:42 UTC+1, t... at tomforb.es wrote: > >> > _sentinel = object() > >> > _val = _sentinel > >> > def val(): > >> > if _val is _sentinel: > >> > # Calculate _val > >> > return _val > >> > > >> > seems entirely sufficient for this case. Write a custom decorator if you use the idiom often enough to make it worth the effort. > >> > >> I did some timings with this as part of my timings above and found it to be significantly slower than lru_cache with the C extension. I had to add `nonlocal` to get `_val` to resolve, which I think kills performance a bit. > >> > >> I agree with the premise though, it might be worth exploring. > > > > It's worth pointing out that there's nothing *wrong* with using lru_cache with maxsize=None. You're going to find it hard to get a pure-Python equivalent that's faster (after all, even maintaining a single variable is still a dict lookup, which is all the cache does when LRU functionality is disabled). > > The single variable is only a dict lookup if it's a global. Locals and > closures are faster. > > def simple_cache(function): > sentinel = object() > cached = sentinel > > @functools.wraps(function) > def wrapper(*args, **kwargs): > nonlocal cached > if args or kwargs: > return function(*args, **kwargs) # No caching with args > if cached is sentinel: > cached = function() > return cached > return wrapper > > *Zero* dict lookups at call-time. If that's not (marginally) faster > than lru_cache with maxsize=None I'll eat my socks. I hope you washed them! def test_func(): return 1 %timeit test_simple_cache() The slowest run took 11.06 times longer than the fastest. This could mean that an intermediate result is being cached. 10000000 loops, best of 3: 183 ns per loop %timeit test_lru_cache() The slowest run took 42.92 times longer than the fastest. This could mean that an intermediate result is being cached. 10000000 loops, best of 3: 46.9 ns per loop %timeit test_func() 10000000 loops, best of 3: 55.3 ns per loop From storchaka at gmail.com Thu Aug 3 11:55:19 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 3 Aug 2017 18:55:19 +0300 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: 03.08.17 18:36, Ian Kelly ????: > The single variable is only a dict lookup if it's a global. Locals and > closures are faster. > > def simple_cache(function): > sentinel = object() > cached = sentinel > > @functools.wraps(function) > def wrapper(*args, **kwargs): > nonlocal cached > if args or kwargs: > return function(*args, **kwargs) # No caching with args > if cached is sentinel: > cached = function() > return cached > return wrapper > > *Zero* dict lookups at call-time. If that's not (marginally) faster > than lru_cache with maxsize=None I'll eat my socks. With salt? $ ./python -m timeit -s 'from simple_cache import simple_cache; f = simple_cache(int)' -- 'f()' 500000 loops, best of 5: 885 nsec per loop $ ./python -m timeit -s 'from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' 1000000 loops, best of 5: 220 nsec per loop From ian.g.kelly at gmail.com Thu Aug 3 11:57:57 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 09:57:57 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: <3fc75c94-4627-4151-b4fa-8ef3e361319f@googlegroups.com> References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> <3fc75c94-4627-4151-b4fa-8ef3e361319f@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 9:44 AM, wrote: > I hope you washed them! Yes, well as noted in my followup I was comparing pure-Python implementations, not the C implementation. From ian.g.kelly at gmail.com Thu Aug 3 12:02:54 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 10:02:54 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 9:55 AM, Serhiy Storchaka wrote: > 03.08.17 18:36, Ian Kelly ????: >> >> The single variable is only a dict lookup if it's a global. Locals and >> closures are faster. >> >> def simple_cache(function): >> sentinel = object() >> cached = sentinel >> >> @functools.wraps(function) >> def wrapper(*args, **kwargs): >> nonlocal cached >> if args or kwargs: >> return function(*args, **kwargs) # No caching with args >> if cached is sentinel: >> cached = function() >> return cached >> return wrapper >> >> *Zero* dict lookups at call-time. If that's not (marginally) faster >> than lru_cache with maxsize=None I'll eat my socks. > > > With salt? > > $ ./python -m timeit -s 'from simple_cache import simple_cache; f = > simple_cache(int)' -- 'f()' > 500000 loops, best of 5: 885 nsec per loop > $ ./python -m timeit -s 'from functools import lru_cache; f = > lru_cache(maxsize=None)(int)' -- 'f()' > 1000000 loops, best of 5: 220 nsec per loop Fixed: $ python3 -m timeit -s 'from simple_cache import simple_cache; f = simple_cache(int)' -- 'f()' 1000000 loops, best of 3: 0.167 usec per loop $ python3 -m timeit -s 'import sys; sys.modules["_functools"] = None; from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' 1000000 loops, best of 3: 0.783 usec per loop From ian.g.kelly at gmail.com Thu Aug 3 12:08:42 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 10:08:42 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 10:02 AM, Ian Kelly wrote: > Fixed: > > $ python3 -m timeit -s 'from simple_cache import simple_cache; f = > simple_cache(int)' -- 'f()' > 1000000 loops, best of 3: 0.167 usec per loop > $ python3 -m timeit -s 'import sys; sys.modules["_functools"] = None; > from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- > 'f()' > 1000000 loops, best of 3: 0.783 usec per loop This turns out to be because I was running 3.4 which doesn't have the C implementation to begin with. In 3.6 this trick doesn't seem to work as expected for disabling it: $ python3.6 -m timeit -s 'from simple_cache import simple_cache; f = simple_cache(int)' -- 'f()' 10000000 loops, best of 3: 0.152 usec per loop $ python3.6 -m timeit -s 'from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' 10000000 loops, best of 3: 0.0422 usec per loop $ python3.6 -m timeit -s 'import sys; sys.modules["_functools"] = None; from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' 10000000 loops, best of 3: 0.0419 usec per loop From storchaka at gmail.com Thu Aug 3 13:18:53 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 3 Aug 2017 20:18:53 +0300 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: 03.08.17 19:08, Ian Kelly ????: > This turns out to be because I was running 3.4 which doesn't have the > C implementation to begin with. In 3.6 this trick doesn't seem to work > as expected for disabling it: It didn't work because the functools module already was imported at startup. $ ./python -m timeit -s 'from simple_cache import simple_cache; f = simple_cache(int)' -- 'f()' 500000 loops, best of 5: 501 nsec per loop $ ./python -m timeit -s 'from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' 2000000 loops, best of 5: 139 nsec per loop $ ./python -m timeit -s 'import sys; sys.modules["_functools"] = None; del sys.modules["functools"]; from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' 100000 loops, best of 5: 3.39 usec per loop From ian.g.kelly at gmail.com Thu Aug 3 14:17:51 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 12:17:51 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 11:18 AM, Serhiy Storchaka wrote: > $ ./python -m timeit -s 'import sys; sys.modules["_functools"] = None; del > sys.modules["functools"]; from functools import lru_cache; f = > lru_cache(maxsize=None)(int)' -- 'f()' > 100000 loops, best of 5: 3.39 usec per loop Interesting, I had tried that and it didn't work for me: $ python3.6 -m timeit -s 'import sys; sys.modules["_functools"] = None; del sys.modules["functools"]; from functools import lru_cache; f = lru_cache(maxsize=None)(int)' -- 'f()' Could not import runpy module Traceback (most recent call last): File "/usr/lib/python3.4/runpy.py", line 14, in import importlib.machinery # importlib first so we can test #15386 via -m File "/usr/lib/python3.4/importlib/__init__.py", line 34, in _w_long = _bootstrap._w_long AttributeError: module 'importlib._bootstrap' has no attribute '_w_long' From ian.g.kelly at gmail.com Thu Aug 3 14:20:50 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 3 Aug 2017 12:20:50 -0600 Subject: @lru_cache on functions with no arguments In-Reply-To: References: <7f2d87db-e142-4202-ac80-a1e9ea669a94@googlegroups.com> Message-ID: On Thu, Aug 3, 2017 at 12:17 PM, Ian Kelly wrote: > On Thu, Aug 3, 2017 at 11:18 AM, Serhiy Storchaka wrote: >> $ ./python -m timeit -s 'import sys; sys.modules["_functools"] = None; del >> sys.modules["functools"]; from functools import lru_cache; f = >> lru_cache(maxsize=None)(int)' -- 'f()' >> 100000 loops, best of 5: 3.39 usec per loop > > Interesting, I had tried that and it didn't work for me: > > $ python3.6 -m timeit -s 'import sys; sys.modules["_functools"] = > None; del sys.modules["functools"]; from functools import lru_cache; f > = lru_cache(maxsize=None)(int)' -- 'f()' > Could not import runpy module > Traceback (most recent call last): > File "/usr/lib/python3.4/runpy.py", line 14, in > import importlib.machinery # importlib first so we can test #15386 via -m > File "/usr/lib/python3.4/importlib/__init__.py", line 34, in > _w_long = _bootstrap._w_long > AttributeError: module 'importlib._bootstrap' has no attribute '_w_long' Never mind, it's fine now. In the future I should remember not to run python3.6 from the /usr/lib/python3.4 directory. =) From irmen.NOSPAM at xs4all.nl Thu Aug 3 14:30:50 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Thu, 3 Aug 2017 20:30:50 +0200 Subject: SSL/TLS support in Pyro4 Message-ID: <59836bdb$0$749$e4fe514c@news.xs4all.nl> Hi, Pyro4 (http://pyro4.readthedocs.io) allows you to call methods on Python objects running on other machines, as if they were just normal local objects. Regarding the network communication: it hasn't got any real security mechanisms built-in and always explicitly depended on external tools or systems to provide this (such as VPN or SSL tunneling). Until now: I've finally started adding SSL/TLS support to Pyro4 itself. The work-in-progress 4.62 version has it (git master branch). Docs are still lacking right now but there is a working ssl example included. I wonder if any current (or new) users of Pyro4 want to check this out? The biggest concern I have is that I only have dummy (self-signed) certificates so I can't test it with "real" certs to see if the validation works correctly. Alternatively, is there a cheap way to get an 'official' SSL certificate for testing purposes. I don't think letsencrypt can help here because it is only for web sites? (and their certs are only valid for a very short period) Cheers Irmen de Jong From info at tundraware.com Thu Aug 3 17:43:09 2017 From: info at tundraware.com (Tim Daneliuk) Date: Thu, 3 Aug 2017 16:43:09 -0500 Subject: how to fast processing one million strings to remove quotes In-Reply-To: References: Message-ID: On 08/02/2017 10:05 AM, Daiyue Weng wrote: > Hi, I am trying to removing extra quotes from a large set of strings (a > list of strings), so for each original string, it looks like, > > """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" > > > I like to remove the start and end quotes and extra pairs of quotes on each > string value, so the result will look like, > > "str_value1","str_value2","str_value3",1,"str_value4" This part can also be done fairly efficiently with sed: time cat hugequote.txt | sed 's/"""/"/g;s/""/"/g' >/dev/null real 0m2.660s user 0m2.635s sys 0m0.055s hugequote.txt is a file with 1M copies of your test string above in it. Run on a quad core i5 on FreeBSD 10.3-STABLE. From thebalancepro at gmail.com Fri Aug 4 00:21:11 2017 From: thebalancepro at gmail.com (Nick Mellor) Date: Thu, 3 Aug 2017 21:21:11 -0700 (PDT) Subject: how to fast processing one million strings to remove quotes In-Reply-To: References: Message-ID: <6b206975-f943-4894-b5a0-48cb399afcb3@googlegroups.com> Sorry Daiyue, Try this correction: I'm writing code without being able to execute it. > split_on_dbl_dbl_quote = original_list.join('|').split('""') > remove_dbl_dbl_quotes_and_outer_quotes = split_on_dbl_dbl_quote[::2].join('').split('|') split_on_dbl_dbl_quote = original_list.join('|').split('""') remove_dbl_dbl_quotes_and_outer_quotes = '"'.join(split_on_dbl_dbl_quote[::2]).split('|') Cheers, Nick > > You need to be sure of your data: [::2] (return just even-numbered elements) relies on all double-double-quotes both opening and closing within the same string. > > This runs in under a second for a million strings but does affect *all* elements, not just strings. The non-strings would become strings after the second statement. > > As to multi-processing: I would be looking at well-optimised single-thread solutions like split/join before I consider MP. If you can fit the problem to a split-join it'll be much simpler and more "pythonic". > > Cheers, > > Nick From __peter__ at web.de Fri Aug 4 02:52:00 2017 From: __peter__ at web.de (Peter Otten) Date: Fri, 04 Aug 2017 08:52 +0200 Subject: how to fast processing one million strings to remove quotes References: Message-ID: Tim Daneliuk wrote: > On 08/02/2017 10:05 AM, Daiyue Weng wrote: >> Hi, I am trying to removing extra quotes from a large set of strings (a >> list of strings), so for each original string, it looks like, >> >> """str_value1"",""str_value2"",""str_value3"",1,""str_value4""" >> >> >> I like to remove the start and end quotes and extra pairs of quotes on >> each string value, so the result will look like, >> >> "str_value1","str_value2","str_value3",1,"str_value4" > > > > This part can also be done fairly efficiently with sed: > > time cat hugequote.txt | sed 's/"""/"/g;s/""/"/g' >/dev/null > > real 0m2.660s > user 0m2.635s > sys 0m0.055s > > hugequote.txt is a file with 1M copies of your test string above in it. > > Run on a quad core i5 on FreeBSD 10.3-STABLE. It looks like Python is fairly competetive: $ wc -l hugequote.txt 1000000 hugequote.txt $ cat unquote.py import csv with open("hugequote.txt") as instream: for field, in csv.reader(instream): print(field) $ time python3 unquote.py > /dev/null real 0m3.773s user 0m3.665s sys 0m0.082s $ time cat hugequote.txt | sed 's/"""/"/g;s/""/"/g' > /dev/null real 0m4.862s user 0m4.721s sys 0m0.330s Run on ancient AMD hardware ;) From nomail at com.invalid Fri Aug 4 04:07:13 2017 From: nomail at com.invalid (ast) Date: Fri, 4 Aug 2017 10:07:13 +0200 Subject: Catching an exception in a variable Message-ID: <59842b38$0$31614$426a34cc@news.free.fr> Hello try: a = 1 / 0 except ZeroDivisionError as ex: pass >>> ex Traceback (most recent call last): File "", line 1, in ex NameError: name 'ex' is not defined Why variable ex doesn't exist ? From alon.najman at gmail.com Fri Aug 4 04:16:44 2017 From: alon.najman at gmail.com (alon.najman at gmail.com) Date: Fri, 4 Aug 2017 01:16:44 -0700 (PDT) Subject: program that search string in text file and do something Message-ID: Hi, I'm new to thing forum and to this programming in python! can someone help me and write me how to write a program that do: - search for a string in certain text file and if it founds the string it delete the file? and print something? thanks. From ben+python at benfinney.id.au Fri Aug 4 04:21:28 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 04 Aug 2017 18:21:28 +1000 Subject: Catching an exception in a variable References: <59842b38$0$31614$426a34cc@news.free.fr> Message-ID: <85y3qzoi9j.fsf@benfinney.id.au> "ast" writes: > Why variable ex doesn't exist ? Because of a deliberate decision made to delete it. Silently. This is documented: When an exception has been assigned using as target, it is cleared at the end of the except clause. This is as if except E as N: foo was translated to except E as N: try: foo finally: del N This means the exception must be assigned to a different name to be able to refer to it after the except clause. Exceptions are cleared because with the traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs. but I think this is a terrible idea. It silently deletes a name binding from the current scope, without the code explicitly asking for that. -- \ ?For certain people, after fifty, litigation takes the place of | `\ sex.? ?Gore Vidal | _o__) | Ben Finney From robin at reportlab.com Fri Aug 4 04:26:47 2017 From: robin at reportlab.com (Robin Becker) Date: Fri, 4 Aug 2017 09:26:47 +0100 Subject: SSL/TLS support in Pyro4 In-Reply-To: <59836bdb$0$749$e4fe514c@news.xs4all.nl> References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> Message-ID: <6613b313-46ff-19b1-f25a-4348d96078b0@chamonix.reportlab.co.uk> On 03/08/2017 19:30, Irmen de Jong wrote: ......... > > I wonder if any current (or new) users of Pyro4 want to check this out? The biggest > concern I have is that I only have dummy (self-signed) certificates so I can't test it > with "real" certs to see if the validation works correctly. ...... I've used self created authorities with mariadb and mongo to secure local clusters. Could this provide private secure certs for pyro? -- Robin Becker From nomail at com.invalid Fri Aug 4 05:26:27 2017 From: nomail at com.invalid (ast) Date: Fri, 4 Aug 2017 11:26:27 +0200 Subject: program that search string in text file and do something In-Reply-To: References: Message-ID: <59843dc8$0$3690$426a34cc@news.free.fr> a ?crit dans le message de news:b6cc4ee5-71be-4550-be3e-59ebeee7a01b at googlegroups.com... > Hi, I'm new to thing forum and to this programming in python! > > can someone help me and write me how to write a program that do: > - search for a string in certain text file and if it founds the string it delete the file? and > print something? > > thanks. import os pattern = "azerty" found = False with open("foo.txt", "r") as f: for line in f: if pattern in line: found = True break if found: os.remove("foo.txt") From nomail at com.invalid Fri Aug 4 05:27:33 2017 From: nomail at com.invalid (ast) Date: Fri, 4 Aug 2017 11:27:33 +0200 Subject: Catching an exception in a variable In-Reply-To: References: <59842b38$0$31614$426a34cc@news.free.fr> <85y3qzoi9j.fsf@benfinney.id.au> Message-ID: <59843e0b$0$31608$426a34cc@news.free.fr> "Ben Finney" a ?crit dans le message de news:mailman.55.1501834898.28999.python-list at python.org... > "ast" writes: > Ok, ty From __peter__ at web.de Fri Aug 4 05:38:21 2017 From: __peter__ at web.de (Peter Otten) Date: Fri, 04 Aug 2017 11:38:21 +0200 Subject: program that search string in text file and do something References: Message-ID: alon.najman at gmail.com wrote: > Hi, I'm new to thing forum and to this programming in python! > > can someone help me and write me how to write a program that do: > - search for a string in certain text file and if it founds the string it > delete the file? and print something? Programming is mostly about splitting a complex task into baby steps. Do you know how to open a file? Do you know how to iterate over the lines of that file? Do you know how to search for a string in that line (i. e. another string)? Do you know how to delete a file? Work through a Python tutorial or the first chapters of beginner's textbook, then try your hand at each of the subtasks outlined above. Consult the documentation for missing parts. Once you have some code we will help you improve or even fix it. What we won't do is write a program for you ready to present to your teacher. From __peter__ at web.de Fri Aug 4 05:45:00 2017 From: __peter__ at web.de (Peter Otten) Date: Fri, 04 Aug 2017 11:45 +0200 Subject: program that search string in text file and do something References: Message-ID: Peter Otten wrote: > What we won't do is write a program for you ready to present to your > teacher. I should have known better :( From alon.najman at gmail.com Fri Aug 4 06:08:52 2017 From: alon.najman at gmail.com (alon.najman at gmail.com) Date: Fri, 4 Aug 2017 03:08:52 -0700 (PDT) Subject: program that search string in text file and do something In-Reply-To: <59843dc8$0$3690$426a34cc@news.free.fr> References: <59843dc8$0$3690$426a34cc@news.free.fr> Message-ID: On Friday, August 4, 2017 at 12:27:02 PM UTC+3, ast wrote: > a ?crit dans le message de > news:b6cc4ee5-71be-4550-be3e-59ebeee7a01b at googlegroups.com... > > Hi, I'm new to thing forum and to this programming in python! > > > > can someone help me and write me how to write a program that do: > > - search for a string in certain text file and if it founds the string it delete the file? and > > print something? > > > > thanks. > > import os > pattern = "azerty" > found = False > > with open("foo.txt", "r") as f: > for line in f: > if pattern in line: > found = True > break > > if found: > os.remove("foo.txt") thanks man! that works From irmen.NOSPAM at xs4all.nl Fri Aug 4 07:04:02 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Fri, 4 Aug 2017 13:04:02 +0200 Subject: SSL/TLS support in Pyro4 In-Reply-To: References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> <6613b313-46ff-19b1-f25a-4348d96078b0@chamonix.reportlab.co.uk> Message-ID: <598454a2$0$770$e4fe514c@news.xs4all.nl> On 04/08/2017 10:26, Robin Becker wrote: > On 03/08/2017 19:30, Irmen de Jong wrote: > ......... >> >> I wonder if any current (or new) users of Pyro4 want to check this out? The biggest >> concern I have is that I only have dummy (self-signed) certificates so I can't test it >> with "real" certs to see if the validation works correctly. > ...... > > I've used self created authorities with mariadb and mongo to secure local clusters. > Could this provide private secure certs for pyro? Hi Robin I am not sure how this is any benefit over the self-signed root certs that I now use? Except for the fact that these are a root cert as well and don't use any CA trust chain. To be able to validate this cert, I have to load it as a CA cert on the validating side. Which isn't bad perse. I've used openssl as mentioned here to create my certs: https://docs.python.org/3.7/library/ssl.html#self-signed-certificates Irmen From steve+python at pearwood.info Fri Aug 4 07:05:00 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 04 Aug 2017 21:05:00 +1000 Subject: Catching an exception in a variable References: <59842b38$0$31614$426a34cc@news.free.fr> <85y3qzoi9j.fsf@benfinney.id.au> Message-ID: <598454dd$0$1590$c3e8da3$5496439d@news.astraweb.com> On Fri, 4 Aug 2017 06:21 pm, Ben Finney wrote about the unbinding of exception variable on leaving the except block: > I think this is a terrible idea. I agree it is a terrible idea. I'd go so far as to say it is the worst possible way for dealing with the program of exception reference loops, except for all the others. *wink* -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From nomail at com.invalid Fri Aug 4 07:11:46 2017 From: nomail at com.invalid (ast) Date: Fri, 4 Aug 2017 13:11:46 +0200 Subject: program that search string in text file and do something In-Reply-To: References: <59843dc8$0$3690$426a34cc@news.free.fr> Message-ID: <59845678$0$8848$426a34cc@news.free.fr> a ?crit dans le message de news:f705c092-de18-4c37-bde1-42316e8de753 at googlegroups.com... On Friday, August 4, 2017 at 12:27:02 PM UTC+3, ast wrote: > a ?crit dans le message de > news:b6cc4ee5-71be-4550-be3e-59ebeee7a01b at googlegroups.com... > thanks man! that works I hope it is not a school homework From jobmattcon at gmail.com Fri Aug 4 08:11:10 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Fri, 4 Aug 2017 05:11:10 -0700 (PDT) Subject: how to guess the number of cluster when do not know? Message-ID: <94f888be-b5e5-404b-9f35-d3dc96c4561f@googlegroups.com> i find kmeans has to input number of cluster but i do not know how many words in photo before recognization in application of robots vision recognition if separate high, will it become letters instead of word? from pylab import plot,show from numpy import vstack,array from numpy.random import rand from scipy.cluster.vq import kmeans,vq # data generation data = vstack((rand(150,2) + array([.5,.5]),rand(150,2))) # computing K-Means with K = 2 (2 clusters) centroids,_ = kmeans(data,2) From alain at universite-de-strasbourg.fr.invalid Fri Aug 4 08:24:29 2017 From: alain at universite-de-strasbourg.fr.invalid (Alain Ketterlin) Date: Fri, 04 Aug 2017 14:24:29 +0200 Subject: [OT] Re: how to guess the number of cluster when do not know? References: <94f888be-b5e5-404b-9f35-d3dc96c4561f@googlegroups.com> Message-ID: <87lgmz4j2a.fsf@universite-de-strasbourg.fr.invalid> Ho Yeung Lee writes: > i find kmeans has to input number of cluster [...] https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set Completely off-topic on this group/list, please direct your questions elsewhere. -- Alain. From iranna.gani28 at gmail.com Fri Aug 4 08:33:24 2017 From: iranna.gani28 at gmail.com (Iranna Mathapati) Date: Fri, 4 Aug 2017 18:03:24 +0530 Subject: how to grep Message-ID: Hi Team, How to grep values from below out put string. pattern should include "Fabric Module". grepping Fabric module values only str = ''' 22 0 Fabric Module J8N-C9508-FM ok 24 0 Fabric Module J8N-C9508-FM ok 26 0 Fabric Module J8N-C9508-FM ok 22 0 16-slot Fabric Module J8N-C9516-FM-E ok 24 0 16-slot Fabric Module J8N-C9516-FM-E ok''' output = [22,24,26,22,24] Thanks Iranna M From steve+python at pearwood.info Fri Aug 4 08:37:47 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 04 Aug 2017 22:37:47 +1000 Subject: how to grep References: Message-ID: <59846a9d$0$1611$c3e8da3$5496439d@news.astraweb.com> On Fri, 4 Aug 2017 10:33 pm, Iranna Mathapati wrote: > Hi Team, > > How to grep values from below out put string. > > pattern should include "Fabric Module". > > grepping Fabric module values only > > str = ''' > 22 0 Fabric Module J8N-C9508-FM ok > 24 0 Fabric Module J8N-C9508-FM ok > 26 0 Fabric Module J8N-C9508-FM ok > 22 0 16-slot Fabric Module J8N-C9516-FM-E ok > 24 0 16-slot Fabric Module J8N-C9516-FM-E ok''' > > output = [22,24,26,22,24] output = int(line[:2]) for line in string.split('\n') if line] Does that help? If not, you will need to ask a better question, because I cannot understand the question you are asking now. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From irmen.NOSPAM at xs4all.nl Fri Aug 4 09:04:01 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Fri, 4 Aug 2017 15:04:01 +0200 Subject: SSL/TLS support in Pyro4 In-Reply-To: <59836bdb$0$749$e4fe514c@news.xs4all.nl> References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> Message-ID: <598470c2$0$790$e4fe514c@news.xs4all.nl> On 03/08/2017 20:30, Irmen de Jong wrote: > Alternatively, is there a cheap way to get an 'official' SSL certificate for testing > purposes. I don't think letsencrypt can help here because it is only for web sites? > (and their certs are only valid for a very short period) With some host file trickery (had to fool my dev machine into thinking it is my web server) I managed to get it all to work with a letsencrypt cert as well. Irmen From robin at reportlab.com Fri Aug 4 09:44:56 2017 From: robin at reportlab.com (Robin Becker) Date: Fri, 4 Aug 2017 14:44:56 +0100 Subject: SSL/TLS support in Pyro4 In-Reply-To: <598454a2$0$770$e4fe514c@news.xs4all.nl> References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> <6613b313-46ff-19b1-f25a-4348d96078b0@chamonix.reportlab.co.uk> <598454a2$0$770$e4fe514c@news.xs4all.nl> Message-ID: <4e75110a-1699-7633-139f-5879d5bce5ee@chamonix.reportlab.co.uk> .......... > > Hi Robin > > I am not sure how this is any benefit over the self-signed root certs that I now use? > > Except for the fact that these are a root cert as well and don't use any CA trust chain. > To be able to validate this cert, I have to load it as a CA cert on the validating side. > Which isn't bad perse. > > I've used openssl as mentioned here to create my certs: > https://docs.python.org/3.7/library/ssl.html#self-signed-certificates .........Welle I was thinking perhaps you had trouble with self signed certs for some reason. I only used CA type setup because some recipe for mongo clusters seems to want that. I think the mariadb clusters were fine with simple self signed certs. However, if I control the cluster can I not just distribute the cert to all members and have them validate it against itself or does python refuse to do that? I vaguely remember some python apis allow the authority chain to be specified. -- Robin Becker From grant.b.edwards at gmail.com Fri Aug 4 09:52:51 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 4 Aug 2017 13:52:51 +0000 (UTC) Subject: program that search string in text file and do something References: Message-ID: On 2017-08-04, Peter Otten <__peter__ at web.de> wrote: > What we won't do is write a program for you ready to present to your > teacher. Or if we do, it will be subtly sabotaged in a manner that will make it obvious to an experienced Python programmer that you didn't write it. My favorite is to use some combination of particularly obscure and obtuse mechanisms that will actually product the correct results but do so in a way that nobody (including myself a few days later) will be able to explain without some intense study. -- Grant Edwards grant.b.edwards Yow! It don't mean a at THING if you ain't got gmail.com that SWING!! From jobmattcon at gmail.com Fri Aug 4 10:08:29 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Fri, 4 Aug 2017 07:08:29 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> Message-ID: i had changed to use kmeans https://gist.github.com/hoyeunglee/2475391ad554e3d2b2a40ec24ab47940 i do not know whether write it correctly but it seems can cluster to find words in window, but not perfect On Wednesday, August 2, 2017 at 3:06:40 PM UTC+8, Peter Otten wrote: > Glenn Linderman wrote: > > > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > >> Ho Yeung Lee writes: > >> > >>> def isneighborlocation(lo1, lo2): > >>> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > >>> return 1 > >>> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > >>> return 1 > >>> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > >>> return 1 > >>> else: > >>> return 0 > >>> > >>> > >>> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > >>> > >>> return something like > >>> [(1,2),(3,3),(2,5)] > > >> I think you are trying to sort a list of two-dimensional points into a > >> one-dimensiqonal list in such a way thet points that are close together > >> in the two-dimensional sense will also be close together in the > >> one-dimensional list. But that is impossible. > > > It's not impossible, it just requires an appropriate distance function > > used in the sort. > > That's a grossly misleading addition. > > Once you have an appropriate clustering algorithm > > clusters = split_into_clusters(items) # needs access to all items > > you can devise a key function > > def get_cluster(item, clusters=split_into_clusters(items)): > return next( > index for index, cluster in enumerate(clusters) if item in cluster > ) > > such that > > grouped_items = sorted(items, key=get_cluster) > > but that's a roundabout way to write > > grouped_items = sum(split_into_clusters(items), []) > > In other words: sorting is useless, what you really need is a suitable > approach to split the data into groups. > > One well-known algorithm is k-means clustering: > > https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.vq.kmeans.html > > Here is an example with pictures: > > https://dzone.com/articles/k-means-clustering-scipy From jobmattcon at gmail.com Fri Aug 4 10:09:42 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Fri, 4 Aug 2017 07:09:42 -0700 (PDT) Subject: [OT] Re: how to guess the number of cluster when do not know? In-Reply-To: <87lgmz4j2a.fsf@universite-de-strasbourg.fr.invalid> References: <94f888be-b5e5-404b-9f35-d3dc96c4561f@googlegroups.com> <87lgmz4j2a.fsf@universite-de-strasbourg.fr.invalid> Message-ID: <3fd0b158-7f60-4dd2-9e15-c01efa72f152@googlegroups.com> actually i am using python's kmeans library. it is relevant in python i had changed to use kmeans https://gist.github.com/hoyeunglee/2475391ad554e3d2b2a40ec24ab47940 i do not know whether write it correctly but it seems can cluster to find words in window, but not perfect On Friday, August 4, 2017 at 8:24:54 PM UTC+8, Alain Ketterlin wrote: > Ho Yeung Lee writes: > > > i find kmeans has to input number of cluster > [...] > > https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set > > Completely off-topic on this group/list, please direct your questions > elsewhere. > > -- Alain. From irmen.NOSPAM at xs4all.nl Fri Aug 4 10:12:35 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Fri, 4 Aug 2017 16:12:35 +0200 Subject: SSL/TLS support in Pyro4 In-Reply-To: References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> <6613b313-46ff-19b1-f25a-4348d96078b0@chamonix.reportlab.co.uk> <598454a2$0$770$e4fe514c@news.xs4all.nl> <4e75110a-1699-7633-139f-5879d5bce5ee@chamonix.reportlab.co.uk> Message-ID: <598480d4$0$814$e4fe514c@news.xs4all.nl> On 04/08/2017 15:44, Robin Becker wrote: > .......... >> >> Hi Robin >> >> I am not sure how this is any benefit over the self-signed root certs that I now use? >> >> Except for the fact that these are a root cert as well and don't use any CA trust chain. >> To be able to validate this cert, I have to load it as a CA cert on the validating side. >> Which isn't bad perse. >> >> I've used openssl as mentioned here to create my certs: >> https://docs.python.org/3.7/library/ssl.html#self-signed-certificates > .........Welle I was thinking perhaps you had trouble with self signed certs for some > reason. I only used CA type setup because some recipe for mongo clusters seems to want > that. I think the mariadb clusters were fine with simple self signed certs. However, if > I control the cluster can I not just distribute the cert to all members and have them > validate it against itself or does python refuse to do that? I vaguely remember some > python apis allow the authority chain to be specified. You can specify a CAcert using load_verify_locations on the ssl context. Is that what you meant? I figured out that if you set that to the peer's certificate it will then be accepted. I understand it as much as "hey openssl here is a root cert that you should trust if you encounter it". Without doing this, the cert is denied on the SSL level (unless you set the ssl options to no-cert-required but that is definitely not what I wanted) Bottom line is I learned something new :) And also that Python's standard ssl library isn't as bad as I remember it to be a few years ago. Is there still a reason to use, say, PyOpenSSL anymore? Irmen From info at tundraware.com Fri Aug 4 10:20:02 2017 From: info at tundraware.com (Tim Daneliuk) Date: Fri, 4 Aug 2017 09:20:02 -0500 Subject: how to fast processing one million strings to remove quotes In-Reply-To: References: Message-ID: On 08/04/2017 01:52 AM, Peter Otten wrote: > It looks like Python is fairly competetive: > > $ wc -l hugequote.txt > 1000000 hugequote.txt612250 > $ cat unquote.py > import csv > > with open("hugequote.txt") as instream: > for field, in csv.reader(instream): > print(field) > > $ time python3 unquote.py > /dev/null > > real 0m3.773s > user 0m3.665s > sys 0m0.082s > > $ time cat hugequote.txt | sed 's/"""/"/g;s/""/"/g' > /dev/null > > real 0m4.862s > user 0m4.721s > sys 0m0.330s > > Run on ancient AMD hardware ;) > It's actually better than sed. What you're seeing is - I believe - load time dominating the overall time. I reran this with a 20M line file: time cat superhuge.txt | sed 's/"""/"/g;s/""/"/g' >/dev/null real 0m53.091s user 0m52.861s sys 0m0.820s time python unquote.py >/dev/null real 0m22.377s user 0m22.021s sys 0m0.352s Note that this is with python2, not python3. Also, I confirmed that the cat and pipe into sed was not a factor in the performance. My guess is that delimiter recognition logic in the csv module is far more efficient than the general purpose regular expression/dfa implementaton in sed. Extra Credit Assignment: Reimplement in python using: - string substitution - regular expressions Tsch?ss... From jobmattcon at gmail.com Fri Aug 4 10:29:23 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Fri, 4 Aug 2017 07:29:23 -0700 (PDT) Subject: [OT] Re: how to guess the number of cluster when do not know? In-Reply-To: <3fd0b158-7f60-4dd2-9e15-c01efa72f152@googlegroups.com> References: <94f888be-b5e5-404b-9f35-d3dc96c4561f@googlegroups.com> <87lgmz4j2a.fsf@universite-de-strasbourg.fr.invalid> <3fd0b158-7f60-4dd2-9e15-c01efa72f152@googlegroups.com> Message-ID: <2064358c-27cc-4830-a4ec-d48e530d69ec@googlegroups.com> i use number of clusters = 120 https://drive.google.com/file/d/0Bxs_ao6uuBDUZFByNVgzd0Jrdm8/view?usp=sharing seems better, but still has a long distance to be perfect On Friday, August 4, 2017 at 10:09:59 PM UTC+8, Ho Yeung Lee wrote: > actually i am using python's kmeans library. it is relevant in python > > i had changed to use kmeans > > https://gist.github.com/hoyeunglee/2475391ad554e3d2b2a40ec24ab47940 > > i do not know whether write it correctly > but it seems can cluster to find words in window, but not perfect > > > > On Friday, August 4, 2017 at 8:24:54 PM UTC+8, Alain Ketterlin wrote: > > Ho Yeung Lee writes: > > > > > i find kmeans has to input number of cluster > > [...] > > > > https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set > > > > Completely off-topic on this group/list, please direct your questions > > elsewhere. > > > > -- Alain. From jobmattcon at gmail.com Fri Aug 4 10:35:29 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Fri, 4 Aug 2017 07:35:29 -0700 (PDT) Subject: how to group by function if one of the group has relationship with another one in the group? In-Reply-To: References: <1d6f7a4f-86f7-4827-8eb4-b74fa6c8ba40@googlegroups.com> Message-ID: <52ac711d-0610-404c-8216-de76ad0f17e1@googlegroups.com> On Wednesday, August 2, 2017 at 5:25:21 AM UTC+8, Piet van Oostrum wrote: > Ho Yeung Lee writes: > > > which function should be used for this problem? > > > I think it is a kind if clustering, or a connectivity problem. There are special algorithms for that, not just a simple function. Maybe scikit-learn has a suitable algorithm for it. > -- > Piet van Oostrum > WWW: http://piet.vanoostrum.org/ > PGP key: [8DAE142BE17999C4] i use number of clusters = 120 https://gist.github.com/hoyeunglee/2475391ad554e3d2b2a40ec24ab47940 https://drive.google.com/file/d/0Bxs_ao6uuBDUZFByNVgzd0Jrdm8/view?usp=sharing seems better, but still has a long distance to be perfect is there any more that can do for perfect From jobmattcon at gmail.com Fri Aug 4 10:39:06 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Fri, 4 Aug 2017 07:39:06 -0700 (PDT) Subject: how to sort a list of tuples with custom function In-Reply-To: References: <783ec749-4d04-4925-8d13-14e26b20c5ab@googlegroups.com> <44bf85cd-15e2-c70a-fdd4-f92d418fb908@g.nevcal.com> Message-ID: On Friday, August 4, 2017 at 10:08:56 PM UTC+8, Ho Yeung Lee wrote: > i had changed to use kmeans > > https://gist.github.com/hoyeunglee/2475391ad554e3d2b2a40ec24ab47940 > > i do not know whether write it correctly > but it seems can cluster to find words in window, but not perfect > > > On Wednesday, August 2, 2017 at 3:06:40 PM UTC+8, Peter Otten wrote: > > Glenn Linderman wrote: > > > > > On 8/1/2017 2:10 PM, Piet van Oostrum wrote: > > >> Ho Yeung Lee writes: > > >> > > >>> def isneighborlocation(lo1, lo2): > > >>> if abs(lo1[0] - lo2[0]) < 7 and abs(lo1[1] - lo2[1]) < 7: > > >>> return 1 > > >>> elif abs(lo1[0] - lo2[0]) == 1 and lo1[1] == lo2[1]: > > >>> return 1 > > >>> elif abs(lo1[1] - lo2[1]) == 1 and lo1[0] == lo2[0]: > > >>> return 1 > > >>> else: > > >>> return 0 > > >>> > > >>> > > >>> sorted(testing1, key=lambda x: (isneighborlocation.get(x[0]), x[1])) > > >>> > > >>> return something like > > >>> [(1,2),(3,3),(2,5)] > > > > >> I think you are trying to sort a list of two-dimensional points into a > > >> one-dimensiqonal list in such a way thet points that are close together > > >> in the two-dimensional sense will also be close together in the > > >> one-dimensional list. But that is impossible. > > > > > It's not impossible, it just requires an appropriate distance function > > > used in the sort. > > > > That's a grossly misleading addition. > > > > Once you have an appropriate clustering algorithm > > > > clusters = split_into_clusters(items) # needs access to all items > > > > you can devise a key function > > > > def get_cluster(item, clusters=split_into_clusters(items)): > > return next( > > index for index, cluster in enumerate(clusters) if item in cluster > > ) > > > > such that > > > > grouped_items = sorted(items, key=get_cluster) > > > > but that's a roundabout way to write > > > > grouped_items = sum(split_into_clusters(items), []) > > > > In other words: sorting is useless, what you really need is a suitable > > approach to split the data into groups. > > > > One well-known algorithm is k-means clustering: > > > > https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.vq.kmeans.html > > > > Here is an example with pictures: > > > > https://dzone.com/articles/k-means-clustering-scipy i use number of clusters = 120 https://gist.github.com/hoyeunglee/2475391ad554e3d2b2a40ec24ab47940 https://drive.google.com/file/d/0Bxs_ao6uuBDUZFByNVgzd0Jrdm8/view?usp=sharing using my previous is not suitable for english words but using kmeans is better, however not perfect to cluster words, some words are missing From steve+python at pearwood.info Fri Aug 4 10:51:40 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 00:51:40 +1000 Subject: Challenge: find the first value where two functions differ Message-ID: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> This is a challenge for which I don't have a complete answer, only a partial answer. Here are two functions for calculating the integer square root of a non-negative int argument. The first is known to be exact but may be a bit slow: def isqrt_newton(n): """Integer sqrt using Newton's Method.""" if n == 0: return 0 bits = n.bit_length() a, b = divmod(bits, 2) x = 2**(a+b) while True: y = (x + n//x)//2 if y >= x: return x x = y The second is only exact for some values of n, and for sufficiently large values of n, is will fail altogether: import math def isqrt_float(n): """Integer square root using floating point sqrt.""" return int(math.sqrt(n)) We know that: - for n <= 2**53, isqrt_float(n) is exact; - for n >= 2**1024, isqrt_float(n) will raise OverflowError; - between those two values, 2**53 < n < 2**1024, isqrt_float(n) will sometimes be exact, and sometimes not exact; - there is some value, let's call it M, which is the smallest integer where isqrt_float is not exact. Your mission, should you choose to accept it, is to find M. Hint: a linear search starting at 2**53 will find it -- eventually. But it might take a long time. Personally I gave up after five minutes, but for all I know if I had a faster computer I'd already have the answer. (But probably not.) Another hint: if you run this code: for i in range(53, 1024): n = 2**i if isqrt_newton(n) != isqrt_float(n): print(n) break you can find a much better upper bound for M: 2**53 < M <= 2**105 which is considerable smaller that the earlier upper bound of 2**1024. But even so, that's still 40564819207303331840695247831040 values to be tested. On the assumption that we want a solution before the return of Halley's Comet, how would you go about finding M? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From robin at reportlab.com Fri Aug 4 11:11:04 2017 From: robin at reportlab.com (Robin Becker) Date: Fri, 4 Aug 2017 16:11:04 +0100 Subject: SSL/TLS support in Pyro4 In-Reply-To: <598480d4$0$814$e4fe514c@news.xs4all.nl> References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> <6613b313-46ff-19b1-f25a-4348d96078b0@chamonix.reportlab.co.uk> <598454a2$0$770$e4fe514c@news.xs4all.nl> <4e75110a-1699-7633-139f-5879d5bce5ee@chamonix.reportlab.co.uk> <598480d4$0$814$e4fe514c@news.xs4all.nl> Message-ID: <8b61dd4f-430f-06db-a8e8-bf7b120c23df@chamonix.reportlab.co.uk> On 04/08/2017 15:12, Irmen de Jong wrote: > On 04/08/2017 15:44, Robin Becker wrote: .......... > You can specify a CAcert using load_verify_locations on the ssl context. Is that what > you meant? I figured out that if you set that to the peer's certificate it will then be yes I think so. Certainly the self signed certs I tried with python3 urllib seemed to require valid hostnames. If I just use this as server from http.server import HTTPServer, BaseHTTPRequestHandler, SimpleHTTPRequestHandler import ssl httpd = HTTPServer(('localhost', 4443), SimpleHTTPRequestHandler) httpd.socket = ssl.wrap_socket (httpd.socket, keyfile="/home/rptlab/tmp/key.pem", certfile='/home/rptlab/tmp/cert.pem', server_side=True) httpd.serve_forever() and this as requester from urllib import request req = request.urlopen('https://localhost:4443', cafile='/home/rptlab/tmp/cert.pem') print(req.read()) then provided the self signed cert has the name localhost requests can be made OK. I'm guessing this would also work OK if the cert had multiple names embedded in it which would allow a small cluster to be used. I don't know which part of the socket does the host name checking, but perhaps that can be turned off somewhere. > accepted. I understand it as much as "hey openssl here is a root cert that you should > trust if you encounter it". > Without doing this, the cert is denied on the SSL level (unless you set the ssl options > to no-cert-required but that is definitely not what I wanted) > > Bottom line is I learned something new :) > > And also that Python's standard ssl library isn't as bad as I remember it to be a few > years ago. Is there still a reason to use, say, PyOpenSSL anymore? > it's getting better any how. > > Irmen > -- Robin Becker From leamhall at gmail.com Fri Aug 4 11:22:58 2017 From: leamhall at gmail.com (leam hall) Date: Fri, 4 Aug 2017 11:22:58 -0400 Subject: PyYaml not using Yaml 1.2? Message-ID: Getting in to Ansible and back into Python. Ansible uses pyyaml which says it parses yaml version 1.1. Is there a reason it doesn't do yaml version 1.2? Thanks! Leam From rhodri at kynesim.co.uk Fri Aug 4 11:35:47 2017 From: rhodri at kynesim.co.uk (Rhodri James) Date: Fri, 4 Aug 2017 16:35:47 +0100 Subject: Challenge: find the first value where two functions differ In-Reply-To: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <9c9b2fd9-7678-cf4c-a2ed-8d412e135598@kynesim.co.uk> On 04/08/17 15:51, Steve D'Aprano wrote: > Another hint: if you run this code: > > > for i in range(53, 1024): > n = 2**i > if isqrt_newton(n) != isqrt_float(n): > print(n) > break > > > you can find a much better upper bound for M: > > 2**53 < M <= 2**105 > > which is considerable smaller that the earlier upper bound of 2**1024. But even > so, that's still 40564819207303331840695247831040 values to be tested. > > On the assumption that we want a solution before the return of Halley's Comet, > how would you go about finding M? I tried a variation of what you used to cut down the search space further: for j in range(0, 53): for i in range(53, 105): n = 2**i + 2**j if isqrt_newton(n) != isqrt_float(n): print(n, i, j) sys.exit(1) which gave me a new upper bound of 2**54+2**28. Reversing the order of the loops would probably have been more sensible, but what the heck. That's only (!) 9007199523176448 values to test, which my machine seemed to be quite happy with, but you could repeat the exercise with more layers if you really wanted to. -- Rhodri James *-* Kynesim Ltd From rosuav at gmail.com Fri Aug 4 11:44:22 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 01:44:22 +1000 Subject: Challenge: find the first value where two functions differ In-Reply-To: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 5, 2017 at 12:51 AM, Steve D'Aprano wrote: > def isqrt_float(n): > """Integer square root using floating point sqrt.""" > return int(math.sqrt(n)) > > > > We know that: > > - for n <= 2**53, isqrt_float(n) is exact; > > - for n >= 2**1024, isqrt_float(n) will raise OverflowError; > > - between those two values, 2**53 < n < 2**1024, isqrt_float(n) > will sometimes be exact, and sometimes not exact; > > - there is some value, let's call it M, which is the smallest > integer where isqrt_float is not exact. > > > Your mission, should you choose to accept it, is to find M. Hmm. Thinking aloud a bit here. We know that isqrt_float(n) is not technically *exact* for any n that is not a square. So what I'd do is assume that for (n*n+1) to (n+1)*(n+1)-1, it's going to return the same value. I would then probe every perfect square, and the values one above and one below it. Now, that's still probably too many to check, but it's going to be a lot faster; for starters, we don't actually need to use isqrt_newton to compare against it. for root in range(2**26, 2**53): square = root * root if isqrt_float(square - 1) != root - 1: print(square - 1) break if isqrt_float(square) != root: print(square) break if isqrt_float(square + 1) != root: print(square + 1) break That gave me this result almost instantaneously: 4503599761588224 which has been rounded up instead of down. I don't know if that counts as sufficiently wrong? >>> isqrt_float(4503599761588224) 67108865 >>> isqrt_newton(4503599761588224) 67108864 >>> 67108865 ** 2 4503599761588225 ChrisA From rosuav at gmail.com Fri Aug 4 11:47:00 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 01:47:00 +1000 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 5, 2017 at 1:44 AM, Chris Angelico wrote: > That gave me this result almost instantaneously: > > 4503599761588224 > > which has been rounded up instead of down. I don't know if that counts > as sufficiently wrong? Oh, and I forgot to say: I have no actual *proof* that this is the lowest number for which this will occur. It does not occur with 4503599761588223 (the next lower integer), but could happen with something between two squares, for all I know. However, I suspect that it wouldn't. ChrisA From ian.g.kelly at gmail.com Fri Aug 4 11:47:07 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 09:47:07 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 8:51 AM, Steve D'Aprano wrote: > This is a challenge for which I don't have a complete answer, only a partial > answer. > > Here are two functions for calculating the integer square root of a non-negative > int argument. The first is known to be exact but may be a bit slow: > > def isqrt_newton(n): > """Integer sqrt using Newton's Method.""" > if n == 0: > return 0 > bits = n.bit_length() > a, b = divmod(bits, 2) > x = 2**(a+b) > while True: > y = (x + n//x)//2 > if y >= x: > return x > x = y > > > The second is only exact for some values of n, and for sufficiently large values > of n, is will fail altogether: > > > import math > > def isqrt_float(n): > """Integer square root using floating point sqrt.""" > return int(math.sqrt(n)) > > > > We know that: > > - for n <= 2**53, isqrt_float(n) is exact; > > - for n >= 2**1024, isqrt_float(n) will raise OverflowError; > > - between those two values, 2**53 < n < 2**1024, isqrt_float(n) > will sometimes be exact, and sometimes not exact; > > - there is some value, let's call it M, which is the smallest > integer where isqrt_float is not exact. > > > Your mission, should you choose to accept it, is to find M. > > Hint: a linear search starting at 2**53 will find it -- eventually. But it might > take a long time. Personally I gave up after five minutes, but for all I know > if I had a faster computer I'd already have the answer. > > (But probably not.) > > > Another hint: if you run this code: > > > for i in range(53, 1024): > n = 2**i > if isqrt_newton(n) != isqrt_float(n): > print(n) > break > > > you can find a much better upper bound for M: > > 2**53 < M <= 2**105 > > which is considerable smaller that the earlier upper bound of 2**1024. But even > so, that's still 40564819207303331840695247831040 values to be tested. > > On the assumption that we want a solution before the return of Halley's Comet, > how would you go about finding M? Here's a much smaller upper bound: >>> n = 2 ** 53 >>> s = isqrt_newton(n) >>> n 9007199254740992 >>> s 94906265 >>> m = (s+1)**2 - 1 >>> m 9007199326062755 >>> isqrt_newton(m) == isqrt_float(m) False From skip.montanaro at gmail.com Fri Aug 4 11:52:16 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Fri, 4 Aug 2017 10:52:16 -0500 Subject: PyYaml not using Yaml 1.2? In-Reply-To: References: Message-ID: > Getting in to Ansible and back into Python. Ansible uses pyyaml which says > it parses yaml version 1.1. Is there a reason it doesn't do yaml version > 1.2? Nobody's done the work? Note that on the PyPI page: https://pypi.python.org/pypi/PyYAML the last release was almost a year ago. That said, 1.2 has been out for awhile. There is an open ticket, nearly four years old: https://bitbucket.org/xi/pyyaml/issues/23/support-yaml-12 Perhaps you can help move that forward. Skip From robin at reportlab.com Fri Aug 4 11:54:29 2017 From: robin at reportlab.com (Robin Becker) Date: Fri, 4 Aug 2017 16:54:29 +0100 Subject: Challenge: find the first value where two functions differ In-Reply-To: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <31594817-7661-c365-c1ce-ace7d757fdc5@chamonix.reportlab.co.uk> Well I tried a handomatic binary search and this number seems to differ 33347481357698898183343210233857L whereas this does not 33347481357698898183343210233856L On 04/08/2017 15:51, Steve D'Aprano wrote: > This is a challenge for which I don't have a complete answer, only a partial > answer. > > Here are two functions for calculating the integer square root of a non-negative > int argument. The first is known to be exact but may be a bit slow: > > def isqrt_newton(n): > """Integer sqrt using Newton's Method.""" > if n == 0: > return 0 > bits = n.bit_length() > a, b = divmod(bits, 2) > x = 2**(a+b) > while True: > y = (x + n//x)//2 > if y >= x: > return x > x = y > > > The second is only exact for some values of n, and for sufficiently large values > of n, is will fail altogether: > > > import math > > def isqrt_float(n): > """Integer square root using floating point sqrt.""" > return int(math.sqrt(n)) > > > > We know that: > > - for n <= 2**53, isqrt_float(n) is exact; > > - for n >= 2**1024, isqrt_float(n) will raise OverflowError; > > - between those two values, 2**53 < n < 2**1024, isqrt_float(n) > will sometimes be exact, and sometimes not exact; > > - there is some value, let's call it M, which is the smallest > integer where isqrt_float is not exact. > > > Your mission, should you choose to accept it, is to find M. > > Hint: a linear search starting at 2**53 will find it -- eventually. But it might > take a long time. Personally I gave up after five minutes, but for all I know > if I had a faster computer I'd already have the answer. > > (But probably not.) > > > Another hint: if you run this code: > > > for i in range(53, 1024): > n = 2**i > if isqrt_newton(n) != isqrt_float(n): > print(n) > break > > > you can find a much better upper bound for M: > > 2**53 < M <= 2**105 > > which is considerable smaller that the earlier upper bound of 2**1024. But even > so, that's still 40564819207303331840695247831040 values to be tested. > > On the assumption that we want a solution before the return of Halley's Comet, > how would you go about finding M? > > > > -- Robin Becker From robin at reportlab.com Fri Aug 4 11:54:29 2017 From: robin at reportlab.com (Robin Becker) Date: Fri, 4 Aug 2017 16:54:29 +0100 Subject: Challenge: find the first value where two functions differ In-Reply-To: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <31594817-7661-c365-c1ce-ace7d757fdc5@chamonix.reportlab.co.uk> Well I tried a handomatic binary search and this number seems to differ 33347481357698898183343210233857L whereas this does not 33347481357698898183343210233856L On 04/08/2017 15:51, Steve D'Aprano wrote: > This is a challenge for which I don't have a complete answer, only a partial > answer. > > Here are two functions for calculating the integer square root of a non-negative > int argument. The first is known to be exact but may be a bit slow: > > def isqrt_newton(n): > """Integer sqrt using Newton's Method.""" > if n == 0: > return 0 > bits = n.bit_length() > a, b = divmod(bits, 2) > x = 2**(a+b) > while True: > y = (x + n//x)//2 > if y >= x: > return x > x = y > > > The second is only exact for some values of n, and for sufficiently large values > of n, is will fail altogether: > > > import math > > def isqrt_float(n): > """Integer square root using floating point sqrt.""" > return int(math.sqrt(n)) > > > > We know that: > > - for n <= 2**53, isqrt_float(n) is exact; > > - for n >= 2**1024, isqrt_float(n) will raise OverflowError; > > - between those two values, 2**53 < n < 2**1024, isqrt_float(n) > will sometimes be exact, and sometimes not exact; > > - there is some value, let's call it M, which is the smallest > integer where isqrt_float is not exact. > > > Your mission, should you choose to accept it, is to find M. > > Hint: a linear search starting at 2**53 will find it -- eventually. But it might > take a long time. Personally I gave up after five minutes, but for all I know > if I had a faster computer I'd already have the answer. > > (But probably not.) > > > Another hint: if you run this code: > > > for i in range(53, 1024): > n = 2**i > if isqrt_newton(n) != isqrt_float(n): > print(n) > break > > > you can find a much better upper bound for M: > > 2**53 < M <= 2**105 > > which is considerable smaller that the earlier upper bound of 2**1024. But even > so, that's still 40564819207303331840695247831040 values to be tested. > > On the assumption that we want a solution before the return of Halley's Comet, > how would you go about finding M? > > > > -- Robin Becker From ian.g.kelly at gmail.com Fri Aug 4 12:00:15 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 10:00:15 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 9:47 AM, Chris Angelico wrote: > On Sat, Aug 5, 2017 at 1:44 AM, Chris Angelico wrote: >> That gave me this result almost instantaneously: >> >> 4503599761588224 >> >> which has been rounded up instead of down. I don't know if that counts >> as sufficiently wrong? > > Oh, and I forgot to say: I have no actual *proof* that this is the > lowest number for which this will occur. It does not occur with > 4503599761588223 (the next lower integer), but could happen with > something between two squares, for all I know. However, I suspect that > it wouldn't. Your example demonstrates that the "2**53 < M" assumption was wrong, which is interesting. It may be worth checking values less than 2**26 as well. From ian.g.kelly at gmail.com Fri Aug 4 12:03:43 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 10:03:43 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 10:00 AM, Ian Kelly wrote: > On Fri, Aug 4, 2017 at 9:47 AM, Chris Angelico wrote: >> On Sat, Aug 5, 2017 at 1:44 AM, Chris Angelico wrote: >>> That gave me this result almost instantaneously: >>> >>> 4503599761588224 >>> >>> which has been rounded up instead of down. I don't know if that counts >>> as sufficiently wrong? >> >> Oh, and I forgot to say: I have no actual *proof* that this is the >> lowest number for which this will occur. It does not occur with >> 4503599761588223 (the next lower integer), but could happen with >> something between two squares, for all I know. However, I suspect that >> it wouldn't. > > Your example demonstrates that the "2**53 < M" assumption was wrong, > which is interesting. It may be worth checking values less than 2**26 > as well. Less than (2**26)**2, I mean. From leamhall at gmail.com Fri Aug 4 12:14:07 2017 From: leamhall at gmail.com (leam hall) Date: Fri, 4 Aug 2017 12:14:07 -0400 Subject: PyYaml not using Yaml 1.2? In-Reply-To: References: Message-ID: On Fri, Aug 4, 2017 at 11:52 AM, Skip Montanaro wrote: > > Getting in to Ansible and back into Python. Ansible uses pyyaml which > says > > it parses yaml version 1.1. Is there a reason it doesn't do yaml version > > 1.2? > > Nobody's done the work? Note that on the PyPI page: > > https://pypi.python.org/pypi/PyYAML > > the last release was almost a year ago. That said, 1.2 has been out > for awhile. There is an open ticket, nearly four years old: > > https://bitbucket.org/xi/pyyaml/issues/23/support-yaml-12 > > Perhaps you can help move that forward. > > Skip > Hey Skip, thanks! Tracked down the GitHub repo (https://github.com/yaml/pyyaml) and it seems to be gearing back up. I'll see what I can do to help. Leam From python at mrabarnett.plus.com Fri Aug 4 12:31:55 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 4 Aug 2017 17:31:55 +0100 Subject: Challenge: find the first value where two functions differ In-Reply-To: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 2017-08-04 15:51, Steve D'Aprano wrote: > This is a challenge for which I don't have a complete answer, only a partial > answer. > > Here are two functions for calculating the integer square root of a non-negative > int argument. The first is known to be exact but may be a bit slow: > > def isqrt_newton(n): > """Integer sqrt using Newton's Method.""" > if n == 0: > return 0 > bits = n.bit_length() > a, b = divmod(bits, 2) > x = 2**(a+b) > while True: > y = (x + n//x)//2 > if y >= x: > return x > x = y > > > The second is only exact for some values of n, and for sufficiently large values > of n, is will fail altogether: > > > import math > > def isqrt_float(n): > """Integer square root using floating point sqrt.""" > return int(math.sqrt(n)) > > > > We know that: > > - for n <= 2**53, isqrt_float(n) is exact; > > - for n >= 2**1024, isqrt_float(n) will raise OverflowError; > > - between those two values, 2**53 < n < 2**1024, isqrt_float(n) > will sometimes be exact, and sometimes not exact; > > - there is some value, let's call it M, which is the smallest > integer where isqrt_float is not exact. > > > Your mission, should you choose to accept it, is to find M. > > Hint: a linear search starting at 2**53 will find it -- eventually. But it might > take a long time. Personally I gave up after five minutes, but for all I know > if I had a faster computer I'd already have the answer. > > (But probably not.) > > > Another hint: if you run this code: > > > for i in range(53, 1024): > n = 2**i > if isqrt_newton(n) != isqrt_float(n): > print(n) > break > > > you can find a much better upper bound for M: > > 2**53 < M <= 2**105 > > which is considerable smaller that the earlier upper bound of 2**1024. But even > so, that's still 40564819207303331840695247831040 values to be tested. > > On the assumption that we want a solution before the return of Halley's Comet, > how would you go about finding M? > Why would isqrt_float not give the correct answer? Probably because of truncation (or rounding up?) of the floating point. I'd expect it to fail first near a square. From christian at python.org Fri Aug 4 12:33:02 2017 From: christian at python.org (Christian Heimes) Date: Fri, 4 Aug 2017 18:33:02 +0200 Subject: SSL/TLS support in Pyro4 In-Reply-To: <8b61dd4f-430f-06db-a8e8-bf7b120c23df@chamonix.reportlab.co.uk> References: <59836bdb$0$749$e4fe514c@news.xs4all.nl> <6613b313-46ff-19b1-f25a-4348d96078b0@chamonix.reportlab.co.uk> <598454a2$0$770$e4fe514c@news.xs4all.nl> <4e75110a-1699-7633-139f-5879d5bce5ee@chamonix.reportlab.co.uk> <598480d4$0$814$e4fe514c@news.xs4all.nl> <8b61dd4f-430f-06db-a8e8-bf7b120c23df@chamonix.reportlab.co.uk> Message-ID: On 2017-08-04 17:11, Robin Becker wrote: > On 04/08/2017 15:12, Irmen de Jong wrote: >> On 04/08/2017 15:44, Robin Becker wrote: > .......... >> You can specify a CAcert using load_verify_locations on the ssl >> context. Is that what >> you meant? I figured out that if you set that to the peer's >> certificate it will then be > > yes I think so. Certainly the self signed certs I tried with python3 > urllib seemed to require valid hostnames. If I just use this as server > > > from http.server import HTTPServer, BaseHTTPRequestHandler, > SimpleHTTPRequestHandler > import ssl > > > httpd = HTTPServer(('localhost', 4443), SimpleHTTPRequestHandler) > > httpd.socket = ssl.wrap_socket (httpd.socket, > keyfile="/home/rptlab/tmp/key.pem", > certfile='/home/rptlab/tmp/cert.pem', server_side=True) > > httpd.serve_forever() > > and this as requester > > from urllib import request > req = request.urlopen('https://localhost:4443', > cafile='/home/rptlab/tmp/cert.pem') > print(req.read()) > > > then provided the self signed cert has the name localhost requests can > be made OK. > > I'm guessing this would also work OK if the cert had multiple names > embedded in it which would allow a small cluster to be used. > > I don't know which part of the socket does the host name checking, but > perhaps that can be turned off somewhere. This approach works but requires a carefully crafted certificate. The certificate must be a valid CA and EE certificate at the same time. Either you must not include any X509v3 extensions or correctly pick the right combination of BasicConstraint, Key Usage and Extended Key Usage. For my tests I use my own project CA. For example https://github.com/latchset/custodia/tree/master/tests/ca/ contains a script to generate a CA and two EE certs. The server cert is valid for localhost and 127.0.0.1. You can easily extend the configuration to include one or multiple intermediate CAs. Christian From dnmalkin1 at gmail.com Fri Aug 4 12:39:31 2017 From: dnmalkin1 at gmail.com (dnmalkin1 at gmail.com) Date: Fri, 4 Aug 2017 09:39:31 -0700 (PDT) Subject: Basic sample code, pandas and cython Message-ID: <1243f8c8-d5cf-4624-99c3-2792b01ded49@googlegroups.com> Does anyone have a really basic cython example where you create a dataframe (pandas) of random numbers 1 to 5 for 100 rows and cythonize the code? Is it already cythonized by the Pandas pd module? From steve+python at pearwood.info Fri Aug 4 13:37:38 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 03:37:38 +1000 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5984b0e4$0$1598$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 01:44 am, Chris Angelico wrote: > On Sat, Aug 5, 2017 at 12:51 AM, Steve D'Aprano > wrote: >> def isqrt_float(n): >> """Integer square root using floating point sqrt.""" >> return int(math.sqrt(n)) [...] > Hmm. Thinking aloud a bit here. We know that isqrt_float(n) is not > technically *exact* for any n that is not a square. Actually we do. You seem to be thinking about the "true" square root, not the integer square root. I'm sorry, I should have posted a link to the definition of integer square root, that's my mistake. But I thought that everyone would either already know, or know how to use Wikipedia :-) https://en.wikipedia.org/wiki/Integer_square_root Mea culpa. The integer square root is, *by definition*, the floor (round down to nearest integer, which for positive values is the same as just truncating) of the true square root. So the first few integer square roots are: n=1 isqrt=1 n=2 isqrt=1 n=3 isqrt=1 n=4 isqrt=2 and isqrt_float is exact for those n. It's definitely[1] exact for all n up to 2**53, and many more beyond that. By exact I mean that it returns the same (correct) root as isqrt_newton, rather than the root plus (or minus) a bit. An example of where it is *not* exact: py> isqrt_float(2**119) 815238614083298944 py> isqrt_newton(2**119) 815238614083298888 That's a difference of just 56 or one part in 14557 trillion, which is *approximately* correct :-) Up to 2**53, there is no rounding error when converting from int to float, which is why I am confident that int(math.sqrt(n)) will always give the exact value of integer square root up to at least 2**53. We have math.sqrt(n) return the correctly rounded true square root, and int() truncates it, which is the definition of integer square root. For example: py> isqrt_float(2**53) 94906265 py> isqrt_newton(2**53) 94906265 They're the same, and I stated earlier that you can take isqrt_newton as always exact. (Perhaps I should have said "correct" rather than exact?) You may be concerned that 94906265**2 != 2**53. That's not a problem. All that matters is that 94906265 is the largest integer which, when squared, is less than or equal to the original 2**53. And that is the case: py> 94906265**2 <= 2**53 True py> 94906266**2 > 2**53 True [1] I have only proved this is correct, not tested it. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 4 13:44:27 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 03:44:27 +1000 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 01:47 am, Ian Kelly wrote: > Here's a much smaller upper bound: > >>>> n = 2 ** 53 >>>> s = isqrt_newton(n) >>>> n > 9007199254740992 >>>> s > 94906265 >>>> m = (s+1)**2 - 1 >>>> m > 9007199326062755 >>>> isqrt_newton(m) == isqrt_float(m) > False Oooh, interesting. How did you get that? By luck, or do you have some reason for picking (s+1)**2 - 1? I have managed to find an upper bound *almost* as small: 9008783381281320 by running a script for the last 15 or 16 hours, which randomly tests ints between lower and upper bound. If it finds a miss, it reduces the upper bound. That started off very promised, and was extremely fast at first, but as the range of values to check gets tighter, it also becomes harder to find any misses. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Fri Aug 4 13:48:02 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 03:48:02 +1000 Subject: Challenge: find the first value where two functions differ In-Reply-To: <5984b0e4$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b0e4$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 5, 2017 at 3:37 AM, Steve D'Aprano wrote: > On Sat, 5 Aug 2017 01:44 am, Chris Angelico wrote: > >> On Sat, Aug 5, 2017 at 12:51 AM, Steve D'Aprano >> wrote: >>> def isqrt_float(n): >>> """Integer square root using floating point sqrt.""" >>> return int(math.sqrt(n)) > [...] > >> Hmm. Thinking aloud a bit here. We know that isqrt_float(n) is not >> technically *exact* for any n that is not a square. > > Actually we do. You seem to be thinking about the "true" square root, not the > integer square root. > > I'm sorry, I should have posted a link to the definition of integer square root, > that's my mistake. But I thought that everyone would either already know, or > know how to use Wikipedia :-) > > https://en.wikipedia.org/wiki/Integer_square_root > > Mea culpa. So my assumption turned out correct, albeit for slightly incorrect reasons. In any case, I based things on a discrepancy between isqrt_float and isqrt_newton. > and isqrt_float is exact for those n. It's definitely[1] exact for all n up to > 2**53, and many more beyond that. By exact I mean that it returns the same > (correct) root as isqrt_newton, rather than the root plus (or minus) a bit. > > An example of where it is *not* exact: > > py> isqrt_float(2**119) > 815238614083298944 > py> isqrt_newton(2**119) > 815238614083298888 > > [1] I have only proved this is correct, not tested it. And that's what I looked at. >>> isqrt_float(4503599761588224) 67108865 >>> isqrt_newton(4503599761588224) 67108864 This number is (2**52 + 2**27), and is one less than a square. The floating-point function is rounding it up, and as such is not returning the integer square root, which should be rounded down. Is my analysis correct? This value is lower than 2**53. ChrisA From rosuav at gmail.com Fri Aug 4 13:50:29 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 03:50:29 +1000 Subject: Challenge: find the first value where two functions differ In-Reply-To: <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 5, 2017 at 3:44 AM, Steve D'Aprano wrote: > On Sat, 5 Aug 2017 01:47 am, Ian Kelly wrote: > >> Here's a much smaller upper bound: >> >>>>> n = 2 ** 53 >>>>> s = isqrt_newton(n) >>>>> n >> 9007199254740992 >>>>> s >> 94906265 >>>>> m = (s+1)**2 - 1 >>>>> m >> 9007199326062755 >>>>> isqrt_newton(m) == isqrt_float(m) >> False > > Oooh, interesting. How did you get that? By luck, or do you have some reason for > picking (s+1)**2 - 1? > > > I have managed to find an upper bound *almost* as small: > > 9008783381281320 > > by running a script for the last 15 or 16 hours, which randomly tests ints > between lower and upper bound. If it finds a miss, it reduces the upper bound. > > That started off very promised, and was extremely fast at first, but as the > range of values to check gets tighter, it also becomes harder to find any > misses. My logic was that floating point rounding is easiest to notice when you're working with a number that's very close to something, and since we're working with square roots, "something" should be a perfect square. The integer square root of n**2 is n, the ISR of n**2+1 is also n, and the ISR of n**2-1 should be n-1. I actually wanted to start at 2**53, but being an odd power, that doesn't have an integer square root, so I started at 2**52, which has an ISR of 2**26. The phenomenon MAY depend on the current FPU rounding rules. ChrisA From steve+python at pearwood.info Fri Aug 4 13:51:11 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 03:51:11 +1000 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5984b412$0$1605$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 02:31 am, MRAB wrote: > Why would isqrt_float not give the correct answer? Probably because of > truncation (or rounding up?) of the floating point. I'd expect it to > fail first near a square. Assuming your math.sqrt() is an IEEE-754 correctly-rounded square root, and that int() correctly truncates, the only source of errors is that not all integers are representable as floats. No integer larger than or equal to 2**1024 can be represented as a float. No *odd* integer larger than 2**53 can be represented as a float. Between 2**53 and 2**54, float can only represent multiples of 2. Between 2**54 and 2**55, float can only represent multiples of 4. Between 2**55 and 2**56, float can only represent multiples of 8. And so on. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ian.g.kelly at gmail.com Fri Aug 4 13:54:31 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 11:54:31 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 11:44 AM, Steve D'Aprano wrote: > On Sat, 5 Aug 2017 01:47 am, Ian Kelly wrote: > >> Here's a much smaller upper bound: >> >>>>> n = 2 ** 53 >>>>> s = isqrt_newton(n) >>>>> n >> 9007199254740992 >>>>> s >> 94906265 >>>>> m = (s+1)**2 - 1 >>>>> m >> 9007199326062755 >>>>> isqrt_newton(m) == isqrt_float(m) >> False > > Oooh, interesting. How did you get that? By luck, or do you have some reason for > picking (s+1)**2 - 1? Partly luck. I reasoned that a mismatch would be due to incorrect rounding, which would most likely happen just before a perfect square. So I tried the value one less than the first perfect square after 2 ** 53 and it happened to work. I also tried the value two less, which did not. In any case, Chris's finding beats mine by a factor of two. From ian.g.kelly at gmail.com Fri Aug 4 13:59:13 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 11:59:13 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 11:50 AM, Chris Angelico wrote: > My logic was that floating point rounding is easiest to notice when > you're working with a number that's very close to something, and since > we're working with square roots, "something" should be a perfect > square. The integer square root of n**2 is n, the ISR of n**2+1 is > also n, and the ISR of n**2-1 should be n-1. I actually wanted to > start at 2**53, but being an odd power, that doesn't have an integer > square root, so I started at 2**52, which has an ISR of 2**26. A slight irony here is that it actually would have taken your script a *very* long time to get to 2**53 having started at 2**52, even only iterating over the perfect squares. From steve+python at pearwood.info Fri Aug 4 14:03:28 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 04:03:28 +1000 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5984b6f2$0$1619$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 01:44 am, Chris Angelico wrote: > Hmm. Thinking aloud a bit here. We know that isqrt_float(n) is not > technically *exact* for any n that is not a square. I got bogged down in answering that misapprehension, but it may not actually have mattered. You then said: > So what I'd do is > assume that for (n*n+1) to (n+1)*(n+1)-1, it's going to return the > same value. I would then probe every perfect square, and the values > one above and one below it. Now, that's still probably too many to > check, but it's going to be a lot faster; for starters, we don't > actually need to use isqrt_newton to compare against it. That's interesting. I think I need to think more about that when it's not stupid o'clock in the morning, because although I'm not sure your logic is sound I can't deny that you've hit on a *huge* improvement in the upper bound. You have: > That gave me this result almost instantaneously: > > 4503599761588224 > > which has been rounded up instead of down. I don't know if that counts > as sufficiently wrong? It certainly does! >>>> isqrt_float(4503599761588224) > 67108865 >>>> isqrt_newton(4503599761588224) > 67108864 After running a random search for something like 18 hours, I managed to get the bound down to 9008783381281320. Ian managed to pick 9007199326062755 (perhaps by luck?). But you beat us both, handsomely. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Fri Aug 4 14:03:30 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 04:03:30 +1000 Subject: Challenge: find the first value where two functions differ In-Reply-To: <5984b412$0$1605$c3e8da3$5496439d@news.astraweb.com> References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b412$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 5, 2017 at 3:51 AM, Steve D'Aprano wrote: > On Sat, 5 Aug 2017 02:31 am, MRAB wrote: > >> Why would isqrt_float not give the correct answer? Probably because of >> truncation (or rounding up?) of the floating point. I'd expect it to >> fail first near a square. > > Assuming your math.sqrt() is an IEEE-754 correctly-rounded square root To clarify: What you're assuming here is that the floating-point value that math.sqrt returns is exactly the value that you get by rounding the true square root (even if transcendental) to the available precision. I *believe* that that's guaranteed for a floating-point input value, but is it for integer input? Is there any way that (say) 2**53+1 could sqrt to a different value depending on whether you convert the input to float first? ChrisA From ian.g.kelly at gmail.com Fri Aug 4 14:03:30 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 12:03:30 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 11:59 AM, Ian Kelly wrote: > On Fri, Aug 4, 2017 at 11:50 AM, Chris Angelico wrote: >> My logic was that floating point rounding is easiest to notice when >> you're working with a number that's very close to something, and since >> we're working with square roots, "something" should be a perfect >> square. The integer square root of n**2 is n, the ISR of n**2+1 is >> also n, and the ISR of n**2-1 should be n-1. I actually wanted to >> start at 2**53, but being an odd power, that doesn't have an integer >> square root, so I started at 2**52, which has an ISR of 2**26. > > A slight irony here is that it actually would have taken your script a > *very* long time to get to 2**53 having started at 2**52, even only > iterating over the perfect squares. Never mind, I just tried it and it's a few seconds. I guess there are not as many perfect squares in that range as I thought. From rosuav at gmail.com Fri Aug 4 14:14:16 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 04:14:16 +1000 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> <5984b27d$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 5, 2017 at 4:03 AM, Ian Kelly wrote: > On Fri, Aug 4, 2017 at 11:59 AM, Ian Kelly wrote: >> On Fri, Aug 4, 2017 at 11:50 AM, Chris Angelico wrote: >>> My logic was that floating point rounding is easiest to notice when >>> you're working with a number that's very close to something, and since >>> we're working with square roots, "something" should be a perfect >>> square. The integer square root of n**2 is n, the ISR of n**2+1 is >>> also n, and the ISR of n**2-1 should be n-1. I actually wanted to >>> start at 2**53, but being an odd power, that doesn't have an integer >>> square root, so I started at 2**52, which has an ISR of 2**26. >> >> A slight irony here is that it actually would have taken your script a >> *very* long time to get to 2**53 having started at 2**52, even only >> iterating over the perfect squares. > > Never mind, I just tried it and it's a few seconds. I guess there are > not as many perfect squares in that range as I thought. There are about thirty million of them. Python can calculate square roots in a handful of nanoseconds on my system, so "a few seconds" sounds about right. >>> math.sqrt(2**53) - math.sqrt(2**52) 27797401.62425156 >>> 2**26 * 0.41421356 27797401.46499584 ChrisA From ian.g.kelly at gmail.com Fri Aug 4 14:17:22 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 4 Aug 2017 12:17:22 -0600 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 4, 2017 at 10:03 AM, Ian Kelly wrote: > On Fri, Aug 4, 2017 at 10:00 AM, Ian Kelly wrote: >> On Fri, Aug 4, 2017 at 9:47 AM, Chris Angelico wrote: >>> On Sat, Aug 5, 2017 at 1:44 AM, Chris Angelico wrote: >>>> That gave me this result almost instantaneously: >>>> >>>> 4503599761588224 >>>> >>>> which has been rounded up instead of down. I don't know if that counts >>>> as sufficiently wrong? >>> >>> Oh, and I forgot to say: I have no actual *proof* that this is the >>> lowest number for which this will occur. It does not occur with >>> 4503599761588223 (the next lower integer), but could happen with >>> something between two squares, for all I know. However, I suspect that >>> it wouldn't. >> >> Your example demonstrates that the "2**53 < M" assumption was wrong, >> which is interesting. It may be worth checking values less than 2**26 >> as well. > > Less than (2**26)**2, I mean. I modified Chris's code to check every square below 2**52. 4503599761588224 is the smallest example that is at most one off from a perfect square. From steve+python at pearwood.info Fri Aug 4 14:36:20 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 04:36:20 +1000 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5984bea7$0$1621$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 02:00 am, Ian Kelly wrote: > On Fri, Aug 4, 2017 at 9:47 AM, Chris Angelico wrote: >> On Sat, Aug 5, 2017 at 1:44 AM, Chris Angelico wrote: >>> That gave me this result almost instantaneously: >>> >>> 4503599761588224 >>> >>> which has been rounded up instead of down. I don't know if that counts >>> as sufficiently wrong? [...] > Your example demonstrates that the "2**53 < M" assumption was wrong, > which is interesting. It sure is. You're right, of course, I hadn't noticed that Chris' M was approximately half 2**53. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From tjreedy at udel.edu Fri Aug 4 16:17:27 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 4 Aug 2017 16:17:27 -0400 Subject: Challenge: find the first value where two functions differ In-Reply-To: References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/4/2017 11:44 AM, Chris Angelico wrote: > On Sat, Aug 5, 2017 at 12:51 AM, Steve D'Aprano > wrote: >> def isqrt_float(n): >> """Integer square root using floating point sqrt.""" >> return int(math.sqrt(n)) The operations in the integer version are well-defined and so the answer should be the same on any Python 3 and indeed in any language that does proper integer arithmetic (but most do not). In CPython, Math.sqrt wraps the C compiler's double sqrt function. To make it deterministic, we must specify the float representation, rounding rule, and accuracy of the sqrt function. Let's assume that the float answer is IEEE binary64, with 53 binary digits, with rounding rule 'round to nearest, ties to even' and that the algorithm is as exact as possible, which is to say, the exact mathematical answer rounded as specified. With 53 binary digits, all counts from 0 to 2**53 - 1 are exactly represented with a exponent of 0, 2**53 = 2**52 * 2, so it is exactly represented with an exponent of 1. Many other higher counts can be exactly represented with various exponents, but 2**53 + 1 requires 54 digits. So it is the first count that does not have an exact binary64 representation. Under these assumptions, how can isqrt_float(n) fail? Suppose 0 <= m <= 2**26.5, so that m*m <= 2**53. Under the assumptions that m.sqrt is as exact as possible, sqrt(m*m) == float(m) and int(float(m)) == m. The true square root of m*m -1 will be m - e (e < 1) and the integer square root is m-1. However, if e is less than (and I believe equal) to 1/2 of the interval between n and the next lowest float, m - e will be rounded up to float(m) and ifloat(m*m-1) will incorrectly return m instead of m-1. As m increases, e decreases while the interval between floats increases, so we should expect an eventual error In this range of m, sqrt(m*m +1) will always be greater than m, so rounding down cannot lead to an error. For larger m, where float(m*m) is inaccurate enough, it might. As m increases, e decreases while the interval between floats increases, so we should expect an eventual error. Whether it occurs for m <= 2* or not might be determined by careful analysis, but Chris Angelico already gave us the brute force answer. >> We know that: >> >> - for n <= 2**53, isqrt_float(n) is exact; but it is not ;-). In this range, the only possibility is math.sqrt(m*m-1) being m instead of m - delta and that is the case for Chris' answer 4503599761588224 = 67108865**2 - 1. int(math.float(4503599761588224) is 67108865 instead of 67108864. >> - for n >= 2**1024, isqrt_float(n) will raise OverflowError >> - between those two values, 2**53 < n < 2**1024, isqrt_float(n) >> will sometimes be exact, and sometimes not exact; >> - there is some value, let's call it M, which is the smallest >> integer where isqrt_float is not exact. >> Your mission, should you choose to accept it, is to find M. > Hmm. Thinking aloud a bit here. We know that isqrt_float(n) is not > technically *exact* for any n that is not a square. So what I'd do is > assume that for (n*n+1) to (n+1)*(n+1)-1, it's going to return the > same value. I would then probe every perfect square, and the values > one above and one below it. Now, that's still probably too many to > check, but it's going to be a lot faster; for starters, we don't > actually need to use isqrt_newton to compare against it. > > for root in range(2**26, 2**53): > square = root * root > if isqrt_float(square - 1) != root - 1: > print(square - 1) > break > if isqrt_float(square) != root: > print(square) > break > if isqrt_float(square + 1) != root: > print(square + 1) > break > > That gave me this result almost instantaneously: > > 4503599761588224 Your limit was barely low enough ;-). >>> math.log2(math.sqrt(4503599761588224)) 26.000000021497833 If you had started with, say int(2**26.5)-1, you would have missed this. I reran with range(2, 2**26) and there is nothing lower. >>> math.log2(4503599761588224) 52.00000004299566 >>> import decimal as d >>> I = d.Decimal(4503599761588224) >>> I.sqrt() Decimal('67108864.99999999254941951410') >>> float(I.sqrt()) 67108865.0 > which has been rounded up instead of down. I don't know if that counts > as sufficiently wrong? The isqrt_float answer is definitely wrong, and so is the claim for n < 2**53. >>>> isqrt_float(4503599761588224) > 67108865 >>>> isqrt_newton(4503599761588224) > 67108864 >>>> 67108865 ** 2 > 4503599761588225 -- Terry Jan Reedy From lele at metapensiero.it Fri Aug 4 17:17:20 2017 From: lele at metapensiero.it (Lele Gaifax) Date: Fri, 04 Aug 2017 23:17:20 +0200 Subject: PyYaml not using Yaml 1.2? References: Message-ID: <87lgmz823j.fsf@metapensiero.it> leam hall writes: > Tracked down the GitHub repo (https://github.com/yaml/pyyaml) and it seems > to be gearing back up. I'll see what I can do to help. See also https://bitbucket.org/ruamel/yaml, a fork of PyYAML, it seems more actively maintained and already supports format 1.2. ciao, lele. -- nickname: Lele Gaifax | Quando vivr? di quello che ho pensato ieri real: Emanuele Gaifas | comincer? ad aver paura di chi mi copia. lele at metapensiero.it | -- Fortunato Depero, 1929. From bgailer at gmail.com Fri Aug 4 17:57:40 2017 From: bgailer at gmail.com (Bob Gailer) Date: Fri, 4 Aug 2017 17:57:40 -0400 Subject: Code for addition In-Reply-To: References: Message-ID: On Aug 4, 2017 5:27 PM, "Ode Idoko via Python-list" wrote: > > Can anyone help with the python code that can add 101, 102, 103...2033 please? We are here to help but we don't have crystal balls to interpret your request. The best thing you can do is show us what attempts you have made to write code for this problem and the difficulties you have encountered. We always assume when given a problem like this that it's a homework assignment. So it's a good idea to state that upfront. Have you had any success in writing and running any python programs? Assuming that you are in a class, what aspects of python have you already learned? Can you apply any of that to this problem? The more you give us the easier it is for us to help. > As I said before, I'm new to python and need assistance in this regard. > Thanks for always assisting. > > Sent from my iPhone > -- > https://mail.python.org/mailman/listinfo/python-list From marko at pacujo.net Fri Aug 4 18:03:27 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sat, 05 Aug 2017 01:03:27 +0300 Subject: PyYaml not using Yaml 1.2? References: <87lgmz823j.fsf@metapensiero.it> Message-ID: <87vam33s9c.fsf@elektro.pacujo.net> Lele Gaifax : > leam hall writes: > >> Tracked down the GitHub repo (https://github.com/yaml/pyyaml) and it seems >> to be gearing back up. I'll see what I can do to help. > > See also https://bitbucket.org/ruamel/yaml, a fork of PyYAML, it seems more > actively maintained and already supports format 1.2. BTW, happened to land on this blog posting that mentions a security warning regarding PyYAML: A suggested fix is to always use yaml.safe_load for handling YAML serialization you can't trust. Still, the current PyYAML default feels somewhat provoking considering other serialization libraries tend to use dump/load function names for similar purposes, but in a safe manner. Marko From nobozo at gmail.com Fri Aug 4 19:11:18 2017 From: nobozo at gmail.com (Jon Forrest) Date: Fri, 4 Aug 2017 16:11:18 -0700 Subject: Question About When Objects Are Destroyed Message-ID: Consider the following Python shell session (Python 3.6.2, Win64): >>> def givemetwo(): ... x = 'two' ... print(id(x)) ... >>> givemetwo() 1578505988392 So far fine. My understanding of object existence made me think that the object referred to by x would be deleted when the givemetwo() function returned, like a local variable in C. However, this isn't true, as shown by the following in the same session: >>> import ctypes >>> print (ctypes.cast(1578505988392, ctypes.py_object).value) two This shows that the object still exists, which was a surprise. Will this object ever be deleted? I'm learning about function decorators which, as my early studies tell me, depend on calling a function defined inside another function. This suggests that objects defined inside functions are never deleted, otherwise function decorators would never work. (I'm not 100% sure my understanding of function decorators is correct since I'm still learning about them). What's the right way to think about this? Cordially, Jon Forrest From g.starck at gmail.com Fri Aug 4 19:34:51 2017 From: g.starck at gmail.com (gst) Date: Fri, 4 Aug 2017 16:34:51 -0700 (PDT) Subject: Question About When Objects Are Destroyed In-Reply-To: References: Message-ID: <12b6998e-430c-45de-97d3-cf897a9466ef@googlegroups.com> 'two' is a so called constant or literal value .. (of that function). Why not attach it, as a const value/object, to the function itself ? So that a new string object has not to be created each time the function is called. Because anyway strings are immutable. So what would be the point to recreate such object every time the function is called ? From nobozo at gmail.com Fri Aug 4 19:42:56 2017 From: nobozo at gmail.com (Jon Forrest) Date: Fri, 4 Aug 2017 16:42:56 -0700 Subject: Question About When Objects Are Destroyed In-Reply-To: <12b6998e-430c-45de-97d3-cf897a9466ef@googlegroups.com> References: <12b6998e-430c-45de-97d3-cf897a9466ef@googlegroups.com> Message-ID: On 8/4/2017 4:34 PM, gst wrote: > 'two' is a so called constant or literal value .. (of that > function). > > Why not attach it, as a const value/object, to the function itself ? > So that a new string object has not to be created each time the > function is called. Because anyway strings are immutable. So what > would be the point to recreate such object every time the function is > called ? This was just an example program, not meant to do anything meaningful. I would think that the same object behavior would occur if I dynamically created an object in that function. Jon From framstag at rus.uni-stuttgart.de Fri Aug 4 19:45:44 2017 From: framstag at rus.uni-stuttgart.de (Ulli Horlacher) Date: Fri, 4 Aug 2017 23:45:44 +0000 (UTC) Subject: Linux/Windows GUI programming: tk or wx? Message-ID: I have to transfer a python 2.7 CLI programm into one with a (simple) GUI. The program must run on Linux and Windows and must be compilable with pyinstall, because I have to ship a standalone windows.exe Any kind of installer is not acceptable. Reading https://github.com/pyinstaller/pyinstaller/wiki/Supported-Packages supported GUI packages are PyGTK, PyQt4, PyQt5, wxPython I have tested tkinter by myself and it works, too. I do not like GTK and Qt, because they are too complex. I want to do VERY simple things and I prefer a simple GUI toolkit :-) Is there a recommendation for using tk or wx? -- Ullrich Horlacher Server und Virtualisierung Rechenzentrum TIK Universitaet Stuttgart E-Mail: horlacher at tik.uni-stuttgart.de Allmandring 30a Tel: ++49-711-68565868 70569 Stuttgart (Germany) WWW: http://www.tik.uni-stuttgart.de/ From nobozo at gmail.com Fri Aug 4 19:47:49 2017 From: nobozo at gmail.com (Jon Forrest) Date: Fri, 4 Aug 2017 16:47:49 -0700 Subject: Question About When Objects Are Destroyed (continued) Message-ID: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Perhaps the reason the variable isn't destroyed is shown by the following (again, in the same session): >>> import sys >>> sys.getrefcount(1578505988392) 3 So, maybe it's not destroyed because there are still references to it. But, what are these references? Will the reference count ever go to zero? Jon From rosuav at gmail.com Fri Aug 4 19:54:08 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 09:54:08 +1000 Subject: Question About When Objects Are Destroyed In-Reply-To: References: <12b6998e-430c-45de-97d3-cf897a9466ef@googlegroups.com> Message-ID: On Sat, Aug 5, 2017 at 9:42 AM, Jon Forrest wrote: > On 8/4/2017 4:34 PM, gst wrote: >> >> 'two' is a so called constant or literal value .. (of that >> function). >> >> Why not attach it, as a const value/object, to the function itself ? >> So that a new string object has not to be created each time the >> function is called. Because anyway strings are immutable. So what >> would be the point to recreate such object every time the function is >> called ? > > > This was just an example program, not meant to do anything > meaningful. I would think that the same object behavior would > occur if I dynamically created an object in that function. Python doesn't have pointers, so what you have is an arbitrary number. Even if the object had been freed from memory, you could quite probably do the same shenanigans to get a value out of it; the data would still be there. Basically, don't think about object lifetimes. Objects will be flushed from memory once they're not needed any more, and no sooner; so you can safely return anything from any function. ChrisA From rosuav at gmail.com Fri Aug 4 20:00:46 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 10:00:46 +1000 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On Sat, Aug 5, 2017 at 9:47 AM, Jon Forrest wrote: > Perhaps the reason the variable isn't destroyed is > shown by the following (again, in the same session): > >>>> import sys >>>> sys.getrefcount(1578505988392) > 3 > > So, maybe it's not destroyed because there are still > references to it. But, what are these references? > Will the reference count ever go to zero? That's the reference count for the integer object. Nothing to do with the original. Again, don't stress about exactly when objects get disposed of; it doesn't matter. ChrisA From torriem at gmail.com Fri Aug 4 20:35:47 2017 From: torriem at gmail.com (Michael Torrie) Date: Fri, 4 Aug 2017 18:35:47 -0600 Subject: Linux/Windows GUI programming: tk or wx? In-Reply-To: References: Message-ID: <95a5d47f-5cc4-0712-6e4c-2376488ee762@gmail.com> On 08/04/2017 05:45 PM, Ulli Horlacher wrote: > I have to transfer a python 2.7 CLI programm into one with a (simple) GUI. > The program must run on Linux and Windows and must be compilable with > pyinstall, because I have to ship a standalone windows.exe > Any kind of installer is not acceptable. > > Reading https://github.com/pyinstaller/pyinstaller/wiki/Supported-Packages > supported GUI packages are PyGTK, PyQt4, PyQt5, wxPython > I have tested tkinter by myself and it works, too. > I do not like GTK and Qt, because they are too complex. > > I want to do VERY simple things and I prefer a simple GUI toolkit :-) > > Is there a recommendation for using tk or wx? Well tk is already an optional part of the Python standard library, whereas wx is an external package. So for your simple requirements, Tk may be the way to go. I'm guessing the tk would result in the smallest executable as well, though I could be very wrong. As for Qt, it's a large library, but it's not as complex as you think. In fact for simple GUIs it's no more complicated than wx or tk. So don't discount PyQt as being unworkable, though you do need to be aware of PyQt's license, which might be incompatible with your needs (it's GPL only unless you pay for it). PySide is largely compatible with PyQt code and is LGPL instead of GPL, so that could be an option as well. From steve+python at pearwood.info Fri Aug 4 21:19:09 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 11:19:09 +1000 Subject: Question About When Objects Are Destroyed References: Message-ID: <59851d0e$0$1590$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 09:11 am, Jon Forrest wrote: > Consider the following Python shell session (Python 3.6.2, Win64): > > >>> def givemetwo(): > ... x = 'two' > ... print(id(x)) > ... > >>> givemetwo() > 1578505988392 > > So far fine. My understanding of object existence made me > think that the object referred to by x would be deleted when > the givemetwo() function returned, like a local variable in C. Not necessarily. Objects are destroyed when they are no longer referenced by any other object. That may happen when the function exits, but it may not. For example, if you return x, and the caller assigns it to a name, then the object will still be referenced. However, when you exit the function, what is guaranteed is that all local variables will go out of scope and clear *their* references to whatever objects they are bound to. Not necessarily *all* references, but just the ones from local variables. Consider the object "spam and eggs", a string. If I say: s = "spam and eggs" # first reference def func(): t = s # t is a local variable, so now two refs u = t # third ref return None func() While func() is executing, there are three references to the object: s, a global, and t and u, locals. When the function exits, the *names* (variables) t and u go out of scope and those references cease to exist, but the s reference still exists and so the object (string "spam and eggs") still exists. If you then re-bind the name s to something else: s = "foo bar" or delete the name: del s that will remove the last reference to the object and it can be garbage collected. > However, this isn't true, as shown by the following in the same > session: > > >>> import ctypes > >>> print (ctypes.cast(1578505988392, ctypes.py_object).value) > two > > This shows that the object still exists, which was a surprise. You may be right about the object still existing, but for the wrong reasons. The Python interpreter is free to cache objects that it thinks have a good chance of being re-created. This is obviously implementation dependent: it will depend on the specific interpreter (CPython, Jython, IronPython, PyPy, Stackless, Nuika), the specific version, and potentially any other factor the interpreter wishes to take into account, up to and including the phase of the moon. In this case, CPython caches short strings that look like identifiers. It does this because variables are implemented as string keys in dicts, so when you create a variable two = 2 the interpreter creates a string object 'two' to use as a key in the globals() dict. Since object creation is relatively costly, the interpreter caches that string and keeps it around. So your test has accidentally hit an implementation-dependent feature of CPython. If you had used a string that didn't look like an identifier, say "two not three, okay?" you may have seen different results. Or maybe not. This is all implementation dependent. By using ctypes, you are poking around in the internals of the Python interpreter, you aren't looking at what *Python the language* guarantees, but merely whatever this specific version of CPython happens to do, today. For example, you are already on shaky ground by using the ID of an object, which is an opaque integer, as if it were a memory address. Object IDs aren't memory addresses, they are opaque integers. It just happens that for speed, the CPython interpreter uses the address of the object as its ID. But it can only do that because the CPython garbage collector is very simple, and it never relocates objects from place to place. But Jython and IronPython have more sophisticated garbage collectors which do, so they use a different scheme for generating IDs which are consecutive integers. So... you've effectively grabbed an arbitrary address in memory, which may have previously contained a certain string object. You use ctypes to interpret that chunk of memory as an object. Since CPython doesn't move memory around, you might be okay: - either that address actually does point to a live object, and you're safe; - or it points to what *was* a live object, but the memory hasn't been used, and so all the fields are still correctly allocated, and you're safe; but you might not be. What if some other object has re-used that piece of memory? You might now be jumping halfway into some other object, and trying to interpret that as the start of an object. You can segfault CPython with ctypes. > Will this object ever be deleted? The specific object 'two'? Maybe, maybe not. It might be cached for the lifetime of this interpreter session. Or there may be circumstances where cached objects age-out and are deleted. It depends on the implementation of the cache. That isn't a question about Python the language. > I'm learning about function > decorators which, as my early studies tell me, depend on calling > a function defined inside another function. This suggests that > objects defined inside functions are never deleted, otherwise > function decorators would never work. (I'm not 100% sure > my understanding of function decorators is correct since I'm > still learning about them). Nope, that's wrong. Objects defined inside functions will be garbage collected the same as objects defined outside of functions: when there are no references to them left. Decorators work because they create long-lasting references to the object. But if you delete those references, say by re-binding their name to something else, then the objects will be deleted same as anything else. > What's the right way to think about this? 99% of the time, the right way to think about this is not to. Python has a garbage collector so you don't have to worry about object lifetimes. So long as something refers to an object, it will be there if you need it. And when nothing refers to it, as far as you are concerned it will be garbage collected. There are a few tricky corner cases, such as: - interpreter caches (short version: "Ignore them") - object destructor method __del__ (short version: "Don't use it") - reference cycles (short version: "Don't worry, they're taken care of") but even there, 99% of the time you just don't need to care. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 4 21:24:57 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 11:24:57 +1000 Subject: Code for addition References: Message-ID: <59851e6a$0$1599$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 12:43 pm, Ode Idoko wrote: > Can anyone help with the python code that can add 101, 102, 103...2033 please? Sounds like homework. Here are some hints for you to play around with and see if you can get the right answer: sum([101, 102, 103]) range(101, 104) sum(range(1, 4)) What does sum() do? What does range() do? Can you put them together to get the answer you need? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From tjreedy at udel.edu Fri Aug 4 22:36:00 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 4 Aug 2017 22:36:00 -0400 Subject: Question About When Objects Are Destroyed In-Reply-To: References: Message-ID: On 8/4/2017 7:11 PM, Jon Forrest wrote: > Consider the following Python shell session (Python 3.6.2, Win64): > > >>> def givemetwo(): > ... x = 'two' > ... print(id(x)) > ... > >>> givemetwo() > 1578505988392 > > So far fine. My understanding of object existence made me > think that the object referred to by x would be deleted when > the givemetwo() function returned, like a local variable in C. Python does not specifically delete objects. It deletes references to objects, such as an association between a name and an object, or between a key and an object, or between a sequence index and an object. When a function returns, associations between local names and object are deleted. Python on a machine does not necessarily spend time 'cleaning' memory by overwriting it with 0s. > However, this isn't true, as shown by the following in the same > session: > > >>> import ctypes Most everything you see in the manuals (and on this list) has a little * after it. * unless one imports and uses ctypes (or 3rd party modules). For instance, 'Python code, even if buggy, should not crash the interpreter'* and 'If you find such code, it is a bug'*, 'Please open an issue on the tracker'*. If you use ctypes, please don't. > >>> print (ctypes.cast(1578505988392, ctypes.py_object).value) > two > > This shows that the object still exists, which was a surprise. > Will this object ever be deleted? What do you mean deleted? At this point, you are not looking at a normal Python object, as such, but rather the contents of a segment of machine memory at a particular address, extracted into a ctypes.py_object object. I don't think you want that chunk of memory destroyed. The only public attribute of the ctypes.py_object object is .value. It has a few undocumented private attributes, such as ._b_needsfree_ which, when I tried it, is 1. -- Terry Jan Reedy From ethan at stoneleaf.us Fri Aug 4 22:42:38 2017 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 04 Aug 2017 19:42:38 -0700 Subject: pip requirements file Message-ID: <5985309E.1070405@stoneleaf.us> pip freeze will output a list of current packages and their requirements. I have one package that falsely [1] lists another package as a requirement, which was blocking installation as the false requirement wasn't available. Is there a way to modify that output (which would be piped to, for example, requirements.txt) to have pip install -r requirements.txt so pip ignores that one (and only that one) dependency? -- ~Ethan~ [1] For the curious, the package is ZSA, and it list PyXML even though one of its modules says it was created specifically so PyXML is no longer needed -- and none of the modules import PyXML anywhere. From idokolord at yahoo.com Fri Aug 4 22:43:58 2017 From: idokolord at yahoo.com (Ode Idoko) Date: Fri, 4 Aug 2017 19:43:58 -0700 Subject: Code for addition Message-ID: Can anyone help with the python code that can add 101, 102, 103...2033 please? As I said before, I'm new to python and need assistance in this regard. Thanks for always assisting. Sent from my iPhone From rosuav at gmail.com Fri Aug 4 22:46:10 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 5 Aug 2017 12:46:10 +1000 Subject: pip requirements file In-Reply-To: <5985309E.1070405@stoneleaf.us> References: <5985309E.1070405@stoneleaf.us> Message-ID: On Sat, Aug 5, 2017 at 12:42 PM, Ethan Furman wrote: > pip freeze > > will output a list of current packages and their requirements. I have one > package that falsely [1] lists another package as a requirement, which was > blocking installation as the false requirement wasn't available. > > Is there a way to modify that output (which would be piped to, for example, > requirements.txt) to have > > pip install -r requirements.txt > > so pip ignores that one (and only that one) dependency? I'd just edit the file afterwards and delete the line. But if the package claims to need PyXML, it'll still be installed. ChrisA From ethan at stoneleaf.us Fri Aug 4 22:56:37 2017 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 04 Aug 2017 19:56:37 -0700 Subject: pip requirements file In-Reply-To: References: <5985309E.1070405@stoneleaf.us> Message-ID: <598533E5.6000101@stoneleaf.us> On 08/04/2017 07:46 PM, Chris Angelico wrote: > On Sat, Aug 5, 2017 at 12:42 PM, Ethan Furman wrote: >> pip freeze >> >> will output a list of current packages and their requirements. I have one >> package that falsely [1] lists another package as a requirement, which was >> blocking installation as the false requirement wasn't available. >> >> Is there a way to modify that output (which would be piped to, for example, >> requirements.txt) to have >> >> pip install -r requirements.txt >> >> so pip ignores that one (and only that one) dependency? > > I'd just edit the file afterwards and delete the line. But if the > package claims to need PyXML, it'll still be installed. Exactly my point. Is there any way, requirements.txt or otherwise, to tell pip to ignore what a certain package is claiming it needs? I am aware of --no-dependencies, but that (I think) is an all-or-nothing approach, whilst [1] I desire an all-except-one approach. -- ~Ethan~ [1] I blame words like 'whilst' on my new Paperback game by Tim Fowler. The Smarter-AI uses words from Middle-English (!) and spellings not seen for at least 300 years! But hey, my vocabulary is (uselessly) expanding! From dieter at handshake.de Sat Aug 5 00:58:21 2017 From: dieter at handshake.de (dieter) Date: Sat, 05 Aug 2017 06:58:21 +0200 Subject: [OT] Re: how to guess the number of cluster when do not know? References: <94f888be-b5e5-404b-9f35-d3dc96c4561f@googlegroups.com> <87lgmz4j2a.fsf@universite-de-strasbourg.fr.invalid> <3fd0b158-7f60-4dd2-9e15-c01efa72f152@googlegroups.com> Message-ID: <878tiyd30y.fsf@handshake.de> Ho Yeung Lee writes: > actually i am using python's kmeans library. it is relevant in python I agree that it was not bad to ask the question here. However, the provided answer (apart from the "off topic" -- i.e. the reference to "https://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set") was excellent. It tells you that the cluster number is a general parameter for the "kmeans" algorithm (independent of any implementation) and how you can get some approximations. From dieter at handshake.de Sat Aug 5 01:00:07 2017 From: dieter at handshake.de (dieter) Date: Sat, 05 Aug 2017 07:00:07 +0200 Subject: how to grep References: Message-ID: <874ltmd2y0.fsf@handshake.de> Iranna Mathapati writes: > How to grep values from below out put string. > > pattern should include "Fabric Module". One possible way would be to use a regular expression -- see the documentation for the "re" module. From rustompmody at gmail.com Sat Aug 5 01:39:25 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Fri, 4 Aug 2017 22:39:25 -0700 (PDT) Subject: Code for addition In-Reply-To: <59851e6a$0$1599$c3e8da3$5496439d@news.astraweb.com> References: <59851e6a$0$1599$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Saturday, August 5, 2017 at 6:55:09 AM UTC+5:30, Steve D'Aprano wrote: > On Sat, 5 Aug 2017 12:43 pm, Ode Idoko wrote: > > > Can anyone help with the python code that can add 101, 102, 103...2033 please? > > > Sounds like homework. Here are some hints for you to play around with and see if > you can get the right answer: > > > sum([101, 102, 103]) > > range(101, 104) > > sum(range(1, 4)) > > > What does sum() do? > > What does range() do? > > Can you put them together to get the answer you need? > Or study math-history? Gauss? early years https://brilliant.org/wiki/gauss-the-prince-of-mathematics/ From auriocus at gmx.de Sat Aug 5 02:44:18 2017 From: auriocus at gmx.de (Christian Gollwitzer) Date: Sat, 5 Aug 2017 08:44:18 +0200 Subject: Linux/Windows GUI programming: tk or wx? In-Reply-To: References: Message-ID: Am 05.08.17 um 01:45 schrieb Ulli Horlacher: > I have to transfer a python 2.7 CLI programm into one with a (simple) GUI. > The program must run on Linux and Windows and must be compilable with > pyinstall, because I have to ship a standalone windows.exe > Any kind of installer is not acceptable. TkInter works with pyinstaller, done that before. Also I suspect you are continuing your work with the file transfer service, and in that case, congratulations that you came to the conclusion to do a proper GUI ;) Back then I even created a "getting started" version for you, see here: https://groups.google.com/d/msg/comp.lang.python/AB42dD5xB_U/pYG6-rnMBQAJ Maybe it is useful now. If you replace the "askopenfilename" by "askopenfilenames", it will allow to select multiple files and return them as a list. Christian From steve+python at pearwood.info Sat Aug 5 02:54:23 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 05 Aug 2017 16:54:23 +1000 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59856ba2$0$1589$c3e8da3$5496439d@news.astraweb.com> On Sat, 5 Aug 2017 06:17 am, Terry Reedy wrote: [...] > With 53 binary digits, all counts from 0 to 2**53 - 1 are exactly > represented with a exponent of 0, 2**53 = 2**52 * 2, so it is exactly > represented with an exponent of 1. Many other higher counts can be > exactly represented with various exponents, but 2**53 + 1 requires 54 > digits. So it is the first count that does not have an exact binary64 > representation. Indeed. But although 2**53 + 1 cannot be represented as a float, there is no difference between its integer square root and the integer square root of 2**53. Both are 94906265. [...] >>> We know that: >>> >>> - for n <= 2**53, isqrt_float(n) is exact; > > but it is not ;-). In this range, the only possibility is > math.sqrt(m*m-1) being m instead of m - delta and that is the case for > Chris' answer 4503599761588224 = 67108865**2 - 1. > int(math.float(4503599761588224) is 67108865 instead of 67108864. Indeed. I had forgotten one possibility. I was thinking that there are only two cases when n is less than 2**53: (1) n is a perfect square, in which case sqrt(n) is also a whole number which can be represented exactly, and sqrt(n) is the same as integer sqrt(n); (2) or n is not a perfect square, in which case sqrt(n) returns a number of the form a.b, where a is the integer sqrt of n. But in fact there's a third possibility: if the .b part of a.b is sufficiently large that it rounds up to (a+1).0. It was this case that I had forgotten about: the possibility of rounding up to the next whole number. That's exactly what happens here with Chris' case. The exact mathematically correct value of sqrt(4503599761588224) is a surd, but we can use Decimal to get an approximate answer: py> from decimal import Decimal py> m = Decimal(4503599761588224) py> m.sqrt() Decimal('67108864.99999999254941951410') Now 67108864.99999999254941951410... is not exactly representable as a binary float. The two possibilities are: 67108864.99999999 # round down 67108865.00000000 # round up Rounding down is *closer* to the correct value, which suggests that rounding up is a bug: py> m.sqrt() - Decimal('67108864.99999999') # round down Decimal('2.54941951410E-9') py> m.sqrt() - Decimal('67108865.0') # round up Decimal('-7.45058048590E-9') Am I right that math.sqrt(4503599761588224) should round down? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From no.email at nospam.invalid Sat Aug 5 04:39:10 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Sat, 05 Aug 2017 01:39:10 -0700 Subject: Challenge: find the first value where two functions differ References: <598489fe$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87y3qycssx.fsf@nightsong.com> Chris Angelico writes: > 4503599761588224 I get the same result from searching a wider interval (+/- 50) around each perfect square in the relevant range. From ndagis at gmail.com Sat Aug 5 05:02:33 2017 From: ndagis at gmail.com (Ndagi Stanley) Date: Sat, 05 Aug 2017 09:02:33 +0000 Subject: pip requirements file In-Reply-To: <598533E5.6000101@stoneleaf.us> References: <5985309E.1070405@stoneleaf.us> <598533E5.6000101@stoneleaf.us> Message-ID: Yes. There is. I have been in need of this for a while until I found out. 2 steps: - pip install pip-chill - pip-chill The list will only have what you directly installed and will not list itself, which is pretty neat. The only thing you'll notice is that it's not alphabetically arranged. Cheers. On Sat, Aug 5, 2017, 05:57 Ethan Furman wrote: > On 08/04/2017 07:46 PM, Chris Angelico wrote: > > On Sat, Aug 5, 2017 at 12:42 PM, Ethan Furman wrote: > > >> pip freeze > >> > >> will output a list of current packages and their requirements. I have > one > >> package that falsely [1] lists another package as a requirement, which > was > >> blocking installation as the false requirement wasn't available. > >> > >> Is there a way to modify that output (which would be piped to, for > example, > >> requirements.txt) to have > >> > >> pip install -r requirements.txt > >> > >> so pip ignores that one (and only that one) dependency? > > > > I'd just edit the file afterwards and delete the line. But if the > > package claims to need PyXML, it'll still be installed. > > Exactly my point. Is there any way, requirements.txt or otherwise, to > tell pip to ignore what a certain package is > claiming it needs? > > I am aware of --no-dependencies, but that (I think) is an all-or-nothing > approach, whilst [1] I desire an all-except-one > approach. > > -- > ~Ethan~ > > > [1] I blame words like 'whilst' on my new Paperback game by Tim Fowler. > The Smarter-AI uses words from Middle-English > (!) and spellings not seen for at least 300 years! But hey, my vocabulary > is (uselessly) expanding! > -- > https://mail.python.org/mailman/listinfo/python-list > From ned at nedbatchelder.com Sat Aug 5 06:09:20 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Sat, 5 Aug 2017 06:09:20 -0400 Subject: Question About When Objects Are Destroyed In-Reply-To: References: <12b6998e-430c-45de-97d3-cf897a9466ef@googlegroups.com> Message-ID: On 8/4/17 7:42 PM, Jon Forrest wrote: > On 8/4/2017 4:34 PM, gst wrote: >> 'two' is a so called constant or literal value .. (of that >> function). >> >> Why not attach it, as a const value/object, to the function itself ? >> So that a new string object has not to be created each time the >> function is called. Because anyway strings are immutable. So what >> would be the point to recreate such object every time the function is >> called ? > > This was just an example program, not meant to do anything > meaningful. I would think that the same object behavior would > occur if I dynamically created an object in that function. > "The same object behavior" does occur: the object is freed when there are no more references to it. But if the object is a literal in the function, then the function keeps a reference to it. On the other hand, if it's dynamically computed, the function has no reference to it. That reference can change the behavior you see. Others have already mentioned some reasons why you are seeing the behavior you see. Another I don't think I saw mentioned: perhaps with ctypes you are examining memory that has been freed, but not cleared, and in fact the object doesn't still exist. This is the best way I know to explain a lot of these issues: https://nedbatchelder.com/text/names1.html You seem comfortable with C ideas and techniques. You might have to let go of some habits and let Python do its work. :) --Ned. From pertti.kosunen at pp.nic.fi Sat Aug 5 06:14:53 2017 From: pertti.kosunen at pp.nic.fi (Pertti Kosunen) Date: Sat, 5 Aug 2017 13:14:53 +0300 Subject: Linux/Windows GUI programming: tk or wx? In-Reply-To: References: Message-ID: On 8/5/2017 2:45 AM, Ulli Horlacher wrote: > I do not like GTK and Qt, because they are too complex. I'm not a programmer, but at least simple cross platform GUI notification message was easiest to do with PyQt (IMO). From maillist at schwertberger.de Sat Aug 5 06:16:52 2017 From: maillist at schwertberger.de (Dietmar Schwertberger) Date: Sat, 5 Aug 2017 12:16:52 +0200 Subject: Linux/Windows GUI programming: tk or wx? In-Reply-To: References: Message-ID: <3005a1c6-8e30-447b-6511-fe4d664f4b93@schwertberger.de> On 8/5/2017 1:45 AM, Ulli Horlacher wrote: > Any kind of installer is not acceptable. Is the requirement "no installer" or "single file" or both? You can satisfy the "no installer" requirement also by just distributing the .py file, the interpreter and a .bat file that e.g. contains "python27\python.exe programm.py". I have been doing this for years, sometimes just letting people run the .bat from a network share. > Is there a recommendation for using tk or wx? I would recommend wx. For Python 2.7 you can use either the 'Classic' version 3 or the new version 4 called 'Phoenix'. I have been using Python 2 plus Classic for 15 years and have switched to Python 3 and Phoenix a year ago. If you plan to switch to Python 3 at any time then go for Phoenix right now. The pyinstaller may not yet support Phoenix, which is e.g. required for Python 3. So you may be restricted to the Classic version. Classic: https://sourceforge.net/projects/wxpython/files/wxPython/3.0.2.0/ Phoenix: https://pypi.python.org/pypi/wxPython/4.0.0b1 ?? (It's still beta, but is perfectly usable.) For documentation, get the book "wxPython in Action". For questions there's a helpful mailing list wxpython-users. If your requirement is basically to have some user input forms, then you should give wxGlade a try (use the version from the repository https://bitbucket.org/wxglade/wxglade/get/default.zip as a release is in preparation; then press F1 for the tutorial). A GUI builder should make the start much easier, especially when it comes to Sizers (the layout managers). Regards, Dietmar From cl at isbd.net Sat Aug 5 06:52:48 2017 From: cl at isbd.net (Chris Green) Date: Sat, 5 Aug 2017 11:52:48 +0100 Subject: Linux/Windows GUI programming: tk or wx? References: <95a5d47f-5cc4-0712-6e4c-2376488ee762@gmail.com> Message-ID: <0lkg5e-i4k.ln1@esprimo.zbmc.eu> Michael Torrie wrote: > On 08/04/2017 05:45 PM, Ulli Horlacher wrote: > > I have to transfer a python 2.7 CLI programm into one with a (simple) GUI. > > The program must run on Linux and Windows and must be compilable with > > pyinstall, because I have to ship a standalone windows.exe > > Any kind of installer is not acceptable. > > > > Reading https://github.com/pyinstaller/pyinstaller/wiki/Supported-Packages > > supported GUI packages are PyGTK, PyQt4, PyQt5, wxPython > > I have tested tkinter by myself and it works, too. > > I do not like GTK and Qt, because they are too complex. > > > > I want to do VERY simple things and I prefer a simple GUI toolkit :-) > > > > Is there a recommendation for using tk or wx? > > Well tk is already an optional part of the Python standard library, > whereas wx is an external package. So for your simple requirements, Tk > may be the way to go. I'm guessing the tk would result in the smallest > executable as well, though I could be very wrong. > > As for Qt, it's a large library, but it's not as complex as you think. > In fact for simple GUIs it's no more complicated than wx or tk. So > don't discount PyQt as being unworkable, though you do need to be aware > of PyQt's license, which might be incompatible with your needs (it's GPL > only unless you pay for it). PySide is largely compatible with PyQt > code and is LGPL instead of GPL, so that could be an option as well. > I went through a similar process of deciding the easiest (for me) GUI to go with. I've actually ended up with PyGtk as it feels for me the 'least foreign' compared with doing things the CLI way. -- Chris Green ? From torriem at gmail.com Sat Aug 5 10:21:56 2017 From: torriem at gmail.com (Michael Torrie) Date: Sat, 5 Aug 2017 08:21:56 -0600 Subject: Linux/Windows GUI programming: tk or wx? In-Reply-To: <0lkg5e-i4k.ln1@esprimo.zbmc.eu> References: <95a5d47f-5cc4-0712-6e4c-2376488ee762@gmail.com> <0lkg5e-i4k.ln1@esprimo.zbmc.eu> Message-ID: <6b88597b-5082-e92d-b18f-1a14700972a0@gmail.com> On 08/05/2017 04:52 AM, Chris Green wrote: > I went through a similar process of deciding the easiest (for me) GUI > to go with. I've actually ended up with PyGtk as it feels for me the > 'least foreign' compared with doing things the CLI way. Yes PyGtk is fairly Pythonic and natural feeling. PyQt feels more like a thin wrapper around the C++ API, because that's what it is. In other words you feel like you're programming in C++ using Python syntax. Unfortunately the GTK3 bindings are much less pythonic than PyGTK (GTK2). The bindings work through the GTK introspection mechanism so the resulting in a thinner abstraction layer, and exposing a bit more of GTK's C-isms to you. It's been a while since I used it so I can't point to a concrete example of what I mean, but it's just more of a general feel. The upside to the new binding system for GTK3 is that any library based on Glib and GTK3 can be accessed via Python now, even third-party ones. GTK2 is no longer under active development so if you still use PyGTK, you really should start porting your projects to PyGObject and GTK3. In the end I choose to use PyQt or PySide because Qt has the best cross-platform support of all the toolkits. Windows and Mac support in GTK3 is there, but it lags way behind the Linux version. and it doesn't integrate the look and feel as well as Qt does. From vek.m1234 at gmail.com Sat Aug 5 10:28:20 2017 From: vek.m1234 at gmail.com (veek) Date: Sat, 05 Aug 2017 19:58:20 +0530 Subject: Signals and Slots - Summerfield - what exactly is a signal? Message-ID: 1. What exactly is a signal. In hardware, an interrupt can be viewed as a signal and the voltage on a pin will suddenly jump to +5V as an indicator that an interrupt has occurred. With Qt signals - if a widget-c++ code has to 'signal' an event - what does it do? As a consequence of not understanding the above.. 2. How do you connect a single signal to multiple slots? Do the slots/methods get called one by one? or are they treated as independent threads and run on different cores? 3. pg 130 of Summerfield class ZeroSpinBox(QObject): def __init__(self, parent=None): super(...blah initialize QObject with parent self.connect(self, SIGNAL("valuedChanged(int)"), self.checkzero) def checkzero(self): if self.value() == 0: self.emit(SIGNAL("atzero"), self.zeros) basically when SpinBox gets set to zero we emit 'atzero' and return a zeros counter. What i don't get is the valueChanged(int) bit.. he clearly defines an (int) being passed to checkzero so shouldn't the definition reflect the same? Mistake? A. additionally I did not understand short circuit signals where you can drop the (type1, type2) in the signature and just do SIGNAL("atzero") Is this doable ONLY in emit() or also in connect()?? 4. pg 131 'any data can be passed as arguments to the emit method and they can be passed as Python objects' self.emit(SIGNAL("atzero"), 10, 20, 30) or self.emit(SIGNAL("atzero"), [10, 20, 30]) does he mean i can pass a SINGLE OBJECT of any python type or does he mean multiple independent containers? (assuming the definition matches) 5. He says 'a signal with one argument is a Qt signal or a non-short-circuit Python signal' So if I have a Qt widget in C++ and it emits a valueChanged(int) signal.. okay he's going to have to convert our asm/x86 int to python-integer and then call the python-method that was mapped to 'valueChanged' with the python-integer argument OR the signal is being generated from Python code itself AND WILL be converted to C++ datatype - huh???? why?? I'm guessing there's some dispatch code that maintains a mapping table?? SO why can't it differentiate between inhouse python widget and Qt-c++ widget?? 6. "If we use the SIGNAL() function with a signalSignature (a possibly empty parenthesized list of comma-separated PyQt types)..."?? how can it be an empty () list..?? If there's a list it's no longer empty.. 7. What exactly is a Python signal vs a Qt signal originating from a C++- asm-widget?? PyQt is a wrapper around C++Qt so.. where are the python widgets?? 8. class TaxRate(QObject): def __init__(self): super(TaxRate, self).__init__() self.__rate = 17.5 def rate(self): return self.__rate def setRate(self, rate): if rate != self.__rate: self.__rate = rate self.emit(SIGNAL("rateChanged"), self.__rate) def rateChanged(value): print "TaxRate changed to %.2f%%" % value vat = TaxRate() vat.connect(vat, SIGNAL("rateChanged"), rateChanged) vat.setRate(17.5) # No change will occur (new rate is the same) vat.setRate(8.5) # A change will occur (new rate is different) Isn't this a mistake? self.connect( should be: vat.connect(vat, SIGNAL("rateChanged"), rate) From steve+python at pearwood.info Sat Aug 5 11:17:21 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sun, 06 Aug 2017 01:17:21 +1000 Subject: Signals and Slots - Summerfield - what exactly is a signal? References: Message-ID: <5985e183$0$1586$c3e8da3$5496439d@news.astraweb.com> On Sun, 6 Aug 2017 12:28 am, veek wrote: > 1. What exactly is a signal. In hardware, an interrupt can be viewed as a > signal and the voltage on a pin will suddenly jump to +5V as an indicator > that an interrupt has occurred. With Qt signals - if a widget-c++ code has > to 'signal' an event - what does it do? I don't know what Qt signals are. Unix signals are an interrupt mechanism used by Unix and Linux operating systems. Windows may support them as well. The "kill" system command sends signals to a specific running process, which will then jump to a specific piece of code. The command is called "kill" because the main use for this is to terminate processes. Python supports these signals: https://docs.python.org/3/library/signal.html https://pymotw.com/3/signal/index.html > As a consequence of not understanding the above.. > > 2. How do you connect a single signal to multiple slots? Do the > slots/methods get called one by one? or are they treated as independent > threads and run on different cores? What are slots? > 3. pg 130 of Summerfield What is Summerfield? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From info at tundraware.com Sat Aug 5 11:23:26 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 10:23:26 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On 08/04/2017 07:00 PM, Chris Angelico wrote: > Again, don't stress about exactly when objects get > disposed of; it doesn't matter. Respectfully, I disagree strongly. Objects get build on the heap and persist even when they go out of scope until such time garbage collection takes place. This is unlike languages that build things in stack frames which naturally disappear with an exit of scope. For small or trivial programs, it does not matter. But when there is a lot of dynamic object construction - say, in very large programs, object factories, etc. - it can be important to harvest the space of expired objects sooner, rather than later. This, after all, is one of the rationale' for Python contexts - to ensure the release of resources no matter how the logic ends - correctly or by exception. From vek.m1234 at gmail.com Sat Aug 5 12:03:48 2017 From: vek.m1234 at gmail.com (veek) Date: Sat, 05 Aug 2017 21:33:48 +0530 Subject: Signals and Slots - Summerfield - what exactly is a signal? References: <5985e183$0$1586$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > On Sun, 6 Aug 2017 12:28 am, veek wrote: > >> 1. What exactly is a signal. In hardware, an interrupt can be viewed as a >> signal and the voltage on a pin will suddenly jump to +5V as an indicator >> that an interrupt has occurred. With Qt signals - if a widget-c++ code >> has to 'signal' an event - what does it do? > > I don't know what Qt signals are. > > Unix signals are an interrupt mechanism used by Unix and Linux operating > systems. Windows may support them as well. The "kill" system command sends > signals to a specific running process, which will then jump to a specific > piece of code. The command is called "kill" because the main use for this > is to terminate processes. > > Python supports these signals: > > https://docs.python.org/3/library/signal.html > > https://pymotw.com/3/signal/index.html > > > >> As a consequence of not understanding the above.. >> >> 2. How do you connect a single signal to multiple slots? Do the >> slots/methods get called one by one? or are they treated as independent >> threads and run on different cores? > > What are slots? > > >> 3. pg 130 of Summerfield > > What is Summerfield? > > > The book I'm reading is: Mark Summerfield - Rapid GUI Programming with Python and Qt. PyQt is a wrapper around the C++/Qt library and they have a Signal and Slot mechanism for doing GUI/event-driven work - Qt doesn't have it. Basically if you have a widget like QSpinBox it'll be rendered/drawn using a C++ Qt library (which is fast). Anyway, widgets support 'events' like mouse-over and click and they are constantly generating events which are mostly ignored by the PyQt library and discarded. However if you decide you want to handle an event then you use PyQt's signal/slot mechanism: slot's a method and signal looks to be basically a string. Eg: class Form(QWidget): def __init__(self, parent=None): super(Form, self).__init__(parent) #init QWidget with parent is set combo = QComboBox() self.connect(combo, SIGNAL("some_event(int)"),self.combo_event_handler) def combo_event_handler(self, i): pass combo_event_handler's the slot.. it's just a python OR Qt method. QComboBox() will result in a combo box being drawn when the app is started via app = QApplication() app.exec_() then if I mouse over the widget it'll generate an 'event'/'signal' and call the handler to process - event driven programming "some_event()" is a string being passed to connect() and that's a function signature that tells connect what types the handler expects. combo_event_handler can be a Qt method in which case conversion occurs to C++ data types but it can also be a python method and if you short ckt then no conversion to C++ types occurs. From ned at nedbatchelder.com Sat Aug 5 12:16:37 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Sat, 5 Aug 2017 12:16:37 -0400 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On 8/5/17 11:23 AM, Tim Daneliuk wrote: > On 08/04/2017 07:00 PM, Chris Angelico wrote: >> Again, don't stress about exactly when objects get >> disposed of; it doesn't matter. > > Respectfully, I disagree strongly. Objects get build on the heap and > persist even when they go out of scope until such time garbage > collection takes place. This is unlike languages that build things in > stack frames which naturally disappear with an exit of scope. > > For small or trivial programs, it does not matter. But when there is a > lot of dynamic object construction - say, in very large programs, object > factories, etc. - it can be important to harvest the space of expired > objects sooner, rather than later. This, after all, is one of the > rationale' for Python contexts - to ensure the release of resources no > matter how the logic ends - correctly or by exception. You might want to look into how CPython works more closely. It uses reference counting, so most objects are reclaimed immediately when their reference count goes to zero, such as at the end of local scopes. The exception is objects that are in circular structures (A references B which references C which references A, for example). Those have to wait until an asynchronous garbage collection takes place. You can run into problems if you accidentally are still referring to large circular structures. Then it is important to understand where the references are, and add some code to delete the references. But this is unusual, and is not an issue with delayed garbage collection, but with references keeping unwanted structures. People in worlds with manually managed memory (such as C) are rightly anxious about the details of their memory management. But they typically don't need to bring that anxiety with them to Python. --Ned. From vincent.vande.vyvre at telenet.be Sat Aug 5 12:20:19 2017 From: vincent.vande.vyvre at telenet.be (Vincent Vande Vyvre) Date: Sat, 5 Aug 2017 18:20:19 +0200 Subject: Signals and Slots - Summerfield - what exactly is a signal? In-Reply-To: References: Message-ID: Le 05/08/17 ? 16:28, veek a ?crit : > 1. What exactly is a signal. In hardware, an interrupt can be viewed as a > signal and the voltage on a pin will suddenly jump to +5V as an indicator > that an interrupt has occurred. With Qt signals - if a widget-c++ code has > to 'signal' an event - what does it do? > > As a consequence of not understanding the above.. > > 2. How do you connect a single signal to multiple slots? Do the > slots/methods get called one by one? or are they treated as independent > threads and run on different cores? You have to connect yours slots each by each. self.my_button.clicked.connect(self.foo) self.my_button.clicked.connect(self.baz) ... Be care you can't know the order of the execution of foo and baz. Any thread will be created for that, the binding will be executed into the main loop of your app. But, if your signal is emitted from a thread, the slot will be executed into the main thread, this is a great advantage, your slot can interact safely with the graphics part of your app. > > 3. pg 130 of Summerfield > > class ZeroSpinBox(QObject): > def __init__(self, parent=None): > super(...blah initialize QObject with parent > self.connect(self, SIGNAL("valuedChanged(int)"), self.checkzero) > > def checkzero(self): > if self.value() == 0: > self.emit(SIGNAL("atzero"), self.zeros) > > basically when SpinBox gets set to zero we emit 'atzero' and return a zeros > counter. > > What i don't get is the valueChanged(int) bit.. he clearly defines an (int) > being passed to checkzero so shouldn't the definition reflect the same? > Mistake? This is the old signal-slot methods, I encourage you to use the new (new but not recent) method Like this: from QtCore import pyqtSignal class ZeroSpinBox(QObject): atZero = pyqtSignal(int) def __init__(self, parent=None): super(...blah initialize QObject with parent self.valuedChanged.connect(self.checkzero) def checkzero(self, value): if not value: # maybe increment self.zeros ? self.atzero.emit(self.zeros) > > A. additionally I did not understand short circuit signals where you can > drop the (type1, type2) in the signature and just do > SIGNAL("atzero") > > Is this doable ONLY in emit() or also in connect()?? I don't know, never used this construction of code. > > > 4. pg 131 'any data can be passed as arguments to the emit method and they > can be passed as Python objects' > > self.emit(SIGNAL("atzero"), 10, 20, 30) or > self.emit(SIGNAL("atzero"), [10, 20, 30]) > does he mean i can pass a SINGLE OBJECT of any python type or does he mean > multiple independent containers? > (assuming the definition matches) When you define your signal you can use any Python type sig = pyqtSignal(int, float, str, str, ...) > > 5. He says 'a signal with one argument is a Qt signal or a non-short-circuit > Python signal' > > So if I have a Qt widget in C++ and it emits a valueChanged(int) signal.. > okay he's going to have to convert our asm/x86 int to python-integer and > then call the python-method that was mapped to 'valueChanged' with the > python-integer argument OR the signal is being generated from Python code > itself AND WILL be converted to C++ datatype - huh???? why?? The wrapper use simply the CPython "PyLong_AsLong" or "PyUnicode_FromString" or "Py_BuildValue" or other and you get always a Python object. > > I'm guessing there's some dispatch code that maintains a mapping table?? SO > why can't it differentiate between inhouse python widget and Qt-c++ widget?? > > > 6. "If we use the SIGNAL() function with a signalSignature (a possibly empty > parenthesized list of comma-separated PyQt types)..."?? > > how can it be an empty () list..?? If there's a list it's no longer empty.. > > 7. What exactly is a Python signal vs a Qt signal originating from a C++- > asm-widget?? PyQt is a wrapper around C++Qt so.. where are the python > widgets?? > > 8. > class TaxRate(QObject): > def __init__(self): > super(TaxRate, self).__init__() > self.__rate = 17.5 > > def rate(self): > return self.__rate > > def setRate(self, rate): > if rate != self.__rate: > self.__rate = rate > self.emit(SIGNAL("rateChanged"), self.__rate) > > def rateChanged(value): > print "TaxRate changed to %.2f%%" % value > > vat = TaxRate() > vat.connect(vat, SIGNAL("rateChanged"), rateChanged) > vat.setRate(17.5) # No change will occur (new rate is the same) > vat.setRate(8.5) # A change will occur (new rate is different) > > Isn't this a mistake? self.connect( should be: > vat.connect(vat, SIGNAL("rateChanged"), rate) > Again, use the new syntaxe (new but not recent) it's more clear. Vincent From phd at phdru.name Sat Aug 5 13:11:08 2017 From: phd at phdru.name (Oleg Broytman) Date: Sat, 5 Aug 2017 19:11:08 +0200 Subject: SQLObject 3.4.0 Message-ID: <20170805171108.GA15747@phdru.name> Hello! I'm pleased to announce version 3.4.0, the first stable release of branch 3.4 of SQLObject. What's new in SQLObject ======================= Contributor for this release is Dr. Neil Muller. Features -------- * Python 2.6 is no longer supported. The minimal supported version is Python 2.7. Drivers (work in progress) -------------------------- * Encode binary values for py-postgresql driver. This fixes the last remaining problems with the driver. * Encode binary values for PyGreSQL driver using the same encoding as for py-postgresql driver. This fixes the last remaining problems with the driver. Our own encoding is needed because unescape_bytea(escape_bytea()) is not idempotent. See the comment for PQunescapeBytea at https://www.postgresql.org/docs/9.6/static/libpq-exec.html: This conversion is not exactly the inverse of PQescapeBytea, because the string is not expected to be "escaped" when received from PQgetvalue. In particular this means there is no need for string quoting considerations. * List all drivers in extras_require in setup.py. Minor features -------------- * Use base64.b64encode/b64decode instead of deprecated encodestring/decodestring. Tests ----- * Fix a bug with sqlite-memory: rollback transaction and close connection. The solution was found by Dr. Neil Muller. * Use remove-old-files.py from ppu to cleanup pip cache at Travis and AppVeyor. * Add test_csvimport.py more as an example how to use load_csv from sqlobject.util.csvimport. For a more complete list, please see the news: http://sqlobject.org/News.html What is SQLObject ================= SQLObject is an object-relational mapper. Your database tables are described as classes, and rows are instances of those classes. SQLObject is meant to be easy to use and quick to get started with. SQLObject supports a number of backends: MySQL, PostgreSQL, SQLite, Firebird, Sybase, MSSQL and MaxDB (also known as SAPDB). Python 2.7 or 3.4+ is required. Where is SQLObject ================== Site: http://sqlobject.org Development: http://sqlobject.org/devel/ Mailing list: https://lists.sourceforge.net/mailman/listinfo/sqlobject-discuss Download: https://pypi.python.org/pypi/SQLObject/3.4.0 News and changes: http://sqlobject.org/News.html StackOverflow: https://stackoverflow.com/questions/tagged/sqlobject Example ======= Create a simple class that wraps a table:: >>> from sqlobject import * >>> >>> sqlhub.processConnection = connectionForURI('sqlite:/:memory:') >>> >>> class Person(SQLObject): ... fname = StringCol() ... mi = StringCol(length=1, default=None) ... lname = StringCol() ... >>> Person.createTable() Use the object:: >>> p = Person(fname="John", lname="Doe") >>> p >>> p.fname 'John' >>> p.mi = 'Q' >>> p2 = Person.get(1) >>> p2 >>> p is p2 True Queries:: >>> p3 = Person.selectBy(lname="Doe")[0] >>> p3 >>> pc = Person.select(Person.q.lname=="Doe").count() >>> pc 1 Oleg. -- Oleg Broytman http://phdru.name/ phd at phdru.name Programmers don't die, they just GOSUB without RETURN. From torriem at gmail.com Sat Aug 5 13:18:15 2017 From: torriem at gmail.com (Michael Torrie) Date: Sat, 5 Aug 2017 11:18:15 -0600 Subject: Signals and Slots - Summerfield - what exactly is a signal? In-Reply-To: References: Message-ID: <0b71660d-ecd8-30bf-e6f2-9ab913791e5c@gmail.com> Forgive Steven for his off-topic reply. I assume he's trying to goad you into having a more specific subject line. He knows darn well what PyQt, even if he has no experience with it. And of course, as always you will want to post a complete, working example that we can see and comment on, rather than extracts of the code. It's much harder to comment on that. On 08/05/2017 08:28 AM, veek wrote: > 1. What exactly is a signal. In hardware, an interrupt can be viewed as a > signal and the voltage on a pin will suddenly jump to +5V as an indicator > that an interrupt has occurred. With Qt signals - if a widget-c++ code has > to 'signal' an event - what does it do? Basically a signal emission is a call to the main loop that indicates that an event has occurred, and then the main loop sees if there are any registered callbacks that want to be notified of this event, and if so it calls them, letting them execute. This is how event-driven programming works. The concept of signals and slots is very similar to explicit registering of callbacks in function. It differs only in form. So it sounds from your post that the book you are following is older and uses some of the older forms for signals and slots in PyQt. In recent years, PyQt has made some things nicer, make making signals just be members of the class that you can access through python as if they were a member of the instance. so my code in response to your questions will reflect this newer style. I recommend you look at the various online tutorials for PyQt (I still am using PyQt4, but PyQt5 will be nearly the same). > As a consequence of not understanding the above.. > > 2. How do you connect a single signal to multiple slots? Do the > slots/methods get called one by one? or are they treated as independent > threads and run on different cores? You simply have more than one connect() call. for example: button1.clicked.connect(callback1) button1.clicked.connect(callback2) Both callbacks will run when button1 emits its "clicked" signal. Then the callbacks are executed in some kind of order when the signal is emitted, one at a time. GUIs are typically single-threaded. That's why it's important to not have long-running code in a callback. If you do need to do something in a call back that takes a while, you could spawn a thread and turn the work over to a thread, and then return control of the GUI thread back to the main loop. > > 3. pg 130 of Summerfield > > class ZeroSpinBox(QObject): ^^^^^^^^ I'm guessing that should be QSpinBox, not QObject, as this class is just adding behavior to the spinbox. If the book really has it as QObject, I would suspect it is a mistake. But without seeing the entire example program, I cannot say. > def __init__(self, parent=None): > super(...blah initialize QObject with parent > self.connect(self, SIGNAL("valuedChanged(int)"), self.checkzero) > > def checkzero(self): > if self.value() == 0: > self.emit(SIGNAL("atzero"), self.zeros) > > basically when SpinBox gets set to zero we emit 'atzero' and return a zeros > counter. > > What i don't get is the valueChanged(int) bit.. he clearly defines an (int) > being passed to checkzero so shouldn't the definition reflect the same? > Mistake? Normally it should match the signature, yes. Whether this is a mistake, I don't know. I believe PyQt could be ignoring the parameters the slot callback doesn't have defined. And since he's calling self.value() to read the actual value, he doesn't really need the int parameter, though if it were me I'd use the parameter and not call self.value() at all. > A. additionally I did not understand short circuit signals where you can > drop the (type1, type2) in the signature and just do > SIGNAL("atzero") > > Is this doable ONLY in emit() or also in connect()?? As far as I know, only in the emit(). I'm not familiar with this "short circuit" thing. In fact I've never heard of it and have done a few things in PyQt. For defining signals, PyQt has defined a new method for creating signals that's much cleaner than using the SIGNAL() call: class ZeroSpinBox(QSpinbox): atzero = PyQt4.pyqtSignal() #could list arguments here if desired someother = PyQt4.pyqtSignal('int','bool') ... def checkzero(self, value): if value == 0: self.atzero.emit() Note that parameters to pyqtSignal can be either Python types that PyQt can marshall (int, float,str, any QObject-derived class etc), or C++ types as a name in a string. > 4. pg 131 'any data can be passed as arguments to the emit method and they > can be passed as Python objects' > > self.emit(SIGNAL("atzero"), 10, 20, 30) or > self.emit(SIGNAL("atzero"), [10, 20, 30]) > does he mean i can pass a SINGLE OBJECT of any python type or does he mean > multiple independent containers? > (assuming the definition matches) You can pass any number of extra parameters when emitting a signal. I've not used this feature before, so I'm not sure how it works exactly. > > 5. He says 'a signal with one argument is a Qt signal or a non-short-circuit > Python signal' > > So if I have a Qt widget in C++ and it emits a valueChanged(int) signal.. > okay he's going to have to convert our asm/x86 int to python-integer and > then call the python-method that was mapped to 'valueChanged' with the > python-integer argument OR the signal is being generated from Python code > itself AND WILL be converted to C++ datatype - huh???? why?? Basically what it means is that all the types used in signals are native C++ types. That's because, well, Qt is a C++ library. So at some point python objects have to be marshalled into C++ data types, and the reverse is also true. > I'm guessing there's some dispatch code that maintains a mapping table?? SO > why can't it differentiate between inhouse python widget and Qt-c++ widget?? Yes. It can't because it's written in C++. Any time you want to go between the C++ backend and Python, you have to marshall between > 6. "If we use the SIGNAL() function with a signalSignature (a possibly empty > parenthesized list of comma-separated PyQt types)..."?? > > how can it be an empty () list..?? If there's a list it's no longer empty.. He just means the call itself. SIGNAL() defines a signal with no signature. SIGNAL('int') defines a signal with one parameter, which will be a C++ int type (or Python integer) > > 7. What exactly is a Python signal vs a Qt signal originating from a C++- > asm-widget?? PyQt is a wrapper around C++Qt so.. where are the python > widgets?? That's a complicated question. Basically every PyQt object in Python consists of two objects. One is the underlying C++ QObject-based object which is opaque to Python, and one is the Python wrapper around that object that exposes the Qt object's attributes and methods to Python. Each call into Qt requires converting Python objects into C++ data types, and information returned from Qt calls is converted (wrapped) into python objects. This process is not always pythonic and sometimes you get C++-ism and Qt-isms such as QString's or QList's leaking into Python code. A signal emitted from Python code calls in the same C++ mechanism that dispatches signals from C++Qt code. It all goes through Qt, which is C++. In other words, signals are not propagated at the Python level, but rather at the underlying C++ level. The main loop is C++ and it's in charge. when a callback is executed, if it's a PyQt callback, it will be bubbled up through the Python interpreter into your python code, from Qt in C++. > 8. > class TaxRate(QObject): > def __init__(self): > super(TaxRate, self).__init__() > self.__rate = 17.5 > > def rate(self): > return self.__rate > > def setRate(self, rate): > if rate != self.__rate: > self.__rate = rate > self.emit(SIGNAL("rateChanged"), self.__rate) > > def rateChanged(value): > print "TaxRate changed to %.2f%%" % value > > vat = TaxRate() > vat.connect(vat, SIGNAL("rateChanged"), rateChanged) > vat.setRate(17.5) # No change will occur (new rate is the same) > vat.setRate(8.5) # A change will occur (new rate is different) > > Isn't this a mistake? self.connect( should be: > vat.connect(vat, SIGNAL("rateChanged"), rate) No. rateChanged is correct. There is no "rate" in the scope where where the vat.connect() call is made. From marko at pacujo.net Sat Aug 5 14:19:21 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sat, 05 Aug 2017 21:19:21 +0300 Subject: Signals and Slots - Summerfield - what exactly is a signal? References: <0b71660d-ecd8-30bf-e6f2-9ab913791e5c@gmail.com> Message-ID: <8760e1513q.fsf@elektro.pacujo.net> Michael Torrie : > Basically a signal emission is a call to the main loop that indicates > that an event has occurred, and then the main loop sees if there are > any registered callbacks that want to be notified of this event, and > if so it calls them, letting them execute. This is how event-driven > programming works. The concept of signals and slots is very similar to > explicit registering of callbacks in function. It differs only in > form. I would express it as just saying that the Qt developers appropriated the word "signal" for what is simply a callback. Years back I took a brief loook at Qt. I had heard that one of their great selling points was that they did C++. At the time, C++ was my bread and butter, and I had been baffled at how bad C++ was at expressing such a basic thing as callbacks. Turns out Qt didn't do callbacks using C++. Instead they specified a sort of macro language to express callbacks and offered what was known as a "metacompiler" that converted those macros into real C++. It was a big disappointment both with respect to C++ and Qt. Now, the Standard Template Library offered elaborate macros (aka functor templates) that allowed you to express callbacks with zero, one or two arguments (in a cumbersome way). Boost, a famous C++ class library, added functor support to three, four, five, six, seven, eight, nine, and--hear this!--TEN arguments. All this nonsense because it hadn't occurred to Bjarne Stroustrup to define so-called method pointers in a sane manner. It was left to another Dane, Anders Hejlsberg, to demonstrate how they ought to have been defined, namely, as delegates (as in Delphi and C#). Unfortunately, it was too late for C++. Now, I'm hearing C++ supports proper closures: . I wonder if Qt would eventually migrate to them. At any rate, Python never had to come up with such tricks for callbacks. Python's closure syntax is maybe the most natural there is. Too bad if PyQt confuses Python programmers with "signals" and "slots" when they are simply methods. Marko From marko at pacujo.net Sat Aug 5 14:25:52 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sat, 05 Aug 2017 21:25:52 +0300 Subject: Question About When Objects Are Destroyed (continued) References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: <871sop50sv.fsf@elektro.pacujo.net> Tim Daneliuk : > On 08/04/2017 07:00 PM, Chris Angelico wrote: >> Again, don't stress about exactly when objects get disposed of; it >> doesn't matter. > > Respectfully, I disagree strongly. Objects get build on the heap and > persist even when they go out of scope until such time garbage > collection takes place. This is unlike languages that build things in > stack frames which naturally disappear with an exit of scope. Python never has to dispose of a single object. It is allowed to do so if it doesn't affect the correct behavior of the program. > For small or trivial programs, it does not matter. But when there is a > lot of dynamic object construction - say, in very large programs, > object factories, etc. - it can be important to harvest the space of > expired objects sooner, rather than later. This, after all, is one of > the rationale' for Python contexts - to ensure the release of > resources no matter how the logic ends - correctly or by exception. You are correct that maintaining references to stale objects prevents Python's garbage collection from reclaiming memory space. Releasing non-memory resources is a different matter. I suppose Chris was only referring to RAM usage. Marko From torriem at gmail.com Sat Aug 5 14:51:45 2017 From: torriem at gmail.com (Michael Torrie) Date: Sat, 5 Aug 2017 12:51:45 -0600 Subject: Signals and Slots - Summerfield - what exactly is a signal? In-Reply-To: <8760e1513q.fsf@elektro.pacujo.net> References: <0b71660d-ecd8-30bf-e6f2-9ab913791e5c@gmail.com> <8760e1513q.fsf@elektro.pacujo.net> Message-ID: <263dbb38-3d92-134c-c6c2-8b46d6ca8a5a@gmail.com> On 08/05/2017 12:19 PM, Marko Rauhamaa wrote: > I would express it as just saying that the Qt developers appropriated > the word "signal" for what is simply a callback. I'd say a slot is a callback. A signal is the designation of something that will trigger callbacks. > Years back I took a brief loook at Qt. I had heard that one of their > great selling points was that they did C++. At the time, C++ was my > bread and butter, and I had been baffled at how bad C++ was at > expressing such a basic thing as callbacks. > > Turns out Qt didn't do callbacks using C++. Instead they specified a > sort of macro language to express callbacks and offered what was known > as a "metacompiler" that converted those macros into real C++. Off-topic, but probably still worth talking about, since the OP does appear interested in Qt internals and how they relate to Python. As for Qt not being really C++, that's only partially true these days. Qt code you write is actual C++, directly compile-able with any standards-compliant C++ compiler. moc, the metacompiler you're referring to, generates some helper code that is required to tie the Qt objects together. And you can argue this is only necessary because of deficiencies in C++ (at least pre-STL days). But this is no different or burdensome than requiring a step to compile an XML ui file to code like many/most UI toolkits do. The biggest problem with moc in my mind is that it hides the fact that signal emission is done by name in the Qt engine, using string lookups and comparisons. In your code they look like actual identifiers but moc generates string equivalents in the meta class code. This can lead to really weird bugs. It's been a long time since I ran into this problem so I can't remember the specifics. I'm not sure if this problem would manifest itself in Python code, but I suspect it might. > It was a big disappointment both with respect to C++ and Qt. > > Now, the Standard Template Library offered elaborate macros (aka functor > templates) that allowed you to express callbacks with zero, one or two > arguments (in a cumbersome way). Boost, a famous C++ class library, > added functor support to three, four, five, six, seven, eight, nine, > and--hear this!--TEN arguments. Yeah Qt has never used templates because they didn't exist when Qt was first started. Now I think you could use templates to do a lot of what moc does, and indeed Gtkmm uses templates to make a very nice, very native C++ binding for GTK+. I have had to, on occasion, make my own templates for gtkmm when the number of parameters I needed to bind was different than the prefab templates provided. Templates can be really cumbersome. One area that the template-based GTKmm really shone compared to Qt was that, in C++ at least, signatures between the signal and slot were checked at compile time, thanks to templates. In Qt, they end up being essentially bare function pointers (might get a runtime error? I can't remember). > All this nonsense because it hadn't occurred to Bjarne Stroustrup to > define so-called method pointers in a sane manner. It was left to > another Dane, Anders Hejlsberg, to demonstrate how they ought to have > been defined, namely, as delegates (as in Delphi and C#). Unfortunately, > it was too late for C++. > > Now, I'm hearing C++ supports proper closures: http://en.cppreference.com/w/cpp/language/lambda>. I wonder if Qt would > eventually migrate to them. > > At any rate, Python never had to come up with such tricks for callbacks. > Python's closure syntax is maybe the most natural there is. Too bad if > PyQt confuses Python programmers with "signals" and "slots" when they > are simply methods. True enough. When you work with PyQt, unfortunately these C++ details do leak through, which is the biggest weakness of PyQt (and also PySide). So I guess that's reason enough to be familiar with the warts. Despite the warts, PyQt is my go-to toolkit for doing the simple GUI stuff I need, as it is easy to install and run on any platform and looks great. I wrote a simple compatibility shim to let me use both PySide and PyQt4 with the same code. That way if I need to release code in a non-GPL way, I can just switch to PySide. PySide had its own issues because of how the bindings are made. One of them is that occasionally PySide drops a reference to a Qt C++ object, which can lead to a segfault. And I have no idea the state of PySide for Qt5. From torriem at gmail.com Sat Aug 5 14:55:28 2017 From: torriem at gmail.com (Michael Torrie) Date: Sat, 5 Aug 2017 12:55:28 -0600 Subject: Signals and Slots - Summerfield - what exactly is a signal? In-Reply-To: References: Message-ID: On 08/05/2017 08:28 AM, veek wrote: > At a certain point beyond the general stuff, questions about PyQt might be better suited to the PyQt mailing list, hosted by the company that maintains PyQt: https://www.riverbankcomputing.com/mailman/listinfo/pyqt From rosuav at gmail.com Sat Aug 5 16:21:10 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 6 Aug 2017 06:21:10 +1000 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On Sun, Aug 6, 2017 at 1:23 AM, Tim Daneliuk wrote: > On 08/04/2017 07:00 PM, Chris Angelico wrote: >> Again, don't stress about exactly when objects get >> disposed of; it doesn't matter. > > > Respectfully, I disagree strongly. Objects get build on the heap and > persist even when they go out of scope until such time garbage > collection takes place. This is unlike languages that build things in > stack frames which naturally disappear with an exit of scope. > > For small or trivial programs, it does not matter. But when there is a > lot of dynamic object construction - say, in very large programs, object > factories, etc. - it can be important to harvest the space of expired > objects sooner, rather than later. This, after all, is one of the > rationale' for Python contexts - to ensure the release of resources no > matter how the logic ends - correctly or by exception. By "contexts", you're presumably talking about the way you can use a 'with' block to guarantee resource release. But that is actually orthogonal to object destruction; in fact, it's specifically because the object might NOT be destroyed at that point. Before that feature was implemented, people depended on CPython's reference counting and consequent object destruction (and __del__) to close files and other resources. That doesn't work reliably in all Python implementations, though, so a more dependable system was needed. After a 'with' block, the object *still exists*, but it has been "exited" in some way (usually by closing/releasing an underlying resource). So, again, you must not concern yourself with when the objects themselves get destroyed. If there's a resource you need to clean up, you clean that up explicitly, so the object's lifetime shouldn't matter to you. ChrisA From kryptxy at protonmail.com Sat Aug 5 17:17:05 2017 From: kryptxy at protonmail.com (Kryptxy) Date: Sat, 05 Aug 2017 17:17:05 -0400 Subject: Package not visible/available on pypi Message-ID: I had recently uploaded a package on pypi. For some reason, I removed the package, and committed a BIG mistake along the way. I clicked the DELETE PACKAGE [Warning about NEVER TO CLICK THAT BUTTON] (silly me!) Now, after re-uploading the package, its not visible on pypi. How can I fix this? I already have uploaded the package. But it's not visible on pypi (neither under packages in my dashboard). From info at tundraware.com Sat Aug 5 17:32:31 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 16:32:31 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On 08/05/2017 03:21 PM, Chris Angelico wrote: > After a 'with' block, > the object *still exists*, but it has been "exited" in some way > (usually by closing/releasing an underlying resource). The containing object exists, but the things that the closing logic explicitly released do not. In some sense, a context acts like a deconstructor, just not on the object it's associated with. > If there's a resource you need to clean up, you clean that up > explicitly, Such "resources" *are* objects themselves notionally. You are exactly killing those objects to free the underlying resources they consume. > so the object's lifetime shouldn't matter to you. I disagree with this most strongly. That's only true when the machine resources being consumed by your Python object are small in size. But when you're dynamically cranking out millions of objects of relatively short lifetime, you can easily bump into the real world limits of practical machinery. "Wait until the reference count sweep gets rid of it" only works when you have plenty of room to squander. Also, waiting for the reference count/gc to do its thing is nondeterministic in time. It's going to happen sooner or later, but not at the same or a predictable interval. If you want to write large, performant code, you don't want this kind of variability. While I realize that we're not typically writing embedded realtime drivers in Python, the principle remains - where possible make things as predictable and repeatable as you can. For reasons I am not free discuss here, I can say with some assurance that there are real world applications where managing Python object lifetimes is very much indicated. From info at tundraware.com Sat Aug 5 17:41:59 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 16:41:59 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: <8mqh5e-f73.ln1@oceanview.tundraware.com> On 08/05/2017 11:16 AM, Ned Batchelder wrote: > It uses > reference counting, so most objects are reclaimed immediately when their > reference count goes to zero, such as at the end of local scopes. Given this code: class SomeObject: ..... for foo in somelist: a = SomeObject(foo) b = SomeObject(foo) c = SomeObject(foo) # Do something or other ... # Bottom of 'for' scope Are you saying that each time a,b,c are reassigned to new instances of SomeObject the old instance counts go to 0 and are immediately - as in synchronously, right now, on the spot - removed from memory? My understanding was (and I may well be wrong), that the reference count does get decremented - in this case to 0 - but the *detection* of that fact does not happen until the gc sweep looks through the heap for such stale objects. From marko at pacujo.net Sat Aug 5 18:12:53 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sun, 06 Aug 2017 01:12:53 +0300 Subject: Question About When Objects Are Destroyed (continued) References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> <8mqh5e-f73.ln1@oceanview.tundraware.com> Message-ID: <87r2wp3bq2.fsf@elektro.pacujo.net> Tim Daneliuk : > Are you saying that each time a,b,c are reassigned to new instances of > SomeObject the old instance counts go to 0 and are immediately - as in > synchronously, right now, on the spot - removed from memory? That depends on the implementation of Python. CPython employs reference counting so the answer to your question is often yes. Objects that participate in reference cycles, cannot be cleared on the spot. They have to wait for a GC analysis. > My understanding was (and I may well be wrong), that the reference > count does get decremented - in this case to 0 - but the *detection* > of that fact does not happen until the gc sweep looks through the heap > for such stale objects. You are confusing two mechanisms. The reference count mechanism kicks in right away when 0 is reached. The sweep method doesn't make any use of reference counting. There are also Python implementations that don't make any use of reference counting. Marko From python at mrabarnett.plus.com Sat Aug 5 18:13:23 2017 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 5 Aug 2017 23:13:23 +0100 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: <8mqh5e-f73.ln1@oceanview.tundraware.com> References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> <8mqh5e-f73.ln1@oceanview.tundraware.com> Message-ID: <33ad9ee2-bb5c-004d-953c-9a4cc94a04bc@mrabarnett.plus.com> On 2017-08-05 22:41, Tim Daneliuk wrote: > On 08/05/2017 11:16 AM, Ned Batchelder wrote: >> It uses >> reference counting, so most objects are reclaimed immediately when their >> reference count goes to zero, such as at the end of local scopes. > > Given this code: > > class SomeObject: > ..... > > > for foo in somelist: > > a = SomeObject(foo) > b = SomeObject(foo) > c = SomeObject(foo) > > # Do something or other > ... > > # Bottom of 'for' scope > > > Are you saying that each time a,b,c are reassigned to new instances of > SomeObject the old instance counts go to 0 and are immediately - as in > synchronously, right now, on the spot - removed from memory? My > understanding was (and I may well be wrong), that the reference count > does get decremented - in this case to 0 - but the *detection* of that > fact does not happen until the gc sweep looks through the heap for such > stale objects. > After this: a = SomeObject(foo) the name "a" is bound to an instance of SomeObject and the reference count of that instance is 1. If you then bind "a" to something else: a = None the reference count of the instance is decremented to 0, at which point the instance is reclaimed. The GC sweep stuff is for handling cycles where an object is unreachable but its reference count is non-zero. From ned at nedbatchelder.com Sat Aug 5 18:36:13 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Sat, 5 Aug 2017 18:36:13 -0400 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: <8mqh5e-f73.ln1@oceanview.tundraware.com> References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> <8mqh5e-f73.ln1@oceanview.tundraware.com> Message-ID: On 8/5/17 5:41 PM, Tim Daneliuk wrote: > On 08/05/2017 11:16 AM, Ned Batchelder wrote: >> It uses >> reference counting, so most objects are reclaimed immediately when their >> reference count goes to zero, such as at the end of local scopes. > Given this code: > > class SomeObject: > ..... > > > for foo in somelist: > > a = SomeObject(foo) > b = SomeObject(foo) > c = SomeObject(foo) > > # Do something or other > ... > > # Bottom of 'for' scope > > > Are you saying that each time a,b,c are reassigned to new instances of > SomeObject the old instance counts go to 0 and are immediately - as in > synchronously, right now, on the spot - removed from memory? Yes, that is what I am saying. In CPython, that is. Other implementation can behave differently. Jython and IronPython use the garbage collectors from the JVM and .net, I don't know specifically how they behave. > My > understanding was (and I may well be wrong), that the reference count > does get decremented - in this case to 0 - but the *detection* of that > fact does not happen until the gc sweep looks through the heap for such > stale objects. That is how classic garbage collectors worked. And Python has something like that, but it's only used to collect circular structures, where the reference counts will never go to zero, but nevertheless the entire structure can be unreferenced as a whole. --Ned. From leamhall at gmail.com Sat Aug 5 18:57:02 2017 From: leamhall at gmail.com (leam hall) Date: Sat, 5 Aug 2017 18:57:02 -0400 Subject: SQLObject 3.4.0 In-Reply-To: <20170805171108.GA15747@phdru.name> References: <20170805171108.GA15747@phdru.name> Message-ID: #I'm pleased to announce version 3.4.0, the first stable release of branch #3.4 of SQLObject. # # #What's new in SQLObject #======================= # #* Python 2.6 is no longer supported. The minimal supported version is # Python 2.7. Is there a particular reason to eliminate RHEL 6 (Python 2.6) support? That would seem to limit your enterprise adoption. From rosuav at gmail.com Sat Aug 5 18:58:57 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 6 Aug 2017 08:58:57 +1000 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On Sun, Aug 6, 2017 at 7:32 AM, Tim Daneliuk wrote: > On 08/05/2017 03:21 PM, Chris Angelico wrote: >> After a 'with' block, >> the object *still exists*, but it has been "exited" in some way >> (usually by closing/releasing an underlying resource). > > The containing object exists, but the things that the closing > logic explicitly released do not. In some sense, a context > acts like a deconstructor, just not on the object it's associated > with. > >> If there's a resource you need to clean up, you clean that up >> explicitly, > > Such "resources" *are* objects themselves notionally. You are exactly > killing those objects to free the underlying resources they consume. Utterly irrelevant. The original post was about the string in memory. An "open file" is no more an object than the part of a floating point number after the decimal is. >> so the object's lifetime shouldn't matter to you. > > I disagree with this most strongly. That's only true when the machine > resources being consumed by your Python object are small in size. But > when you're dynamically cranking out millions of objects of relatively > short lifetime, you can easily bump into the real world limits of > practical machinery. "Wait until the reference count sweep gets rid of > it" only works when you have plenty of room to squander. > > Also, waiting for the reference count/gc to do its thing is > nondeterministic in time. It's going to happen sooner or later, but not > at the same or a predictable interval. If you want to write large, > performant code, you don't want this kind of variability. While I > realize that we're not typically writing embedded realtime drivers in > Python, the principle remains - where possible make things as > predictable and repeatable as you can. > > For reasons I am not free discuss here, I can say with some assurance > that there are real world applications where managing Python object > lifetimes is very much indicated. Very VERY few. How often do you actually care about the lifetime of a specific Python object, and not (say) about the return of a block of memory to the OS? Memory in CPython is allocated in pages, and those pages are then suballocated into objects (or other uses). Sometimes you care about that block going back to the OS; other times, all you care about is that a subsequent allocation won't require more memory (which can be handled with free lists). But most of the time, you don't need to think about either, because the language *does the right thing*. The nondeterminism of the GC is irrelevant to most Python programs; in CPython, that GC sweep applies only to reference *cycles* (and to weak references, I think??), so unless you frequently create those, you shouldn't have to care. I've written plenty of large programs in high level languages. Some of them in Python, some in Pike (which has the same refcount semantics), and some in REXX (which has very different technical semantics but comes to the same thing). I've had those programs running for months on end; in more than one instance, I've had a program running for over a year (over two years, even) without restarting the process or anything. Aside from taking care not to create cyclic references, I have not needed to care about when the garbage collector runs, with the sole exception of an instance where I built my own system on top of the base GC (using weak references and an autoloader to emulate a lookup table larger than memory). So yes, I maintain that most of the time, object lifetimes *should not matter* to a Python programmer. Python is not C, and you shouldn't treat it as C. ChrisA From info at tundraware.com Sat Aug 5 20:13:48 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 19:13:48 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On 08/05/2017 05:58 PM, Chris Angelico wrote: > On Sun, Aug 6, 2017 at 7:32 AM, Tim Daneliuk wrote: >> On 08/05/2017 03:21 PM, Chris Angelico wrote: >>> After a 'with' block, >>> the object *still exists*, but it has been "exited" in some way >>> (usually by closing/releasing an underlying resource). >> >> The containing object exists, but the things that the closing >> logic explicitly released do not. In some sense, a context >> acts like a deconstructor, just not on the object it's associated >> with. >> >>> If there's a resource you need to clean up, you clean that up >>> explicitly, >> >> Such "resources" *are* objects themselves notionally. You are exactly >> killing those objects to free the underlying resources they consume. > > Utterly irrelevant. The original post was about the string in memory. > An "open file" is no more an object than the part of a floating point > number after the decimal is. > >>> so the object's lifetime shouldn't matter to you. >> >> I disagree with this most strongly. That's only true when the machine >> resources being consumed by your Python object are small in size. But >> when you're dynamically cranking out millions of objects of relatively >> short lifetime, you can easily bump into the real world limits of >> practical machinery. "Wait until the reference count sweep gets rid of >> it" only works when you have plenty of room to squander. >> >> Also, waiting for the reference count/gc to do its thing is >> nondeterministic in time. It's going to happen sooner or later, but not >> at the same or a predictable interval. If you want to write large, >> performant code, you don't want this kind of variability. While I >> realize that we're not typically writing embedded realtime drivers in >> Python, the principle remains - where possible make things as >> predictable and repeatable as you can. >> >> For reasons I am not free discuss here, I can say with some assurance >> that there are real world applications where managing Python object >> lifetimes is very much indicated. > > Very VERY few. How often do you actually care about the lifetime of a > specific Python object, and not (say) about the return of a block of > memory to the OS? Memory in CPython is allocated in pages, and those > pages are then suballocated into objects (or other uses). Sometimes > you care about that block going back to the OS; other times, all you > care about is that a subsequent allocation won't require more memory > (which can be handled with free lists). But most of the time, you > don't need to think about either, because the language *does the right > thing*. The nondeterminism of the GC is irrelevant to most Python > programs; in CPython, that GC sweep applies only to reference *cycles* > (and to weak references, I think??), so unless you frequently create > those, you shouldn't have to care. > > I've written plenty of large programs in high level languages. Some of > them in Python, some in Pike (which has the same refcount semantics), > and some in REXX (which has very different technical semantics but > comes to the same thing). I've had those programs running for months > on end; in more than one instance, I've had a program running for over > a year (over two years, even) without restarting the process or > anything. Aside from taking care not to create cyclic references, I > have not needed to care about when the garbage collector runs, with > the sole exception of an instance where I built my own system on top > of the base GC (using weak references and an autoloader to emulate a > lookup table larger than memory). So yes, I maintain that most of the > time, object lifetimes *should not matter* to a Python programmer. > Python is not C, and you shouldn't treat it as C. > > ChrisA > OK, noted, and thanks for the clear explanation. From info at tundraware.com Sat Aug 5 20:14:13 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 19:14:13 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On 08/05/2017 05:58 PM, Chris Angelico wrote: > On Sun, Aug 6, 2017 at 7:32 AM, Tim Daneliuk wrote: >> On 08/05/2017 03:21 PM, Chris Angelico wrote: >>> After a 'with' block, >>> the object *still exists*, but it has been "exited" in some way >>> (usually by closing/releasing an underlying resource). >> >> The containing object exists, but the things that the closing >> logic explicitly released do not. In some sense, a context >> acts like a deconstructor, just not on the object it's associated >> with. >> >>> If there's a resource you need to clean up, you clean that up >>> explicitly, >> >> Such "resources" *are* objects themselves notionally. You are exactly >> killing those objects to free the underlying resources they consume. > > Utterly irrelevant. The original post was about the string in memory. > An "open file" is no more an object than the part of a floating point > number after the decimal is. > >>> so the object's lifetime shouldn't matter to you. >> >> I disagree with this most strongly. That's only true when the machine >> resources being consumed by your Python object are small in size. But >> when you're dynamically cranking out millions of objects of relatively >> short lifetime, you can easily bump into the real world limits of >> practical machinery. "Wait until the reference count sweep gets rid of >> it" only works when you have plenty of room to squander. >> >> Also, waiting for the reference count/gc to do its thing is >> nondeterministic in time. It's going to happen sooner or later, but not >> at the same or a predictable interval. If you want to write large, >> performant code, you don't want this kind of variability. While I >> realize that we're not typically writing embedded realtime drivers in >> Python, the principle remains - where possible make things as >> predictable and repeatable as you can. >> >> For reasons I am not free discuss here, I can say with some assurance >> that there are real world applications where managing Python object >> lifetimes is very much indicated. > > Very VERY few. How often do you actually care about the lifetime of a > specific Python object, and not (say) about the return of a block of > memory to the OS? Memory in CPython is allocated in pages, and those > pages are then suballocated into objects (or other uses). Sometimes > you care about that block going back to the OS; other times, all you > care about is that a subsequent allocation won't require more memory > (which can be handled with free lists). But most of the time, you > don't need to think about either, because the language *does the right > thing*. The nondeterminism of the GC is irrelevant to most Python > programs; in CPython, that GC sweep applies only to reference *cycles* > (and to weak references, I think??), so unless you frequently create > those, you shouldn't have to care. > > I've written plenty of large programs in high level languages. Some of > them in Python, some in Pike (which has the same refcount semantics), > and some in REXX (which has very different technical semantics but > comes to the same thing). I've had those programs running for months > on end; in more than one instance, I've had a program running for over > a year (over two years, even) without restarting the process or > anything. Aside from taking care not to create cyclic references, I > have not needed to care about when the garbage collector runs, with > the sole exception of an instance where I built my own system on top > of the base GC (using weak references and an autoloader to emulate a > lookup table larger than memory). So yes, I maintain that most of the > time, object lifetimes *should not matter* to a Python programmer. > Python is not C, and you shouldn't treat it as C. > > ChrisA > OK, noted, and thanks for the clear explanation. From info at tundraware.com Sat Aug 5 20:14:42 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 19:14:42 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> <8mqh5e-f73.ln1@oceanview.tundraware.com> Message-ID: <06cd7a11-f3c5-d1be-adfb-1856d8bd72d8@tundraware.com> On 08/05/2017 05:36 PM, Ned Batchelder wrote: > On 8/5/17 5:41 PM, Tim Daneliuk wrote: >> On 08/05/2017 11:16 AM, Ned Batchelder wrote: >>> It uses >>> reference counting, so most objects are reclaimed immediately when their >>> reference count goes to zero, such as at the end of local scopes. >> Given this code: >> >> class SomeObject: >> ..... >> >> >> for foo in somelist: >> >> a = SomeObject(foo) >> b = SomeObject(foo) >> c = SomeObject(foo) >> >> # Do something or other >> ... >> >> # Bottom of 'for' scope >> >> >> Are you saying that each time a,b,c are reassigned to new instances of >> SomeObject the old instance counts go to 0 and are immediately - as in >> synchronously, right now, on the spot - removed from memory? > Yes, that is what I am saying. In CPython, that is. Other > implementation can behave differently. Jython and IronPython use the > garbage collectors from the JVM and .net, I don't know specifically how > they behave. >> My >> understanding was (and I may well be wrong), that the reference count >> does get decremented - in this case to 0 - but the *detection* of that >> fact does not happen until the gc sweep looks through the heap for such >> stale objects. > That is how classic garbage collectors worked. And Python has something > like that, but it's only used to collect circular structures, where the > reference counts will never go to zero, but nevertheless the entire > structure can be unreferenced as a whole. > > --Ned. > Interesting. I haz a confuzed. Thanks for clearing that up. From info at tundraware.com Sat Aug 5 20:14:55 2017 From: info at tundraware.com (Tim Daneliuk) Date: Sat, 5 Aug 2017 19:14:55 -0500 Subject: Question About When Objects Are Destroyed (continued) In-Reply-To: References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> <8mqh5e-f73.ln1@oceanview.tundraware.com> Message-ID: On 08/05/2017 05:36 PM, Ned Batchelder wrote: > On 8/5/17 5:41 PM, Tim Daneliuk wrote: >> On 08/05/2017 11:16 AM, Ned Batchelder wrote: >>> It uses >>> reference counting, so most objects are reclaimed immediately when their >>> reference count goes to zero, such as at the end of local scopes. >> Given this code: >> >> class SomeObject: >> ..... >> >> >> for foo in somelist: >> >> a = SomeObject(foo) >> b = SomeObject(foo) >> c = SomeObject(foo) >> >> # Do something or other >> ... >> >> # Bottom of 'for' scope >> >> >> Are you saying that each time a,b,c are reassigned to new instances of >> SomeObject the old instance counts go to 0 and are immediately - as in >> synchronously, right now, on the spot - removed from memory? > Yes, that is what I am saying. In CPython, that is. Other > implementation can behave differently. Jython and IronPython use the > garbage collectors from the JVM and .net, I don't know specifically how > they behave. >> My >> understanding was (and I may well be wrong), that the reference count >> does get decremented - in this case to 0 - but the *detection* of that >> fact does not happen until the gc sweep looks through the heap for such >> stale objects. > That is how classic garbage collectors worked. And Python has something > like that, but it's only used to collect circular structures, where the > reference counts will never go to zero, but nevertheless the entire > structure can be unreferenced as a whole. > > --Ned. > Interesting. I haz a confuzed. Thanks for clearing that up. From steve+python at pearwood.info Sat Aug 5 22:27:55 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sun, 06 Aug 2017 12:27:55 +1000 Subject: Signals and Slots - Summerfield - what exactly is a signal? References: <0b71660d-ecd8-30bf-e6f2-9ab913791e5c@gmail.com> Message-ID: <59867eac$0$22142$c3e8da3$5496439d@news.astraweb.com> On Sun, 6 Aug 2017 03:18 am, Michael Torrie wrote: > Forgive Steven for his off-topic reply. I assume he's trying to goad you > into having a more specific subject line. He knows darn well what PyQt, > even if he has no experience with it. Pardon me, I said: "I don't know what Qt signals are." I know what Qt is. I don't know what Qt signals are, just as I said. Well I do now, thanks to Veek answering his own question with a good explanation of Qt slots. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From stephanh42 at gmail.com Sun Aug 6 03:45:51 2017 From: stephanh42 at gmail.com (Stephan Houben) Date: 06 Aug 2017 07:45:51 GMT Subject: unpacking elements in python - any tips u want to share ? References: Message-ID: Hi Ganesh, Op 2017-07-27, Ganesh Pal schreef : > I have a list with say 7 elements say if I need to unpack first 3 > elements in the list and pass it an argument to the new fuction, here is > my elementary code One way to do exactly what you request here is: new_function(*my_list[:3]) Explanation: 1. my_list[:3] produces a list of the first 3 elements of my_list 2. new_function(*some_sequence) (Note the * in the calling syntax!) is equivalent to calling new_function with all the elements of some_sequence individually: new_function(some_sequence[0], some_sequence[1], ...) But I observe that this is slightly different from the code you actually present: > ... var1,var2,var3,var4,var5,var6,var7 = my_list > ... var8 = get_eighth_element(var1,int(var2),int(var3)) This code actually converts var2 and var3 into an integer first. (By calling int). Short intermezzo: I notice that you are apparently using Python 2, because of this code: > ?.print my_list This code would be print(my_list) in Python 3. If you are just learning Python and there is no particular reason you need Python 2, I would recommend Python 3 at this point. Python 2 is still supported but only until 2020 so you may want to invest in something more future-proof. Anyway, the reason I bring it up is because in Python 3 you can do: var1,var2,var3,*_ = my_list var8 = get_eighth_element(var1,int(var2),int(var3)) This will work for any my_list which has at least 3 elements. The syntax *_ binds the rest of the list to the variable _. _ is a conventional name for a variable in which value you are not interested. If backward-compatibility with Python 2 is important, you can do instead: var1,var2,var3 = my_list[:3] var8 = get_eighth_element(var1,int(var2),int(var3)) Finally, I would want to point out that if these fields of the list have some specific meaning (e.g. my_list[0] is first name, my_list[1] is last name, my_list[2] is address, etc..), then a more idiomatic Python solution would be to define a class with named members for these things: class Person: def __init__(self, first_name, last_name, address, city): self.first_name = first_name self.last_name = last_name self.address = address self.city = city Greetings, Stephan From jobmattcon at gmail.com Sun Aug 6 10:18:13 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Sun, 6 Aug 2017 07:18:13 -0700 (PDT) Subject: ValueError: operands could not be broadcast together with shapes Message-ID: <22a685f3-495b-4d8f-90f9-a6b9c8555983@googlegroups.com> def mse(imageA, imageB): err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2) err /= float(imageA.shape[0] * imageA.shape[1]) return err original = cv2.imread("C:\\Users\\hello\\Documents\\words\\" + xx) later = cv2.imread("C:\\Users\\hello\\Documents\\words\\"+ yy) mserr = mse(original, later) Traceback (most recent call last): File "words29.py", line 135, in mserr = mse(original, later) File "words29.py", line 27, in mse err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2) ValueError: operands could not be broadcast together with shapes (7,29,3) (7,37,3) From __peter__ at web.de Sun Aug 6 11:19:08 2017 From: __peter__ at web.de (Peter Otten) Date: Sun, 06 Aug 2017 17:19:08 +0200 Subject: ValueError: operands could not be broadcast together with shapes References: <22a685f3-495b-4d8f-90f9-a6b9c8555983@googlegroups.com> Message-ID: Ho Yeung Lee wrote: > def mse(imageA, imageB): > err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2) > err /= float(imageA.shape[0] * imageA.shape[1]) > return err > > original = cv2.imread("C:\\Users\\hello\\Documents\\words\\" + xx) > later = cv2.imread("C:\\Users\\hello\\Documents\\words\\"+ yy) > mserr = mse(original, later) > > Traceback (most recent call last): > File "words29.py", line 135, in > mserr = mse(original, later) > File "words29.py", line 27, in mse > err = np.sum((imageA.astype("float") - imageB.astype("float")) ** 2) > ValueError: operands could not be broadcast together with shapes (7,29,3) > (7,37,3) These are probably images represented as numpy arrays. To calculate the pixelwise difference both images have to have the same size whereas one of your samples seems to be 7x29xRGB, and the other 7x37xRGB. From rantingrickjohnson at gmail.com Sun Aug 6 17:48:58 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sun, 6 Aug 2017 14:48:58 -0700 (PDT) Subject: program that search string in text file and do something In-Reply-To: References: Message-ID: <1278c39a-6d4f-4a91-ba2f-8a017905e2be@googlegroups.com> Grant Edwards wrote: > Peter Otten <__peter__ at web.de> wrote: > > > What we won't do is write a program for you ready to > > present to your teacher. > > Or if we do, it will be subtly sabotaged in a manner that > will make it obvious to an experienced Python programmer > that you didn't write it. My favorite is to use some > combination of particularly obscure and obtuse mechanisms > that will actually product the correct results but do so in > a way that nobody (including myself a few days later) will > be able to explain without some intense study. I would caution the OP against blindly soliciting for free homework answers on the internet, most especially when the request includes the deletion of files. Perhaps in this forum the worst case scenario would be the return of a scornful rebuke or a heavily obfuscated chunk of abysmal code. However, in some of the darker, more devious corners of the web, a naive solicitation such as this could end with the student's file-system suddenly being relieved of the burden of carrying around all those extra files. A most unforgiving lesson in the power and conciseness of the recursive algorithm. From gerd.niemetz at gmail.com Mon Aug 7 02:44:39 2017 From: gerd.niemetz at gmail.com (Gerd Niemetz) Date: Sun, 6 Aug 2017 23:44:39 -0700 (PDT) Subject: Recent Spam problem In-Reply-To: References: Message-ID: <8715acca-ace0-47a9-b04b-9dc7633eb6ec@googlegroups.com> Am Dienstag, 25. Juli 2017 07:13:51 UTC+2 schrieb Rustom Mody: > Of late there has been an explosion of spam > Thought it was only a google-groups (USENET?) issue and would be barred from the mailing list. > > But then find its there in the mailing list archives as well > Typical example: https://mail.python.org/pipermail/python-list/2017-July/724085.html > > What gives?? > > On a different note this problem seems to be peculiar to comp.lang.python > via google-groups and is absent on ? dozen other google groups I see. > > Since spammers are unlikely to be choosy about whom they spam: > Tentative conclusion: Something about the USENET-ML gateway is more leaky > out here than elsewhere What i do is to "install" the bookmarklet "Jquerify" from https://mreidsma.github.io/bookmarklets/jquerify.html, open the developer tools (i use Google Chrome), go to the console and paste the following javascript: $('tr > td > div > div > div > div > div > div > div:contains("Case Solution"), div:contains("Test Banks")').closest("tr").hide(); $('tr > td > div > div > div > div > div > div > a').each(function(){if($(this).text().length > 100) $(this).closest("tr").hide()}); This hides all the posts from "Case Solution" and "Test Banks" and all posts with a subject length > 100. Rerun the code to hide more, not elegant but helpful (at least for me :) ) best regards, Gerd From grant.b.edwards at gmail.com Mon Aug 7 10:37:23 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 7 Aug 2017 14:37:23 +0000 (UTC) Subject: Linux/Windows GUI programming: tk or wx? References: <95a5d47f-5cc4-0712-6e4c-2376488ee762@gmail.com> Message-ID: On 2017-08-05, Michael Torrie wrote: > Well tk is already an optional part of the Python standard library, > whereas wx is an external package. So for your simple requirements, > Tk may be the way to go. I find it much easier to get a simple application written and working with Tk than with wx. However, once the size/complexity increases beyond a certain point, I find wx to be less work. > I'm guessing the tk would result in the > smallest executable as well, though I could be very wrong. The last time I compared wx vs tk bundled sizes using py2exe (for a fairly simple application), using tk generated far larger .exe files. When you use Tk, it pulls in a complete TCL implementation as well as the Tk libraries (which contain way more library files than wx -- IIRC, there was a _lot_ of localization stuff in the Tk libraries). -- Grant Edwards grant.b.edwards Yow! ... he dominates the at DECADENT SUBWAY SCENE. gmail.com From ikorot01 at gmail.com Mon Aug 7 10:47:09 2017 From: ikorot01 at gmail.com (Igor Korot) Date: Mon, 7 Aug 2017 10:47:09 -0400 Subject: Linux/Windows GUI programming: tk or wx? In-Reply-To: References: <95a5d47f-5cc4-0712-6e4c-2376488ee762@gmail.com> Message-ID: Hi, Grant, On Mon, Aug 7, 2017 at 10:37 AM, Grant Edwards wrote: > On 2017-08-05, Michael Torrie wrote: > >> Well tk is already an optional part of the Python standard library, >> whereas wx is an external package. So for your simple requirements, >> Tk may be the way to go. > > I find it much easier to get a simple application written and working > with Tk than with wx. However, once the size/complexity increases > beyond a certain point, I find wx to be less work. What version of wx/python did you try? It is very easy to work with wx{Python, Phoenix} no matter which application {complexity} we are talking about. There are a lot of samples/demos on the wxpython web site. Thank you. > >> I'm guessing the tk would result in the >> smallest executable as well, though I could be very wrong. > > The last time I compared wx vs tk bundled sizes using py2exe (for a > fairly simple application), using tk generated far larger .exe files. > > When you use Tk, it pulls in a complete TCL implementation as well as > the Tk libraries (which contain way more library files than wx -- > IIRC, there was a _lot_ of localization stuff in the Tk libraries). > > -- > Grant Edwards grant.b.edwards Yow! ... he dominates the > at DECADENT SUBWAY SCENE. > gmail.com > > -- > https://mail.python.org/mailman/listinfo/python-list From grant.b.edwards at gmail.com Mon Aug 7 10:49:06 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 7 Aug 2017 14:49:06 +0000 (UTC) Subject: Linux/Windows GUI programming: tk or wx? References: <95a5d47f-5cc4-0712-6e4c-2376488ee762@gmail.com> <0lkg5e-i4k.ln1@esprimo.zbmc.eu> Message-ID: On 2017-08-05, Chris Green wrote: > Michael Torrie wrote: > > I went through a similar process of deciding the easiest (for me) GUI > to go with. I've actually ended up with PyGtk as it feels for me the > 'least foreign' compared with doing things the CLI way. I definitely think PyGtk feels the "most Pythonic". It seems simpler than wx, yet is able to handle complex applications. The last time I read up on it, it didn't sound like a very good option if you want Windows compatibility. If I hadn't cared about Windows, I definitely would have picked PyGtk over wx. I haven't used it in a while, and I don't the state of gtk2 vs. gtk3 (pygobject). -- Grant Edwards grant.b.edwards Yow! ... I want a COLOR at T.V. and a VIBRATING BED!!! gmail.com From grant.b.edwards at gmail.com Mon Aug 7 10:56:20 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 7 Aug 2017 14:56:20 +0000 (UTC) Subject: Question About When Objects Are Destroyed (continued) References: <6b4d555d-e155-17b3-e0f0-5061332c968d@gmail.com> Message-ID: On 2017-08-05, Tim Daneliuk wrote: > On 08/05/2017 03:21 PM, Chris Angelico wrote: >> so the object's lifetime shouldn't matter to you. > > I disagree with this most strongly. That's only true when the > machine resources being consumed by your Python object are small in > size. But when you're dynamically cranking out millions of objects > of relatively short lifetime, you can easily bump into the real > world limits of practical machinery. "Wait until the reference > count sweep gets rid of it" only works when you have plenty of room > to squander. I've been writing Python applications for almost 20 years. I've never paid any attention _at_all_ (none, zero) to object lifetimes, and it's never caused any problems for me. Admittedly they didn't involve gigabytes of data, but many of them ran for days at a time... -- Grant Edwards grant.b.edwards Yow! Jesuit priests are at DATING CAREER DIPLOMATS!! gmail.com From grant.b.edwards at gmail.com Mon Aug 7 10:58:55 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 7 Aug 2017 14:58:55 +0000 (UTC) Subject: Code for addition References: Message-ID: On 2017-08-05, Ode Idoko via Python-list wrote: > Can anyone help with the python code that can add 101, 102, 103...2033 please? > As I said before, I'm new to python and need assistance in this regard. > Thanks for always assisting. $ python Python 2.7.12 (default, Jan 3 2017, 10:08:10) [GCC 4.9.4] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> sum(range(101,2034)) 2062511 -- Grant Edwards grant.b.edwards Yow! Alright, you!! at Imitate a WOUNDED SEAL gmail.com pleading for a PARKING SPACE!! From Cecil at decebal.nl Mon Aug 7 11:57:17 2017 From: Cecil at decebal.nl (Cecil Westerhof) Date: Mon, 07 Aug 2017 17:57:17 +0200 Subject: Upgrade of pysmbc with pip3 goes wrong Message-ID: <87tw1jweua.fsf@munus.decebal.nl> When I execute: pip3 install --upgrade pysmbc I get: Collecting pysmbc Using cached pysmbc-1.0.15.7.tar.bz2 Complete output from command python setup.py egg_info: Traceback (most recent call last): File "", line 1, in File "/tmp/pip-build-9b9p_652/pysmbc/setup.py", line 92, in include_dirs=pkgconfig_I("smbclient"))]) File "/tmp/pip-build-9b9p_652/pysmbc/setup.py", line 59, in pkgconfig_I stdout=subprocess.PIPE) File "/usr/lib/python3.5/subprocess.py", line 676, in __init__ restore_signals, start_new_session) File "/usr/lib/python3.5/subprocess.py", line 1282, in _execute_child raise child_exception_type(errno_num, err_msg) FileNotFoundError: [Errno 2] No such file or directory: 'pkg-config' ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-9b9p_652/pysmbc/ What could be the problem? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From ethan at stoneleaf.us Mon Aug 7 14:15:00 2017 From: ethan at stoneleaf.us (Ethan Furman) Date: Mon, 07 Aug 2017 11:15:00 -0700 Subject: pip requirements file In-Reply-To: <598533E5.6000101@stoneleaf.us> References: <5985309E.1070405@stoneleaf.us> <598533E5.6000101@stoneleaf.us> Message-ID: <5988AE24.2000204@stoneleaf.us> On 08/04/2017 07:56 PM, Ethan Furman wrote: > On 08/04/2017 07:46 PM, Chris Angelico wrote: >> On Sat, Aug 5, 2017 at 12:42 PM, Ethan Furman wrote: > >>> pip freeze >>> >>> will output a list of current packages and their requirements. I have one >>> package that falsely [1] lists another package as a requirement, which was >>> blocking installation as the false requirement wasn't available. >>> >>> Is there a way to modify that output (which would be piped to, for example, >>> requirements.txt) to have >>> >>> pip install -r requirements.txt >>> >>> so pip ignores that one (and only that one) dependency? >> >> I'd just edit the file afterwards and delete the line. But if the >> package claims to need PyXML, it'll still be installed. > > Exactly my point. Is there any way, requirements.txt or otherwise, to tell pip to ignore what a certain package is > claiming it needs? > > I am aware of --no-dependencies, but that (I think) is an all-or-nothing approach, whilst [1] I desire an all-except-one > approach. Light finally turned on. If requirements.txt has all my installed requirements, that would include any dependencies actually needed; so I specify --no-dependencies, then dependencies not listed in the requirements.txt file will not be installed. -- ~Ethan~ From taaymihaj at gmail.com Mon Aug 7 15:11:04 2017 From: taaymihaj at gmail.com (taaymihaj at gmail.com) Date: Mon, 7 Aug 2017 12:11:04 -0700 (PDT) Subject: Case Solution: Alqueria More than Just a Glass of Milk (A) by Nathalia Franco, Sebastian Duenas, Margarita Castillo In-Reply-To: <813fc4de-f9c1-4978-9dfe-41e663c918ca@googlegroups.com> References: <813fc4de-f9c1-4978-9dfe-41e663c918ca@googlegroups.com> Message-ID: <12585306-aabe-4632-baeb-26ea6d83be3e@googlegroups.com> Le samedi 5 ao?t 2017 23:30:34 UTC+1, Case Solution & Analysis a ?crit?: > Case Solution and Analysis of Alqueria: More than Just a Glass of Milk (A) by Nathalia Franco, Sebastian Duenas, Margarita Castillo is available at a lowest price, send email to casesolutionscentre(at)gmail(dot)com if you want to order the Case Solution. > > Case Study ID: AN0028 > > Get Case Study Solution and Analysis of Alqueria: More than Just a Glass of Milk (A) in a FAIR PRICE!! > > Our e-mail address is CASESOLUTIONSCENTRE (AT) GMAIL (DOT) COM. Please replace (at) by @ and (dot) by . > > YOU MUST WRITE THE FOLLOWING WHILE PLACING YOUR ORDER: > Complete Case Study Name > Authors > Case Study ID > Publisher of Case Study > Your Requirements / Case Questions > > Note: Do not REPLY to this post because we do not reply to posts here. If you need any Case Solution please send us an email. We can help you to get it. From neilc at norwich.edu Mon Aug 7 16:39:28 2017 From: neilc at norwich.edu (Neil Cerutti) Date: Mon, 7 Aug 2017 20:39:28 +0000 (UTC) Subject: Code for addition References: Message-ID: On 2017-08-05, Ode Idoko via Python-list wrote: > Can anyone help with the python code that can add 101, 102, > 103...2033 please? As I said before, I'm new to python and need > assistance in this regard. Thanks for always assisting. >>> (2033 - 101 + 1) * (101 + 2033) / 2 You could also calculate it with a combination of sum and range builtins, as others have hinted, and if it's homework that's probably a good idea. -- Neil Cerutti From marko at pacujo.net Mon Aug 7 16:59:48 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Mon, 07 Aug 2017 23:59:48 +0300 Subject: Code for addition References: Message-ID: <87inhz14cb.fsf@elektro.pacujo.net> Neil Cerutti : > On 2017-08-05, Ode Idoko via Python-list > wrote: >> Can anyone help with the python code that can add 101, 102, >> 103...2033 please? As I said before, I'm new to python and need >> assistance in this regard. Thanks for always assisting. > >>>> (2033 - 101 + 1) * (101 + 2033) / 2 > > You could also calculate it with a combination of sum and range > builtins, as others have hinted, and if it's homework that's > probably a good idea. During college, one project was to develop a factorial subprogram using the assembly language of an imaginary, 18-bit CPU. I told the student who got the task that the only sane implementation would be a lookup table with a possible range check as in: def factorial(n): return [1, 1, 2, 6, 24, 120, 720, 5040, 40320][n] I believe he chickened out, though, and implemented a loop with multiplications. Marko From gandalf at shopzeus.com Tue Aug 8 02:21:41 2017 From: gandalf at shopzeus.com (=?UTF-8?Q?Nagy_L=c3=a1szl=c3=b3_Zsolt?=) Date: Tue, 8 Aug 2017 08:21:41 +0200 Subject: Firebird 1.5 and Python 3.4 - is this possible? Message-ID: Hi! I have an old HIS program written in Delphi. It uses Firebird 1.5 database. I need to make an interface to exchange data with other healthcare providers. I do not want to do this in Delphi, that is ancient code. It is also not an option to rewrite the whole program from scratch. I just need to add a service that runs in the background and sends/receives data. Is it possible to somehow connect and use firebird 1.5 database from Python 3? I have tried kinterbasdb with no luck. There are a number of firebird libraries out there, but none of them seems to support firebird 1.5. Does anyone know a library that can do this? Thanks, Laszlo From sandeep.gk789 at gmail.com Tue Aug 8 06:18:48 2017 From: sandeep.gk789 at gmail.com (sandeep.gk789 at gmail.com) Date: Tue, 8 Aug 2017 03:18:48 -0700 (PDT) Subject: Need python script to get last 6 month's monthly billing Message-ID: Hi, I would like to create AWS monthly billing graph using python and python flask.so for this i need python script using that i have to get last 6 month's monthly bill in AWS. for this, i have created one virtual environment in my local machine. for examplle my ip is: 127.0.0.0:5000. Here after pull that script, it's automatically connected to AWS and display's last 6 month's data. its my requirement. Thanks in advance. Thank you, Sandeep From larry at hastings.org Tue Aug 8 06:58:55 2017 From: larry at hastings.org (Larry Hastings) Date: Tue, 8 Aug 2017 03:58:55 -0700 Subject: [RELEASED] Python 3.5.4 is now available Message-ID: <86871e7f-2117-f05f-7c55-c3a7ddab920d@hastings.org> On behalf of the Python development community and the Python 3.5 release team, I'm pleased to announce the availability of Python 3.5.4. Python 3.5.4 is the final 3.5 release in "bug fix" mode. The Python 3.5 branch has now transitioned into "security fixes mode"; all future improvements in the 3.5 branch will be security fixes only, and no conventional bug fixes will be merged. You can find Python 3.5.4 here: https://www.python.org/downloads/release/python-354/ Python 3.4.7 final will be released later today. Happy Pythoning, //arry/ From joel.goldstick at gmail.com Tue Aug 8 07:34:32 2017 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Tue, 8 Aug 2017 07:34:32 -0400 Subject: Need python script to get last 6 month's monthly billing In-Reply-To: References: Message-ID: On Tue, Aug 8, 2017 at 6:18 AM, wrote: > Hi, > > > I would like to create AWS monthly billing graph using python and python > flask.so for this i need python script using that i have to get last 6 > month's monthly bill in AWS. > for this, i have created one virtual environment in my local machine. for > examplle my ip is: 127.0.0.0:5000. > Here after pull that script, it's automatically connected to AWS and > display's last 6 month's data. its my requirement. > > Thanks in advance. > > Thank you, > Sandeep > -- > https://mail.python.org/mailman/listinfo/python-list > You haven't asked a question. It is doubtful someone here would write code for you. In any case your problem isn't well stated. Why don't you show the code you have written, and explain where it fails? -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From rosuav at gmail.com Tue Aug 8 10:29:49 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 00:29:49 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: References: Message-ID: On Wed, Aug 9, 2017 at 12:19 AM, Stefan Ram wrote: > I am planning a Python course. > Before answering any other questions, answer this one: Why a new Python course? How is it different from what already exists? The answer to that will govern just about everything else. The specifics that you're asking about are unanswerable without first knowing your audience, for instance. ChrisA From peter.heitzer at rz.uni-regensburg.de Tue Aug 8 10:54:42 2017 From: peter.heitzer at rz.uni-regensburg.de (Peter Heitzer) Date: 8 Aug 2017 14:54:42 GMT Subject: Planning a Python Course for Beginners References: Message-ID: Stefan Ram wrote: > I am planning a Python course. [different topics] > Are there any other very simple things that > I have missed and that should be covered very > early in a Python course? The differences between blanks and tabs :-) -- Dipl.-Inform(FH) Peter Heitzer, peter.heitzer at rz.uni-regensburg.de From rosuav at gmail.com Tue Aug 8 11:17:21 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 01:17:21 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: References: Message-ID: On Wed, Aug 9, 2017 at 1:02 AM, Stefan Ram wrote: > Chris Angelico writes: >>Why a new Python course? > > It is not a course in the sense of a written text > (which I would call "course notes"). > > It is a course in the sense of an event, where I will meet > participants in a classroom. I will get paid for it, so this > payment is the reason I do it (simplified ;-). Ah. Well, that's a good answer to the question of "why are you even bothering to write this", but unfortunately doesn't answer the questions that I hoped it would, about target audience and such. Heh. C'est la vie. > Since this is my first-ever Python course, but has not yet > begun, I do not know the participants, but I can say this: > > - the course description requires that the participant > have experiences "working with a computer", but not that > they have any knowledge about programming. > > - the participants in my other courses for other > programming languages usually are slow learners, so I > prepare for this kind of audience. I try to avoid topics > that are abstract, advanced or complicated as much as > possible. I try to include very simple exercises. > Most books and tutorials assume faster learners, > so that's another reasone why I don't use them. So, this here is the important info. In that case, I would start with wowing them with the amazing stuff Python can do. Start with a few demonstrations of the simplicity and beauty of expression evaluation. It's okay to use concepts you haven't yet explained; instead of starting with concrete info and building up to something interesting, start with something interesting and then explain how it all works. Just my opinion, of course, but if you didn't want totally unbacked opinions, you wouldn't have come to this list :) ChrisA From walters.justin01 at gmail.com Tue Aug 8 11:23:26 2017 From: walters.justin01 at gmail.com (justin walters) Date: Tue, 8 Aug 2017 08:23:26 -0700 Subject: Planning a Python Course for Beginners In-Reply-To: References: Message-ID: On Tue, Aug 8, 2017 at 7:19 AM, Stefan Ram wrote: > I am planning a Python course. > > I started by writing the course akin to courses I gave > in other languages, that means, the course starts roughly > with these topics: > > - number and string literals > - types of number and string literals > (just giving the names ?int?, ?float?, and ?string?) > - using simple predefined operators (+, -, *, /) > (including 2*"a" and "a"+"b") > - calling simple predefined functions (len, type, ...) > > . This is a little bit boring however and might not > show off Python's strength early in the course. > > So, I now think that maybe I should start to also > include list (like > > [1,2,3] > > ) right from the start. A list conceptually is not > much more difficult than a string since a string > "abc" resembles a list ["a","b","c"]. I.e., the > course then would start as follows: > > - number, string, and list literals > - types of number, string and list literals > (just giving the names ?int?, ?float?, ?string?, > and ?list?) > - using simple predefined operators (+, -, *, /) > (including 2*"a", "a"+"b", 2*["a"], and [1]+[2]) > - calling simple predefined functions (len, type, ...) > > However, once the box has been opened, what else > to let out? What about tuples (like > > (1,2,3) > > ). Should I also teach tuples right from the start? > > But then how to explain to beginners why two > different types (lists AND tuples) are needed for > the concept of a linear arrangement of things? > > Are there any other very simple things that > I have missed and that should be covered very > early in a Python course? > > (Especially things that can show off fantastic > Python features that are missing from other > programming languages, but still only using > literals, operators and function calls.) > > -- > https://mail.python.org/mailman/listinfo/python-list > One thing I find that gets overlooked in a lot of beginner Python courses is Python's module system. Covering the module system will allow you to hit on the subject of namespacing and scope. Python's module system is one of its greatest strengths in my opinion. No other language I've used makes it so simple to structure a project. Another idea: Dictionaries Dictionaries are a conceptually simple data structure that should be easy for beginners to grok. Obviously, their implementation is a bit complex, but I don't think you would need to get into that. Dictionaries are very powerful data structures that can be used to keep code DRY and store important data to be accessed from anywhere in an application or script. Dictionaries also have a time complexity average of O(1) for read access which makes them fairly efficient. From grant.b.edwards at gmail.com Tue Aug 8 11:38:42 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 8 Aug 2017 15:38:42 +0000 (UTC) Subject: Planning a Python Course for Beginners References: Message-ID: On 2017-08-08, Peter Heitzer wrote: > Stefan Ram wrote: >> I am planning a Python course. > [different topics] >> Are there any other very simple things that >> I have missed and that should be covered very >> early in a Python course? > > The differences between blanks and tabs :-) You've misspelled "Tabs are evil and should never be used". ;) -- Grant Edwards grant.b.edwards Yow! We just joined the at civil hair patrol! gmail.com From steve.dower at python.org Tue Aug 8 12:21:51 2017 From: steve.dower at python.org (Steve Dower) Date: Tue, 8 Aug 2017 09:21:51 -0700 Subject: [ANN] Daily Windows builds of Python 3.x Message-ID: <2e89743a-4a08-d1df-1fb7-a3c08bd35187@python.org> Hi all As part of a deal with Zach Ware at PyCon, I agreed that if he removed the Subversion dependency from our builds, I would set up daily Windows builds of Python. Zach did an excellent job, and so I am now following through on my half of the deal :) For a while I've been uploading the official releases to nuget.org. These packages can be installed with nuget.exe (latest version always available at https://aka.ms/nugetclidl), which is quickly becoming a standard tool in Microsoft's build toolsets. It's very much a CI-focused package manager, rather than a user-focused one, and CI on Windows was previously an area where it was difficult to use Python. See the official feed at https://www.nuget.org/packages/python, and related packages pythonx86, python2 and python2x86. For people looking for an official "no installer" version of Python for Windows, this is it. And since all the infrastructure was there already, I decided to publish daily builds in a similar way to myget.org: https://www.myget.org/feed/python/package/nuget/pythondaily To install the latest daily build, run nuget.exe with this command: nuget.exe pythondaily -Source https://www.myget.org/F/python/api/v3/index.json (Note that if you already have a "pythondaily" package in that directory, nuget will consider the requirement satisfied. As I said, it's meant for reproducible CI builds rather than users who want to update things in the least amount of keystrokes :) ) The sys.version string contains the short commit hash. Please include this string when reporting bugs in these builds. Also, only the amd64 Release build is available pre-built. >>> sys.version '3.7.0a0 (remotes/origin/master:733d0f63c, Aug 8 2017, 15:56:14) [MSC v.1900 64 bit (AMD64)]' Hopefully this is valuable for people who want to include daily builds in their own test runs or validate recent bug fixes. Cheers, Steve From larry.martell at gmail.com Tue Aug 8 12:37:19 2017 From: larry.martell at gmail.com (Larry Martell) Date: Tue, 8 Aug 2017 12:37:19 -0400 Subject: Validating regexp Message-ID: Anyone have any code or know of any packages for validating a regexp? I have an app that allows users to enter regexps for db searching. When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it causes downstream issues. I'd like to flag it at entry time. From rosuav at gmail.com Tue Aug 8 12:51:15 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 02:51:15 +1000 Subject: Validating regexp In-Reply-To: References: Message-ID: On Wed, Aug 9, 2017 at 2:37 AM, Larry Martell wrote: > Anyone have any code or know of any packages for validating a regexp? > > I have an app that allows users to enter regexps for db searching. > When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it > causes downstream issues. I'd like to flag it at entry time. re.compile()? Although I'm not sure that 'A|B|' is actually invalid. But re.compile("(") throws. ChrisA From python at mrabarnett.plus.com Tue Aug 8 12:56:23 2017 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 8 Aug 2017 17:56:23 +0100 Subject: Validating regexp In-Reply-To: References: Message-ID: <60f4d9d6-2b05-5c49-5c4f-c6e8abb130ef@mrabarnett.plus.com> On 2017-08-08 17:37, Larry Martell wrote: > Anyone have any code or know of any packages for validating a regexp? > > I have an app that allows users to enter regexps for db searching. > When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it > causes downstream issues. I'd like to flag it at entry time. > Couldn't you just try compile the regex and catch any exception? Also, in that way is 'A|B|' invalid? From larry.martell at gmail.com Tue Aug 8 12:57:49 2017 From: larry.martell at gmail.com (Larry Martell) Date: Tue, 8 Aug 2017 12:57:49 -0400 Subject: Validating regexp In-Reply-To: References: Message-ID: On Tue, Aug 8, 2017 at 12:51 PM, Chris Angelico wrote: > On Wed, Aug 9, 2017 at 2:37 AM, Larry Martell wrote: >> Anyone have any code or know of any packages for validating a regexp? >> >> I have an app that allows users to enter regexps for db searching. >> When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it >> causes downstream issues. I'd like to flag it at entry time. > > re.compile()? Although I'm not sure that 'A|B|' is actually invalid. > But re.compile("(") throws. Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty subexpression for regexp' I'd like to flag it before it gets to SQL. From skip.montanaro at gmail.com Tue Aug 8 13:00:11 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 8 Aug 2017 12:00:11 -0500 Subject: Validating regexp In-Reply-To: References: Message-ID: > I have an app that allows users to enter regexps for db searching. > When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it > causes downstream issues. I'd like to flag it at entry time. Just call re.compile(...) on it and catch any exceptions, modulo caveats about operating with unvalidated user input. Skip From larry.martell at gmail.com Tue Aug 8 13:06:23 2017 From: larry.martell at gmail.com (Larry Martell) Date: Tue, 8 Aug 2017 13:06:23 -0400 Subject: Validating regexp In-Reply-To: References: Message-ID: On Tue, Aug 8, 2017 at 12:57 PM, Larry Martell wrote: > On Tue, Aug 8, 2017 at 12:51 PM, Chris Angelico wrote: >> On Wed, Aug 9, 2017 at 2:37 AM, Larry Martell wrote: >>> Anyone have any code or know of any packages for validating a regexp? >>> >>> I have an app that allows users to enter regexps for db searching. >>> When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it >>> causes downstream issues. I'd like to flag it at entry time. >> >> re.compile()? Although I'm not sure that 'A|B|' is actually invalid. >> But re.compile("(") throws. > > Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty > subexpression for regexp' I'd like to flag it before it gets to SQL. I guess I will have to do a test query with it and catch the error. From rosuav at gmail.com Tue Aug 8 13:10:37 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 03:10:37 +1000 Subject: Validating regexp In-Reply-To: References: Message-ID: On Wed, Aug 9, 2017 at 2:57 AM, Larry Martell wrote: > On Tue, Aug 8, 2017 at 12:51 PM, Chris Angelico wrote: >> On Wed, Aug 9, 2017 at 2:37 AM, Larry Martell wrote: >>> Anyone have any code or know of any packages for validating a regexp? >>> >>> I have an app that allows users to enter regexps for db searching. >>> When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it >>> causes downstream issues. I'd like to flag it at entry time. >> >> re.compile()? Although I'm not sure that 'A|B|' is actually invalid. >> But re.compile("(") throws. > > Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty > subexpression for regexp' I'd like to flag it before it gets to SQL. Okay, so your definition of validity is "what MySQL will accept". In that case, I'd feed it to MySQL and see if it accepts it. Regexps are sufficiently varied that you really need to use the same engine for validation as for execution. ChrisA From jon+usenet at unequivocal.eu Tue Aug 8 13:31:58 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 8 Aug 2017 17:31:58 -0000 (UTC) Subject: Validating regexp References: Message-ID: On 2017-08-08, Chris Angelico wrote: > On Wed, Aug 9, 2017 at 2:57 AM, Larry Martell wrote: >> Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty >> subexpression for regexp' I'd like to flag it before it gets to SQL. > > Okay, so your definition of validity is "what MySQL will accept". In > that case, I'd feed it to MySQL and see if it accepts it. Regexps are > sufficiently varied that you really need to use the same engine for > validation as for execution. ... but bear in mind, there have been ways of doing denial-of-service attacks with valid-but-nasty regexps in the past, and I wouldn't want to rely on there not being any now. From p.f.moore at gmail.com Tue Aug 8 13:59:34 2017 From: p.f.moore at gmail.com (Paul Moore) Date: Tue, 8 Aug 2017 18:59:34 +0100 Subject: [Python-Dev] [ANN] Daily Windows builds of Python 3.x In-Reply-To: <2e89743a-4a08-d1df-1fb7-a3c08bd35187@python.org> References: <2e89743a-4a08-d1df-1fb7-a3c08bd35187@python.org> Message-ID: On 8 August 2017 at 17:21, Steve Dower wrote: > For a while I've been uploading the official releases to nuget.org. These > packages can be installed with nuget.exe (latest version always available at > https://aka.ms/nugetclidl), which is quickly becoming a standard tool in > Microsoft's build toolsets. It's very much a CI-focused package manager, > rather than a user-focused one, and CI on Windows was previously an area > where it was difficult to use Python. > > See the official feed at https://www.nuget.org/packages/python, and related > packages pythonx86, python2 and python2x86. > > For people looking for an official "no installer" version of Python for > Windows, this is it. I've been aware of these builds for a while, but wasn't 100% sure of the status of them. It would be really useful if they could be publicised more widely - if for no other reason than to steer people towards these rather than the embedded distribution when these are more appropriate. But regardless of that minor point, the availability of these builds is really nice. > And since all the infrastructure was there already, I decided to publish > daily builds in a similar way to myget.org: > > https://www.myget.org/feed/python/package/nuget/pythondaily > > To install the latest daily build, run nuget.exe with this command: > > nuget.exe pythondaily -Source > https://www.myget.org/F/python/api/v3/index.json > > (Note that if you already have a "pythondaily" package in that directory, > nuget will consider the requirement satisfied. As I said, it's meant for > reproducible CI builds rather than users who want to update things in the > least amount of keystrokes :) ) > > The sys.version string contains the short commit hash. Please include this > string when reporting bugs in these builds. Also, only the amd64 Release > build is available pre-built. > > >>> sys.version > '3.7.0a0 (remotes/origin/master:733d0f63c, Aug 8 2017, 15:56:14) [MSC > v.1900 64 bit (AMD64)]' > > Hopefully this is valuable for people who want to include daily builds in > their own test runs or validate recent bug fixes. Nice! I can imagine these being a really useful resource for people wanting to (say) test against the development version in their Appveyor builds. Thanks for putting the effort into producing these :-) Paul From bgailer at gmail.com Tue Aug 8 15:55:26 2017 From: bgailer at gmail.com (Bob Gailer) Date: Tue, 8 Aug 2017 15:55:26 -0400 Subject: Planning a Python Course for Beginners In-Reply-To: References: Message-ID: On Aug 8, 2017 10:20 AM, "Stefan Ram" wrote: > > I am planning a Python course. > > I started by writing the course akin to courses I gave > in other languages, that means, the course starts roughly > with these topics: > > - number and string literals > - types of number and string literals > (just giving the names ?int?, ?float?, and ?string?) > - using simple predefined operators (+, -, *, /) > (including 2*"a" and "a"+"b") > - calling simple predefined functions (len, type, ...) > > . This is a little bit boring however and might not > show off Python's strength early in the course. > > So, I now think that maybe I should start to also > include list (like > > [1,2,3] > > ) right from the start. A list conceptually is not > much more difficult than a string since a string > "abc" resembles a list ["a","b","c"]. I.e., the > course then would start as follows: > > - number, string, and list literals > - types of number, string and list literals > (just giving the names ?int?, ?float?, ?string?, > and ?list?) > - using simple predefined operators (+, -, *, /) > (including 2*"a", "a"+"b", 2*["a"], and [1]+[2]) > - calling simple predefined functions (len, type, ...) > > However, once the box has been opened, what else > to let out? What about tuples (like > > (1,2,3) > > ). Should I also teach tuples right from the start? > > But then how to explain to beginners why two > different types (lists AND tuples) are needed for > the concept of a linear arrangement of things? > > Are there any other very simple things that > I have missed and that should be covered very > early in a Python course? IMHO its a good idea to introduce conversational programming early. Start with input() and print() then int(), if, while, break . Add one item at a time. This will be more interesting and useful than a bunch of data types and operators, and answer a lot of questions that otherwise show up on the help and tutor lists. Also explain tracebacks. None of the above in great detail; just let students know there is more detail to come later > > (Especially things that can show off fantastic > Python features that are missing from other > programming languages, but still only using > literals, operators and function calls.) I think program flow is more important than fantastic or unique > > -- > https://mail.python.org/mailman/listinfo/python-list From arequipeno at gmail.com Tue Aug 8 20:08:16 2017 From: arequipeno at gmail.com (Ian Pilcher) Date: Tue, 8 Aug 2017 19:08:16 -0500 Subject: __new__ and __init__ - why does this work? Message-ID: I have created a class to provide a "hash consing"[1] set. class UniqueSet(frozenset): _registry = dict() def __new__(cls, *args, **kwargs): set = frozenset(*args, **kwargs) try: return UniqueSet._registry[set] except KeyError: self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) UniqueSet._registry[set] = self return self def __init__(self, *args, **kwargs): pass I can't figure out how it works, though. In particular, I can't figure out how the call to __new__ actually initializes the set (since my __init__ never calls the superclass __init__). Is this a particular behavior of frozenset, or am I missing something about the way that __new__ and __init__ interact? -- ======================================================================== Ian Pilcher arequipeno at gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ======================================================================== From cs at cskk.id.au Tue Aug 8 22:03:08 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Wed, 9 Aug 2017 12:03:08 +1000 Subject: Validating regexp In-Reply-To: References: Message-ID: <20170809020308.GA50699@cskk.homeip.net> On 08Aug2017 17:31, Jon Ribbens wrote: >On 2017-08-08, Chris Angelico wrote: >> On Wed, Aug 9, 2017 at 2:57 AM, Larry Martell wrote: >>> Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty >>> subexpression for regexp' I'd like to flag it before it gets to SQL. >> >> Okay, so your definition of validity is "what MySQL will accept". In >> that case, I'd feed it to MySQL and see if it accepts it. Regexps are >> sufficiently varied that you really need to use the same engine for >> validation as for execution. > >... but bear in mind, there have been ways of doing denial-of-service >attacks with valid-but-nasty regexps in the past, and I wouldn't want >to rely on there not being any now. The ones I've seen still require some input length (I'm thinking exponential rematch backoff stuff here). I suspect that if your test query matches the RE against a fixed empty string it is hard to be exploited. i.e. I think most of this stuff isn't expensive in terms of compiling the regexp but in executing it against text. Happy to hear to falsifications to my beliefs here. Cheers, Cameron Simpson (formerly cs at zip.com.au) From ian.g.kelly at gmail.com Tue Aug 8 23:19:30 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 8 Aug 2017 21:19:30 -0600 Subject: __new__ and __init__ - why does this work? In-Reply-To: References: Message-ID: On Tue, Aug 8, 2017 at 6:08 PM, Ian Pilcher wrote: > I have created a class to provide a "hash consing"[1] set. > > class UniqueSet(frozenset): > > _registry = dict() > > def __new__(cls, *args, **kwargs): > set = frozenset(*args, **kwargs) > try: > return UniqueSet._registry[set] > except KeyError: > self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) > UniqueSet._registry[set] = self > return self > > def __init__(self, *args, **kwargs): > pass > > I can't figure out how it works, though. In particular, I can't figure > out how the call to __new__ actually initializes the set (since my > __init__ never calls the superclass __init__). > > Is this a particular behavior of frozenset, or am I missing something > about the way that __new__ and __init__ interact? It's initialized by the superclass call to __new__. frozenset is immutable, and __init__ methods of immutable types generally don't do anything (if they could, then they wouldn't be immutable), which is why it doesn't really matter that you didn't call it. At the same time, it generally doesn't hurt to call it, and you probably shouldn't even have an override of __init__ here if it doesn't do anything. It seems a bit inefficient that you create *two* sets in __new__ and then map one of them to the other in your registry. Why not just create the UniqueSet and then map it to itself if it's not already registered? Something like this (untested): def __new__(cls, *args, **kwargs): self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) return UniqueSet._registry.setdefault(self, self) From larry at hastings.org Wed Aug 9 03:31:12 2017 From: larry at hastings.org (Larry Hastings) Date: Wed, 9 Aug 2017 00:31:12 -0700 Subject: [RELEASED] Python 3.4.7 is now available Message-ID: <513e80d5-170f-21f8-1429-de86a6752169@hastings.org> On behalf of the Python development community and the Python 3.4 release team, I'm pleased to announce the availability of Python 3.4.7. Python 3.4 is now in "security fixes only" mode. This is the final stage of support for Python 3.4. Python 3.4 now only receives security fixes, not bug fixes, and Python 3.4 releases are source code only--no more official binary installers will be produced. You can find Python 3.4.7 here: https://www.python.org/downloads/release/python-347/ Happy Pythoning, //arry/ From __peter__ at web.de Wed Aug 9 04:14:34 2017 From: __peter__ at web.de (Peter Otten) Date: Wed, 09 Aug 2017 10:14:34 +0200 Subject: __new__ and __init__ - why does this work? References: Message-ID: Ian Pilcher wrote: > I have created a class to provide a "hash consing"[1] set. > > class UniqueSet(frozenset): > > _registry = dict() > > def __new__(cls, *args, **kwargs): > set = frozenset(*args, **kwargs) > try: > return UniqueSet._registry[set] > except KeyError: > self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) > UniqueSet._registry[set] = self > return self > > def __init__(self, *args, **kwargs): > pass > > I can't figure out how it works, though. In particular, I can't figure > out how the call to __new__ actually initializes the set (since my > __init__ never calls the superclass __init__). > > Is this a particular behavior of frozenset, or am I missing something > about the way that __new__ and __init__ interact? I think __init__() is called to initialise the object after it has been created with __new__(), roughly the following, run by the metaclass: obj = UniqueSet_.__new__(UniqueSet, ...) if isinstance(obj, UniqueSet): obj.__init__(...) As Ian says, for immutable classes __init__() usually does nothing, as by definition the instance cannot be changed once created: >>> t = tuple.__new__(tuple, "ab") >>> t ('a', 'b') >>> t.__init__(None) >>> t.__init__(x=42) >>> t.__init__("whatever", "you", "like") >>> t ('a', 'b') I'm a bit surprised that the signature isn't restricted to a single positional argument... From saurabh.hooda at gmail.com Wed Aug 9 04:29:08 2017 From: saurabh.hooda at gmail.com (Saurabh Hooda) Date: Wed, 9 Aug 2017 01:29:08 -0700 (PDT) Subject: Are these tutorials the best tutorials for learning Python? Message-ID: Hello, https://hackr.io/tutorials/learn-python proclaims that it's a collection of the best tutorials recommended by the programming community. Do you agree? Is there any better tutorial? Thanks in advance, Saurabh Hooda From ben+python at benfinney.id.au Wed Aug 9 05:11:18 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 09 Aug 2017 19:11:18 +1000 Subject: Are these tutorials the best tutorials for learning Python? References: Message-ID: <85shh1jebt.fsf@benfinney.id.au> Saurabh Hooda writes: > https://hackr.io/tutorials/learn-python proclaims that it's a > collection of the best tutorials recommended by the programming > community. Do you agree? I agree that those are recommended by the programming community. Do I agree those are the best? I don't have a good metric of ?best?. > Is there any better tutorial? I think ?better? makes sense only when we know what it's better *for*. And, when talking about materials for learning: better for *whom*, which *what* learning goals. Can you specify those? -- \ ?Oh, I realize it's a penny here and a penny there, but look at | `\ me: I've worked myself up from nothing to a state of extreme | _o__) poverty.? ?Groucho Marx | Ben Finney From kwpolska at gmail.com Wed Aug 9 05:12:17 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Wed, 9 Aug 2017 11:12:17 +0200 Subject: Are these tutorials the best tutorials for learning Python? In-Reply-To: References: Message-ID: On 9 August 2017 at 10:29, Saurabh Hooda wrote: > Hello, > [advertisement] proclaims that it's a collection of the best tutorials recommended by the programming community. Do you agree? Is there any better tutorial? > > Thanks in advance, > Saurabh Hooda > -- > https://mail.python.org/mailman/listinfo/python-list So, I started by writing my opinion of those recommendations, and that the ?community? is very small (<1k Twitter followers, 2.7k Facebook likes). But then I went to the ?About Us? page, and found your name and your profile picture there. Native advertising is evil and rude. You made it sound as if you were an user, genuinely looking for help in learning Python. But in reality, you just want people to visit your website, get ad revenue and potentially get people to join your community. Shame on you. --- Your top recommendation is the worst Python tutorial in existence. Learn Python The Hard Way is not worth the $30 price tag. It?s discouragingly slow and boring. 19% of the book is printing. It makes you memorize truth tables instead of understanding logic. It often makes you Google things instead of teaching them. The author published an article full of FUD against Python 3 (explained: https://eev.ee/blog/2016/11/23/a-rebuttal-for-python-3/ )? and released a beta version of his Python 3 book shortly afterwards. You also have a lot of Python 2 content on the site. Content that teaches a legacy language. My recommendations: * Think Python, 2nd edition: http://greenteapress.com/wp/think-python-2e/ * Automate the Boring Stuff with Python: https://automatetheboringstuff.com/ * official Python tutorial, if you can already program, or to complement the other two: https://docs.python.org/3/tutorial/index.html All three are free to read online. -- Chris Warrick PGP: 5EAAEA16 From learning at sriramsrinivasan.in Wed Aug 9 05:35:24 2017 From: learning at sriramsrinivasan.in (learning at sriramsrinivasan.in) Date: Wed, 9 Aug 2017 15:05:24 +0530 Subject: Are these tutorials the best tutorials for learning Python? In-Reply-To: References: Message-ID: <011601d310f2$d42faa60$7c8eff20$@sriramsrinivasan.in> Hi Saurabh, those are good for ones to become proficient in writing Python Code. Regards, Sriram Srinivasan www.sriramsrinivasan.in -----Original Message----- From: Python-list [mailto:python-list-bounces+learning=sriramsrinivasan.in at python.org] On Behalf Of Saurabh Hooda Sent: 09 August 2017 13:59 To: python-list at python.org Subject: Are these tutorials the best tutorials for learning Python? Hello, https://hackr.io/tutorials/learn-python proclaims that it's a collection of the best tutorials recommended by the programming community. Do you agree? Is there any better tutorial? Thanks in advance, Saurabh Hooda -- https://mail.python.org/mailman/listinfo/python-list --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus From saurabh.hooda at gmail.com Wed Aug 9 05:36:52 2017 From: saurabh.hooda at gmail.com (Saurabh Hooda) Date: Wed, 9 Aug 2017 02:36:52 -0700 (PDT) Subject: [Repost] Are these tutorials the best tutorials for learning Python? Message-ID: <82619e14-2ee5-4e2a-bbc0-1aae7cb80c97@googlegroups.com> Hello, I am the co-founder of Hackr.io, a community where developers can share and recommend the tutorials they have found useful. This is the page for Python tutorials: https://hackr.io/tutorials/learn-python I am interested in listening to your feedback on how we can improve Hackr.io Python tutorials? Are the tutorials listed for Python good ones? Am all ears. Thanks in advance, Saurabh Hooda PS: Reposting because in the first post I didn't mention that I am the co-founder. One group-user highlighted that it is wrong and now am reposting it with the edit. From marko at pacujo.net Wed Aug 9 05:50:23 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 12:50:23 +0300 Subject: Planning a Python Course for Beginners References: Message-ID: <87o9rpqdcw.fsf@elektro.pacujo.net> Dennis Lee Bieber : > Tabs are logical entities indicating structure and should always be > used! I wrote an entire database program using only tabs. Marko From marko at pacujo.net Wed Aug 9 05:51:35 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 12:51:35 +0300 Subject: Planning a Python Course for Beginners References: Message-ID: <87k22dqdaw.fsf@elektro.pacujo.net> Dennis Lee Bieber : > Then there is the facet that tuples (being unmutable) can be used as > keys into a dictionary... Mutable objects can be used as keys into a dictionary. Marko From rosuav at gmail.com Wed Aug 9 06:05:23 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 20:05:23 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <87k22dqdaw.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> Message-ID: On Wed, Aug 9, 2017 at 7:51 PM, Marko Rauhamaa wrote: > Dennis Lee Bieber : > >> Then there is the facet that tuples (being unmutable) can be used as >> keys into a dictionary... > > Mutable objects can be used as keys into a dictionary. Only when the objects' mutability does not affect their values. ChrisA From peter.heitzer at rz.uni-regensburg.de Wed Aug 9 06:13:47 2017 From: peter.heitzer at rz.uni-regensburg.de (Peter Heitzer) Date: 9 Aug 2017 10:13:47 GMT Subject: Validating regexp References: Message-ID: Larry Martell wrote: >On Tue, Aug 8, 2017 at 12:51 PM, Chris Angelico wrote: >> On Wed, Aug 9, 2017 at 2:37 AM, Larry Martell wrote: >>> Anyone have any code or know of any packages for validating a regexp? >>> >>> I have an app that allows users to enter regexps for db searching. >>> When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it >>> causes downstream issues. I'd like to flag it at entry time. >> >> re.compile()? Although I'm not sure that 'A|B|' is actually invalid. >> But re.compile("(") throws. >Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty >subexpression for regexp' I'd like to flag it before it gets to SQL. Then you need to do a real sql query with the regex and check if it throws. -- Dipl.-Inform(FH) Peter Heitzer, peter.heitzer at rz.uni-regensburg.de From marko at pacujo.net Wed Aug 9 06:38:58 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 13:38:58 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> Message-ID: <87efslqb3x.fsf@elektro.pacujo.net> Chris Angelico : > On Wed, Aug 9, 2017 at 7:51 PM, Marko Rauhamaa wrote: >> Mutable objects can be used as keys into a dictionary. > > Only when the objects' mutability does not affect their values. Up to equality. The objects can carry all kinds of mutable payload as long as __hash__() and __eq__() don't change with it. And Python doesn't enforce this in any way except for lists. That's somewhat unfortunate since sometimes you really would like an immutable (or rather, no-longer-mutable) list to act as a key. Marko From alister.ware at ntlworld.com Wed Aug 9 06:40:57 2017 From: alister.ware at ntlworld.com (alister) Date: Wed, 09 Aug 2017 10:40:57 GMT Subject: Planning a Python Course for Beginners References: Message-ID: On Tue, 08 Aug 2017 14:19:53 +0000, Stefan Ram wrote: > I am planning a Python course. > > I started by writing the course akin to courses I gave in other > languages, that means, the course starts roughly with these topics: > > - number and string literals - types of number and string literals > (just giving the names ?int?, ?float?, and ?string?) > - using simple predefined operators (+, -, *, /) > (including 2*"a" and "a"+"b") > - calling simple predefined functions (len, type, ...) > > . This is a little bit boring however and might not show off Python's > strength early in the course. > > So, I now think that maybe I should start to also include list (like > > [1,2,3] > > ) right from the start. A list conceptually is not much more difficult > than a string since a string "abc" resembles a list ["a","b","c"]. > I.e., the course then would start as follows: > > - number, string, and list literals - types of number, string and list > literals > (just giving the names ?int?, ?float?, ?string?, and ?list?) > - using simple predefined operators (+, -, *, /) > (including 2*"a", "a"+"b", 2*["a"], and [1]+[2]) > - calling simple predefined functions (len, type, ...) > > However, once the box has been opened, what else to let out? What > about tuples (like > > (1,2,3) > > ). Should I also teach tuples right from the start? > > But then how to explain to beginners why two different types (lists > AND tuples) are needed for the concept of a linear arrangement of > things? > > Are there any other very simple things that I have missed and that > should be covered very early in a Python course? > > (Especially things that can show off fantastic Python features that > are missing from other programming languages, but still only using > literals, operators and function calls.) if these are beginners with no basic programming knowledge then try not to confuse them with anything unduly complicated, I would even go so far as to start with psuedo code on a pen & paper processor & only introduce the concepts of different data types only when they have progressed to the point that they need to know. -- Round Numbers are always false. -- Samuel Johnson From jon+usenet at unequivocal.eu Wed Aug 9 06:46:19 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 9 Aug 2017 10:46:19 -0000 (UTC) Subject: Validating regexp References: <20170809020308.GA50699@cskk.homeip.net> Message-ID: On 2017-08-09, Cameron Simpson wrote: > On 08Aug2017 17:31, Jon Ribbens wrote: >>On 2017-08-08, Chris Angelico wrote: >>> On Wed, Aug 9, 2017 at 2:57 AM, Larry Martell wrote: >>>> Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty >>>> subexpression for regexp' I'd like to flag it before it gets to SQL. >>> >>> Okay, so your definition of validity is "what MySQL will accept". In >>> that case, I'd feed it to MySQL and see if it accepts it. Regexps are >>> sufficiently varied that you really need to use the same engine for >>> validation as for execution. >> >>... but bear in mind, there have been ways of doing denial-of-service >>attacks with valid-but-nasty regexps in the past, and I wouldn't want >>to rely on there not being any now. > > The ones I've seen still require some input length (I'm thinking exponential > rematch backoff stuff here). I suspect that if your test query matches the RE > against a fixed empty string it is hard to be exploited. i.e. I think most of > this stuff isn't expensive in terms of compiling the regexp but in > executing it against text. Well yes, but presumably if the OP is receiving regexps from users they will be executed against text sooner or later. From rosuav at gmail.com Wed Aug 9 06:59:18 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 20:59:18 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <87efslqb3x.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> Message-ID: On Wed, Aug 9, 2017 at 8:38 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Wed, Aug 9, 2017 at 7:51 PM, Marko Rauhamaa wrote: >>> Mutable objects can be used as keys into a dictionary. >> >> Only when the objects' mutability does not affect their values. > > Up to equality. The objects can carry all kinds of mutable payload as > long as __hash__() and __eq__() don't change with it. Which means that its value won't change. That's what I said. Two things will be equal regardless of that metadata. > And Python doesn't enforce this in any way except for lists. That's > somewhat unfortunate since sometimes you really would like an immutable > (or rather, no-longer-mutable) list to act as a key. Then make a tuple out of it. Job done. You're trying to say that its value won't now change. ChrisA From duane.kaufman at gmail.com Wed Aug 9 07:41:30 2017 From: duane.kaufman at gmail.com (TheSeeker) Date: Wed, 9 Aug 2017 04:41:30 -0700 (PDT) Subject: Validating regexp In-Reply-To: References: Message-ID: <19108673-269a-4d5a-b29b-7de5adadd19f@googlegroups.com> On Tuesday, August 8, 2017 at 11:38:34 AM UTC-5, Larry.... at gmail.com wrote: > Anyone have any code or know of any packages for validating a regexp? > > I have an app that allows users to enter regexps for db searching. > When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it > causes downstream issues. I'd like to flag it at entry time. Hello, IIRC, there is a built-in regexp builder/tester in Boa Constructor: http://boa-constructor.sourceforge.net/ I used this a long time ago. Duane From marko at pacujo.net Wed Aug 9 08:00:15 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 15:00:15 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> Message-ID: <873791q7cg.fsf@elektro.pacujo.net> Chris Angelico : > On Wed, Aug 9, 2017 at 8:38 PM, Marko Rauhamaa wrote: >> Chris Angelico : >> >>> On Wed, Aug 9, 2017 at 7:51 PM, Marko Rauhamaa wrote: >>>> Mutable objects can be used as keys into a dictionary. >>> >>> Only when the objects' mutability does not affect their values. >> >> Up to equality. The objects can carry all kinds of mutable payload as >> long as __hash__() and __eq__() don't change with it. > > Which means that its value won't change. That's what I said. Two > things will be equal regardless of that metadata. In relational-database terms, your "value" is the primary key and your "metadata" is the rest of the columns. >> And Python doesn't enforce this in any way except for lists. That's >> somewhat unfortunate since sometimes you really would like an >> immutable (or rather, no-longer-mutable) list to act as a key. > > Then make a tuple out of it. Job done. You're trying to say that its > value won't now change. Yeah, when there's a will, there's a way. Marko From larry.martell at gmail.com Wed Aug 9 08:43:53 2017 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 9 Aug 2017 08:43:53 -0400 Subject: Planning a Python Course for Beginners In-Reply-To: <873791q7cg.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> Message-ID: On Wed, Aug 9, 2017 at 8:00 AM, Marko Rauhamaa wrote: > Yeah, when there's a will, there's a way. My Dad used to say "Where there's a will, there's relatives." From larry.martell at gmail.com Wed Aug 9 08:44:23 2017 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 9 Aug 2017 08:44:23 -0400 Subject: Validating regexp In-Reply-To: References: Message-ID: On Wed, Aug 9, 2017 at 6:13 AM, Peter Heitzer wrote: > Larry Martell wrote: >>On Tue, Aug 8, 2017 at 12:51 PM, Chris Angelico wrote: >>> On Wed, Aug 9, 2017 at 2:37 AM, Larry Martell wrote: >>>> Anyone have any code or know of any packages for validating a regexp? >>>> >>>> I have an app that allows users to enter regexps for db searching. >>>> When a user enters an invalid one (e.g. 'A|B|' is one I just saw) it >>>> causes downstream issues. I'd like to flag it at entry time. >>> >>> re.compile()? Although I'm not sure that 'A|B|' is actually invalid. >>> But re.compile("(") throws. > >>Yeah, it does not throw for 'A|B|' - but mysql chokes on it with empty >>subexpression for regexp' I'd like to flag it before it gets to SQL. > > Then you need to do a real sql query with the regex and check if it throws. Yes, that is what I ended up doing. From steve+python at pearwood.info Wed Aug 9 08:54:00 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 09 Aug 2017 22:54:00 +1000 Subject: __new__ and __init__ - why does this work? References: Message-ID: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> On Wed, 9 Aug 2017 10:08 am, Ian Pilcher wrote: > I have created a class to provide a "hash consing"[1] set. Your footnote for [1] appears to be missing. What's a hash consing set? It appears to be nothing more than frozen sets which you put in a cache so as to confuse identity and value *wink* I doubt very much you're actually saving any time, since you create a temporary frozen set before returning the one in the cache. You might save some memory though. > class UniqueSet(frozenset): > _registry = dict() > def __new__(cls, *args, **kwargs): > set = frozenset(*args, **kwargs) > try: > return UniqueSet._registry[set] > except KeyError: > self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) > UniqueSet._registry[set] = self > return self > > def __init__(self, *args, **kwargs): > pass > > I can't figure out how it works, though. In particular, I can't figure > out how the call to __new__ actually initializes the set (since my > __init__ never calls the superclass __init__). Since frozensets are immutable, they have to be initialised in the __new__ constructor, because by the time __init__ is called the instance is immutable and cannot be updated. Your call to super() above creates a new instance. Its effectively a frozenset, except that the class of it is set to your subclass ("cls", in this case). So all the initalisation of the frozenset happens inside frozenset.__new__, which you call via super(). Your __init__ method does nothing. Get rid of it and save two lines of code :-) Also, there is at least theoretically the vague possibility that frozenset.__init__ does something (phones home to Guido?) so you shouldn't block it if you don't need to. > Is this a particular behavior of frozenset, or am I missing something > about the way that __new__ and __init__ interact? Its not just frozenset. Any mutable class must initialise its instances in __new__. Immutable classes can use either __new__ or __init__, but for historical reasons typically use __init__. The way __new__ and __init__ are called is: (1) __new__ is called; (2) if it returns an instance of cls, then instance.__init__ is called (It is not mandatory for __new__ to return a new instance of its class; it can return whatever you like. That is a feature, and there are occasional uses for it.) -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 9 08:55:02 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 09 Aug 2017 22:55:02 +1000 Subject: Planning a Python Course for Beginners References: Message-ID: <598b0628$0$1620$c3e8da3$5496439d@news.astraweb.com> On Wed, 9 Aug 2017 02:19 pm, Dennis Lee Bieber wrote: > On Tue, 8 Aug 2017 15:38:42 +0000 (UTC), Grant Edwards > declaimed the following: > >>On 2017-08-08, Peter Heitzer wrote: [...] >>> The differences between blanks and tabs :-) >> >>You've misspelled "Tabs are evil and should never be used". ;) > > > Tabs are logical entities indicating structure and should always be used! > Amen to that brother! -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 9 08:58:39 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 09 Aug 2017 22:58:39 +1000 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> Message-ID: <598b0701$0$1620$c3e8da3$5496439d@news.astraweb.com> On Wed, 9 Aug 2017 07:51 pm, Marko Rauhamaa wrote: > Dennis Lee Bieber : > >> Then there is the facet that tuples (being unmutable) can be used as >> keys into a dictionary... > > Mutable objects can be used as keys into a dictionary. Indeed. And people can also put their hand into a fire in order to pull out a red-hot burning coal. I wouldn't recommend either, at least not under uncontrolled conditions. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 9 08:59:35 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 09 Aug 2017 22:59:35 +1000 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> Message-ID: <598b073a$0$1620$c3e8da3$5496439d@news.astraweb.com> On Wed, 9 Aug 2017 08:38 pm, Marko Rauhamaa wrote: > sometimes you really would like an immutable > (or rather, no-longer-mutable) list to act as a key. There's a word for frozen list: "tuple". :-) -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Wed Aug 9 09:24:46 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 9 Aug 2017 23:24:46 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <873791q7cg.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> Message-ID: On Wed, Aug 9, 2017 at 10:00 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> Which means that its value won't change. That's what I said. Two >> things will be equal regardless of that metadata. > > In relational-database terms, your "value" is the primary key and your > "metadata" is the rest of the columns. I would say the primary key is the "identity" and the rest of the columns are the "value". But if you're defining "value" solely by the PK, then you have to ask yourself what you're using this in a dictionary for - are you going to construct multiple objects representing the same underlying database row, and expect them to compare equal? And if they're equal without being identical, how do you know which one of them actually corresponds to the database? Down this path lies a form of madness that I want nothing to do with. >>> And Python doesn't enforce this in any way except for lists. That's >>> somewhat unfortunate since sometimes you really would like an >>> immutable (or rather, no-longer-mutable) list to act as a key. >> >> Then make a tuple out of it. Job done. You're trying to say that its >> value won't now change. > > Yeah, when there's a will, there's a way. I don't understand your comment. Do you mean that if someone wants to change it, s/he will? Because that's not really the point. If you're declaring that a list can now be safely compared by value, you don't want it to be mutable in any way. That's what a tuple is for. ChrisA From marko at pacujo.net Wed Aug 9 09:25:17 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 16:25:17 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <598b073a$0$1620$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87wp6cq3eq.fsf@elektro.pacujo.net> ram at zedat.fu-berlin.de (Stefan Ram): > Steve D'Aprano writes: >>There's a word for frozen list: "tuple". > > Yes, but one should not forget that a tuple > can contain mutable entries (such as lists). Not when used as keys: >>> hash(([], [])) Traceback (most recent call last): File "", line 1, in TypeError: unhashable type: 'list' Marko From tdldev at gmail.com Wed Aug 9 09:41:45 2017 From: tdldev at gmail.com (Verde Denim) Date: Wed, 9 Aug 2017 09:41:45 -0400 Subject: Planning a Python Course for Beginners In-Reply-To: <87wp6cq3eq.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <598b073a$0$1620$c3e8da3$5496439d@news.astraweb.com> <87wp6cq3eq.fsf@elektro.pacujo.net> Message-ID: <517fda12-e0ee-338e-8e8b-34721b9444ca@gmail.com> On 8/9/2017 9:25 AM, Marko Rauhamaa wrote: > ram at zedat.fu-berlin.de (Stefan Ram): > >> Steve D'Aprano writes: >>> There's a word for frozen list: "tuple". >> Yes, but one should not forget that a tuple >> can contain mutable entries (such as lists). > Not when used as keys: > > >>> hash(([], [])) > Traceback (most recent call last): > File "", line 1, in > TypeError: unhashable type: 'list' > > > Marko Hence the word 'can' and not 'will' or 'must' or 'shall' ... --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus From grant.b.edwards at gmail.com Wed Aug 9 09:42:31 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 9 Aug 2017 13:42:31 +0000 (UTC) Subject: Are these tutorials the best tutorials for learning Python? References: Message-ID: On 2017-08-09, Chris Warrick wrote: > On 9 August 2017 at 10:29, Saurabh Hooda wrote: >> Hello, >> [advertisement] > So, I started by writing my opinion of those recommendations, and that > the ?community? is very small (<1k Twitter followers, 2.7k Facebook > likes). But then I went to the ?About Us? page, and found your name > and your profile picture there. Native advertising is evil and rude. Just plonk posts from google-groups. Replying to them just punishes those of us who have already learned that lesson. -- Grant Edwards grant.b.edwards Yow! RHAPSODY in Glue! at gmail.com From marko at pacujo.net Wed Aug 9 09:46:05 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 16:46:05 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> Message-ID: <87shh0q2g2.fsf@elektro.pacujo.net> Chris Angelico : > On Wed, Aug 9, 2017 at 10:00 PM, Marko Rauhamaa wrote: >> Chris Angelico : >> >>> Which means that its value won't change. That's what I said. Two >>> things will be equal regardless of that metadata. >> >> In relational-database terms, your "value" is the primary key and >> your "metadata" is the rest of the columns. > > I would say the primary key is the "identity" and the rest of the > columns are the "value". Your response illustrates why you and I are not yet on the same page on this. Typically, an object's equality is simply the "is" relation. The only thing remaining for its usability as a key is a hash method. In fact, just defining: def __hash__(self): return 0 will technically make any class applicable as a key or set member. The interesting fields of the object (which you disparagingly referred to as "metadata") don't need to participate in the calculation of the hash. You ought to pick the maximal collection of immutable fields as a basis of your hash, and you are all set (no pun intended). > But if you're defining "value" solely by the PK, then you have to ask > yourself what you're using this in a dictionary for - are you going to > construct multiple objects representing the same underlying database > row, and expect them to compare equal? Let's leave the relational world and return to objects. Really, the most obvious use case for hashed objects is their membership in a set. For example: invitees = set(self.bff) invitees |= self.classmates() invitees |= self.relatives() >>>> And Python doesn't enforce this in any way except for lists. That's >>>> somewhat unfortunate since sometimes you really would like an >>>> immutable (or rather, no-longer-mutable) list to act as a key. >>> >>> Then make a tuple out of it. Job done. You're trying to say that its >>> value won't now change. >> >> Yeah, when there's a will, there's a way. > > I don't understand your comment. Do you mean that if someone wants to > change it, s/he will? No. I mean coercing lists to tuples can be quite a hefty operation. On the other hand, so could hashing a list unless the value is memoized. More importantly, tuple(collection) goes against the grain of what a tuple is. Tuples are not collections. In particular, tuples in a given role ordinarily have the same arity. Marko From rosuav at gmail.com Wed Aug 9 10:07:41 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 10 Aug 2017 00:07:41 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <87shh0q2g2.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> Message-ID: On Wed, Aug 9, 2017 at 11:46 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Wed, Aug 9, 2017 at 10:00 PM, Marko Rauhamaa wrote: >>> Chris Angelico : >>> >>>> Which means that its value won't change. That's what I said. Two >>>> things will be equal regardless of that metadata. >>> >>> In relational-database terms, your "value" is the primary key and >>> your "metadata" is the rest of the columns. >> >> I would say the primary key is the "identity" and the rest of the >> columns are the "value". > > Your response illustrates why you and I are not yet on the same page on > this. > > Typically, an object's equality is simply the "is" relation. The only > thing remaining for its usability as a key is a hash method. In fact, > just defining: > > def __hash__(self): > return 0 > > will technically make any class applicable as a key or set member. Yes, at the cost of making all your set operations into linear searches. Basically, if all your objects have the same hashes, you might as well use lists instead of sets, except that lists don't have the methods/operators you want. > The interesting fields of the object (which you disparagingly referred > to as "metadata") don't need to participate in the calculation of the > hash. You ought to pick the maximal collection of immutable fields as a > basis of your hash, and you are all set (no pun intended). The rules are (1) two objects that compare equal (__eq__) MUST have the same hash; and (2) an object's hash must never change. Also, for efficiency's sake, objects that compare unequal should ideally have different hashes. That's why I refer to it as metadata; it's not allowed to be part of the object's value, because two objects MUST compare equal even if those other fields change. Can you give me a real-world example of where two objects are equal but have important attributes that differ? >> But if you're defining "value" solely by the PK, then you have to ask >> yourself what you're using this in a dictionary for - are you going to >> construct multiple objects representing the same underlying database >> row, and expect them to compare equal? > > Let's leave the relational world and return to objects. > > Really, the most obvious use case for hashed objects is their membership > in a set. For example: > > invitees = set(self.bff) > invitees |= self.classmates() > invitees |= self.relatives() Okay. So you should define value by object identity - NOT any sort of external primary key. That goes completely against your original statement, which I shall quote again: >>> In relational-database terms, your "value" is the primary key and >>> your "metadata" is the rest of the columns. If there is any possibility that you could have two objects in memory with the same primary key but other attributes different, you'd have major MAJOR problems with this kind of set operation. The best solution would be to use the IDs themselves (as integers) in the set, and ignore the whole question of identity and value. ChrisA From steve+python at pearwood.info Wed Aug 9 11:14:46 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 10 Aug 2017 01:14:46 +1000 Subject: Are these tutorials the best tutorials for learning Python? References: Message-ID: <598b26e8$0$1604$c3e8da3$5496439d@news.astraweb.com> On Wed, 9 Aug 2017 07:12 pm, Chris Warrick wrote: > So, I started by writing my opinion of those recommendations, and that > the ?community? is very small (<1k Twitter followers, 2.7k Facebook > likes). But then I went to the ?About Us? page, and found your name > and your profile picture there. Native advertising is evil and rude. > You made it sound as if you were an user, genuinely looking for help > in learning Python. But in reality, you just want people to visit your > website, get ad revenue and potentially get people to join your > community. > > Shame on you. Why is this shameful? Why shouldn't people make money from their Python expertise, if they can? Do you oppose people who get paid to program in Python? If you're opposed to advertising, use an ad blocker, or just avoid the site. So long as the website isn't *exploitative* (ripping off other people's content without providing any added value) there is nothing wrong with promoting it here. It is on-topic, and if it provides some added value (not just a link farm), doesn't serve malware, then let it compete for eyeballs and hearts and minds on its merits. > Your top recommendation is the worst Python tutorial in existence. > > Learn Python The Hard Way is not worth the $30 price tag. Well, that's one opinion. I also happen to agree with it. I don't understand why "The Hard Way" books have such a devoted following. Perhaps it is a programmer's machismo thing -- if programming is hard to do, then it should be hard to learn as well. [...] > You also have a lot of Python 2 content on the site. Content that > teaches a legacy language. Python 2 is the same language as Python 3. Let's not spread FUD that they are different languages. They are minor variant dialects of the same language. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 9 11:19:32 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 10 Aug 2017 01:19:32 +1000 Subject: __new__ and __init__ - why does this work? References: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> Message-ID: <598b2805$0$1604$c3e8da3$5496439d@news.astraweb.com> On Thu, 10 Aug 2017 12:39 am, Dennis Lee Bieber wrote: > On Wed, 09 Aug 2017 22:54:00 +1000, Steve D'Aprano > declaimed the following: > >>Its not just frozenset. Any mutable class must initialise its instances in >>__new__. Immutable classes can use either __new__ or __init__, but for >>historical reasons typically use __init__. >> > Think you swapped mutable and immutable there... Doh! So I did. This is what happens when you try typing a response while caring on a conversation with the missus... -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Wed Aug 9 11:24:10 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 10 Aug 2017 01:24:10 +1000 Subject: Are these tutorials the best tutorials for learning Python? In-Reply-To: <598b26e8$0$1604$c3e8da3$5496439d@news.astraweb.com> References: <598b26e8$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 10, 2017 at 1:14 AM, Steve D'Aprano wrote: > On Wed, 9 Aug 2017 07:12 pm, Chris Warrick wrote: > >> So, I started by writing my opinion of those recommendations, and that >> the ?community? is very small (<1k Twitter followers, 2.7k Facebook >> likes). But then I went to the ?About Us? page, and found your name >> and your profile picture there. Native advertising is evil and rude. >> You made it sound as if you were an user, genuinely looking for help >> in learning Python. But in reality, you just want people to visit your >> website, get ad revenue and potentially get people to join your >> community. >> >> Shame on you. > > Why is this shameful? Why shouldn't people make money from their Python > expertise, if they can? Do you oppose people who get paid to program in Python? The shameful part is the deception. Or rather, the perceived deception; the OP sent a second post which correctly acknowledged the association. Unfortunately, people who use Google Groups think that the way to correct an error is to delete the post and put up a new one, which is IMO wrong even in a web forum; it's frankly ridiculous on a newsgroup or mailing list. But had that info been sent as a proper follow-up/reply, I don't think anyone would have considered it shameful. There's nothing wrong with making money from Python expertise. There's plenty wrong with lying about what you're making money from. "Hey, check out this book I wrote about Python - it's on Amazon for $1.99 or $11.99" is fine; "Hey, everyone, tell me if this is a good book" and pretending you want third-party reviews is not. ChrisA From kwpolska at gmail.com Wed Aug 9 11:30:28 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Wed, 9 Aug 2017 17:30:28 +0200 Subject: Are these tutorials the best tutorials for learning Python? In-Reply-To: <598b26e8$0$1604$c3e8da3$5496439d@news.astraweb.com> References: <598b26e8$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 9 August 2017 at 17:14, Steve D'Aprano wrote: > On Wed, 9 Aug 2017 07:12 pm, Chris Warrick wrote: > >> So, I started by writing my opinion of those recommendations, and that >> the ?community? is very small (<1k Twitter followers, 2.7k Facebook >> likes). But then I went to the ?About Us? page, and found your name >> and your profile picture there. Native advertising is evil and rude. >> You made it sound as if you were an user, genuinely looking for help >> in learning Python. But in reality, you just want people to visit your >> website, get ad revenue and potentially get people to join your >> community. >> >> Shame on you. > > Why is this shameful? Why shouldn't people make money from their Python > expertise, if they can? Do you oppose people who get paid to program in Python? > > If you're opposed to advertising, use an ad blocker, or just avoid the site. > > So long as the website isn't *exploitative* (ripping off other people's content > without providing any added value) there is nothing wrong with promoting it > here. It is on-topic, and if it provides some added value (not just a link > farm), doesn't serve malware, then let it compete for eyeballs and hearts and > minds on its merits. I?m not opposed to advertising on websites[0], or to paying for expertise. I am opposed to the way the original post was phrased ? it was a textbook case of native advertising. Wikipedia says: ?Native advertising is a type of advertising, mostly online, that matches the form and function of the platform upon which it appears.? (from https://en.wikipedia.org/wiki/Native_advertising ) The original poster sent a message that looked like a genuine call for help by someone looking to learn Python. They somehow found the list[1] and want our opinion on it. But that wasn?t the posters real motive: the motive was to get people to use their website. And this is not okay. Compare the second revision (with [Repost] in the Subject line) ? that one has clear information regarding the poster and their intentions, and it?s perfectly fine in my book. The damage was already done nevertheless. [0] As long as said advertising is not user-hostile. [1] It appears as the 10th hit in Google for ?python tutorials? over here. -- Chris Warrick PGP: 5EAAEA16 From steve+python at pearwood.info Wed Aug 9 11:32:31 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 10 Aug 2017 01:32:31 +1000 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> Message-ID: <598b2b11$0$1608$c3e8da3$5496439d@news.astraweb.com> On Wed, 9 Aug 2017 11:46 pm, Marko Rauhamaa wrote: > Typically, an object's equality is simply the "is" relation. "Typically"? I don't think so. Are you sure you've programmed in Python before? *wink* py> [1, 2] is [1, 2] False The most commonly used objects don't define equality as identity, e.g. strings, lists, tuples, ints, bytes, dicts etc don't. It would mean that two objects with the same value would nevertheless compare as unequal. In general, caring about `is` (identity) is a failure of abstraction. Why should we care about object identity? Take the value 42 -- why should anyone care whether that is represented in computer memory by a single object or by a billion separate objects? You might care about memory constraints, but that's a leaky abstraction. Ideally, where memory is not a constraint, if you care about identity, you are probably doing it wrong. I'll allow, in principle, that caring about the identity of stateless, valueless objects that are defined only by their identity such as None and NotImplemented may be acceptable. But the Singleton design pattern, as beloved by Java programmers, puts the emphasis on the wrong place: identity, instead of state. Why not have one or a million objects, so long as they have the same state? Hence the Borg design pattern. There are, in my opinion, very few legitimate uses for `is` and identity checking, and nearly all of them are either: - testing for None; or - debugging implementation details. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From marko at pacujo.net Wed Aug 9 13:07:48 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 09 Aug 2017 20:07:48 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> Message-ID: <87a8381xgb.fsf@elektro.pacujo.net> Chris Angelico : > On Wed, Aug 9, 2017 at 11:46 PM, Marko Rauhamaa wrote: >> Really, the most obvious use case for hashed objects is their membership >> in a set. For example: >> >> invitees = set(self.bff) >> invitees |= self.classmates() >> invitees |= self.relatives() > > Okay. So you should define value by object identity - NOT any sort of > external primary key. Good point! A very good __hash__() implementation is: def __hash__(self): return id(self) In fact, I didn't know Python (kinda) did this by default already. I can't find that information in the definition of object.__hash__(): I only found it out by trying it. > That goes completely against your original statement, which I shall > quote again: > >>>> In relational-database terms, your "value" is the primary key and >>>> your "metadata" is the rest of the columns. > > If there is any possibility that you could have two objects in memory > with the same primary key but other attributes different, you'd have > major MAJOR problems with this kind of set operation. In light of the above realization, don't override __hash__() in any way in your class, and your object works perfectly as a key or a set member. A __hash__() definition is only needed when your __eq__() definition is different from "is". As for running into "major MAJOR" problems, yes, you need to know what you're doing and face the consequences. It's a bit analogous to sort() depending on the definitions of the "rich" comparison. Marko From arequipeno at gmail.com Wed Aug 9 14:44:44 2017 From: arequipeno at gmail.com (Ian Pilcher) Date: Wed, 9 Aug 2017 13:44:44 -0500 Subject: __new__ and __init__ - why does this work? In-Reply-To: References: Message-ID: On 08/08/2017 10:19 PM, Ian Kelly wrote: > It's initialized by the superclass call to __new__. frozenset is > immutable, and __init__ methods of immutable types generally don't do > anything (if they could, then they wouldn't be immutable), which is > why it doesn't really matter that you didn't call it. At the same > time, it generally doesn't hurt to call it, and you probably shouldn't > even have an override of __init__ here if it doesn't do anything. Thanks for the explanation. I'll admit that I'm a bit paranoid about the potential effects of "re-__init__-ing" an object, at least in the general case. What do you think of this? def __new__(cls, *args, **kwargs): self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) self._initialized = False return UniqueSet._registry.setdefault(self, self) def __init__(self, *args, **kwargs): if not self._initialized: super(UniqueSet, self).__init__(self, *args, **kwargs) self._initialized = True > It seems a bit inefficient that you create *two* sets in __new__ and > then map one of them to the other in your registry. Why not just > create the UniqueSet and then map it to itself if it's not already > registered? Something like this (untested): > > def __new__(cls, *args, **kwargs): > self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) > return UniqueSet._registry.setdefault(self, self) That was mainly me being unfamiliar with the frozenset API (and not overly concerned about the size of the _registry, since I expect that there will be a very small number of entries). Your version is much more elegant. Thank you! -- ======================================================================== Ian Pilcher arequipeno at gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ======================================================================== From arequipeno at gmail.com Wed Aug 9 15:59:20 2017 From: arequipeno at gmail.com (Ian Pilcher) Date: Wed, 9 Aug 2017 14:59:20 -0500 Subject: __new__ and __init__ - why does this work? In-Reply-To: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> References: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 08/09/2017 07:54 AM, Steve D'Aprano wrote: > On Wed, 9 Aug 2017 10:08 am, Ian Pilcher wrote: > >> I have created a class to provide a "hash consing"[1] set. > > Your footnote for [1] appears to be missing. What's a hash consing set? It > appears to be nothing more than frozen sets which you put in a cache so as to > confuse identity and value *wink* Uugh. Here's the link: https://en.wikipedia.org/wiki/Hash_consing > I doubt very much you're actually saving any time, since you create a temporary > frozen set before returning the one in the cache. You might save some memory > though. Indeed. This is all about using memory efficiently. > Your __init__ method does nothing. Get rid of it and save two lines of code :-) Well, it prevents frozenset.__init__ from being called. > Also, there is at least theoretically the vague possibility that > frozenset.__init__ does something (phones home to Guido?) so you shouldn't > block it if you don't need to. I do want to prevent frozenset.__init__ from being called *again* when an existing instance is returned, so I've decided to take this approach: def __new__(cls, *args, **kwargs): self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) self._initialized = False return UniqueSet._registry.setdefault(self, self) def __init__(self, *args, **kwargs): if not self._initialized: super(UniqueSet, self).__init__(self, *args, **kwargs) self._initialized = True -- ======================================================================== Ian Pilcher arequipeno at gmail.com -------- "I grew up before Mark Zuckerberg invented friendship" -------- ======================================================================== From ethan at stoneleaf.us Wed Aug 9 16:20:36 2017 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 09 Aug 2017 13:20:36 -0700 Subject: __new__ and __init__ - why does this work? In-Reply-To: References: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> Message-ID: <598B6E94.1040104@stoneleaf.us> On 08/09/2017 12:59 PM, Ian Pilcher wrote: > I do want to prevent frozenset.__init__ from being called *again* when > an existing instance is returned, so I've decided to take this > approach: > > def __new__(cls, *args, **kwargs): > self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) > self._initialized = False > return UniqueSet._registry.setdefault(self, self) > > def __init__(self, *args, **kwargs): > if not self._initialized: > super(UniqueSet, self).__init__(self, *args, **kwargs) > self._initialized = True Whom do you think is going to call __init__ a second time? -- ~Ethan~ From ian.g.kelly at gmail.com Wed Aug 9 18:39:52 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 9 Aug 2017 16:39:52 -0600 Subject: __new__ and __init__ - why does this work? In-Reply-To: <598B6E94.1040104@stoneleaf.us> References: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> <598B6E94.1040104@stoneleaf.us> Message-ID: On Wed, Aug 9, 2017 at 2:20 PM, Ethan Furman wrote: > On 08/09/2017 12:59 PM, Ian Pilcher wrote: > >> I do want to prevent frozenset.__init__ from being called *again* when >> an existing instance is returned, so I've decided to take this >> approach: >> >> def __new__(cls, *args, **kwargs): >> self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) >> self._initialized = False >> return UniqueSet._registry.setdefault(self, self) >> >> def __init__(self, *args, **kwargs): >> if not self._initialized: >> super(UniqueSet, self).__init__(self, *args, **kwargs) >> self._initialized = True > > > Whom do you think is going to call __init__ a second time? The __call__ method of the metaclass. Here's an example using a singleton class: class Singleton: _instance = None def __new__(cls): if cls._instance is None: cls._instance = super(Singleton, cls).__new__(cls) return cls._instance def __init__(self): self.count = getattr(self, 'count', 0) + 1 print('__init__ called %d times' % self.count) >>> Singleton() __init__ called 1 times <__main__.Singleton object at 0x76b54a717518> >>> Singleton() __init__ called 2 times <__main__.Singleton object at 0x76b54a717518> >>> Singleton() is Singleton() __init__ called 3 times __init__ called 4 times True By the way, "whom" is not the verb object in "Whom do you think is going to call", so it should properly be "who do you think is going to call". I point this out because although I don't really care when people use "who" incorrectly, it looks pretty silly (and pretentious) to use "whom" incorrectly. From ian.g.kelly at gmail.com Wed Aug 9 18:54:11 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 9 Aug 2017 16:54:11 -0600 Subject: __new__ and __init__ - why does this work? In-Reply-To: References: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> <598B6E94.1040104@stoneleaf.us> Message-ID: On Aug 9, 2017 4:39 PM, "Ian Kelly" wrote: By the way, "whom" is not the verb object in "Whom do you think is going to call", so it should properly be "who do you think is going to call". I point this out because although I don't really care when people use "who" incorrectly, it looks pretty silly (and pretentious) to use "whom" incorrectly. Er, sorry, I'm wrong of course. I don't know why my brain parsed your statement the way that it did. From cs at cskk.id.au Wed Aug 9 20:33:42 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 10 Aug 2017 10:33:42 +1000 Subject: Validating regexp In-Reply-To: References: Message-ID: <20170810003342.GA52258@cskk.homeip.net> On 09Aug2017 10:46, Jon Ribbens wrote: >On 2017-08-09, Cameron Simpson wrote: >> On 08Aug2017 17:31, Jon Ribbens wrote: >>>... but bear in mind, there have been ways of doing denial-of-service >>>attacks with valid-but-nasty regexps in the past, and I wouldn't want >>>to rely on there not being any now. >> >> The ones I've seen still require some input length (I'm thinking exponential >> rematch backoff stuff here). I suspect that if your test query matches the RE >> against a fixed empty string it is hard to be exploited. i.e. I think most of >> this stuff isn't expensive in terms of compiling the regexp but in >> executing it against text. > >Well yes, but presumably if the OP is receiving regexps from users >they will be executed against text sooner or later. True, but the OP (Larry) was after validation. The risk then depends on the degree of trust in the user. If the user is a random person-from-the-internets, sure there's a risk there. However, if the regexp is part of some internal configuration being set up by trusted people (eg staff pursuing a goal) then validation will normally be enough. Of course, that is a call for Larry to make, not us, but it need to be bourne in mind by him. Cheers, Cameron Simpson (formerly cs at zip.com.au) From ethan at stoneleaf.us Wed Aug 9 20:46:39 2017 From: ethan at stoneleaf.us (Ethan Furman) Date: Wed, 09 Aug 2017 17:46:39 -0700 Subject: __new__ and __init__ - why does this work? In-Reply-To: References: <598b05ea$0$1620$c3e8da3$5496439d@news.astraweb.com> <598B6E94.1040104@stoneleaf.us> Message-ID: <598BACEF.9020708@stoneleaf.us> On 08/09/2017 03:39 PM, Ian Kelly wrote: > On Wed, Aug 9, 2017 at 2:20 PM, Ethan Furman wrote: >> On 08/09/2017 12:59 PM, Ian Pilcher wrote: >>> I do want to prevent frozenset.__init__ from being called *again* when >>> an existing instance is returned, so I've decided to take this >>> approach: >>> >>> def __new__(cls, *args, **kwargs): >>> self = super(UniqueSet, cls).__new__(cls, *args, **kwargs) >>> self._initialized = False >>> return UniqueSet._registry.setdefault(self, self) >>> >>> def __init__(self, *args, **kwargs): >>> if not self._initialized: >>> super(UniqueSet, self).__init__(self, *args, **kwargs) >>> self._initialized = True >> >> >> Whom do you think is going to call __init__ a second time? > > The __call__ method of the metaclass. Here's an example using a singleton class: > >--> Singleton() > __init__ called 1 times > <__main__.Singleton object at 0x76b54a717518> >--> Singleton() > __init__ called 2 times > <__main__.Singleton object at 0x76b54a717518> >--> Singleton() is Singleton() > __init__ called 3 times > __init__ called 4 times > True Ah, cool! I hadn't known about that particular side effect of singletons. -- ~Ethan~ From gandalf at shopzeus.com Thu Aug 10 02:45:16 2017 From: gandalf at shopzeus.com (=?UTF-8?Q?Nagy_L=c3=a1szl=c3=b3_Zsolt?=) Date: Thu, 10 Aug 2017 08:45:16 +0200 Subject: [SOLVED] Re: Firebird 1.5 and Python 3.4 - is this possible? In-Reply-To: References: Message-ID: <49d62105-351a-f26b-f9a0-b41dd53cfea2@shopzeus.com> To answer my own question: - You can convert a firebird 1.5 database into 2.5 with this tool: http://gsbelarus.com/gs/fdbconvert/fdbconvert_eng.html - You can install firebird 2.5 instead of 1.5. Old BDE based program will still work with it, because the Firebird 2.5 server can talk with a 1.5 client. - The official fdb module (https://pypi.python.org/pypi/fdb right now at version 1.7) can be used from Python 3, and it works with Firebird 2.5 Problem solved! > Hi! > > I have an old HIS program written in Delphi. It uses Firebird 1.5 > database. I need to make an interface to exchange data with other > healthcare providers. I do not want to do this in Delphi, that is > ancient code. It is also not an option to rewrite the whole program from > scratch. I just need to add a service that runs in the background and > sends/receives data. > > Is it possible to somehow connect and use firebird 1.5 database from > Python 3? I have tried kinterbasdb with no luck. There are a number of > firebird libraries out there, but none of them seems to support firebird > 1.5. > > Does anyone know a library that can do this? > > Thanks, > > Laszlo > > > From gandalf at shopzeus.com Thu Aug 10 02:48:43 2017 From: gandalf at shopzeus.com (=?UTF-8?Q?Nagy_L=c3=a1szl=c3=b3_Zsolt?=) Date: Thu, 10 Aug 2017 08:48:43 +0200 Subject: Python 3.4.7 binaries for windows? Message-ID: <254ca169-16d4-7c86-f823-4414939377a9@shopzeus.com> Hi! On the official python site, it is possible to download python 3.4.4 here: https://www.python.org/downloads/release/python-344/ There are binary installation files for Windows. But Python 3.4.4 is two years old. There is 3.4.7 that was just released, but there are no binaries. https://www.python.org/downloads/release/python-347/ There is a note on that page: "Also, Python 3.4.7 has only been released in source code form; no more official binary installers will be produced for Python 3.4.". Is there a way to download a binary installer from another site? Compiling it by myself seems to be a big pain. Thanks, Laszlo From ben+python at benfinney.id.au Thu Aug 10 02:58:42 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 10 Aug 2017 16:58:42 +1000 Subject: [SOLVED] Re: Firebird 1.5 and Python 3.4 - is this possible? References: <49d62105-351a-f26b-f9a0-b41dd53cfea2@shopzeus.com> Message-ID: <85k22bkixp.fsf@benfinney.id.au> Nagy L?szl? Zsolt writes: > Problem solved! Congratulations. And thank you for reporting the succesful resolution :-) -- \ ?It is clear that thought is not free if the profession of | `\ certain opinions makes it impossible to earn a living.? | _o__) ?Bertrand Russell, _Free Thought and Official Propaganda_, 1928 | Ben Finney From steve+comp.lang.python at pearwood.info Thu Aug 10 04:04:43 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 10 Aug 2017 08:04:43 GMT Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> Message-ID: <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> On Wed, 09 Aug 2017 20:07:48 +0300, Marko Rauhamaa wrote: > Good point! A very good __hash__() implementation is: > > def __hash__(self): > return id(self) > > In fact, I didn't know Python (kinda) did this by default already. I > can't find that information in the definition of object.__hash__(): Hmmm... using id() as the hash would be a terrible hash function. Objects would fall into similar buckets if they were created at similar times, regardless of their value, rather than being well distributed. But let's see whether or not objects actually do so, as you claim: >>> a, b, c, d = "abc", "def", "ghi", "jki" >>> [id(obj) for obj in (a,b,c,d)] [139932454814752, 139932454814808, 139932454814920, 139932454913616] >>> [hash(obj) for obj in (a,b,c,d)] [7231609897320296628, -876470178105133015, -5049894847448874792, 5697571649565117128] Wait, maybe you're referring to hash() of object(), inherited by classes that don't define their own __hash__. Let's check it out: >>> a, b, c, d = [object() for i in range(4)] >>> [id(obj) for obj in (a,b,c,d)] [139932455747696, 139932455747712, 139932455747728, 139932455747744] >>> [hash(obj) for obj in (a,b,c,d)] [8745778484231, 8745778484232, 8745778484233, 8745778484234] Maybe object does something different for itself than for subclasses? >>> class X(object): ... pass ... >>> a, b, c, d = [X() for i in range(4)] >>> [id(obj) for obj in (a,b,c,d)] [139932454939952, 139932454939896, 139932454940008, 139932454940064] >>> [hash(obj) for obj in (a,b,c,d)] [8745778433747, -9223363291076342065, -9223363291076342058, 8745778433754] I see zero evidence that Python uses id() as the default hash. Not even for classic classes in Python 2. -- ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From h.goebel at crazy-compilers.com Thu Aug 10 04:47:22 2017 From: h.goebel at crazy-compilers.com (Hartmut Goebel) Date: Thu, 10 Aug 2017 10:47:22 +0200 Subject: OT: Rejecting whitespace-only changes at github Message-ID: <0251f6c0-493f-efa0-5a5a-78b79f716d54@crazy-compilers.com> Hello, Is there some tool or online-service which can check patches if they contain white-space-only changes and all test-wrapping changes? One of the projects I'm maintaining (pyinstaller) wants to forbid changes of theses types. If we could integrate resp. checks into the tooling (github), this would give contributors feedback quickly and ease the burden for the maintainers. Sorry for this off-topic question, but I assume to find a competent answer here. And thanks for any pointer. -- Regards Hartmut Goebel | Hartmut Goebel | h.goebel at crazy-compilers.com | | www.crazy-compilers.com | compilers which you thought are impossible | From __peter__ at web.de Thu Aug 10 05:00:54 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 10 Aug 2017 11:00:54 +0200 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: Steven D'Aprano wrote: > On Wed, 09 Aug 2017 20:07:48 +0300, Marko Rauhamaa wrote: > >> Good point! A very good __hash__() implementation is: >> >> def __hash__(self): >> return id(self) >> >> In fact, I didn't know Python (kinda) did this by default already. I >> can't find that information in the definition of object.__hash__(): > > > Hmmm... using id() as the hash would be a terrible hash function. Objects It's actually id(self) >> 4 (almost, see C code below), to account for memory alignment. >>> obj = object() >>> hex(id(obj)) '0x7f1f058070b0' >>> hex(hash(obj)) '0x7f1f058070b' >>> sample = (object() for _ in range(10)) >>> all(id(obj) >> 4 == hash(obj) for obj in sample) True > would fall into similar buckets if they were created at similar times, > regardless of their value, rather than being well distributed. If that were the problem it wouldn't be solved by the current approach: >>> sample = [object() for _ in range(10)] >>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] [1, 1, 1, 1, 1, 1, 1, 1, 1] Py_hash_t _Py_HashPointer(void *p) { Py_hash_t x; size_t y = (size_t)p; /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid excessive hash collisions for dicts and sets */ y = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4)); x = (Py_hash_t)y; if (x == -1) x = -2; return x; } From ned at nedbatchelder.com Thu Aug 10 05:42:37 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Thu, 10 Aug 2017 05:42:37 -0400 Subject: OT: Rejecting whitespace-only changes at github In-Reply-To: <0251f6c0-493f-efa0-5a5a-78b79f716d54@crazy-compilers.com> References: <0251f6c0-493f-efa0-5a5a-78b79f716d54@crazy-compilers.com> Message-ID: <0f3deafc-0659-fb6c-69c7-708ea60abd5b@nedbatchelder.com> On 8/10/17 4:47 AM, Hartmut Goebel wrote: > Hello, > > Is there some tool or online-service which can check patches if they > contain white-space-only changes and all test-wrapping changes? > > One of the projects I'm maintaining (pyinstaller) wants to forbid > changes of theses types. If we could integrate resp. checks into the > tooling (github), this would give contributors feedback quickly and ease > the burden for the maintainers. > > Sorry for this off-topic question, but I assume to find a competent > answer here. And thanks for any pointer. > I don't think you can run code on GitHub like that. You can write a bot that listens for new pull requests, and comments on them, but you have to find your own place to run that bot. I'm curious though: are you getting enough pull requests that are whitespace-only changes that it will be worth doing this? --Ned. From rosuav at gmail.com Thu Aug 10 05:50:02 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 10 Aug 2017 19:50:02 +1000 Subject: OT: Rejecting whitespace-only changes at github In-Reply-To: <0f3deafc-0659-fb6c-69c7-708ea60abd5b@nedbatchelder.com> References: <0251f6c0-493f-efa0-5a5a-78b79f716d54@crazy-compilers.com> <0f3deafc-0659-fb6c-69c7-708ea60abd5b@nedbatchelder.com> Message-ID: On Thu, Aug 10, 2017 at 7:42 PM, Ned Batchelder wrote: > On 8/10/17 4:47 AM, Hartmut Goebel wrote: >> Hello, >> >> Is there some tool or online-service which can check patches if they >> contain white-space-only changes and all test-wrapping changes? >> >> One of the projects I'm maintaining (pyinstaller) wants to forbid >> changes of theses types. If we could integrate resp. checks into the >> tooling (github), this would give contributors feedback quickly and ease >> the burden for the maintainers. >> >> Sorry for this off-topic question, but I assume to find a competent >> answer here. And thanks for any pointer. >> > > I don't think you can run code on GitHub like that. You can write a bot > that listens for new pull requests, and comments on them, but you have > to find your own place to run that bot. > > I'm curious though: are you getting enough pull requests that are > whitespace-only changes that it will be worth doing this? I suspect it's not "that *are*" so much as "that *have*". I've seen a number of submissions around the place where you have a certain amount of substantive change, but also a good number of whitespace-only changes in the same patch. It's just noise and unnecessary merge failures. One solution is to apply the patch, then run "git diff -w" or "git diff -b". If the output is shorter than the original patch, raise a warning. How you'd go about writing a PR bot to do this, though, I'm not sure. Probably would need to maintain a local clone and stuff. ChrisA From kwpolska at gmail.com Thu Aug 10 06:26:25 2017 From: kwpolska at gmail.com (Chris Warrick) Date: Thu, 10 Aug 2017 12:26:25 +0200 Subject: OT: Rejecting whitespace-only changes at github In-Reply-To: <0251f6c0-493f-efa0-5a5a-78b79f716d54@crazy-compilers.com> References: <0251f6c0-493f-efa0-5a5a-78b79f716d54@crazy-compilers.com> Message-ID: On 10 August 2017 at 10:47, Hartmut Goebel wrote: > Hello, > > Is there some tool or online-service which can check patches if they > contain white-space-only changes and all test-wrapping changes? > > One of the projects I'm maintaining (pyinstaller) wants to forbid > changes of theses types. If we could integrate resp. checks into the > tooling (github), this would give contributors feedback quickly and ease > the burden for the maintainers. > > Sorry for this off-topic question, but I assume to find a competent > answer here. And thanks for any pointer. First, make sure you have a clear policy regarding code style. Set up an editorconfig file, mention it in CONTRIBUTING.rst or other developer documentation. There are some tools that enforce code style ? eg. Codacy ? but that might not be what you want. You can write a tool that interacts with GitHub in this way by writing a webhook: https://developer.github.com/webhooks/ You will need your own server (even the cheapest VPS will do) and some simple code in your favorite Python web framework (Flask). Get a webhook request whenever PRs are opened/changed, check if the PR is ?clean? (download diff from GitHub, find whitespace-only changes?) and use the GitHub API to close PRs/comment on them/set status checks to ?failed?. (Closing those PRs might be seen as harsh and discouraging to new contributors) -- Chris Warrick PGP: 5EAAEA16 From jon+usenet at unequivocal.eu Thu Aug 10 06:35:29 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 10 Aug 2017 10:35:29 -0000 (UTC) Subject: Validating regexp References: <20170810003342.GA52258@cskk.homeip.net> Message-ID: On 2017-08-10, Cameron Simpson wrote: > On 09Aug2017 10:46, Jon Ribbens wrote: >>On 2017-08-09, Cameron Simpson wrote: >>> On 08Aug2017 17:31, Jon Ribbens wrote: >>>>... but bear in mind, there have been ways of doing denial-of-service >>>>attacks with valid-but-nasty regexps in the past, and I wouldn't want >>>>to rely on there not being any now. >>> >>> The ones I've seen still require some input length (I'm thinking >>> exponential rematch backoff stuff here). I suspect that if your >>> test query matches the RE against a fixed empty string it is hard >>> to be exploited. i.e. I think most of this stuff isn't expensive >>> in terms of compiling the regexp but in executing it against text. >> >>Well yes, but presumably if the OP is receiving regexps from users >>they will be executed against text sooner or later. > > True, but the OP (Larry) was after validation. > > The risk then depends on the degree of trust in the user. If the user is a > random person-from-the-internets, sure there's a risk there. However, if the > regexp is part of some internal configuration being set up by trusted people > (eg staff pursuing a goal) then validation will normally be enough. > > Of course, that is a call for Larry to make, not us, but it need to be bourne > in mind by him. Yes... hence my mentioning it. From saifulhoque30 at gmail.com Thu Aug 10 07:13:11 2017 From: saifulhoque30 at gmail.com (saifulhoque30 at gmail.com) Date: Thu, 10 Aug 2017 04:13:11 -0700 (PDT) Subject: instructor solution manual for MODERN OPERATING SYSTEMS 2nd ed A.S.TANENBAUM In-Reply-To: <4fdfba0f-66e8-43b1-a282-f93d0c38ee98@r27g2000yqb.googlegroups.com> References: <4fdfba0f-66e8-43b1-a282-f93d0c38ee98@r27g2000yqb.googlegroups.com> Message-ID: solutions manual to MODERN OPERATING SYSTEMS 3rd ed A.S.TANENBAUM can you plz provide it for me.. From bgailer at gmail.com Thu Aug 10 09:06:21 2017 From: bgailer at gmail.com (Bob Gailer) Date: Thu, 10 Aug 2017 09:06:21 -0400 Subject: instructor solution manual for MODERN OPERATING SYSTEMS 2nd ed A.S.TANENBAUM In-Reply-To: References: <4fdfba0f-66e8-43b1-a282-f93d0c38ee98@r27g2000yqb.googlegroups.com> Message-ID: On Aug 10, 2017 7:15 AM, wrote: > > > > solutions manual to MODERN OPERATING SYSTEMS 3rd ed A.S.TANENBAUM > > > can you plz provide it for me.. This mailing list is for the Python programming language, not for operating systems. It is possible that someone else on this list might be able to help you anyway. Did you try Googling? > -- > https://mail.python.org/mailman/listinfo/python-list From v+python at g.nevcal.com Thu Aug 10 09:29:55 2017 From: v+python at g.nevcal.com (Glenn Linderman) Date: Thu, 10 Aug 2017 06:29:55 -0700 Subject: Python 3.4.7 binaries for windows? In-Reply-To: <254ca169-16d4-7c86-f823-4414939377a9@shopzeus.com> References: <254ca169-16d4-7c86-f823-4414939377a9@shopzeus.com> Message-ID: On 8/9/2017 11:48 PM, Nagy L?szl? Zsolt wrote: > Hi! > > On the official python site, it is possible to download python 3.4.4 here: > > https://www.python.org/downloads/release/python-344/ > > There are binary installation files for Windows. But Python 3.4.4 is two > years old. There is 3.4.7 that was just released, but there are no > binaries. > > https://www.python.org/downloads/release/python-347/ > > There is a note on that page: "Also, Python 3.4.7 has only been released > in source code form; no more official binary installers will be produced > for Python 3.4.". > > Is there a way to download a binary installer from another site? > Compiling it by myself seems to be a big pain. > > Thanks, > > Laszlo > Is there any reason not to upgrade to Python 3.7? For which binary installers are available? I think the general philosophy, is that the security updates to the older releases are supplied only in source form so that there is an available path for people that must stay with those older releases to stay secure, but that the pain of doing the compiles is a tradeoff versus the pain of upgrading to newer versions which also include the security fixes, but are more interesting to support going forward in time. You get to decide which is more painful, and which path to take. Personally, I highly recommend keeping your code updated to work with the latest version of Python; I find that relatively straightforward for my own code, as few incompatibilities are introduced in newer versions of Python, and only a small subset of those actually have ever affected my code. Cheers, Glenn From marko at pacujo.net Thu Aug 10 09:31:56 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 10 Aug 2017 16:31:56 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: <8760dvy2er.fsf@elektro.pacujo.net> Peter Otten <__peter__ at web.de>: > Steven D'Aprano wrote: >> On Wed, 09 Aug 2017 20:07:48 +0300, Marko Rauhamaa wrote: >> >>> Good point! A very good __hash__() implementation is: >>> >>> def __hash__(self): >>> return id(self) >>> >>> In fact, I didn't know Python (kinda) did this by default already. I >>> can't find that information in the definition of object.__hash__(): >> >> >> Hmmm... using id() as the hash would be a terrible hash function. id() is actually an ideal return value of __hash__(). The only criterion is that the returned number should be different if the __eq__() is False. That is definitely true for id(). > It's actually id(self) >> 4 (almost, see C code below), to account for > memory alignment. Memory alignment makes no practical difference. It it is any good, the internal implementation will further scramble and scale the returned hash value. For example: index = hash(obj) % prime_table_size >> would fall into similar buckets if they were created at similar >> times, regardless of their value, rather than being well distributed. > > If that were the problem it wouldn't be solved by the current approach: It is not a problem. Hash values don't need to be well distributed, they simply need to be discerning to tiny differences in equality. >>>> sample = [object() for _ in range(10)] >>>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] > [1, 1, 1, 1, 1, 1, 1, 1, 1] Nice demo :-) Marko From larry.martell at gmail.com Thu Aug 10 09:38:49 2017 From: larry.martell at gmail.com (Larry Martell) Date: Thu, 10 Aug 2017 09:38:49 -0400 Subject: Validating regexp In-Reply-To: <20170810003342.GA52258@cskk.homeip.net> References: <20170810003342.GA52258@cskk.homeip.net> Message-ID: On Wed, Aug 9, 2017 at 8:33 PM, Cameron Simpson wrote: > On 09Aug2017 10:46, Jon Ribbens wrote: >> >> On 2017-08-09, Cameron Simpson wrote: >>> >>> On 08Aug2017 17:31, Jon Ribbens wrote: >>>> >>>> ... but bear in mind, there have been ways of doing denial-of-service >>>> attacks with valid-but-nasty regexps in the past, and I wouldn't want >>>> to rely on there not being any now. >>> >>> >>> The ones I've seen still require some input length (I'm thinking >>> exponential >>> rematch backoff stuff here). I suspect that if your test query matches >>> the RE >>> against a fixed empty string it is hard to be exploited. i.e. I think >>> most of >>> this stuff isn't expensive in terms of compiling the regexp but in >>> executing it against text. >> >> >> Well yes, but presumably if the OP is receiving regexps from users >> they will be executed against text sooner or later. > > > True, but the OP (Larry) was after validation. > > The risk then depends on the degree of trust in the user. If the user is a > random person-from-the-internets, sure there's a risk there. However, if the > regexp is part of some internal configuration being set up by trusted people > (eg staff pursuing a goal) then validation will normally be enough. > > Of course, that is a call for Larry to make, not us, but it need to be > bourne in mind by him. The input comes from in house people, not from the internet. From python at example.invalid Thu Aug 10 09:39:55 2017 From: python at example.invalid (Python) Date: Thu, 10 Aug 2017 15:39:55 +0200 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > id() is actually an ideal return value of __hash__(). The only criterion > is that the returned number should be different if the __eq__() is > False. That is definitely true for id(). $ python Python 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> nan = float('NaN') >>> id(nan) == id(nan) True >>> nan == nan False >>> From marko at pacujo.net Thu Aug 10 09:59:41 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 10 Aug 2017 16:59:41 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> Message-ID: <871sojy14i.fsf@elektro.pacujo.net> Python : > Marko Rauhamaa wrote: >> id() is actually an ideal return value of __hash__(). The only criterion >> is that the returned number should be different if the __eq__() is >> False. That is definitely true for id(). > > $ python > Python 2.7.13 (default, Jan 19 2017, 14:48:08) > [GCC 6.3.0 20170118] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> nan = float('NaN') >>>> id(nan) == id(nan) > True >>>> nan == nan > False >>>> Point being? Marko From python at example.invalid Thu Aug 10 10:01:48 2017 From: python at example.invalid (Python) Date: Thu, 10 Aug 2017 16:01:48 +0200 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > Python : > >> Marko Rauhamaa wrote: >>> id() is actually an ideal return value of __hash__(). The only criterion >>> is that the returned number should be different if the __eq__() is >>> False. That is definitely true for id(). >> >> $ python >> Python 2.7.13 (default, Jan 19 2017, 14:48:08) >> [GCC 6.3.0 20170118] on linux2 >> Type "help", "copyright", "credits" or "license" for more information. >>>>> nan = float('NaN') >>>>> id(nan) == id(nan) >> True >>>>> nan == nan >> False >>>>> > > Point being? It is a counter example to your claim that if __eq__(...) is false then id should return different values. From steve+python at pearwood.info Thu Aug 10 10:28:03 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 11 Aug 2017 00:28:03 +1000 Subject: Proposed new syntax Message-ID: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Every few years, the following syntax comes up for discussion, with some people saying it isn't obvious what it would do, and others disagreeing and saying that it is obvious. So I thought I'd do an informal survey. What would you expect this syntax to return? [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] For comparison, what would you expect this to return? (Without actually trying it, thank you.) [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] How about these? [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] Thanks for your comments! -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From info at tundraware.com Thu Aug 10 10:35:16 2017 From: info at tundraware.com (Tim Daneliuk) Date: Thu, 10 Aug 2017 09:35:16 -0500 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <6i7u5e-qfn1.ln1@oceanview.tundraware.com> On 08/10/2017 09:28 AM, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1,2,3] > > > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] [1,2,3,4,5,] > > > > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] [100,200,101,201,102,202] > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100,200,101,201,102,202.103,203,104,204 ] > > > > Thanks for your comments! > > > From ian.g.kelly at gmail.com Thu Aug 10 10:44:54 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 10 Aug 2017 08:44:54 -0600 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 10, 2017 at 8:28 AM, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] I would expect the for to be an outer loop and the while to be an inner, so this would loop infinitely. > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] This is already valid syntax. I would expect [1, 2, 3, 4, 5]. > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] Infinite loop. > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] From rosuav at gmail.com Thu Aug 10 10:45:19 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 11 Aug 2017 00:45:19 +1000 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 11, 2017 at 12:28 AM, Steve D'Aprano wrote: > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > I know exactly what the current syntax does, and yet I fell into an automatic mental trap of expecting (100, 200) to be a range. So "intuitiveness" is not necessarily reliable. ChrisA From steve+python at pearwood.info Thu Aug 10 10:45:25 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 11 Aug 2017 00:45:25 +1000 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> On Thu, 10 Aug 2017 07:00 pm, Peter Otten wrote: > Steven D'Aprano wrote: > >> On Wed, 09 Aug 2017 20:07:48 +0300, Marko Rauhamaa wrote: >> >>> Good point! A very good __hash__() implementation is: >>> >>> def __hash__(self): >>> return id(self) >>> >>> In fact, I didn't know Python (kinda) did this by default already. I >>> can't find that information in the definition of object.__hash__(): >> >> >> Hmmm... using id() as the hash would be a terrible hash function. Objects > > It's actually id(self) >> 4 (almost, see C code below), to account for > memory alignment. Thanks for tracking that down. As you show, the default hash isn't id() itself. The C code says: > /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid > excessive hash collisions for dicts and sets */ which I think agrees with my comment: using the id() itself would put too many objects in the same bucket (i.e. too many collisions). >>>> obj = object() >>>> hex(id(obj)) > '0x7f1f058070b0' >>>> hex(hash(obj)) > '0x7f1f058070b' > >>>> sample = (object() for _ in range(10)) >>>> all(id(obj) >> 4 == hash(obj) for obj in sample) > True > >> would fall into similar buckets if they were created at similar times, >> regardless of their value, rather than being well distributed. > > If that were the problem it wouldn't be solved by the current approach: > >>>> sample = [object() for _ in range(10)] >>>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] > [1, 1, 1, 1, 1, 1, 1, 1, 1] Arguably that's a flaw with the current approach that (maybe?) makes object()'s hash too closely. But: - perhaps it doesn't matter in practice, since the hash is taken modulo the size of the hash table; - or maybe Python's dicts and sets are good enough that a difference of 1 is sufficient to give a good distribution of objects in the hash table; - or maybe it does matter, but since people hardly ever use object() itself as the keys in dicts, it doesn't come up. Here's your example with a class that inherits from object, rather than object itself: py> class X(object): ... pass ... py> sample = [X() for x in range(10)] py> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] [-5338, -10910, -2976, -2284, -21326, 4, -8, 2, -4] So my money is on object() being anomalous: because it is so small, the hashes end up so similar. For "typical" classes, the hash function does a much better job of mixing the hash values up. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Thu Aug 10 10:58:29 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 11 Aug 2017 00:58:29 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 11, 2017 at 12:45 AM, Steve D'Aprano wrote: > The C code says: > >> /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >> excessive hash collisions for dicts and sets */ > > which I think agrees with my comment: using the id() itself would put too many > objects in the same bucket (i.e. too many collisions). > > >> If that were the problem it wouldn't be solved by the current approach: >> >>>>> sample = [object() for _ in range(10)] >>>>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] >> [1, 1, 1, 1, 1, 1, 1, 1, 1] A difference of 1 in a hash is usually going to mean dropping something into the next bucket. A difference of 4, 8, or 16 would mean that a tiny dictionary (which has 8 slots and thus uses modulo-8) would have everything on the same slot. > > So my money is on object() being anomalous: because it is so small, the hashes > end up so similar. For "typical" classes, the hash function does a much better > job of mixing the hash values up. > And this is also possible, but most likely the difference would simply widen; small dictionaries would still have all objects landing in the zeroth bucket. Hence rotating away the low bits. ChrisA From skip.montanaro at gmail.com Thu Aug 10 11:04:20 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Thu, 10 Aug 2017 10:04:20 -0500 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1, 2, 3] > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] [1, 2, 3, 4, 5] > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202] > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] Skip From marko at pacujo.net Thu Aug 10 11:37:24 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 10 Aug 2017 18:37:24 +0300 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> Message-ID: <87valvwi17.fsf@elektro.pacujo.net> Python : > Marko Rauhamaa wrote: >> Python : >> >>> Marko Rauhamaa wrote: >>>> id() is actually an ideal return value of __hash__(). The only criterion >>>> is that the returned number should be different if the __eq__() is >>>> False. That is definitely true for id(). >>> >>> $ python >>> Python 2.7.13 (default, Jan 19 2017, 14:48:08) >>> [GCC 6.3.0 20170118] on linux2 >>> Type "help", "copyright", "credits" or "license" for more information. >>>>>> nan = float('NaN') >>>>>> id(nan) == id(nan) >>> True >>>>>> nan == nan >>> False >>>>>> >> >> Point being? > > It is a counter example to your claim that if __eq__(...) is false > then id should return different values. No it's not: * __hash__() *should* return different values. It is neither possible nor necessary in the general case. * For NaN, there's no better alternative. * Dictionaries and sets try "is" before __eq__(...) so everything works anyway. So, to be precise, the __hash__() rule is: a.__hash__() *should* return a different number than b.__hash__() if a is not b and not a.__eq__(b) a.__hash__() *must* return the same number as b.__hash__() if a is b or a.__eq__(b) Marko From walters.justin01 at gmail.com Thu Aug 10 11:41:07 2017 From: walters.justin01 at gmail.com (justin walters) Date: Thu, 10 Aug 2017 08:41:07 -0700 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 10, 2017 at 7:28 AM, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some > people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > >>> [1, 2, 3, 4] > > > For comparison, what would you expect this to return? (Without actually > trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > > >>> [1, 2, 3, 4, 5] > > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > I'd expect this to throw a syntax error. > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > Syntax error again. > > > > Thanks for your comments! > > > > -- > 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 > From alister.ware at ntlworld.com Thu Aug 10 11:42:33 2017 From: alister.ware at ntlworld.com (alister) Date: Thu, 10 Aug 2017 15:42:33 GMT Subject: Validating regexp References: <20170810003342.GA52258@cskk.homeip.net> Message-ID: On Thu, 10 Aug 2017 09:38:49 -0400, Larry Martell wrote: > On Wed, Aug 9, 2017 at 8:33 PM, Cameron Simpson wrote: >> On 09Aug2017 10:46, Jon Ribbens wrote: >>> >>> On 2017-08-09, Cameron Simpson wrote: >>>> >>>> On 08Aug2017 17:31, Jon Ribbens wrote: >>>>> >>>>> ... but bear in mind, there have been ways of doing >>>>> denial-of-service attacks with valid-but-nasty regexps in the past, >>>>> and I wouldn't want to rely on there not being any now. >>>> >>>> >>>> The ones I've seen still require some input length (I'm thinking >>>> exponential rematch backoff stuff here). I suspect that if your test >>>> query matches the RE against a fixed empty string it is hard to be >>>> exploited. i.e. I think most of this stuff isn't expensive in terms >>>> of compiling the regexp but in executing it against text. >>> >>> >>> Well yes, but presumably if the OP is receiving regexps from users >>> they will be executed against text sooner or later. >> >> >> True, but the OP (Larry) was after validation. >> >> The risk then depends on the degree of trust in the user. If the user >> is a random person-from-the-internets, sure there's a risk there. >> However, if the regexp is part of some internal configuration being set >> up by trusted people (eg staff pursuing a goal) then validation will >> normally be enough. >> >> Of course, that is a call for Larry to make, not us, but it need to be >> bourne in mind by him. > > The input comes from in house people, not from the internet. The question would still be should the input be trusted & I would still say no, accidental errors can cause as much damage as malicious input if not correctly sanitised. my experience with regex's is insufficient to help with any of the rest of this query -- For some reason, this fortune reminds everyone of Marvin Zelkowitz. From larry.martell at gmail.com Thu Aug 10 11:50:09 2017 From: larry.martell at gmail.com (Larry Martell) Date: Thu, 10 Aug 2017 11:50:09 -0400 Subject: Validating regexp In-Reply-To: References: <20170810003342.GA52258@cskk.homeip.net> Message-ID: On Thu, Aug 10, 2017 at 11:42 AM, alister via Python-list wrote: > On Thu, 10 Aug 2017 09:38:49 -0400, Larry Martell wrote: > >> On Wed, Aug 9, 2017 at 8:33 PM, Cameron Simpson wrote: >>> On 09Aug2017 10:46, Jon Ribbens wrote: >>>> >>>> On 2017-08-09, Cameron Simpson wrote: >>>>> >>>>> On 08Aug2017 17:31, Jon Ribbens wrote: >>>>>> >>>>>> ... but bear in mind, there have been ways of doing >>>>>> denial-of-service attacks with valid-but-nasty regexps in the past, >>>>>> and I wouldn't want to rely on there not being any now. >>>>> >>>>> >>>>> The ones I've seen still require some input length (I'm thinking >>>>> exponential rematch backoff stuff here). I suspect that if your test >>>>> query matches the RE against a fixed empty string it is hard to be >>>>> exploited. i.e. I think most of this stuff isn't expensive in terms >>>>> of compiling the regexp but in executing it against text. >>>> >>>> >>>> Well yes, but presumably if the OP is receiving regexps from users >>>> they will be executed against text sooner or later. >>> >>> >>> True, but the OP (Larry) was after validation. >>> >>> The risk then depends on the degree of trust in the user. If the user >>> is a random person-from-the-internets, sure there's a risk there. >>> However, if the regexp is part of some internal configuration being set >>> up by trusted people (eg staff pursuing a goal) then validation will >>> normally be enough. >>> >>> Of course, that is a call for Larry to make, not us, but it need to be >>> bourne in mind by him. >> >> The input comes from in house people, not from the internet. > > The question would still be should the input be trusted & I would still > say no, accidental errors can cause as much damage as malicious input if > not correctly sanitised. The regexp is used for a db query, worst that can happen is they run some mega query that slows the db down. Which has happened. So we tell them not do to that anymore. Doctor it hurts when I do this. Then don't do it. From wolfgang.maier at biologie.uni-freiburg.de Thu Aug 10 11:59:41 2017 From: wolfgang.maier at biologie.uni-freiburg.de (Wolfgang Maier) Date: Thu, 10 Aug 2017 17:59:41 +0200 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 08/10/2017 04:28 PM, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? As one of the people who have suggested this or similar syntax once I hope I'm not too far off a potential consensus :) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > [1, 2, 3] > > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > [1, 2, 3, 4, 5] > > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > [100, 200, 101, 201, 102, 202] > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] > > Thanks for your comments! > > > From python at example.invalid Thu Aug 10 12:02:50 2017 From: python at example.invalid (Python) Date: Thu, 10 Aug 2017 18:02:50 +0200 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> <87valvwi17.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > Python : > >> Marko Rauhamaa wrote: >>> Python : >>> >>>> Marko Rauhamaa wrote: >>>>> id() is actually an ideal return value of __hash__(). The only criterion >>>>> is that the returned number should be different if the __eq__() is >>>>> False. That is definitely true for id(). >>>> >>>> $ python >>>> Python 2.7.13 (default, Jan 19 2017, 14:48:08) >>>> [GCC 6.3.0 20170118] on linux2 >>>> Type "help", "copyright", "credits" or "license" for more information. >>>>>>> nan = float('NaN') >>>>>>> id(nan) == id(nan) >>>> True >>>>>>> nan == nan >>>> False >>>>>>> >>> >>> Point being? >> >> It is a counter example to your claim that if __eq__(...) is false >> then id should return different values. > > No it's not: > > * __hash__() *should* return different values. It is neither possible > nor necessary in the general case. > > * For NaN, there's no better alternative. > > * Dictionaries and sets try "is" before __eq__(...) so everything works > anyway. > > > So, to be precise, the __hash__() rule is: > > a.__hash__() *should* return a different number than b.__hash__() if > a is not b and not a.__eq__(b) > > a.__hash__() *must* return the same number as b.__hash__() if > a is b or a.__eq__(b) I didn't disagree with any of these statements about __hash__, but only your statement about id and __eq__: > id() is actually an ideal return value of __hash__(). The only criterion > is that the returned number should be different if the __eq__() is > False. That is definitely true for id() nan is a clear, simple, undeniable counterexample to that claim. the hash function for floats is quite interesting btw, you may want to look what is its value for nan. From steve+python at pearwood.info Thu Aug 10 12:41:23 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 11 Aug 2017 02:41:23 +1000 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> Message-ID: <598c8cb5$0$1610$c3e8da3$5496439d@news.astraweb.com> On Fri, 11 Aug 2017 12:58 am, Chris Angelico wrote: > On Fri, Aug 11, 2017 at 12:45 AM, Steve D'Aprano > wrote: > >> The C code says: >> >>> /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >>> excessive hash collisions for dicts and sets */ >> >> which I think agrees with my comment: using the id() itself would put too >> many objects in the same bucket (i.e. too many collisions). >> >> >>> If that were the problem it wouldn't be solved by the current approach: >>> >>>>>> sample = [object() for _ in range(10)] >>>>>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] >>> [1, 1, 1, 1, 1, 1, 1, 1, 1] > > A difference of 1 in a hash is usually going to mean dropping > something into the next bucket. A difference of 4, 8, or 16 would mean > that a tiny dictionary (which has 8 slots and thus uses modulo-8) > would have everything on the same slot. Um... yes? And how does that relate to the comment given in the source code? "bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid excessive hash collisions for dicts and sets" According to the comment, IDs of objects are typically: 0b(bunch of bits)1000 0b(bunch of bits)0000 i.e. they're typically multiples of 8 or 16. Right? So modulo 8, they'll all map to the zeroeth bucket; modulo 16, they'll all map to the zeroeth or eighth bucket. Collisions, just like I said. (Was I wrong?) By stripping of the first four bits, you get: 0b(bunch of bits) which will hopefully be well-mixed modulo 8 or 16. Are we in agreement so far? >> So my money is on object() being anomalous: because it is so small, the >> hashes end up so similar. For "typical" classes, the hash function does a >> much better job of mixing the hash values up. >> > > And this is also possible, but most likely the difference would simply > widen; small dictionaries would still have all objects landing in the > zeroth bucket. Hence rotating away the low bits. I can't tell if you're disagreeing with me or not. I said: using the object ID itself would be a terrible hash, because there would be lots of collisions. Lo and behold the source code for the default hash says (paraphrased), "don't use the ID itself, that will have lots of collisions" and processes the ID by doing a >> 4 to strip off the least significant four bits. So I'm genuinely puzzled on where (if anywhere) our point of disagreement is. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From m at funkyhat.org Thu Aug 10 12:54:59 2017 From: m at funkyhat.org (Matt Wheeler) Date: Thu, 10 Aug 2017 16:54:59 +0000 (UTC) Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, 10 Aug 2017 at 15:28 Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some > people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > Without reading the rest of the thread so far :)... > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > [1, 2, 3] > For comparison, what would you expect this to return? (Without actually > trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > [1, 2, 3, 4, 5] > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > [100, 200, 101, 201, 102, 202] > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] -- -- Matt Wheeler http://funkyh.at From rosuav at gmail.com Thu Aug 10 12:58:17 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 11 Aug 2017 02:58:17 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <598c8cb5$0$1610$c3e8da3$5496439d@news.astraweb.com> References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> <598c8cb5$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 11, 2017 at 2:41 AM, Steve D'Aprano wrote: > On Fri, 11 Aug 2017 12:58 am, Chris Angelico wrote: > >> On Fri, Aug 11, 2017 at 12:45 AM, Steve D'Aprano >> wrote: >> >>> The C code says: >>> >>>> /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >>>> excessive hash collisions for dicts and sets */ >>> >>> which I think agrees with my comment: using the id() itself would put too >>> many objects in the same bucket (i.e. too many collisions). >>> >>> >>>> If that were the problem it wouldn't be solved by the current approach: >>>> >>>>>>> sample = [object() for _ in range(10)] >>>>>>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] >>>> [1, 1, 1, 1, 1, 1, 1, 1, 1] >> >> A difference of 1 in a hash is usually going to mean dropping >> something into the next bucket. A difference of 4, 8, or 16 would mean >> that a tiny dictionary (which has 8 slots and thus uses modulo-8) >> would have everything on the same slot. > > Um... yes? And how does that relate to the comment given in the source code? > > "bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid excessive hash > collisions for dicts and sets" > Are we in agreement so far? Yes, we're in agreement. It may have been unclear from my quoting style, but the main point I was disagreeing with was this: >>>> If that were the problem it wouldn't be solved by the current approach: >>>> >>>>>>> sample = [object() for _ in range(10)] >>>>>>> [hash(b) - hash(a) for a, b in zip(sample, sample[1:])] >>>> [1, 1, 1, 1, 1, 1, 1, 1, 1] Incrementing hashes by 1 usually will put things into successive buckets. Incrementing by 8 or 16 will usually put things into the same bucket. Sorry for the confusion. ChrisA From marko at pacujo.net Thu Aug 10 13:03:45 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 10 Aug 2017 20:03:45 +0300 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> <87valvwi17.fsf@elektro.pacujo.net> Message-ID: <87lgmrz766.fsf@elektro.pacujo.net> Python : > Marko Rauhamaa wrote: > I didn't disagree with any of these statements about __hash__, but only > your statement about id and __eq__: > >> id() is actually an ideal return value of __hash__(). The only >> criterion is that the returned number should be different if the >> __eq__() is False. That is definitely true for id() > > nan is a clear, simple, undeniable counterexample to that claim. Still, I don't see the point you are trying to make. Marko From python at mrabarnett.plus.com Thu Aug 10 13:18:24 2017 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 10 Aug 2017 18:18:24 +0100 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <4838fa33-0b56-8f50-de38-2c7491546cab@mrabarnett.plus.com> On 2017-08-10 15:28, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > > > > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > > > > Thanks for your comments! > There's a subtlety there. Initially I would've thought that the 'while' would terminate the iteration of the preceding 'for', but then when I thought about how I would expand it into multiple lines, I realised that the 'while' would have to be expanded to "if x < 5: break", not an inner 'while' loop. From __peter__ at web.de Thu Aug 10 13:42:20 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 10 Aug 2017 19:42:20 +0200 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > The C code says: > >>/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >>excessive hash collisions for dicts and sets */ > > which I think agrees with my comment: using the id() itself would put too > many objects in the same bucket (i.e. too many collisions). There's a subtle diffence: you expected objects with nearby memory addresses to end up in the same "bucket" while actually all addresses (are likely to) have the same low bits, and creation time does not matter. From blindanagram at nowhere.com Thu Aug 10 13:45:51 2017 From: blindanagram at nowhere.com (BlindAnagram) Date: Thu, 10 Aug 2017 18:45:51 +0100 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <9vWdnY4efL5TBhHEnZ2dnUU78f2dnZ2d@brightview.co.uk> On 10/08/2017 15:28, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] 1, 2, 3 > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] 1, 2, 3, 4, 5 > > > > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] 100, 200, 101, 201, 102, 202 > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] 100, 200, 102, 201, 102, 202, 103, 203, 104, 204 From gordon at panix.com Thu Aug 10 13:48:33 2017 From: gordon at panix.com (John Gordon) Date: Thu, 10 Aug 2017 17:48:33 +0000 (UTC) Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: In <598c6d74$0$1588$c3e8da3$5496439d at news.astraweb.com> Steve D'Aprano writes: > What would you expect this syntax to return? > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1, 2, 3] > For comparison, what would you expect this to return? (Without actually > trying it, thank you.) > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] [1, 2, 3, 4, 5] > How about these? > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] [100, 101, 102, 200, 201, 202] > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100, 101, 102, 103, 104, 200, 201, 202, 203, 204] -- John Gordon A is for Amy, who fell down the stairs gordon at panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" From jussi.piitulainen at helsinki.fi Thu Aug 10 14:04:10 2017 From: jussi.piitulainen at helsinki.fi (Jussi Piitulainen) Date: Thu, 10 Aug 2017 21:04:10 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano writes: > Every few years, the following syntax comes up for discussion, with > some people saying it isn't obvious what it would do, and others > disagreeing and saying that it is obvious. So I thought I'd do an > informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1, 2, 3] > For comparison, what would you expect this to return? (Without > actually trying it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] [1, 2, 3, 4, 5] > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202] > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] From oliver.schoenborn at gmail.com Thu Aug 10 14:18:02 2017 From: oliver.schoenborn at gmail.com (oliver) Date: Thu, 10 Aug 2017 18:18:02 +0000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: Then what about [x for x in (0, 1, 2, 3, 4, 66, 7, 8, 9, 10) while x < 10 if x % 2 == 0] Seems it should be valid and [0, 2, 4]. On Thu, Aug 10, 2017, 14:06 Jussi Piitulainen, < jussi.piitulainen at helsinki.fi> wrote: > Steve D'Aprano writes: > > > Every few years, the following syntax comes up for discussion, with > > some people saying it isn't obvious what it would do, and others > > disagreeing and saying that it is obvious. So I thought I'd do an > > informal survey. > > > > What would you expect this syntax to return? > > > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > [1, 2, 3] > > > For comparison, what would you expect this to return? (Without > > actually trying it, thank you.) > > > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > > [1, 2, 3, 4, 5] > > > How about these? > > > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > > [100, 200, 101, 201, 102, 202] > > > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > > [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] > -- > https://mail.python.org/mailman/listinfo/python-list > -- Oliver My StackOverflow contributions My CodeProject articles My Github projects My SourceForget.net projects From jussi.piitulainen at helsinki.fi Thu Aug 10 15:11:47 2017 From: jussi.piitulainen at helsinki.fi (Jussi Piitulainen) Date: Thu, 10 Aug 2017 22:11:47 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <4838fa33-0b56-8f50-de38-2c7491546cab@mrabarnett.plus.com> Message-ID: MRAB writes: > On 2017-08-10 15:28, Steve D'Aprano wrote: >> Every few years, the following syntax comes up for discussion, with >> some people saying it isn't obvious what it would do, and others >> disagreeing and saying that it is obvious. So I thought I'd do an >> informal survey. >> >> What would you expect this syntax to return? >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] >> >> >> For comparison, what would you expect this to return? (Without >> actually trying it, thank you.) >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] >> >> >> >> How about these? >> >> [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] >> >> [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] >> >> >> >> Thanks for your comments! >> > There's a subtlety there. > > Initially I would've thought that the 'while' would terminate the > iteration of the preceding 'for', but then when I thought about how I > would expand it into multiple lines, I realised that the 'while' would > have to be expanded to "if x < 5: break", not an inner 'while' loop. I wonder how such expansions would work in general. [x + y for x in (0, 1, 2, 999, 3, 4) for y in (100, 200) while x < 5] [x + y for x in (0, 1, 2, 999, 3, 4) for y in (100, 200) while x < y] From tjreedy at udel.edu Thu Aug 10 15:49:56 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 10 Aug 2017 15:49:56 -0400 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/10/2017 10:28 AM, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] I expect it to continue to raise SyntaxError as I would be flabbergasted if something so awful were to be accepted into Python. If it were were to mean what it 'obviously' should, by analogy with the current meaning and translation val = [] for x in (0, 1, 2, 999, 3, 4): while x < 5: val.append(x) then it would 'mean' an infinite list of, in this case, 1's, and raise OutOfMemoryError. This is, of course, useless. Better to leave it as a SyntaxError. If 'while cond' were to not mean 'conditionally loop', but, as some want, 'conditionally break an existing loop', something like 'if not cond: break', it would mean 'Python is really confusing and inconsistent'. It would be terrible to have a keyword with two such related but opposite meanings. Better to allow people to say what they mean, something like 'if cond break'. A 'semi-obvious' translations might then be val = [] it = iter((0, 1, 2, 999, 3, 4)) for x in it: if x < 5: val.append(x+1) else: break val = [1,2,3] Notice that this consumes one item in iterator it without processing it. A likely source of bugs if one intends to resume use of it. I believe some want to add to the confusion by breaking more rules of comprehension interpretation by translating to something like val = [] it = iter((0, 1, 2, 999, 3, 4)) for x in it: val.append(x+1) if x >= 5: break val = [1,2,3,100] This has the opposite potential bug of including the stop value. Summary: If 'while cond' in comprehensions were no longer a SyntaxError, I would expect unending confusion and ultimately regret. -- Terry Jan Reedy From marko at pacujo.net Thu Aug 10 16:03:59 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 10 Aug 2017 23:03:59 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: <87fuczyyts.fsf@elektro.pacujo.net> Peter Otten <__peter__ at web.de>: > Steve D'Aprano wrote: >> The C code says: >> >>>/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >>>excessive hash collisions for dicts and sets */ >> >> which I think agrees with my comment: using the id() itself would put >> too many objects in the same bucket (i.e. too many collisions). > > There's a subtle diffence: you expected objects with nearby memory > addresses to end up in the same "bucket" while actually all addresses > (are likely to) have the same low bits, and creation time does not > matter. I see no point in CPython's rotation magic. Marko From python at mrabarnett.plus.com Thu Aug 10 16:13:06 2017 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 10 Aug 2017 21:13:06 +0100 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <4838fa33-0b56-8f50-de38-2c7491546cab@mrabarnett.plus.com> Message-ID: On 2017-08-10 20:11, Jussi Piitulainen wrote: > MRAB writes: [snip] >>> How about these? >>> >>> [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] >>> >>> [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] >>> >>> >>> >>> Thanks for your comments! >>> >> There's a subtlety there. >> >> Initially I would've thought that the 'while' would terminate the >> iteration of the preceding 'for', but then when I thought about how I >> would expand it into multiple lines, I realised that the 'while' would >> have to be expanded to "if x < 5: break", not an inner 'while' loop. > Oops! Of course I meant "if not (x < 5): break". > I wonder how such expansions would work in general. > > [x + y for x in (0, 1, 2, 999, 3, 4) for y in (100, 200) while x < 5] > [x + y for x in (0, 1, 2, 999, 3, 4) for y in (100, 200) while x < y] > From rosuav at gmail.com Thu Aug 10 16:16:47 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 11 Aug 2017 06:16:47 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <87fuczyyts.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <87fuczyyts.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 11, 2017 at 6:03 AM, Marko Rauhamaa wrote: > Peter Otten <__peter__ at web.de>: > >> Steve D'Aprano wrote: >>> The C code says: >>> >>>>/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >>>>excessive hash collisions for dicts and sets */ >>> >>> which I think agrees with my comment: using the id() itself would put >>> too many objects in the same bucket (i.e. too many collisions). >> >> There's a subtle diffence: you expected objects with nearby memory >> addresses to end up in the same "bucket" while actually all addresses >> (are likely to) have the same low bits, and creation time does not >> matter. > > I see no point in CPython's rotation magic. Have you ever implemented a hashtable? The most common way to pick a bucket for an object is to use modulo on the number of buckets. ChrisA From ian.g.kelly at gmail.com Thu Aug 10 16:28:50 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 10 Aug 2017 14:28:50 -0600 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 10, 2017 at 1:49 PM, Terry Reedy wrote: > On 8/10/2017 10:28 AM, Steve D'Aprano wrote: >> >> Every few years, the following syntax comes up for discussion, with some >> people >> saying it isn't obvious what it would do, and others disagreeing and >> saying >> that it is obvious. So I thought I'd do an informal survey. >> >> What would you expect this syntax to return? >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > > I expect it to continue to raise SyntaxError as I would be flabbergasted if > something so awful were to be accepted into Python. > > If it were were to mean what it 'obviously' should, by analogy with the > current meaning and translation > > val = [] > for x in (0, 1, 2, 999, 3, 4): > while x < 5: > val.append(x) > > then it would 'mean' an infinite list of, in this case, 1's, and raise > OutOfMemoryError. This is, of course, useless. Better to leave it as a > SyntaxError. > > If 'while cond' were to not mean 'conditionally loop', but, as some want, > 'conditionally break an existing loop', something like 'if not cond: break', > it would mean 'Python is really confusing and inconsistent'. It would be > terrible to have a keyword with two such related but opposite meanings. > > Better to allow people to say what they mean, something like 'if cond > break'. A 'semi-obvious' translations might then be > > val = [] > it = iter((0, 1, 2, 999, 3, 4)) > for x in it: > if x < 5: > val.append(x+1) > else: > break > > val = [1,2,3] So, perhaps a better syntax could be: [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5 else break] From __peter__ at web.de Thu Aug 10 16:35:00 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 10 Aug 2017 22:35 +0200 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: Marko Rauhamaa wrote: > Peter Otten <__peter__ at web.de>: > >> Steve D'Aprano wrote: >>> The C code says: >>> >>>>/* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >>>>excessive hash collisions for dicts and sets */ >>> >>> which I think agrees with my comment: using the id() itself would put >>> too many objects in the same bucket (i.e. too many collisions). >> >> There's a subtle diffence: you expected objects with nearby memory >> addresses to end up in the same "bucket" while actually all addresses >> (are likely to) have the same low bits, and creation time does not >> matter. > > I see no point in CPython's rotation magic. Let's see: $ cat hashperf.py class A(object): __slots__ = ["_hash"] def __hash__(self): return self._hash def no_magic(): a = A() a._hash = id(a) return a def magic(): a = A() a._hash = id(a) >> 4 return a $ python3 -m timeit -s 'from hashperf import magic, no_magic; s = {no_magic() for _ in range(10**5)}' 'for x in s: x in s' 10 loops, best of 3: 70.7 msec per loop $ python3 -m timeit -s 'from hashperf import magic, no_magic; s = {magic() for _ in range(10**5)}' 'for x in s: x in s' 10 loops, best of 3: 52.8 msec per loop "magic" wins this makeshift test. Other than that you're right ;) From Cecil at decebal.nl Thu Aug 10 16:45:59 2017 From: Cecil at decebal.nl (Cecil Westerhof) Date: Thu, 10 Aug 2017 22:45:59 +0200 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87fucz1794.fsf@munus.decebal.nl> Terry Reedy writes: > On 8/10/2017 10:28 AM, Steve D'Aprano wrote: >> Every few years, the following syntax comes up for discussion, with some people >> saying it isn't obvious what it would do, and others disagreeing and saying >> that it is obvious. So I thought I'd do an informal survey. >> >> What would you expect this syntax to return? >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > I expect it to continue to raise SyntaxError as I would be flabbergasted > if something so awful were to be accepted into Python. Correct: SyntaxError: invalid syntax -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From marko at pacujo.net Thu Aug 10 16:56:11 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 10 Aug 2017 23:56:11 +0300 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <87fuczyyts.fsf@elektro.pacujo.net> Message-ID: <878tirywes.fsf@elektro.pacujo.net> Chris Angelico : > On Fri, Aug 11, 2017 at 6:03 AM, Marko Rauhamaa wrote: >> I see no point in CPython's rotation magic. > > Have you ever implemented a hashtable? The most common way to pick a > bucket for an object is to use modulo on the number of buckets. Like I said earlier, CPython takes the __hash__() value and scrambles it. Look for "perturb" in: >From a comment: Now the probe sequence depends (eventually) on every bit in the hash code, and the pseudo-scrambling property of recurring on 5*j+1 is more valuable, because it quickly magnifies small differences in the bits that didn't affect the initial index. Marko From rosuav at gmail.com Thu Aug 10 17:05:53 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 11 Aug 2017 07:05:53 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <878tirywes.fsf@elektro.pacujo.net> References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <87fuczyyts.fsf@elektro.pacujo.net> <878tirywes.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 11, 2017 at 6:56 AM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Fri, Aug 11, 2017 at 6:03 AM, Marko Rauhamaa wrote: >>> I see no point in CPython's rotation magic. >> >> Have you ever implemented a hashtable? The most common way to pick a >> bucket for an object is to use modulo on the number of buckets. > > Like I said earlier, CPython takes the __hash__() value and scrambles > it. Look for "perturb" in: > > > > From a comment: > > Now the probe sequence depends (eventually) on every bit in the hash > code, and the pseudo-scrambling property of recurring on 5*j+1 is > more valuable, because it quickly magnifies small differences in the > bits that didn't affect the initial index. I'm aware of this. Doesn't change the fact that the *INITIAL INDEX* is based on exactly what I said. Yaknow? ChrisA From marko at pacujo.net Thu Aug 10 17:17:08 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 11 Aug 2017 00:17:08 +0300 Subject: Planning a Python Course for Beginners References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: <874ltfyvfv.fsf@elektro.pacujo.net> Peter Otten <__peter__ at web.de>: > Marko Rauhamaa wrote: >> I see no point in CPython's rotation magic. > > Let's see: > > $ cat hashperf.py > class A(object): > __slots__ = ["_hash"] > > def __hash__(self): > return self._hash > > def no_magic(): > a = A() > a._hash = id(a) > return a > > def magic(): > a = A() > a._hash = id(a) >> 4 > return a > > $ python3 -m timeit -s 'from hashperf import magic, no_magic; s = > {no_magic() for _ in range(10**5)}' 'for x in s: x in s' > 10 loops, best of 3: 70.7 msec per loop > > $ python3 -m timeit -s 'from hashperf import magic, no_magic; s = {magic() > for _ in range(10**5)}' 'for x in s: x in s' > 10 loops, best of 3: 52.8 msec per loop > > "magic" wins this makeshift test. Other than that you're right ;) That's interesting, but suggests there's something weird (~ suboptimal) going on with CPython's scrambling algorithm. Also, your performance test might yield completely different results on other Python implementations. Apart from uniqueness, there's no particular reason to prefer one __hash__() value over another as long as the interesting bits are inside the CPU's simple integer range. Marko From marko at pacujo.net Thu Aug 10 17:23:20 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 11 Aug 2017 00:23:20 +0300 Subject: Planning a Python Course for Beginners References: <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <87fuczyyts.fsf@elektro.pacujo.net> <878tirywes.fsf@elektro.pacujo.net> Message-ID: <87zib7xgl3.fsf@elektro.pacujo.net> Chris Angelico : > I'm aware of this. Doesn't change the fact that the *INITIAL INDEX* is > based on exactly what I said. > > Yaknow? What you're saying is that CPython heavily prefers the low-order bits to be unique performance-wise. I don't know why that particular heuristic bias was chosen. Marko From rosuav at gmail.com Thu Aug 10 17:31:02 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 11 Aug 2017 07:31:02 +1000 Subject: Planning a Python Course for Beginners In-Reply-To: <874ltfyvfv.fsf@elektro.pacujo.net> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <874ltfyvfv.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 11, 2017 at 7:17 AM, Marko Rauhamaa wrote: > That's interesting, but suggests there's something weird (~ suboptimal) > going on with CPython's scrambling algorithm. Also, your performance > test might yield completely different results on other Python > implementations. > > Apart from uniqueness, there's no particular reason to prefer one > __hash__() value over another as long as the interesting bits are inside > the CPU's simple integer range. Not true. Every time you probe a new location [1], you have to fetch more data from RAM. That delays you significantly. An ideal hashing system is going to give a high probability of giving you an empty bucket on the first try, to minimize the number of main memory accesses required. CPython's scrambling algorithm means that, even when its first try doesn't succeed, there's a good chance that its second will succeed. But that doesn't change the fact that you want the first one to succeed as often as possible. ChrisA [1] Unless it's within the same cache line, which is eight pointers wide on my CPU. Highly unlikely when working with 100,000 pointers. From marko at pacujo.net Thu Aug 10 18:01:14 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 11 Aug 2017 01:01:14 +0300 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <874ltfyvfv.fsf@elektro.pacujo.net> Message-ID: <87valvxetx.fsf@elektro.pacujo.net> Chris Angelico : > On Fri, Aug 11, 2017 at 7:17 AM, Marko Rauhamaa wrote: >> That's interesting, but suggests there's something weird (~ suboptimal) >> going on with CPython's scrambling algorithm. Also, your performance >> test might yield completely different results on other Python >> implementations. >> >> Apart from uniqueness, there's no particular reason to prefer one >> __hash__() value over another as long as the interesting bits are inside >> the CPU's simple integer range. > > Not true. Every time you probe a new location [1], you have to fetch > more data from RAM. That delays you significantly. An ideal hashing > system is going to give a high probability of giving you an empty > bucket on the first try, to minimize the number of main memory > accesses required. > > CPython's scrambling algorithm means that, even when its first try > doesn't succeed, there's a good chance that its second will succeed. > But that doesn't change the fact that you want the first one to > succeed as often as possible. What does all that have to do with where the unique bits are in the hash value? 0x10000000 0x20000000 0x30000000 0x40000000 should be no worse as __hash__() values than 0x1000 0x2000 0x3000 0x4000 or 1 2 3 4 Of course, some algorithms can (and, we have learned, do) prefer some bits over others, but that's inside the implementation black box. I would think every bit should carry an approximately equal weight. Marko From ben+python at benfinney.id.au Thu Aug 10 18:49:39 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Fri, 11 Aug 2017 08:49:39 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <85fuczjaws.fsf@benfinney.id.au> Steve D'Aprano writes: > Every few years, the following syntax comes up for discussion, with > some people saying it isn't obvious what it would do, and others > disagreeing and saying that it is obvious. So I thought I'd do an > informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] I agree that the syntax is confusing. The comprehension encourages thinking in sets: an operation that takes a collection as input, and emits a different collection, through one conceptual operation. Adding ?while? in there encourages thinking not in terms of a single set-based operation, but an iteration of separate operations. That confuses the model, and I no longer have a coherent model about which to reason what the syntax might mean. > For comparison, what would you expect this to return? (Without > actually trying it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] Though ?for? is used elsewhere in Python to mean iteration, ?for? also has strong connotation in mathematics for set-based operations (?the result is foo for all bar, if baz?). So the same confusion doesn't occur: this is a comprehension which is about set-based thinking, which is supported by all the semantic connotations of the syntax. So I think ?while? should not be added to the syntax of comprehension expressions. I agree with those who think it is not obvious what it would mean. -- \ ?I love to go down to the schoolyard and watch all the little | `\ children jump up and down and run around yelling and screaming. | _o__) They don't know I'm only using blanks.? ?Emo Philips | Ben Finney From greg.ewing at canterbury.ac.nz Thu Aug 10 19:14:08 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Fri, 11 Aug 2017 11:14:08 +1200 Subject: Planning a Python Course for Beginners In-Reply-To: References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> <87valvwi17.fsf@elektro.pacujo.net> Message-ID: Python wrote: > Marko Rauhamaa wrote: > >> id() is actually an ideal return value of __hash__(). The only criterion >> is that the returned number should be different if the __eq__() is >> False. That is definitely true for id() > > nan is a clear, simple, undeniable counterexample to that claim. It's a counterexample to the claim that id() *must* be different if __eq__() is False, but that's not the claim that was made. The claim was that it *should* be different, which allows for the possibility that it might not be different. (I'll put away my hairsplitting axe and go away now.) -- Greg From greg.ewing at canterbury.ac.nz Thu Aug 10 19:18:57 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Fri, 11 Aug 2017 11:18:57 +1200 Subject: Planning a Python Course for Beginners In-Reply-To: <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> References: <87k22dqdaw.fsf@elektro.pacujo.net> <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <598c7187$0$1600$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > On Thu, 10 Aug 2017 07:00 pm, Peter Otten wrote: > >> /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid >> excessive hash collisions for dicts and sets */ > > which I think agrees with my comment: using the id() itself would put too many > objects in the same bucket (i.e. too many collisions). I suspect this is more of a minor performance tweak than a vital issue. Otherwise it would mean that dict's algorithm for assigning items to buckets based on the hash isn't all that great. -- Greg From greg.ewing at canterbury.ac.nz Thu Aug 10 19:33:21 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Fri, 11 Aug 2017 11:33:21 +1200 Subject: Planning a Python Course for Beginners In-Reply-To: <87valvxetx.fsf@elektro.pacujo.net> References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <874ltfyvfv.fsf@elektro.pacujo.net> <87valvxetx.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > Of course, some algorithms can (and, we have learned, do) prefer some > bits over others, but that's inside the implementation black box. I > would think every bit should carry an approximately equal weight. Ideally that would be true, but you need to consider the performance cost of making it so. Dict could go to the trouble of thoroughly scrambling the hash bits before even making the first probe, but that would slow down *every* dict lookup. The way things are, it uses a very simple technique for the first probe that *usually* gives good results, which speeds things up overall. -- Greg From mikhailwas at gmail.com Thu Aug 10 22:54:29 2017 From: mikhailwas at gmail.com (Mikhail V) Date: Fri, 11 Aug 2017 04:54:29 +0200 Subject: Proposed new syntax Message-ID: > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > Nice question BTW I'd suppose two possible outcomes: a) It will behave exactly the same as if there was "if" instead of "while" so [1, 2, 3, 4, 5]. b) It will return syntax error, because "while" is a loop statement withot following colon and anything. but at a first glance, "while" reads as "if" as in english. For comparison, what would you expect this to return? (Without actually > trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > > I'd say it will return: [1, 2, 3, 4, 5] How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > No idea... cognitive dissonans ;) By answering I did not test it and did not look into others answers, serious. From steve+python at pearwood.info Fri Aug 11 01:25:49 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 11 Aug 2017 15:25:49 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87fucz1794.fsf@munus.decebal.nl> Message-ID: <598d3fdf$0$1601$c3e8da3$5496439d@news.astraweb.com> On Fri, 11 Aug 2017 06:45 am, Cecil Westerhof wrote: > Correct: > SyntaxError: invalid syntax Perhaps you missed the key words in the subject line, that this is PROPOSED NEW syntax, rather than existing syntax. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 11 01:29:23 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 11 Aug 2017 15:29:23 +1000 Subject: Proposed new syntax References: Message-ID: <598d40b5$0$1601$c3e8da3$5496439d@news.astraweb.com> On Fri, 11 Aug 2017 12:54 pm, Mikhail V wrote: > but at a first glance, "while" reads as "if" as in english. In English the two words don't mean the same thing. That's why if foo: ... and while foo: ... are different. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 11 01:45:28 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 11 Aug 2017 15:45:28 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> Message-ID: <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> On Fri, 11 Aug 2017 08:49 am, Ben Finney wrote: > The comprehension encourages thinking in sets: an operation that takes a > collection as input, and emits a different collection, through one > conceptual operation. > > Adding ?while? in there encourages thinking not in terms of a single > set-based operation, but an iteration of separate operations. That > confuses the model, and I no longer have a coherent model about which to > reason what the syntax might mean. Sorry Ben, you've completely lost me. If you had said that tradition functional style operations such as: map(func, iterable) filter(pred, iterable) "encourages thinking in sets: an operation that takes a collection as input, and emits a different collection, through one conceptual operation" then I would completely agree with you. I agree that is absolutely true: traditional functional programming idioms encourage thinking of looping as a single conceptual operation. For simplicity, both map() and filter() are often implemented as a for loop that operates on one item at a time, in order, but conceptually the map and filter could operate in parallel on all items at once. But that's not the case for list comprehensions and generator expressions (which use almost exactly the same syntax). The sequential, one-item-at-a-time nature isn't a mere implementation detail, it is an essential part of the semantics of the comprehension. Comprehension syntax makes the sequential loop explicit: the loop is right there in the syntax: [expr for x in iterable] It makes no sense to me to argue that this explicit looping construct with a defined order is conceptually "set based". The comprehension: [print(i) for i in (1, 2, 3)] better print the values 1, 2, 3 *in that order* or there is a serious problem. The same is not true of map(), at least not conceptually. >> For comparison, what would you expect this to return? (Without >> actually trying it, thank you.) >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > > Though ?for? is used elsewhere in Python to mean iteration, ?for? also > has strong connotation in mathematics for set-based operations (?the > result is foo for all bar, if baz?). So the same confusion doesn't > occur: this is a comprehension which is about set-based thinking, which > is supported by all the semantic connotations of the syntax. I don't understand this. I *think* what you're saying is "I have internalised the explicit for-loop and think of it as a filter plus a map and no longer think of it as a for-loop", but I'm not sure. > So I think ?while? should not be added to the syntax of comprehension > expressions. I agree with those who think it is not obvious what it > would mean. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From no.email at nospam.invalid Fri Aug 11 04:01:52 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Fri, 11 Aug 2017 01:01:52 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87k22apm6n.fsf@nightsong.com> Steve D'Aprano writes: > What would you expect this syntax to return? > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1,2,3] though the later example is more confusing. I don't think we need this since we have itertools.takewhile: from operator import gt from functools import partial from itertools import takewhile [x + 1 for x in takewhile(partial(gt,5), (0,1,2,999,3,4))] In the eye of the beholder maybe, but I think it's less ugly in Haskell: [x + 1 | x <- takeWhile (< 5) [0,1,2,999,3,4]] From python at example.invalid Fri Aug 11 06:37:24 2017 From: python at example.invalid (Python) Date: Fri, 11 Aug 2017 12:37:24 +0200 Subject: Planning a Python Course for Beginners References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> <87valvwi17.fsf@elektro.pacujo.net> <87lgmrz766.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > Python : > >> Marko Rauhamaa wrote: >> I didn't disagree with any of these statements about __hash__, but only >> your statement about id and __eq__: >> >>> id() is actually an ideal return value of __hash__(). The only >>> criterion is that the returned number should be different if the >>> __eq__() is False. That is definitely true for id() >> >> nan is a clear, simple, undeniable counterexample to that claim. > > Still, I don't see the point you are trying to make. You do have a cognitive disease, don't you? From alain at universite-de-strasbourg.fr.invalid Fri Aug 11 06:58:47 2017 From: alain at universite-de-strasbourg.fr.invalid (Alain Ketterlin) Date: Fri, 11 Aug 2017 12:58:47 +0200 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87bmnm4bh4.fsf@universite-de-strasbourg.fr.invalid> Ian Kelly writes: > On Thu, Aug 10, 2017 at 8:28 AM, Steve D'Aprano > wrote: >> What would you expect this syntax to return? >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > I would expect the for to be an outer loop and the while to be an > inner, so this would loop infinitely. +1. By the way, how is that supposed to be parsed? Is it (sorry for the braces): {for x in for x in (0, 1, 2, 999, 3, 4)} {while x < 5} or {for x in {(0, 1, 2, 999, 3, 4) while x < 5}} I mean: would the "while ..." be another comp_iter [1], or be a qualifier for an iterable/generator? If the former, it doesn't make any sense unless you allow side-effects in the comprehension's expression (as Ian pointed out), and this would be a very bad idea. If the latter, it could make more sense, similar to conditional expressions (but I still dislike it, and don't think such a feature requires syntactic support). -- Alain. [1] https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries From storchaka at gmail.com Fri Aug 11 08:48:36 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Fri, 11 Aug 2017 15:48:36 +0300 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: 10.08.17 17:28, Steve D'Aprano ????: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] I would expect it to be equivalent to the following code: result = [] for x in (0, 1, 2, 999, 3, 4): while x < 5: result.append(x + 1) This is an infinite loop. > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] result = [] for x in (0, 1, 2, 999, 3, 4): if x < 5: result.append(x + 1) > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] result = [] for x in (0, 1, 2, 999, 3, 4): while x < 5: for y in (100, 200): result.append(x + y) > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] result = [] for x in (0, 1, 2, 999, 3, 4): if x < 5: for y in (100, 200): result.append(x + y) From storchaka at gmail.com Fri Aug 11 08:53:33 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Fri, 11 Aug 2017 15:53:33 +0300 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: 10.08.17 23:28, Ian Kelly ????: > So, perhaps a better syntax could be: > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5 else break] (0, 1, 2, 999, 3, 4) if x < 5 else break looks too similar to the ternary operator. From marko at pacujo.net Fri Aug 11 09:02:51 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 11 Aug 2017 16:02:51 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87h8xew938.fsf@elektro.pacujo.net> Serhiy Storchaka : > 10.08.17 17:28, Steve D'Aprano ????: >> What would you expect this syntax to return? >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > I would expect it to be equivalent to the following code: > > result = [] > for x in (0, 1, 2, 999, 3, 4): > while x < 5: > result.append(x + 1) And I would expect this: result = [] for x in (0, 1, 2, 999, 3, 4): if not x < 5: break result.append(x + 1) Marko From breamoreboy at gmail.com Fri Aug 11 09:20:09 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Fri, 11 Aug 2017 06:20:09 -0700 (PDT) Subject: ActiveState recipes now on github Message-ID: FYI - please see https://www.activestate.com/blog/2017/08/code-recipes-now-github-5000-recipes-python-perl-ruby-and-more Kindest regards. Mark Lawrence. From ned at nedbatchelder.com Fri Aug 11 10:37:53 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Fri, 11 Aug 2017 10:37:53 -0400 Subject: Planning a Python Course for Beginners In-Reply-To: References: <87efslqb3x.fsf@elektro.pacujo.net> <873791q7cg.fsf@elektro.pacujo.net> <87shh0q2g2.fsf@elektro.pacujo.net> <87a8381xgb.fsf@elektro.pacujo.net> <598c139b$0$2878$c3e8da3$76491128@news.astraweb.com> <8760dvy2er.fsf@elektro.pacujo.net> <871sojy14i.fsf@elektro.pacujo.net> <87valvwi17.fsf@elektro.pacujo.net> <87lgmrz766.fsf@elektro.pacujo.net> Message-ID: <3b98af34-676b-7d6a-b4c3-33f439181d83@nedbatchelder.com> On 8/11/17 6:37 AM, Python wrote: > Marko Rauhamaa wrote: >> Python : >> >>> Marko Rauhamaa wrote: >>> I didn't disagree with any of these statements about __hash__, but only >>> your statement about id and __eq__: >>> >>>> id() is actually an ideal return value of __hash__(). The only >>>> criterion is that the returned number should be different if the >>>> __eq__() is False. That is definitely true for id() >>> >>> nan is a clear, simple, undeniable counterexample to that claim. >> >> Still, I don't see the point you are trying to make. > > You do have a cognitive disease, don't you? > > > Maybe it's time to just drop it, rather than starting to insult each other? --Ned. From ian.g.kelly at gmail.com Fri Aug 11 10:39:52 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 11 Aug 2017 08:39:52 -0600 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 11, 2017 at 6:53 AM, Serhiy Storchaka wrote: > 10.08.17 23:28, Ian Kelly ????: >> >> So, perhaps a better syntax could be: >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5 else break] > > > (0, 1, 2, 999, 3, 4) if x < 5 else break > > looks too similar to the ternary operator. It is entirely intentional and a point in its favor, in my view, that "x + 1 ... if x < 5 else break" resembles the ternary operator, as it basically is a special syntax of that. But I take your point that it also resembles the ternary in "(0, 1, 2, 999, 3, 4) if x < 5 else break", which could lead to some confusion. From torriem at gmail.com Fri Aug 11 10:45:14 2017 From: torriem at gmail.com (Michael Torrie) Date: Fri, 11 Aug 2017 08:45:14 -0600 Subject: Proposed new syntax In-Reply-To: <598d40b5$0$1601$c3e8da3$5496439d@news.astraweb.com> References: <598d40b5$0$1601$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 08/10/2017 11:29 PM, Steve D'Aprano wrote: > On Fri, 11 Aug 2017 12:54 pm, Mikhail V wrote: > >> but at a first glance, "while" reads as "if" as in english. > > In English the two words don't mean the same thing. But actually in some contexts they really do seem to mean the same thing: Make hay while the sun shines. If it's sunny, make hay. Essentially the same meaning, though we can argue whether "while" implies some kind of long-running activity that the if does not. Particularly people who are learning English may not even see the difference between while and if as far as a logical statement, similar to the ones above, goes. > > That's why > > if foo: > ... > > > and > > while foo: > ... > > > are different. In computer languages, sure. Spoken language is certainly not so clear cut. From ian.g.kelly at gmail.com Fri Aug 11 11:02:15 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 11 Aug 2017 09:02:15 -0600 Subject: Proposed new syntax In-Reply-To: <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 10, 2017 at 11:45 PM, Steve D'Aprano wrote: > On Fri, 11 Aug 2017 08:49 am, Ben Finney wrote: > >> The comprehension encourages thinking in sets: an operation that takes a >> collection as input, and emits a different collection, through one >> conceptual operation. >> >> Adding ?while? in there encourages thinking not in terms of a single >> set-based operation, but an iteration of separate operations. That >> confuses the model, and I no longer have a coherent model about which to >> reason what the syntax might mean. > > > Sorry Ben, you've completely lost me. > > If you had said that tradition functional style operations such as: > > map(func, iterable) > > filter(pred, iterable) > > "encourages thinking in sets: an operation that takes a collection as input, and > emits a different collection, through one conceptual operation" > > then I would completely agree with you. I agree that is absolutely true: > traditional functional programming idioms encourage thinking of looping as a > single conceptual operation. For simplicity, both map() and filter() are often > implemented as a for loop that operates on one item at a time, in order, but > conceptually the map and filter could operate in parallel on all items at once. > > But that's not the case for list comprehensions and generator expressions (which > use almost exactly the same syntax). The sequential, one-item-at-a-time nature > isn't a mere implementation detail, it is an essential part of the semantics of > the comprehension. > > Comprehension syntax makes the sequential loop explicit: the loop is right there > in the syntax: > > [expr for x in iterable] This is a peculiarity of Python. Here's a list comprehension in Haskell, which has supported them since version 1.0 in 1990, much longer than Python: [x * 2 | x <- L, x * x > 3] The same thing in Erlang: [2*X || X <- L, X*X > 3] C#: var ns = from x in L where x*x > 3 select x*2; (Note "from", not "for") Scheme: (list-ec (: x 100) (if (> (* x x) 3)) (* x 2)) The grand-daddy of them all, NPL (which actually called them "set comprehensions" after mathematics): setofeven(X) <= <:x: x in X & even(x) :> Nothing about any of these suggests a loop or a requirement for serial processing. Granted, there are other languages I've not listed here that use loop syntax like Python. >> Though ?for? is used elsewhere in Python to mean iteration, ?for? also >> has strong connotation in mathematics for set-based operations (?the >> result is foo for all bar, if baz?). So the same confusion doesn't >> occur: this is a comprehension which is about set-based thinking, which >> is supported by all the semantic connotations of the syntax. > > I don't understand this. I *think* what you're saying is "I have internalised > the explicit for-loop and think of it as a filter plus a map and no longer > think of it as a for-loop", but I'm not sure. More like, "Python has externalized the list comprehension as a for loop despite the rich tradition to the contrary." From ben.usenet at bsb.me.uk Fri Aug 11 15:49:32 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 11 Aug 2017 20:49:32 +0100 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87r2whc2b7.fsf@bsb.me.uk> Steve D'Aprano writes: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] These are not unclear (I think I'd guess that same as most people) but adding a new while clause, and the existing if clause, both seem to be rather narrow solutions. The general solution would be to filter the iterable (if that's the right term for it). In Haskell: [x+1 | x <- takeWhile (<5) [0, 1, 2, 999, 3, 4]] [x+1 | x <- filter (<5) [0, 1, 2, 999, 3, 4]] I am sure you can already do this in Python but presumably it's not convenient or there would be little incentive to build "takeWhile" into the language. -- Ben. From steve+python at pearwood.info Fri Aug 11 20:44:10 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 12 Aug 2017 10:44:10 +1000 Subject: Proposed new syntax References: <598d40b5$0$1601$c3e8da3$5496439d@news.astraweb.com> Message-ID: <598e4f5d$0$1603$c3e8da3$5496439d@news.astraweb.com> On Sat, 12 Aug 2017 12:45 am, Michael Torrie wrote: > On 08/10/2017 11:29 PM, Steve D'Aprano wrote: >> On Fri, 11 Aug 2017 12:54 pm, Mikhail V wrote: >> >>> but at a first glance, "while" reads as "if" as in english. >> >> In English the two words don't mean the same thing. > But actually in some contexts they really do seem to mean the same thing: > > Make hay while the sun shines. > If it's sunny, make hay. > > Essentially the same meaning, though we can argue whether "while" > implies some kind of long-running activity that the if does not. We really shouldn't argue about that, because that is the crux of the difference. If \If\, conj. 1. In case that; granting, allowing, or supposing that; -- introducing a condition or supposition. [1913 Webster] While \While\, conj. 1. During the time that; as long as; whilst; at the same time that; as, while I write, you sleep. "While I have time and space." --Chaucer. [1913 Webster] Of course there is overlap: both are conjunctions, both depend on a condition, but the fundamental difference is that of duration. Your two examples are not actually equivalent: "Make hay while the sun shines" implies that making hay is a process you can continue for as long as the sun continues to shine; "If it's sunny, make hay" implies that making hay is a once-off job that you do once, provided it is sunny, and then go on to do other things even if it remains sunny. And that is why the English proverb is the first, not the second. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rustompmody at gmail.com Fri Aug 11 22:41:31 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Fri, 11 Aug 2017 19:41:31 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> On Friday, August 11, 2017 at 8:33:32 PM UTC+5:30, Ian wrote: > The grand-daddy of them all, NPL (which actually called them "set > comprehensions" after mathematics): > > setofeven(X) <= <:x: x in X & even(x) :> Thanks for reminding of NPL; will add it to my history summary at http://blog.languager.org/2015/04/cs-history-1.html > > > Nothing about any of these suggests a loop or a requirement for serial > processing. Granted, there are other languages I've not listed here > that use loop syntax like Python. > > > >> Though ?for? is used elsewhere in Python to mean iteration, ?for? also > >> has strong connotation in mathematics for set-based operations (?the > >> result is foo for all bar, if baz?). So the same confusion doesn't > >> occur: this is a comprehension which is about set-based thinking, which > >> is supported by all the semantic connotations of the syntax. > > > > I don't understand this. I *think* what you're saying is "I have internalised > > the explicit for-loop and think of it as a filter plus a map and no longer > > think of it as a for-loop", but I'm not sure. > > More like, "Python has externalized the list comprehension as a for > loop despite the rich tradition to the contrary." Very true. Like Occam's razor, we have a Guido-razor "Minimize new keywords? which helps compatibility across language versions but not comprehension (of not just comprehensions!) Actually list comprehensions go further than NPL to SETL except that they were called ?set-formers? not ?set-comprehensions' [ My conjecture: The word ?comprehension? used this way in English is meaningless and is probably an infelicious translation of something which makes sense in German] Interestingly from the SETL manual [4 page 22] about Set-formers in SETL (SETL term for set-comprehension) ?The SETL iterator has exactly the same form as a loop iterator, except that the keyword for is omitted? History-Capsule (as I understand it): List comprehensions in python (2.0 c. 2000) come from haskell [1] [2] Haskell (c. 1990) got it from Miranda Miranda (c. 1980) got it from SETL [4] SETL (c. 1960) main innovation was sets, sequences and 'set-builder notation' whose SETL name was 'set-former' nowadays called comprehension notation SETL, as best as I know, is the first computer language using the math notation ? which itself goes back to Zermelo (c. 1930) who gave his axiomatization for set theory? ?Containing the comprehension-axiom [3] ?Which was needed to avoid problems like Russell's paradox R = {x | x ? x} is disallowed, since allows to directly derive the contradiction R?R iff R?R So the axiom-of-comprehension mandated by Zermelo/Fraenkel is that one must define R from some previous set P R = {x ? P | x ? x} which in more programmerish notation becomes R = {x | x ? P, x ? x} which renders the x ? x harmless Or more pythonically: R = {x for x in P if x not in x} [1] https://docs.python.org/3/whatsnew/2.0.html [2] https://docs.python.org/3/howto/functional.html [3] https://en.wikipedia.org/wiki/Axiom_schema_of_specification [4] http://cs.nyu.edu/~bacon/setl/doc-legacy/setlprog.pdf From jussi.piitulainen at helsinki.fi Sat Aug 12 03:47:29 2017 From: jussi.piitulainen at helsinki.fi (Jussi Piitulainen) Date: Sat, 12 Aug 2017 10:47:29 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> Message-ID: Rustom Mody writes: > [ My conjecture: The word ?comprehension? used this way in English is > meaningless and is probably an infelicious translation of something > which makes sense in German] >From a Latin word for "taking together", through Middle French, according to this source, which has further details: https://en.wiktionary.org/wiki/comprehension https://en.wiktionary.org/wiki/comprehensio#Latin https://en.wiktionary.org/wiki/comprehendo#Latin From marko at pacujo.net Sat Aug 12 04:54:55 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sat, 12 Aug 2017 11:54:55 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> Message-ID: <87shgxw4gw.fsf@elektro.pacujo.net> Jussi Piitulainen : > Rustom Mody writes: >> [ My conjecture: The word ?comprehension? used this way in English is >> meaningless and is probably an infelicious translation of something >> which makes sense in German] > > From a Latin word for "taking together", through Middle French, Metaphors' galore: English: understand < stand under something French: comprendre < take something in German: verstehen < stand in front of something Finnish: ymm?rt?? < surround something all mean the same thing. Marko From jussi.piitulainen at helsinki.fi Sat Aug 12 06:50:53 2017 From: jussi.piitulainen at helsinki.fi (Jussi Piitulainen) Date: Sat, 12 Aug 2017 13:50:53 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa writes: > Jussi Piitulainen writes: > >> Rustom Mody writes: >>> [ My conjecture: The word ?comprehension? used this way in English is >>> meaningless and is probably an infelicious translation of something >>> which makes sense in German] >> >> From a Latin word for "taking together", through Middle French, > > Metaphors' galore: > > English: understand < stand under something > French: comprendre < take something in > German: verstehen < stand in front of something > Finnish: ymm?rt?? < surround something > > all mean the same thing. English also has "comprehend" (in English it seems to me opaque). Finnish also has "k?sitt??" 'understand' < 'get a hold of', from "k?si" 'hand' (at least it looks to me like it might be so derived). But what is "set comprehension" in French, German, or Finnish? From __peter__ at web.de Sat Aug 12 07:55:09 2017 From: __peter__ at web.de (Peter Otten) Date: Sat, 12 Aug 2017 13:55:09 +0200 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> Message-ID: Rustom Mody wrote: > [ My conjecture: The word ?comprehension? used this way in English is > meaningless and is probably an infelicious translation of something which > makes sense in German] The meaning of comprehension is probably closer to "comprise" than "comprehend". https://en.wiktionary.org/wiki/comprise """ ...from Latin comprehendere... ...To be made up of; to consist of... """ From rustompmody at gmail.com Sat Aug 12 08:05:51 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Sat, 12 Aug 2017 05:05:51 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> Message-ID: <92da9fe6-4270-4b9e-86b8-02ca8eb9c8fd@googlegroups.com> On Saturday, August 12, 2017 at 5:25:43 PM UTC+5:30, Peter Otten wrote: > Rustom Mody wrote: > > > [ My conjecture: The word ?comprehension? used this way in English is > > meaningless and is probably an infelicious translation of something which > > makes sense in German] > > The meaning of comprehension is probably closer to "comprise" than > "comprehend". > > https://en.wiktionary.org/wiki/comprise > """ > ...from Latin comprehendere... > > ...To be made up of; to consist of... > """ Yeah? I guessed something like that 1,2,3,4 is ?just? a set which, when we put brackets round them {1,2,3,4} is, well, 'comprised' :-) Sounds silly? Less so if we say it as ?The set comprising of?" [In all probability when Zermelo/Fraenkel were doing their stuff they did not really distinguish between what today python calls a set-literal and a set-comprehension] From larry.martell at gmail.com Sat Aug 12 08:22:35 2017 From: larry.martell at gmail.com (Larry Martell) Date: Sat, 12 Aug 2017 08:22:35 -0400 Subject: cpython version Message-ID: For the first time in my 30+ year career I am, unfortunately, working on Windows. A package I need, rpy2, comes in various flavors for different cpython versions: rpy2?2.7.8?cp27?none?win32.whl rpy2?2.7.8?cp27?none?win_amd64.whl rpy2?2.7.8?cp34?none?win32.whl rpy2?2.7.8?cp34?none?win_amd64.whl rpy2?2.7.8?cp35?none?win32.whl rpy2?2.7.8?cp35?none?win_amd64.whl rpy2?2.8.6?cp35?cp35m?win32.whl rpy2?2.8.6?cp35?cp35m?win_amd64.whl rpy2?2.8.6?cp36?cp36m?win32.whl rpy2?2.8.6?cp36?cp36m?win_amd64.whl I am running python version 2.7.13. How can I find out my cpython version? From larry.martell at gmail.com Sat Aug 12 08:24:54 2017 From: larry.martell at gmail.com (Larry Martell) Date: Sat, 12 Aug 2017 08:24:54 -0400 Subject: cpython version In-Reply-To: References: Message-ID: On Sat, Aug 12, 2017 at 8:22 AM, Larry Martell wrote: > For the first time in my 30+ year career I am, unfortunately, working > on Windows. A package I need, rpy2, comes in various flavors for > different cpython versions: > > rpy2?2.7.8?cp27?none?win32.whl > rpy2?2.7.8?cp27?none?win_amd64.whl > rpy2?2.7.8?cp34?none?win32.whl > rpy2?2.7.8?cp34?none?win_amd64.whl > rpy2?2.7.8?cp35?none?win32.whl > rpy2?2.7.8?cp35?none?win_amd64.whl > rpy2?2.8.6?cp35?cp35m?win32.whl > rpy2?2.8.6?cp35?cp35m?win_amd64.whl > rpy2?2.8.6?cp36?cp36m?win32.whl > rpy2?2.8.6?cp36?cp36m?win_amd64.whl > > I am running python version 2.7.13. How can I find out my cpython version? Never mind - not enough sleep or coffee. Obviously cp27 for python 2.7. From python.list at tim.thechases.com Sat Aug 12 09:20:39 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Sat, 12 Aug 2017 08:20:39 -0500 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <20170812082039.50d60204@bigbox.christie.dr> On 2017-08-11 00:28, Steve D'Aprano wrote: > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1, 2, 3] I would see this "while-in-a-comprehension" as a itertools.takewhile() sort of syntactic sugar: >>> [x + 1 for x in takewhile(lambda m: m < 5, (0,1,2,999,3,4))] [1, 2, 3] > For comparison, what would you expect this to return? [snip] > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, > 200)] This one could make sense as either [100, 200, 101, 201, 102, 202] or [100, 101, 102] (I think the default evaluation order of nested "for"s in a comprehension would produce the former rather than the latter) Thus it would be good to define behavior for both of these cases: [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] vs. [x + y for x in (0, 1, 2, 999, 3, 4) for y in (100, 200) while x < 5] -tkc Things would get even weirder when you have nested loopings like that and one of the sources is an iterator. -tkc From rosuav at gmail.com Sat Aug 12 10:09:21 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 13 Aug 2017 00:09:21 +1000 Subject: cpython version In-Reply-To: References: Message-ID: On Sat, Aug 12, 2017 at 10:24 PM, Larry Martell wrote: > On Sat, Aug 12, 2017 at 8:22 AM, Larry Martell wrote: >> For the first time in my 30+ year career I am, unfortunately, working >> on Windows. A package I need, rpy2, comes in various flavors for >> different cpython versions: >> >> rpy2?2.7.8?cp27?none?win32.whl >> rpy2?2.7.8?cp27?none?win_amd64.whl >> rpy2?2.7.8?cp34?none?win32.whl >> rpy2?2.7.8?cp34?none?win_amd64.whl >> rpy2?2.7.8?cp35?none?win32.whl >> rpy2?2.7.8?cp35?none?win_amd64.whl >> rpy2?2.8.6?cp35?cp35m?win32.whl >> rpy2?2.8.6?cp35?cp35m?win_amd64.whl >> rpy2?2.8.6?cp36?cp36m?win32.whl >> rpy2?2.8.6?cp36?cp36m?win_amd64.whl >> >> I am running python version 2.7.13. How can I find out my cpython version? > > Never mind - not enough sleep or coffee. Obviously cp27 for python 2.7. Correct. I'd take it one further, though, and suggest that you shouldn't need to match it yourself; just use pip to download and install the right wheel. It'll match versions, architectures, and anything else it needs to match. ChrisA From larry.martell at gmail.com Sat Aug 12 10:24:06 2017 From: larry.martell at gmail.com (Larry Martell) Date: Sat, 12 Aug 2017 10:24:06 -0400 Subject: cpython version In-Reply-To: References: Message-ID: On Sat, Aug 12, 2017 at 10:09 AM, Chris Angelico wrote: > On Sat, Aug 12, 2017 at 10:24 PM, Larry Martell wrote: >> On Sat, Aug 12, 2017 at 8:22 AM, Larry Martell wrote: >>> For the first time in my 30+ year career I am, unfortunately, working >>> on Windows. A package I need, rpy2, comes in various flavors for >>> different cpython versions: >>> >>> rpy2?2.7.8?cp27?none?win32.whl >>> rpy2?2.7.8?cp27?none?win_amd64.whl >>> rpy2?2.7.8?cp34?none?win32.whl >>> rpy2?2.7.8?cp34?none?win_amd64.whl >>> rpy2?2.7.8?cp35?none?win32.whl >>> rpy2?2.7.8?cp35?none?win_amd64.whl >>> rpy2?2.8.6?cp35?cp35m?win32.whl >>> rpy2?2.8.6?cp35?cp35m?win_amd64.whl >>> rpy2?2.8.6?cp36?cp36m?win32.whl >>> rpy2?2.8.6?cp36?cp36m?win_amd64.whl >>> >>> I am running python version 2.7.13. How can I find out my cpython version? >> >> Never mind - not enough sleep or coffee. Obviously cp27 for python 2.7. > > Correct. I'd take it one further, though, and suggest that you > shouldn't need to match it yourself; just use pip to download and > install the right wheel. It'll match versions, architectures, and > anything else it needs to match. Problem is that rpy2 will not install with pip. It gets: Error: Tried to guess R's HOME but no command 'R' in the PATH. Even though R's HOME is in the PATH. Googling this I found it's a very common problem, with no solution I could find. I finally found a post by the author of rpy that says "There is no official support for Windows,". and he refers people to this site http://www.lfd.uci.edu/~gohlke/pythonlibs/#rpy2 that has 'unofficial and unstable' prebuilt windows binaries for it. If anyone is interested as to why I am embarking on this very unpleasant task, I have a django app that runs in linux. I have successfully deployed it with Docker, vagrant/VirtualBox, VMware, kvm, and on bare metal. But now I have prospective client that refuses to run linux, even in a VM. So I am tying to get my app running on Windows Server 2016, piece by painful piece. From marko at pacujo.net Sat Aug 12 11:58:48 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sat, 12 Aug 2017 18:58:48 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> Message-ID: <87k228wzev.fsf@elektro.pacujo.net> Jussi Piitulainen : > But what is "set comprehension" in French, German, or Finnish? The comprehension principle has to do with the assumption in Naive Set Theory that for any logical predicate, there is a corresponding set. To put it in plain English, every adjective is equivalent to a collection and vice versa. [I'm sure you know this, Jussi, but not everybody might.] The Finnish Wikipedia entry uses the term "abstraktioskeema" (Engl. "abstraction scheme", ). I have not heard that term before, and Google doesn't find other hits for it. Myself, I might propose the word "koonta" as a simple Finnish translation for "comprehension". Marko From python at mrabarnett.plus.com Sat Aug 12 12:12:04 2017 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 12 Aug 2017 17:12:04 +0100 Subject: Proposed new syntax In-Reply-To: <87shgxw4gw.fsf@elektro.pacujo.net> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> Message-ID: <86e04ac5-05cb-ab90-4443-7155a67e1a3e@mrabarnett.plus.com> On 2017-08-12 09:54, Marko Rauhamaa wrote: > Jussi Piitulainen : > >> Rustom Mody writes: >>> [ My conjecture: The word ?comprehension? used this way in English is >>> meaningless and is probably an infelicious translation of something >>> which makes sense in German] >> >> From a Latin word for "taking together", through Middle French, > > Metaphors' galore: > > English: understand < stand under something Its etymology is here: http://www.etymonline.com/index.php?term=understand > French: comprendre < take something in > German: verstehen < stand in front of something > Finnish: ymm?rt?? < surround something > > all mean the same thing. > From marko at pacujo.net Sat Aug 12 14:04:15 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sat, 12 Aug 2017 21:04:15 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> Message-ID: <87tw1c8xy8.fsf@elektro.pacujo.net> Marko Rauhamaa : > Jussi Piitulainen : > >> But what is "set comprehension" in French, German, or Finnish? > > [...] > > Myself, I might propose the word "koonta" as a simple Finnish > translation for "comprehension". And maybe "culling" or "gleaning" could work in English. Marko From v+python at g.nevcal.com Sat Aug 12 18:36:28 2017 From: v+python at g.nevcal.com (Glenn Linderman) Date: Sat, 12 Aug 2017 15:36:28 -0700 Subject: Proposed new syntax In-Reply-To: <86e04ac5-05cb-ab90-4443-7155a67e1a3e@mrabarnett.plus.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <86e04ac5-05cb-ab90-4443-7155a67e1a3e@mrabarnett.plus.com> Message-ID: On 8/12/2017 9:12 AM, MRAB wrote: > On 2017-08-12 09:54, Marko Rauhamaa wrote: >> Jussi Piitulainen : >> >>> Rustom Mody writes: >>>> [ My conjecture: The word ?comprehension? used this way in English is >>>> meaningless and is probably an infelicious translation of something >>>> which makes sense in German] >>> >>> From a Latin word for "taking together", through Middle French, >> >> Metaphors' galore: >> >> English: understand < stand under something > > Its etymology is here: > > http://www.etymonline.com/index.php?term=understand > >> French: comprendre < take something in >> German: verstehen < stand in front of something >> Finnish: ymm?rt?? < surround something >> >> all mean the same thing. >> I really don't think that "comprehension" in English, in the manner used for Python set manipulation, is equivalent at all to the English word "understand". For the Python comprehension, the word is more related to "complete", or "exhaustive", as in "comprehensive" (covering all possibilities). While a comprehensive explanation of something might lead to an understanding of that something, teaching is not really a requirement of being comprehensive. Being comprehensive is sometimes a good attribute of teaching, or understanding, however. One might think they understand something, but they only understand in part, they might not have a comprehensive understanding. An example of this is Newtonian physics gives an understanding of various physical phenomena, but Einstein's theory of relativity shows that Newtonian physics is only a partial understanding, not a comprehensive one. And maybe someday there'll be a theory that demonstrates that relativity is only a partial understanding as well (someone chime in if that is already true!). Glenn From j.clarke.873638 at gmail.com Sat Aug 12 20:54:29 2017 From: j.clarke.873638 at gmail.com (J. Clarke) Date: Sat, 12 Aug 2017 20:54:29 -0400 Subject: Recent Spam problem References: Message-ID: In article , skybuck2000 at hotmail.com says... > > I see two solutions: > > 1. We build new architecture or adept current one so it's more like a blockchain, have to calculate some hash before being able to post and upload and such. > > or > > 2. We counter-attack by installing a special tool, so we all denial of service attack the source of the message, I am not sure if the source is genuine information, what you make of it: > > NNTP-Posting-Host: 39.52.70.224 > > > Now the first solution would require a lot of work. > > The second solution would be easy to do. > > My question to you is: > > What solution do you pick of any ? =D It would be really nice if someone could convince radical Islam that spammers are offensive to Mohammed. After a few of them got hunted down and blown up, the rest might take the hint. From jussi.piitulainen at helsinki.fi Sun Aug 13 00:25:10 2017 From: jussi.piitulainen at helsinki.fi (Jussi Piitulainen) Date: Sun, 13 Aug 2017 07:25:10 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> <87tw1c8xy8.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa writes: > Marko Rauhamaa : > >> Jussi Piitulainen : >> >>> But what is "set comprehension" in French, German, or Finnish? >> >> [...] >> >> Myself, I might propose the word "koonta" as a simple Finnish >> translation for "comprehension". > > And maybe "culling" or "gleaning" could work in English. Nice. From marko at pacujo.net Sun Aug 13 03:34:33 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Sun, 13 Aug 2017 10:34:33 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <86e04ac5-05cb-ab90-4443-7155a67e1a3e@mrabarnett.plus.com> Message-ID: <87k2279b06.fsf@elektro.pacujo.net> Glenn Linderman : > I really don't think that "comprehension" in English, in the manner > used for Python set manipulation, is equivalent at all to the English > word "understand". Correct. However, the two meanings of "comprehension" have a common etymological ancestor. The literal meaning in Latin was "taking in", "gathering". Both "take in" and "gather" have similar metaphorical meanings in Modern English, as well. Marko From steve+python at pearwood.info Sun Aug 13 09:04:15 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sun, 13 Aug 2017 23:04:15 +1000 Subject: data ecosystem References: <84ff023c-ef40-410c-8b2f-33669af1ebd0@googlegroups.com> Message-ID: <59904e50$0$1617$c3e8da3$5496439d@news.astraweb.com> On Sun, 13 Aug 2017 10:34 am, Man with No Name wrote: > So.... > > I've an idea to make use of python's unique environment (>>>) to form a > peer-to-peer object-sharing ecosystem. Sounds perfectly awful. By the way, Python's interactive interpreter (>>>) is hardly unique. Just off the top of my head, I can think of Lua, Julia, Clojure, Ruby, Haskell, Erlang, Rhino (Javascript), Scala, Boo, F# and PHP which all have either a standard interactive interpreter, or if not standard, at least a well-known one. Pretty much any programming language *could* have an interactive interpreter, if somebody spent the effort to build one. > Just pie-in-the-sky brainstorming... > > When a programmer (or object-user) starts up the python environment, the > environment can check for an internet connection and if present connect to a > central "name service" to provide a list of trusted peers which will form a > back-end, networked, data-object ecosystem. The day that my Python interpreter automatically connects to a peer-to-peer network of other people, "trusted" or not, to download code, will be the day I stop using the Python interpreter. [...] > Python would be breaking new ground, I think (.NET comes perhaps the closest) > for living up to the dream of OOP of a true re-useable object and programmer > ecosystem. The thing about re-useable software components is that it turns out that most of them aren't that re-useable. > I quite like the idea that vigil (see github) What is vigil, and what does it have to do with github? > offered for two keywords that > would offer a very nice contract environment for trusting other objects which > I think will be essential for standardizing objects across the ecosystem. What makes you think that "standardizing objects across the ecosystem" is something that should be done? Such a programming monoculture would be a terrible mistake. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From irmen.NOSPAM at xs4all.nl Sun Aug 13 09:50:59 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Sun, 13 Aug 2017 15:50:59 +0200 Subject: wrote a commodore-64 emulator using just Python Message-ID: <59905943$0$704$e4fe514c@news.xs4all.nl> Hi, As another experiment with using just tkinter for graphics, this time I created a Commodore-64 emulator. You can find it here https://github.com/irmen/pyc64 You only need the pillow library to be able to run this. I guess most people have that one already anyway. It works pretty well :) (although having some slight speed/timing issues on windows) Now, it's not a "true" emulator: obviously it doesn't simulate the C64 on a hardware level. It does however implement enough to load and run simple basic programs that can show interesting PETSCII pictures by manipulating the colors and characters on the screen. And perhaps you can think of doing some other silly things because part of the BASIC dialect is just executed using eval() in python. What about hooking this up as a ssh client to get access to your server in a way nobody thought possible? :-P There's also https://github.com/mnaberez/py65 so... possibilities? Fun fact: emulator source is smaller than 64KB Cheers Irmen. From larry.martell at gmail.com Sun Aug 13 10:02:31 2017 From: larry.martell at gmail.com (Larry Martell) Date: Sun, 13 Aug 2017 10:02:31 -0400 Subject: wrote a commodore-64 emulator using just Python In-Reply-To: <59905943$0$704$e4fe514c@news.xs4all.nl> References: <59905943$0$704$e4fe514c@news.xs4all.nl> Message-ID: On Sun, Aug 13, 2017 at 9:50 AM, Irmen de Jong wrote: > Hi, > > As another experiment with using just tkinter for graphics, this time I created a > Commodore-64 emulator. You can find it here https://github.com/irmen/pyc64 > You only need the pillow library to be able to run this. I guess most people have that > one already anyway. > > It works pretty well :) (although having some slight speed/timing issues on windows) > > Now, it's not a "true" emulator: obviously it doesn't simulate the C64 on a hardware > level. It does however implement enough to load and run simple basic programs that can > show interesting PETSCII pictures by manipulating the colors and characters on the screen. > > And perhaps you can think of doing some other silly things because part of the BASIC > dialect is just executed using eval() in python. What about hooking this up as a ssh > client to get access to your server in a way nobody thought possible? :-P > There's also https://github.com/mnaberez/py65 so... possibilities? > > > Fun fact: emulator source is smaller than 64KB > > Cheers > Irmen. > -- > https://mail.python.org/mailman/listinfo/python-list From larry.martell at gmail.com Sun Aug 13 10:03:27 2017 From: larry.martell at gmail.com (Larry Martell) Date: Sun, 13 Aug 2017 10:03:27 -0400 Subject: wrote a commodore-64 emulator using just Python In-Reply-To: <59905943$0$704$e4fe514c@news.xs4all.nl> References: <59905943$0$704$e4fe514c@news.xs4all.nl> Message-ID: On Sun, Aug 13, 2017 at 9:50 AM, Irmen de Jong wrote: > Hi, > > As another experiment with using just tkinter for graphics, this time I created a > Commodore-64 emulator. You can find it here https://github.com/irmen/pyc64 > You only need the pillow library to be able to run this. I guess most people have that > one already anyway. > > It works pretty well :) (although having some slight speed/timing issues on windows) > > Now, it's not a "true" emulator: obviously it doesn't simulate the C64 on a hardware > level. It does however implement enough to load and run simple basic programs that can > show interesting PETSCII pictures by manipulating the colors and characters on the screen. > > And perhaps you can think of doing some other silly things because part of the BASIC > dialect is just executed using eval() in python. What about hooking this up as a ssh > client to get access to your server in a way nobody thought possible? :-P > There's also https://github.com/mnaberez/py65 so... possibilities? > > > Fun fact: emulator source is smaller than 64KB Damn! I should have saved my Cave Of The Word Wizard floppies. From steve+python at pearwood.info Sun Aug 13 10:36:02 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 14 Aug 2017 00:36:02 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> On Sat, 12 Aug 2017 01:02 am, Ian Kelly wrote: > On Thu, Aug 10, 2017 at 11:45 PM, Steve D'Aprano > wrote: >> Comprehension syntax makes the sequential loop explicit: the loop is right >> there in the syntax: >> >> [expr for x in iterable] > > This is a peculiarity of Python. Yes? We're talking about Python? I haven't accidentally been posting to comp.lang.anything-but-python have I? *wink* I am not referring to syntax from other languages. (One wonders what a list comprehension in Whitespace would look like...) We're talking about Python, which prefers explicit English-like executable pseudo-code over implicit cryptic mathematical symbolic expressions. Python prefers to be explicit, rather than implicit: that's why purely functional idioms like map, filter and reduce are less idiomatic than comprehensions. But for the record, this is not a peculiarity of Python by any means. I count at least a dozen other languages which use an explicit "for" in their comprehension syntax: Boo, Ceylon, Clojure, CoffeeScript, Common Lisp, Cobra, Elixir, F#, Mozilla's Javascript, Julia, Perl6, Racket and Scala. https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28list_comprehension%29 And very possibly the first language with comprehensions, SETL (from 1969), used "forall": [n in [2..N] | forall m in {2..n - 1} | n mod m > 0] https://en.wikipedia.org/wiki/List_comprehension#History > Here's a list comprehension in > Haskell, which has supported them since version 1.0 in 1990, much > longer than Python: > > [x * 2 | x <- L, x * x > 3] Sure. In Haskell, comprehensions are *implicit* loops, rather than explicit like in Python. Python's comprehensions are inspired by Haskell's, but we made different choices than they did: we make the fact that a comprehension is a loop over values explicit, rather than implicit, and we use words instead of cryptic symbols. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From grant.b.edwards at gmail.com Sun Aug 13 12:00:44 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Sun, 13 Aug 2017 16:00:44 +0000 (UTC) Subject: Recent Spam problem References: Message-ID: On 2017-08-13, J. Clarke wrote: > In article , skybuck2000 at hotmail.com says... >> >> I see two solutions: > It would be really nice if someone could convince radical Islam that > spammers are offensive to Mohammed. After a few of them got hunted down > and blown up, the rest might take the hint. It would be really nice if someone could convice people to stopped replying to spam posted from googlegroups. That way people who've taken the common-sense approach and plonked all postings from google groups wouldn't have to see them. -- Grant From python.list at tim.thechases.com Sun Aug 13 17:55:08 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Sun, 13 Aug 2017 16:55:08 -0500 Subject: Proposed new syntax In-Reply-To: <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: <20170813165508.6cd30108@bigbox.christie.dr> On 2017-08-14 00:36, Steve D'Aprano wrote: > Python's comprehensions are inspired by Haskell's, but we made > different choices than they did: we make the fact that a > comprehension is a loop over values explicit, rather than implicit, > and we use words instead of cryptic symbols. I keep wanting to like Haskell for some of the concepts & optimizations it can do, but the whole "words instead of cryptic symbols" readability thing keeps me coming back to Python. -tkc From greg.ewing at canterbury.ac.nz Sun Aug 13 18:55:40 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Mon, 14 Aug 2017 10:55:40 +1200 Subject: Proposed new syntax In-Reply-To: <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > Python's comprehensions are inspired by Haskell's, but we made different choices > than they did: we make the fact that a comprehension is a loop over values > explicit, rather than implicit, and we use words instead of cryptic symbols. The presence of the word "for" in the comprehension syntax doesn't by itself imply that the values are generated by a sequential loop. Comprehensions in Python are intended to be read declaratively. The definition in terms of an expansion into nested loops may imply that if you take it absolutely literally, but when I devised that expansion I only meant it as a way of defining the result -- I didn't intend the equivalence to extend to side effects. However, Steve's other points remain -- Python's overall style is one of explicitness and clarity. The proposed extensions don't fit into that style. -- Greg From steve+python at pearwood.info Sun Aug 13 20:42:07 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 14 Aug 2017 10:42:07 +1000 Subject: data ecosystem References: <84ff023c-ef40-410c-8b2f-33669af1ebd0@googlegroups.com> <59904e50$0$1617$c3e8da3$5496439d@news.astraweb.com> <7a1998a1-311e-4e9c-b907-d48e9c9daa6e@googlegroups.com> Message-ID: <5990f1e1$0$1616$c3e8da3$5496439d@news.astraweb.com> On Mon, 14 Aug 2017 07:39 am, Man with No Name wrote: >> Pretty much any programming language *could* have an interactive interpreter, >> if somebody spent the effort to build one. > > Are you sure? Yes. >> The thing about re-useable software components is that it turns out that most >> of them aren't that re-useable. > > Exactly. I think you're onto something, this re-useability thing. That is > why I argue that the goals of re-useability can be realized with making all > objects have a standard API. That whizzing noise you heard was my point flying just over your head. >> > I quite like the idea that vigil (see github) >> >> What is vigil, and what does it have to do with github? > > It's a software project over at... github,. You should have said, and provided a link. >> What makes you think that "standardizing objects across the ecosystem" is >> something that should be done? > > It makes it easier to reuse code just as your high-level language of choice > allows you to standardize the way you access the underlying machine. Get it? There's only a limited number of underlying machines. The programming ecosystem has an effectively infinite number of problems to solve. Being forced to use your solution to some problem does not necessarily make it easier for my to solve some slightly different problem. Hence my point about software re-useability. > It's pretty cool. There are exabytes of data out there, most of it pretty > categorizable into probably log(N) categories. Oh, it's "cool" is it? Then we should definitely do whatever is "cool" this week. By the way... are you aware that OOP is just one programming paradigm out of many, and despite the hype that it was going to solve all our programming problems, it has turned out to be far from the silver bullet that proponents claimed it would be? >> Such a programming monoculture would be a >> terrible mistake. > > Hmmm. Is python becoming a "programming monoculture"? No. > Shouldn't you use some C and Haskell code in there too? How do you know that I don't? Plenty of people use C, Fortran, Java, R and Julia code in their Python projects. If you've ever used numpy, you're using C or Fortran. I don't know about Haskell -- I suppose somebody has built a Python/Haskell interface by now, but I don't know for sure. > Thanks for your educated input. I detect a note of sarcasm. You did ask for our opinion -- if you had only wanted people who agreed with you to answer, you should have said so. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Sun Aug 13 20:49:44 2017 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 14 Aug 2017 10:49:44 +1000 Subject: data ecosystem In-Reply-To: <5990f1e1$0$1616$c3e8da3$5496439d@news.astraweb.com> References: <84ff023c-ef40-410c-8b2f-33669af1ebd0@googlegroups.com> <59904e50$0$1617$c3e8da3$5496439d@news.astraweb.com> <7a1998a1-311e-4e9c-b907-d48e9c9daa6e@googlegroups.com> <5990f1e1$0$1616$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Mon, Aug 14, 2017 at 10:42 AM, Steve D'Aprano wrote: > On Mon, 14 Aug 2017 07:39 am, Man with No Name wrote: I've no idea who you're responding to. Those posts aren't coming through at my end. ChrisA From steve+python at pearwood.info Sun Aug 13 21:21:59 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 14 Aug 2017 11:21:59 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5990fb37$0$1615$c3e8da3$5496439d@news.astraweb.com> On Mon, 14 Aug 2017 08:55 am, Gregory Ewing wrote: > Steve D'Aprano wrote: > >> Python's comprehensions are inspired by Haskell's, but we made different >> choices than they did: we make the fact that a comprehension is a loop over >> values explicit, rather than implicit, and we use words instead of cryptic >> symbols. > > The presence of the word "for" in the comprehension syntax doesn't > by itself imply that the values are generated by a sequential loop. > Comprehensions in Python are intended to be read declaratively. Where is that documented? Why not use a declarative syntax, like "select where", instead of a procedural syntax, if the intention is to read them declaratively? > The definition in terms of an expansion into nested loops may > imply that if you take it absolutely literally, but when I > devised that expansion I only meant it as a way of defining > the result -- I didn't intend the equivalence to extend to side > effects. Oh, you're to blame for that expansion are you? :-) The core devs now take it literally: Nick and (if I remember correctly) Guido have commented that any future expansions to comprehension syntax must fit into that nested block expansion. In any case, whatever your intention, that equivalence *does* extend to side effects, and it applies to generator expressions as well as comprehensions. I wish that we had standardised on the term "generator comprehension" instead, to emphasise that generator expressions and comprehensions share the same syntax, the same implementation, and the same order of side-effects. (There was a time that list comps and gen expressions had different implementations, and consequently list comps accidentally exposed their loop variable while gen exprs didn't, but that's been fixed in Python 3.) I would argue that in a language like Python that allows side-effects, such a procedural approach should be mandatory: the alternative is that code including comprehensions would be non-deterministic. While it is conceivable that the list comprehension: [x for x in seq] could generate its values in arbitrary order, that does not apply to generator expressions, set comprehensions or dict expressions: (x for x in seq) {x for x in seq} {x:None for x in seq} - Generator expressions have to yield their values in the same order as the input from seq provides them; - set and dict comprehensions have to deal with collisions, in which case the last key seen wins. If they were declarative, there would be no way to reason about which key was seen last. Given the expectation that generator expressions and all three kinds of comprehension should operate the same way, we have no choice but to read them procedurally as a for-loop. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rustompmody at gmail.com Sun Aug 13 22:13:35 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Sun, 13 Aug 2017 19:13:35 -0700 (PDT) Subject: data ecosystem In-Reply-To: <84ff023c-ef40-410c-8b2f-33669af1ebd0@googlegroups.com> References: <84ff023c-ef40-410c-8b2f-33669af1ebd0@googlegroups.com> Message-ID: <9b43c385-b2cf-49f7-9692-56e993ba83b6@googlegroups.com> On Sunday, August 13, 2017 at 6:04:42 AM UTC+5:30, Man with No Name wrote: > So.... > > I've an idea to make use of python's unique environment (>>>) to form a peer-to-peer object-sharing ecosystem. > > Just pie-in-the-sky brainstorming... > > When a programmer (or object-user) starts up the python environment, the environment can check for an internet connection and if present connect to a central "name service" to provide a list of trusted peers which will form a back-end, networked, data-object ecosystem. > > What syntax? > > Well, Mr. Tim Peters seemed to have an idea with namespaces (~/modules/doctest.py). Namespaces could form an ontology (or "folksonomy") of objects (visualization, networking, database templates, applications, etc.) based on a tree data structure, probably and be accessed by some method such as __namespace__.globals.networking.www.myscrapeobject or some similar syntax. > > The namespace could be a global, synchronized object repository as well as holding local copies. I ?Mark? the piquant point that the ?Man with No Name? wishes to suggest global namespaces ? On a more serious note: REST uses URLs as (syntax for) RPC (which above follows respectable industry standard called ASS: Alphabet Soup Simplistified ) From rustompmody at gmail.com Mon Aug 14 00:06:08 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Sun, 13 Aug 2017 21:06:08 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> On Monday, August 14, 2017 at 4:26:06 AM UTC+5:30, Gregory Ewing wrote: > Steve D'Aprano wrote: > > > Python's comprehensions are inspired by Haskell's, but we made different choices > > than they did: we make the fact that a comprehension is a loop over values > > explicit, rather than implicit, and we use words instead of cryptic symbols. > > The presence of the word "for" in the comprehension syntax doesn't > by itself imply that the values are generated by a sequential loop. > > Comprehensions in Python are intended to be read declaratively. > The definition in terms of an expansion into nested loops may Thanks for speaking up Greg [Creator of comprehensions in python 2??] Here's a bunch of different ways in which a mapping comprehension could be implemented: def sq(x): return x*x Just a trivial example def simple(f, l): r = [] for i in range(0,len(l)): r.append(f(l[i])) return r def backwards(f,l): r = [] for i in range(len(l)-1,-1,-1): r.insert(0,f(l[i])) return r def randmap(f,l): """ Map in random order """ from random import shuffle r = [] index = list(range(0,len(l))) shuffle(index) r = [None] * len(l) for i in index: r[i] = f(l[i]) return r def inplace(f, l, lb, le, res): #, rb): """ Helper function: Maps subslice (lb,le) of input l onto (into) output res, with subslice rb,re""" for i in range(lb,le): res[i] = f(l[i]) return None # Side-effecting into res def parprequel0(f,l): """Illustrative trivial prequel to parallelizing version""" r = [None] * len(l) inplace(f,l,0,len(l),r) return r def parprequel1(f,l): """Illustrative prequel to parallelizing version with 2-way split""" r = [None] * len(l) inplace(f,l, 0, len(l)//2, r) inplace(f,l, len(l)//2, len(l), r) return r def par(f,l): """Illustrative prequel to parallelizing version with 2-way split""" from threading import Thread r = [None] * len(l) t1 = Thread(target=inplace, args = (f,l, 0, len(l)//2, r)) t2 = Thread(target=inplace, args = (f,l, len(l)//2, len(l), r)) t1.start() t2.start() t1.join() t2.join() return r From dieter at handshake.de Mon Aug 14 02:14:09 2017 From: dieter at handshake.de (dieter) Date: Mon, 14 Aug 2017 08:14:09 +0200 Subject: Need python script to get last 6 month's monthly billing References: Message-ID: <87y3qmk766.fsf@handshake.de> sandeep.gk789 at gmail.com writes: > I would like to create AWS monthly billing graph using python and python flask.so for this i need python script using that i have to get last 6 month's monthly bill in AWS. > for this, i have created one virtual environment in my local machine. for examplle my ip is: 127.0.0.0:5000. > Here after pull that script, it's automatically connected to AWS and display's last 6 month's data. its my requirement. I agree with Joel: you have explained your problem not particularly well. Apparently, you (unlike me) know a way to get an AWS billing overview. This way is either targeted for human users (likely an HTML based Web interface) or targeted for a program. In the first case, you could try to parse out the relevant information from the received overview page (personally, I would use "lxml" for that; "beautyfulsoup" (maybe spelled slightly differently) (and likely others) can be an alternative). It the second case, you would get a formal description, likely in "xml" or "json" format. Python comes with modules to work with those formates. From dieter at handshake.de Mon Aug 14 02:15:11 2017 From: dieter at handshake.de (dieter) Date: Mon, 14 Aug 2017 08:15:11 +0200 Subject: Package not visible/available on pypi References: Message-ID: <87tw1ak74g.fsf@handshake.de> Kryptxy via Python-list writes: > I had recently uploaded a package on pypi. For some reason, I removed the package, and committed a BIG mistake along the way. > I clicked the DELETE PACKAGE [Warning about NEVER TO CLICK THAT BUTTON] (silly me!) > Now, after re-uploading the package, its not visible on pypi. > How can I fix this? I already have uploaded the package. But it's not visible on pypi (neither under packages in my dashboard). It may take some time before an uploaded package becomes visible. From priisdk at gmail.com Mon Aug 14 03:55:59 2017 From: priisdk at gmail.com (Poul Riis) Date: Mon, 14 Aug 2017 00:55:59 -0700 (PDT) Subject: numpy not working any more Message-ID: <58f6ae18-3401-41db-b857-ee38544592d6@googlegroups.com> For some time I have been using python 3.6.0 on a windows computer. Suddenly, my numpy does not work any more. This one-liner program: import numpy as np results in the long error message below. In an effort to solve the problem I tried to install python 3.6.2 followed by all the modules I need. Here, there was no problem with numpy but then another problem appeared: Installing mayavi apparently needs vtk but pip couldn't find an acceptable vtk version. What is the easiest way to make things work again? Poul Riis Traceback (most recent call last): File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 16, in from . import multiarray ImportError: DLL load failed: Den angivne procedure blev ikke fundet. During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:/pr/python/numpy_test.py", line 1, in import numpy as np File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\__init__.py", line 142, in from . import add_newdocs File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\add_newdocs.py", line 13, in from numpy.lib import add_newdoc File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\__init__.py", line 8, in from .type_check import * File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\lib\type_check.py", line 11, in import numpy.core.numeric as _nx File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 26, in raise ImportError(msg) ImportError: Importing the multiarray numpy extension module failed. Most likely you are trying to import a failed build of numpy. If you're working with a numpy git repo, try `git clean -xdf` (removes all files not under version control). Otherwise reinstall numpy. Original error was: DLL load failed: Den angivne procedure blev ikke fundet. From no.email at nospam.invalid Mon Aug 14 04:27:30 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 14 Aug 2017 01:27:30 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> Message-ID: <87zib2a70t.fsf@nightsong.com> Marko Rauhamaa writes: > Jussi Piitulainen : >> But what is "set comprehension" in French, German, or Finnish? The idea comes from set theory: for some reason English Wikipedia doesn't have Finnish cross-wiki links for most of the relevant terms, but Google translates "axiom of specification" as "M??ritelm?n axiom". Maybe you can find something from there. From no.email at nospam.invalid Mon Aug 14 04:37:14 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 14 Aug 2017 01:37:14 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87valqa6kl.fsf@nightsong.com> Steve D'Aprano writes: > And very possibly the first language with comprehensions, SETL (from 1969), > used "forall" ... It goes back much further, probably to Principia Mathematica, or (with different notation) maybe Frege's Foundations of Arithmetic: https://en.wikipedia.org/wiki/Set-builder_notation I don't think Python should try to turn it into something different. From anthra.norell at bluewin.ch Mon Aug 14 04:47:57 2017 From: anthra.norell at bluewin.ch (Friedrich Rentsch) Date: Mon, 14 Aug 2017 10:47:57 +0200 Subject: Redirecting input of IDLE window Message-ID: Hi, I work interactively in an IDLE window most of the time and find "help (...)" very useful to summarize things. The display comes up directly (doesn't return a text, which I could edit, assign or store). I suspect that there are ways to redirect the display, say to a file. Thanks for suggestions. Frederic From steve+comp.lang.python at pearwood.info Mon Aug 14 04:52:41 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 14 Aug 2017 08:52:41 GMT Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> Message-ID: <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> On Sun, 13 Aug 2017 21:06:08 -0700, Rustom Mody wrote: > Here's a bunch of different ways in which a mapping comprehension could > be implemented: Not in Python they couldn't be, since Python promises deterministic, first-to-last evaluation in the same order as the equivalent for-loop. When a list comprehension is supplied, it consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new list are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce a list element each time the innermost block is reached. https://docs.python.org/2/reference/expressions.html#list-displays The docs for Python 3 are equivalent: https://docs.python.org/3/reference/expressions.html#displays-for-lists- sets-and-dictionaries See also the tutorial, which says more or less the same thing: https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions -- ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From jussi.piitulainen at helsinki.fi Mon Aug 14 04:56:15 2017 From: jussi.piitulainen at helsinki.fi (Jussi Piitulainen) Date: Mon, 14 Aug 2017 11:56:15 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> <87zib2a70t.fsf@nightsong.com> Message-ID: Paul Rubin writes: >> Jussi Piitulainen writes: >>> But what is "set comprehension" in French, German, or Finnish? > > The idea comes from set theory: for some reason English Wikipedia > doesn't have Finnish cross-wiki links for most of the relevant terms, > but Google translates "axiom of specification" as "M??ritelm?n axiom". > Maybe you can find something from there. Most of the relevant pages are missing in the Finnish Wikipedia. However, I did find there a nice name for this axiom schema based on yet another of its many names: "erotteluskeema" ("schema of separation"). I like that. Marko's Finnish suggestion, "koonta", is related to the relevant sense of "comprehension", while his "gleaning" and "culling" relate to "separation". Python's "comprehensions" do both "separation" and "replacement" (another axiom schema), aka filtering and mapping. From marko at pacujo.net Mon Aug 14 05:46:56 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Mon, 14 Aug 2017 12:46:56 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> <87zib2a70t.fsf@nightsong.com> Message-ID: <87valqmqgf.fsf@elektro.pacujo.net> Jussi Piitulainen : > However, I did find there a nice name for this axiom schema based on > yet another of its many names: "erotteluskeema" ("schema of > separation"). I like that. For the non-logicians in the audience, an "axiom schema" is a generator pattern that produces an infinity of actual axioms. For example, the "axiom [schema] of separation" states: ?x ? variables: ?y ? variables: ?? ? first-order formulas: ?z (z ? { x ? y | ? } ? (z ? y ? ?[x/z])) where ?[x/z] refers to a formula obtained from ? by replacing every free occurrence of x with z. Marko From ben+python at benfinney.id.au Mon Aug 14 05:59:47 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Mon, 14 Aug 2017 19:59:47 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> Message-ID: <8560dqjwq4.fsf@benfinney.id.au> Steven D'Aprano writes: > On Sun, 13 Aug 2017 21:06:08 -0700, Rustom Mody wrote: > > > Here's a bunch of different ways in which a mapping comprehension > > could be implemented: > > Not in Python they couldn't be You began by asking what people would expect syntax to mean. Then you expressed surprise that anyone would think a comprehension would be interpreted by the reader as a single operation. The designer of that feature expressed that yes, the intention was that it be interpreted as a single conceptual operation, not a looping sequence of operations. Your latest counter has been that Python means something special, beyond what the feature's designer intended, and it's implemented as a looping sequence of operations. So it's normal to point out that Python's implementation is just one way that it could be implemented, hence the reader can reasonably expect that it's not the way Python implemented it. You were apparently, at the start of this thread, honestly seeking to know how people interpret the syntax. At what point will you accept the feedback: That the comprehension syntax *does not* necessarily connote a procedural loop, but instead can quite reasonably be interpreted as its designer intended, a single conceptual operation. -- \ ?The priesthood have, in all ancient nations, nearly | `\ monopolized learning.? ?John Adams, _Letters to John Taylor_, | _o__) 1814 | Ben Finney From joel.goldstick at gmail.com Mon Aug 14 06:19:46 2017 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Mon, 14 Aug 2017 06:19:46 -0400 Subject: Redirecting input of IDLE window In-Reply-To: References: Message-ID: On Mon, Aug 14, 2017 at 4:47 AM, Friedrich Rentsch wrote: > Hi, > > I work interactively in an IDLE window most of the time and find "help > (...)" very useful to summarize things. The display comes up directly > (doesn't return a text, which I could edit, assign or store). I suspect > that there are ways to redirect the display, say to a file. Thanks for > suggestions. > > > Frederic > > > -- > https://mail.python.org/mailman/listinfo/python-list > do you know about the utility called pydoc? Type it at a command line to learn more. It displays information like help does in a python environment, but you can also redirect it to a file -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From rustompmody at gmail.com Mon Aug 14 07:03:49 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Mon, 14 Aug 2017 04:03:49 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: <4f64c14c-ab39-44d3-acb0-e4aeaf801977@googlegroups.com> On Monday, August 14, 2017 at 3:30:39 PM UTC+5:30, Ben Finney wrote: > Steven D'Aprano writes: > > > On Sun, 13 Aug 2017 21:06:08 -0700, Rustom Mody wrote: > > > > > Here's a bunch of different ways in which a mapping comprehension > > > could be implemented: > > > > Not in Python they couldn't be > > You began by asking what people would expect syntax to mean. > > Then you expressed surprise that anyone would think a comprehension > would be interpreted by the reader as a single operation. > > The designer of that feature expressed that yes, the intention was that > it be interpreted as a single conceptual operation, not a looping > sequence of operations. > > Your latest counter has been that Python means something special, beyond > what the feature's designer intended, and it's implemented as a looping > sequence of operations. > > So it's normal to point out that Python's implementation is just one way > that it could be implemented, hence the reader can reasonably expect > that it's not the way Python implemented it. > > You were apparently, at the start of this thread, honestly seeking to > know how people interpret the syntax. > > At what point will you accept the feedback: That the comprehension > syntax *does not* necessarily connote a procedural loop, but instead can > quite reasonably be interpreted as its designer intended, a single > conceptual operation. ? I thought that this ? Steven's OP ? was some joke or prank question. As best as I could make out all the initial responders giving some supposed meaning to the various 'comprehensions' seemed to be playing along Since I had nothing cute to say? remained quiet Then in quick succession Terry, Cecil, yourself gave responses that I would give in seriousness if anything, better than what I could come up with So once again I had nothing to add I just put in some history to say that yes, you can take the expansion of comprehensions as loops-with-appends given in the python docs as God's Word For myself, if the python docs contradict the last 100 years or prior art/math history, the latter takes precedence All I want to say is the gratuitous incidental resemblance of for-loops with comprehensions confuses not just beginners but even the python implementers: This leak >>> [x for x in range(5)] [0, 1, 2, 3, 4] >>> x 4 >>> got corrected from python2 to 3 >>> [x for x in range(5)] [0, 1, 2, 3, 4] >>> x Traceback (most recent call last): File "", line 1, in NameError: name 'x' is not defined However this leak still remains: >>> fl = [(lambda x : x + i) for i in range(5)] >>> [f(2) for f in fl] [6, 6, 6, 6, 6] Compare to haskell: Prelude> let fl = [(\ x -> x + i) | i <- [0..4]] Prelude> [f 2 | f <- fl] [2,3,4,5,6] Prelude> I strongly suspect this bugginess to be related to Greg's original idea of using that for-loop-containing-append as an informal off-the-cuff explanation becoming the formal definition [And I am still unsure whether this OP is a prank trick-question? ] From steve+python at pearwood.info Mon Aug 14 07:52:32 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 14 Aug 2017 21:52:32 +1000 Subject: data ecosystem References: <84ff023c-ef40-410c-8b2f-33669af1ebd0@googlegroups.com> <9b43c385-b2cf-49f7-9692-56e993ba83b6@googlegroups.com> Message-ID: <59918f02$0$1598$c3e8da3$5496439d@news.astraweb.com> On Mon, 14 Aug 2017 12:13 pm, Rustom Mody wrote: > On Sunday, August 13, 2017 at 6:04:42 AM UTC+5:30, Man with No Name wrote: [...] >> The namespace could be a global, synchronized object repository as well as >> holding local copies. > > I ?Mark? the piquant point that the ?Man with No Name? wishes to suggest > global namespaces ? That's a very good point, and I didn't pick up on that. Thanks for pointing it out. If Man With No Name doesn't actually intend for his proposal to be a world-wide global namespace, perhaps he should explain it a little better. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From irmen at NOSPAM.xs4all.nl Mon Aug 14 10:21:12 2017 From: irmen at NOSPAM.xs4all.nl (Irmen de Jong) Date: Mon, 14 Aug 2017 16:21:12 +0200 Subject: wrote a commodore-64 emulator using just Python In-Reply-To: <59905943$0$704$e4fe514c@news.xs4all.nl> References: <59905943$0$704$e4fe514c@news.xs4all.nl> Message-ID: <5991b1d8$0$809$e4fe514c@news.xs4all.nl> On 08/13/2017 03:50 PM, Irmen de Jong wrote: > Now, it's not a "true" emulator: obviously it doesn't simulate the C64 on a hardware > level. It does however implement enough to load and run simple basic programs that can > show interesting PETSCII pictures by manipulating the colors and characters on the screen. As people have been asking me about this: NO - you cannot run any existing C-64 software with my program. I should have put the word emulator in quotes I suppose. The program is mostly an experiment with tkinter graphics, in this case reproducing the C-64 (textmode) screen. The 'BASIC interpreter' is just enough to be able to print stuff to the screen and POKE the memory to change the contents of the screen and the colors. If you want to run your old c-64 software, use a _real_ emulator such as Vice or ccs64 - this was never my goal :) Irmen From steve+python at pearwood.info Mon Aug 14 10:30:22 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 15 Aug 2017 00:30:22 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <4f64c14c-ab39-44d3-acb0-e4aeaf801977@googlegroups.com> Message-ID: <5991b3ff$0$1609$c3e8da3$5496439d@news.astraweb.com> On Mon, 14 Aug 2017 09:03 pm, Rustom Mody wrote: > For myself, if the python docs contradict the last 100 years or prior art/math > history, the latter takes precedence When theory disagrees with the facts, you ignore the facts? > All I want to say is the gratuitous incidental resemblance of for-loops > with comprehensions confuses not just beginners but even the python > implementers: You have misinterpreted what you are seeing. The Python 2 variable leak has nothing to do with whether comprehensions are for-loops or not. It is a scoping issue: list comps previously shared the same scope as their surrounding, but no longer. > However this leak still remains: > >>>> fl = [(lambda x : x + i) for i in range(5)] >>>> [f(2) for f in fl] > [6, 6, 6, 6, 6] This has nothing to do with list comprehensions or for-loops. We can unroll the loop and demonstrate the same behaviour: fl = [] i = 0 fl.append(lambda x: x + i) i = 1 fl.append(lambda x: x + i) i = 2 fl.append(lambda x: x + i) i = 3 fl.append(lambda x: x + i) i = 4 fl.append(lambda x: x + i) [f(2) for f in fl] It's not a "leak", it's not "bugginess", it has nothing to do with for loops or comprehensions. It's just the standard, normal name resolution. The example in the list comprehension is *slightly* different: the functions there are closures over i, whereas in the unrolled version the functions simply do a global name lookup. But the behaviour is the same because both use late binding semantics: the value of i isn't copied into the function at the time of function creation, it is retrieved only when needed when the function is called. Haskell (it seems) uses early binding instead. Which is "correct"? Both are. Both early and late binding are reasonable design choices, with good reasons for choosing either. Python uses early binding for function default values, and late binding for closures. You might argue for the other choice, but the decision is made and won't change. And neither has anything to do with for-loops. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From __peter__ at web.de Mon Aug 14 10:56:21 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 14 Aug 2017 16:56:21 +0200 Subject: Redirecting input of IDLE window References: Message-ID: Friedrich Rentsch wrote: > Hi, > > I work interactively in an IDLE window most of the time and find > "help (...)" very useful to summarize things. The display comes up > directly (doesn't return a text, which I could edit, assign or store). I > suspect that there are ways to redirect the display, say to a file. > Thanks for suggestions. > > > Frederic Here's a simple example for a custom pager that stores the last help text as a string: >>> import pydoc >>> def mypager(text): global last_help text = pydoc.plain(text) last_help = text print(text) >>> pydoc.pager = mypager >>> help(help) Help on _Helper in module _sitebuiltins object: class _Helper(builtins.object) | Define the builtin 'help'. | | This is a wrapper around pydoc.help that provides a helpful message >>> last_help.splitlines()[0] 'Help on _Helper in module _sitebuiltins object:' From ctippur at gmail.com Mon Aug 14 11:08:15 2017 From: ctippur at gmail.com (Frustrated Learner) Date: Mon, 14 Aug 2017 08:08:15 -0700 (PDT) Subject: Running flask server under virtualenv Message-ID: <869e008d-71a5-4abd-96c4-073aca169abd@googlegroups.com> Hello, I am using Python 3.62 on a mac. I am working under a virtualenv. I generated server code via http://editor.swagger.io (Swagger UI) Steps to reproduce python3 -m venv flaskglobal source flaskglobal/bin/activate cp binary to flaskglobal and unzip contents cd python-flask-server pip install -r requirements.txt python -m swagger_server I am getting the following error when running flask server. I have a model called binary. I am guessing a path issue. In the model, the code is: from __future__ import absolute_import from swagger_server.models.binary import Binary ## <-- Error from .base_model_ import Model from datetime import date, datetime from typing import List, Dict from ..util import deserialize_model ..... Error: from .binary import Binary File "/Users/ctippur/cyclops/cyclopscloud/flaskapi/cyclopsflaskglobal/python-flask-server/swagger_server/models/binary.py", line 4, in from swagger_server.models.binary import Binary Here is the tree for swagger server that got generated via swagger UI (http://editor.swagger.io) ??? Dockerfile ??? README.md ??? git_push.sh ??? requirements.txt ??? setup.py ??? swagger_server ? ??? init.py ? ??? main.py ? ??? pycache ? ? ??? init.cpython-36.pyc ? ? ??? main.cpython-36.pyc ? ? ??? encoder.cpython-36.pyc ? ? ??? util.cpython-36.pyc ? ??? controllers ? ? ??? init.py ? ? ??? default_controller.py ? ??? encoder.py ? ??? models ? ? ??? init.py ? ? ??? pycache ? ? ? ??? init.cpython-36.pyc ? ? ? ??? base_model_.cpython-36.pyc ? ? ? ??? binary.cpython-36.pyc ? ? ? ??? body.cpython-36.pyc ? ? ??? base_model_.py ? ? ??? binary.py Swagger declaration file content or ur Could this be a pythonpath issue? From steve+python at pearwood.info Mon Aug 14 11:12:31 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 15 Aug 2017 01:12:31 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> On Mon, 14 Aug 2017 07:59 pm, Ben Finney wrote: > Steven D'Aprano writes: > >> On Sun, 13 Aug 2017 21:06:08 -0700, Rustom Mody wrote: >> >> > Here's a bunch of different ways in which a mapping comprehension >> > could be implemented: >> >> Not in Python they couldn't be > > You began by asking what people would expect syntax to mean. > > Then you expressed surprise that anyone would think a comprehension > would be interpreted by the reader as a single operation. Yes, and I stand by that. Python list comprehensions are explicitly documented as being equivalent to a loop, the syntax chosen uses the same keyword as a loop, the implementation uses a loop, and when read as pseudo-code they explicitly claim to be a loop. So on what basis would anyone conclude that they aren't loops? That's a genuine question, not a rhetorical question. I meant it when I said I could understand people imagining that the Python 2 versions of map() or filter() could be implemented as something other than a straightforward sequential loop, but I'm puzzled how anyone could imagine that of list comprehensions and generator expressions. The author of the PEP which introduced list comps to the language, Barry Warsaw, wrote: "They [comprehensions] would nest in the same way for loops and if statements nest now." Guido added to the PEP: "The form [... for x... for y...] nests, with the last index varying fastest, just like nested for loops." https://www.python.org/dev/peps/pep-0202/ > The designer of that feature expressed that yes, the intention was that > it be interpreted as a single conceptual operation, not a looping > sequence of operations. What matters is how comprehensions actually *are*, not what Greg intended. - The PEP states that comprehensions are equivalent to loops; if Greg intended different, he should have written the PEP to say so. - The syntax chosen is that of a procedural for-loop, not a declarative "select where" statement. - The semantics of the comprehension is explicitly documented as equivalent to nested for-loops. - Guido blessed both the syntax and the semantics. Greg's intention simply doesn't matter. List comprehensions in Python are as they are documented and implemented, not as he intended them to be. > Your latest counter has been that Python means something special, beyond > what the feature's designer intended, and it's implemented as a looping > sequence of operations. The implementation is the least of my arguments, since it could change to a while loop without affecting the semantics of comprehensions and generator expressions. Or a series of unrolled loops, or to use goto or comefrom for that matter. The critical point is that the actual semantics, as stated in the PEP and the documentation is a for-loop, and the syntax chosen is self-documenting as a for-loop. Greg may have intended that comprehensions being equivalent to nested for-loops be taken as a mere analogy, but that's not the path Python has taken. It is not an analogy, but a language promise that all comprehensions will be semantically equivalent to for-loops. [...] > You were apparently, at the start of this thread, honestly seeking to > know how people interpret the syntax. Indeed. About half the people who responded interpreted it with the same way semantics as the Clojure list comprehensions which inspired it. Some people interpreted it as an infinite loop. You claimed that it was impossible to understand; one person claimed that it would cause unending confusion; one person saw no difference between "while" and "if", and one person seemed to believe that even the existing "if" clause should be a syntax error. > At what point will you accept the feedback: That the comprehension > syntax *does not* necessarily connote a procedural loop, but instead can > quite reasonably be interpreted as its designer intended, a single > conceptual operation. People are free to interpret Python features any way they like, but we don't have to treat them seriously if their interpretation doesn't match the documented semantics of the feature. I might honestly, strongly believe that del x causes the object referenced by x to be garbage collected. I can say that's how it works in other languages, I can say that's what the designer intended all those many years ago, I can even insist that there is no other logical way for del to operate and any other behaviour would be inconceivable and a source of unending confusion. Nevertheless, that isn't how del operates, it isn't how it is documented, and my opinion is simply wrong. If I gave a code review where I insisted that: x = y = some_object() del x print(y) is unsafe because the object has been garbage collected, you would be right to ignore that feedback. Not because you don't like my review, but because it is based on a misconception and is simply factually wrong. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Mon Aug 14 11:17:41 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 15 Aug 2017 01:17:41 +1000 Subject: Running flask server under virtualenv References: <869e008d-71a5-4abd-96c4-073aca169abd@googlegroups.com> Message-ID: <5991bf16$0$1586$c3e8da3$5496439d@news.astraweb.com> On Tue, 15 Aug 2017 01:08 am, Frustrated Learner wrote: > I am getting the following error when running flask server. I have a model > called binary. I am guessing a path issue. In the model, the code is: > > from __future__ import absolute_import > from swagger_server.models.binary import Binary ## <-- Error [...] > Error: > > from .binary import Binary > File > "/Users/ctippur/cyclops/cyclopscloud/flaskapi/cyclopsflaskglobal/python-flask-server/swagger_server/models/binary.py", > line 4, in from swagger_server.models.binary import Binary What's the *entire* traceback? Including the exception type, and the error message. There's a bit of a contradiction in your post. Is the line `from swagger_server.models.binary import Binary` or is it: `from .binary import Binary` ? [...] > Could this be a pythonpath issue? Depends on what exception you're getting, and what the error message says. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ian.g.kelly at gmail.com Mon Aug 14 11:33:33 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Mon, 14 Aug 2017 09:33:33 -0600 Subject: Proposed new syntax In-Reply-To: <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sun, Aug 13, 2017 at 8:36 AM, Steve D'Aprano wrote: > On Sat, 12 Aug 2017 01:02 am, Ian Kelly wrote: > >> On Thu, Aug 10, 2017 at 11:45 PM, Steve D'Aprano >> wrote: > >>> Comprehension syntax makes the sequential loop explicit: the loop is right >>> there in the syntax: >>> >>> [expr for x in iterable] >> >> This is a peculiarity of Python. > > Yes? We're talking about Python? I haven't accidentally been posting to > comp.lang.anything-but-python have I? *wink* > > I am not referring to syntax from other languages. (One wonders what a list > comprehension in Whitespace would look like...) We're talking about Python, > which prefers explicit English-like executable pseudo-code over implicit > cryptic mathematical symbolic expressions. With respect, your own post that I was responding to discussed "traditional functional programming idioms". Why are traditional map/filter on the table for discussion but not traditional list comprehensions? In any case, this thread started with the question of what we would expect a particular list comprehension syntax to look like. While existing Python syntax is certainly important to understanding that (and that was the basis for my own initial response stemming from the knowledge that Python maps fors and ifs to nested blocks and I would expect while to work in the same way), for many Python users their understanding of list comprehensions may not necessarily be rooted in Python syntax, and so I think it is also important to consider how list comprehensions are viewed in other contexts. > But for the record, this is not a peculiarity of Python by any means. I count at > least a dozen other languages which use an explicit "for" in their > comprehension syntax: Yes, as I noted in my reply. > Boo, Ceylon, Clojure, CoffeeScript, Common Lisp, Cobra, Elixir, F#, Mozilla's > Javascript, Julia, Perl6, Racket and Scala. I think some of these take influence from Python. Common Lisp is a bit of an oddball; it doesn't actually have list comprehensions as a distinct syntax. The example given there is just a standard loop using the "collect" keyword. The Javascript example should be removed from that page. The syntax didn't make it into the standard and Mozilla's own documentation has a big red warning saying not to use it. They'll probably eventually remove it from Gecko. > Sure. In Haskell, comprehensions are *implicit* loops, rather than explicit like > in Python. No, they aren't. Haskell list comprehensions use lazy evaluation. Here's an example of an infinite list comprehension: Prelude> let squares = [ x ** 2 | x <- [1 ..] ] :: [Float] Prelude> :print squares squares = (_t1::[Float]) You might say that this is more like a generator expression but the result is in fact a list. We can evaluate the first four elements: Prelude> print $ take 4 squares [1.0,4.0,9.0,16.0] And then see that these have been lazily evaluated in the list: Prelude> :print squares squares = 1.0 : 4.0 : 9.0 : 16.0 : (_t2::[Float]) A Haskell list comprehension is not a loop at all. From tjreedy at udel.edu Mon Aug 14 11:35:46 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 14 Aug 2017 11:35:46 -0400 Subject: Redirecting input of IDLE window In-Reply-To: References: Message-ID: A better subject line would have been Redirecting output interactive help(ob). On 8/14/2017 4:47 AM, Friedrich Rentsch wrote: > I work interactively in an IDLE window most of the time and find > "help (...)" very useful to summarize things. The display comes up > directly (doesn't return a text, which I could edit, assign or store). I > suspect that there are ways to redirect the display, say to a file. Help is added to the global namespace by importing 'site', which is done by default (but can be suppressed). You could suggest on the tracker that it be given a 'file=' option. I have already thought about expanding the help options for IDLE. 1. Put output in a separate editor window, so it does not get in the way of interactive work. Once that is done it could be edited and saved. But: should this be optional? If so, how to invoke the option? I have been waiting until we have tabbed windows, at which point, always putting help output on a new tab would be sensible. 2. Help uses pydoc, which can produce html output. Render that instead of plain text in a separate editor window (as down now with IDLE help). > Thanks for suggestions. Currently, you can copy and paste into a fresh editor window. -- Terry Jan Reedy From rosuav at gmail.com Mon Aug 14 11:40:59 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 15 Aug 2017 01:40:59 +1000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Tue, Aug 15, 2017 at 1:33 AM, Ian Kelly wrote: > On Sun, Aug 13, 2017 at 8:36 AM, Steve D'Aprano >> Sure. In Haskell, comprehensions are *implicit* loops, rather than explicit like >> in Python. > > No, they aren't. Haskell list comprehensions use lazy evaluation. > Here's an example of an infinite list comprehension: > > Prelude> let squares = [ x ** 2 | x <- [1 ..] ] :: [Float] > Prelude> :print squares > squares = (_t1::[Float]) > > You might say that this is more like a generator expression but the > result is in fact a list. We can evaluate the first four elements: > > Prelude> print $ take 4 squares > [1.0,4.0,9.0,16.0] > > And then see that these have been lazily evaluated in the list: > > Prelude> :print squares > squares = 1.0 : 4.0 : 9.0 : 16.0 : (_t2::[Float]) > > A Haskell list comprehension is not a loop at all. What if you don't take the first four, but instead take just the tenth element? Will the preceding elements be calculated too, or do you have a sparse list? If the latter, it's not really comparable to a Python list, but to some sort of cached mapping from input values to output values, which in Python I would implement as a dict with a __missing__ method. And if the former, well, that's still going to have a loop, and it's definitely like a genexp, but genexps have more functionality than they do in Python. ChrisA From tjreedy at udel.edu Mon Aug 14 11:46:59 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 14 Aug 2017 11:46:59 -0400 Subject: Redirecting input of IDLE window In-Reply-To: References: Message-ID: On 8/14/2017 6:19 AM, Joel Goldstick wrote: > do you know about the utility called pydoc? Type it at a command line to > learn more. This only works if a wrapper has been installed in a directory on the system path. 'python -m pydoc' should always work. > It displays information like help does in a python > environment, but you can also redirect it to a file The other way around: help uses pydoc, but help does not expose all of pydoc's options. -- Terry Jan Reedy From ian.g.kelly at gmail.com Mon Aug 14 11:54:25 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Mon, 14 Aug 2017 09:54:25 -0600 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Mon, Aug 14, 2017 at 9:40 AM, Chris Angelico wrote: > On Tue, Aug 15, 2017 at 1:33 AM, Ian Kelly wrote: >> On Sun, Aug 13, 2017 at 8:36 AM, Steve D'Aprano >>> Sure. In Haskell, comprehensions are *implicit* loops, rather than explicit like >>> in Python. >> >> No, they aren't. Haskell list comprehensions use lazy evaluation. >> Here's an example of an infinite list comprehension: >> >> Prelude> let squares = [ x ** 2 | x <- [1 ..] ] :: [Float] >> Prelude> :print squares >> squares = (_t1::[Float]) >> >> You might say that this is more like a generator expression but the >> result is in fact a list. We can evaluate the first four elements: >> >> Prelude> print $ take 4 squares >> [1.0,4.0,9.0,16.0] >> >> And then see that these have been lazily evaluated in the list: >> >> Prelude> :print squares >> squares = 1.0 : 4.0 : 9.0 : 16.0 : (_t2::[Float]) >> >> A Haskell list comprehension is not a loop at all. > > What if you don't take the first four, but instead take just the tenth > element? Will the preceding elements be calculated too, or do you have > a sparse list? If the latter, it's not really comparable to a Python > list, but to some sort of cached mapping from input values to output > values, which in Python I would implement as a dict with a __missing__ > method. And if the former, well, that's still going to have a loop, > and it's definitely like a genexp, but genexps have more functionality > than they do in Python. The answer is, it depends. If it can avoid evaluating the earlier elements it will: Prelude> squares !! 10 121.0 Prelude> :print squares squares = 1.0 : 4.0 : 9.0 : 16.0 : (_t3::Float) : (_t4::Float) : (_t5::Float) : (_t6::Float) : (_t7::Float) : (_t8::Float) : 121.0 : (_t9::[Float]) But sometimes it can't: Prelude> let triangle = [ (i,j) | i <- [1..], j <- [1..i*i] ] Prelude> triangle !! 10 (3,6) Prelude> :print triangle triangle = (1,1) : (2,1) : (2,2) : (2,3) : (2,4) : (3,1) : (3,2) : (3,3) : (3,4) : (3,5) : (3,6) : (_t10::[(Integer, Integer)]) From rosuav at gmail.com Mon Aug 14 12:16:22 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 15 Aug 2017 02:16:22 +1000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Tue, Aug 15, 2017 at 1:54 AM, Ian Kelly wrote: > On Mon, Aug 14, 2017 at 9:40 AM, Chris Angelico wrote: >> On Tue, Aug 15, 2017 at 1:33 AM, Ian Kelly wrote: >>> On Sun, Aug 13, 2017 at 8:36 AM, Steve D'Aprano >>>> Sure. In Haskell, comprehensions are *implicit* loops, rather than explicit like >>>> in Python. >>> >>> No, they aren't. Haskell list comprehensions use lazy evaluation. >>> Here's an example of an infinite list comprehension: >>> >>> Prelude> let squares = [ x ** 2 | x <- [1 ..] ] :: [Float] >>> Prelude> :print squares >>> squares = (_t1::[Float]) >>> >>> You might say that this is more like a generator expression but the >>> result is in fact a list. We can evaluate the first four elements: >>> >>> Prelude> print $ take 4 squares >>> [1.0,4.0,9.0,16.0] >>> >>> And then see that these have been lazily evaluated in the list: >>> >>> Prelude> :print squares >>> squares = 1.0 : 4.0 : 9.0 : 16.0 : (_t2::[Float]) >>> >>> A Haskell list comprehension is not a loop at all. >> >> What if you don't take the first four, but instead take just the tenth >> element? Will the preceding elements be calculated too, or do you have >> a sparse list? If the latter, it's not really comparable to a Python >> list, but to some sort of cached mapping from input values to output >> values, which in Python I would implement as a dict with a __missing__ >> method. And if the former, well, that's still going to have a loop, >> and it's definitely like a genexp, but genexps have more functionality >> than they do in Python. > > The answer is, it depends. If it can avoid evaluating the earlier > elements it will: > > Prelude> squares !! 10 > 121.0 > Prelude> :print squares > squares = 1.0 : 4.0 : 9.0 : 16.0 : (_t3::Float) : (_t4::Float) : > (_t5::Float) : (_t6::Float) : (_t7::Float) : (_t8::Float) : 121.0 : > (_t9::[Float]) > > But sometimes it can't: > > Prelude> let triangle = [ (i,j) | i <- [1..], j <- [1..i*i] ] > Prelude> triangle !! 10 > (3,6) > Prelude> :print triangle > triangle = (1,1) : (2,1) : (2,2) : (2,3) : (2,4) : (3,1) : (3,2) : > (3,3) : (3,4) : (3,5) : (3,6) : (_t10::[(Integer, Integer)]) Well, no, it doesn't depend. It evaluates only those elements that get requested. You just requested all the earlier elements as part of calculating a triangle. :) So it's really nothing to do with a Python list, nor a list comprehension. It's like this lazy map: class Map(dict): def __init__(self, func, *coll): self.func = func self.coll = coll # Collections, not iterables def __missing__(self, key): self[key] = self.func(*(coll[key] for coll in self.coll)) return self[key] >>> squares = Map(lambda x: x*x, range(10000)) >>> squares[5] 25 >>> squares[1000] 1000000 >>> squares {5: 25, 1000: 1000000} Except that the indices used are restricted, presumably. to counting numbers. But still, what you call a lazy list is a function (in the mathematical sense), but not a true collection. ChrisA From rustompmody at gmail.com Mon Aug 14 12:33:58 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Mon, 14 Aug 2017 09:33:58 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: <3e299486-6df9-4d48-af97-e7e948f834f9@googlegroups.com> http://www.cosc.canterbury.ac.nz/greg.ewing/python/listcomp/ Greg's 1999 announcement. If you see the "semantics are equivalent" Steven wins. If you focus on "like other languages" then it's... well not quite equivalent! We can take our pick! For myself, as I earlier said, if python disagrees with math/other-langs, I would typically go with the majoritarian view From tjreedy at udel.edu Mon Aug 14 13:04:40 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 14 Aug 2017 13:04:40 -0400 Subject: Proposed new syntax In-Reply-To: <8560dqjwq4.fsf@benfinney.id.au> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: On 8/14/2017 5:59 AM, Ben Finney wrote: > At what point will you accept the feedback: That the comprehension > syntax *does not* necessarily connote a procedural loop, but instead can > quite reasonably be interpreted as its designer intended, a single > conceptual operation. In a world where functions have 'side-effects', which is to say, implicit inputs and outputs, procedural order is necessary for predictable outcomes. The 'single conception operation' is ambiguious. Suppose stdin contains "a\nb\nc\nd\ne\nf\ng\n". What is the meaning of [input(f"response{i}") for i in range(6)]? In Python, the predictable result is ['a', 'b', 'c', 'd', 'e', 'f'] It would not be with some of Rustom Mody's 'equivalents'. Or let L = . This implementation of list reversal: [L.pop() for i in range(len(L))] Do not functional languages define comprehensions in terms of recursion, equivalent to for loops? -- Terry Jan Reedy From ctippur at gmail.com Mon Aug 14 13:39:32 2017 From: ctippur at gmail.com (Frustrated learner) Date: Mon, 14 Aug 2017 10:39:32 -0700 (PDT) Subject: Running flask server under virtualenv In-Reply-To: <869e008d-71a5-4abd-96c4-073aca169abd@googlegroups.com> References: <869e008d-71a5-4abd-96c4-073aca169abd@googlegroups.com> Message-ID: My bad. I was playing around with it. It should be: from swagger_server.models.binary import Binary From mok-kong.shen at t-online.de Mon Aug 14 14:21:55 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Mon, 14 Aug 2017 20:21:55 +0200 Subject: A question on modification of a list via a function invocation Message-ID: I ran the attached program and got the following output: [1, 2, 3] [3, 6, 9] I don't understand why the modification doesn't work in the case of test() but does work in the case of test1(). Thanks for your help in advance. M. K. Shen ------------------------------------------------------------ def test(alist): alist=[3,6,9] return def test1(alist): alist[0],alist[1],alist[2]=3,6,9 return ss=[1,2,3] test(ss) print(ss) test1(ss) print(ss) From ctippur at gmail.com Mon Aug 14 14:46:53 2017 From: ctippur at gmail.com (Frustrated learner) Date: Mon, 14 Aug 2017 11:46:53 -0700 (PDT) Subject: Running flask server under virtualenv In-Reply-To: <869e008d-71a5-4abd-96c4-073aca169abd@googlegroups.com> References: <869e008d-71a5-4abd-96c4-073aca169abd@googlegroups.com> Message-ID: Here is the complete stack trace Traceback (most recent call last): File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 193, in _run_module_as_main "__main__", mod_spec) File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/runpy.py", line 85, in _run_code exec(code, run_globals) File "/Users/ctippur/cyclops/cyclopscloud/flaskapi/cyclopsflaskglobal/python-flask-server/swagger_server/__main__.py", line 4, in from .encoder import JSONEncoder File "/Users/ctippur/cyclops/cyclopscloud/flaskapi/cyclopsflaskglobal/python-flask-server/swagger_server/encoder.py", line 2, in from swagger_server.models.base_model_ import Model File "/Users/ctippur/cyclops/cyclopscloud/flaskapi/cyclopsflaskglobal/python-flask-server/swagger_server/models/__init__.py", line 5, in from .binary import Binary File "/Users/ctippur/cyclops/cyclopscloud/flaskapi/cyclopsflaskglobal/python-flask-server/swagger_server/models/binary.py", line 4, in from swagger_server.models.binary import Binary ImportError: cannot import name 'Binary' From ned at nedbatchelder.com Mon Aug 14 14:50:51 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Mon, 14 Aug 2017 14:50:51 -0400 Subject: A question on modification of a list via a function invocation In-Reply-To: References: Message-ID: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> On 8/14/17 2:21 PM, Mok-Kong Shen wrote: > I ran the attached program and got the following output: > > [1, 2, 3] > [3, 6, 9] > > I don't understand why the modification doesn't work in the case of > test() but does work in the case of test1(). > > Thanks for your help in advance. > > M. K. Shen > > ------------------------------------------------------------ > > def test(alist): > alist=[3,6,9] > return > > def test1(alist): > alist[0],alist[1],alist[2]=3,6,9 > return > > ss=[1,2,3] > test(ss) > print(ss) > test1(ss) > print(ss) This reassigns the name alist: alist = [3, 6, 9]. That changes the local variable, but cannot affect the caller's variables. This leaves alist as the same object, but reassigns its elements, mutating the list: alist[0] = 3 This talk has more details: https://nedbatchelder.com/text/names1.html --Ned. From mok-kong.shen at t-online.de Mon Aug 14 15:21:45 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Mon, 14 Aug 2017 21:21:45 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> Message-ID: Am 14.08.2017 um 20:50 schrieb Ned Batchelder: > On 8/14/17 2:21 PM, Mok-Kong Shen wrote: >> I ran the attached program and got the following output: >> >> [1, 2, 3] >> [3, 6, 9] >> >> I don't understand why the modification doesn't work in the case of >> test() but does work in the case of test1(). >> >> Thanks for your help in advance. >> >> M. K. Shen >> >> ------------------------------------------------------------ >> >> def test(alist): >> alist=[3,6,9] >> return >> >> def test1(alist): >> alist[0],alist[1],alist[2]=3,6,9 >> return >> >> ss=[1,2,3] >> test(ss) >> print(ss) >> test1(ss) >> print(ss) > > This reassigns the name alist: alist = [3, 6, 9]. That changes the > local variable, but cannot affect the caller's variables. > > This leaves alist as the same object, but reassigns its elements, > mutating the list: alist[0] = 3 > > This talk has more details: https://nedbatchelder.com/text/names1.html I could more or less understand that in test() alist is interpreted as local but in the extended program below in test2() I first write the same as in test1(), after which I logically assume that the name alist is now known as global and then I write alist=[30,60,90] but that doesn't have any effect globally, since I get the output: [1, 2, 3] [3, 6, 9] [3, 6, 9] Could you please explain that? M. K. Shen --------------------------------------------------------- def test(alist): alist=[3,6,9] return def test1(alist): alist[0],alist[1],alist[2]=3,6,9 return def test2(alist): alist[0],alist[1],alist[2]=3,6,9 alist=[30,60,90] return ss=[1,2,3] test(ss) print(ss) test1(ss) print(ss) test2(ss) print(ss) From jobmattcon at gmail.com Mon Aug 14 15:29:58 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Mon, 14 Aug 2017 12:29:58 -0700 (PDT) Subject: why k means do not rectangle the red area drawn by harris corner? Message-ID: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> https://gist.github.com/hoyeunglee/df7e6cb9b76c576b26fd2bb2b26bfe2f sample image https://drive.google.com/file/d/0Bxs_ao6uuBDUY09qM1JMWS1Ob0k/view?usp=sharing would like to rectangle bound the eye ,mouth corner etc which detected by harris corner but using kmeans can not rectangle the red area drawn by harris corner From ned at nedbatchelder.com Mon Aug 14 15:53:22 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Mon, 14 Aug 2017 15:53:22 -0400 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> Message-ID: <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> On 8/14/17 3:21 PM, Mok-Kong Shen wrote: > Am 14.08.2017 um 20:50 schrieb Ned Batchelder: >> On 8/14/17 2:21 PM, Mok-Kong Shen wrote: >>> I ran the attached program and got the following output: >>> >>> [1, 2, 3] >>> [3, 6, 9] >>> >>> I don't understand why the modification doesn't work in the case of >>> test() but does work in the case of test1(). >>> >>> Thanks for your help in advance. >>> >>> M. K. Shen >>> >>> ------------------------------------------------------------ >>> >>> def test(alist): >>> alist=[3,6,9] >>> return >>> >>> def test1(alist): >>> alist[0],alist[1],alist[2]=3,6,9 >>> return >>> >>> ss=[1,2,3] >>> test(ss) >>> print(ss) >>> test1(ss) >>> print(ss) >> >> This reassigns the name alist: alist = [3, 6, 9]. That changes the >> local variable, but cannot affect the caller's variables. >> >> This leaves alist as the same object, but reassigns its elements, >> mutating the list: alist[0] = 3 >> >> This talk has more details: https://nedbatchelder.com/text/names1.html > > I could more or less understand that in test() alist is interpreted as > local but in the extended program below in test2() I first write the > same as in test1(), after which I logically assume that the name alist > is now known as global and then I write alist=[30,60,90] but that > doesn't have any effect globally, since I get the output: > > [1, 2, 3] > [3, 6, 9] > [3, 6, 9] > > Could you please explain that? > > M. K. Shen > --------------------------------------------------------- > > def test(alist): > alist=[3,6,9] > return > > def test1(alist): > alist[0],alist[1],alist[2]=3,6,9 > return > > def test2(alist): > alist[0],alist[1],alist[2]=3,6,9 > alist=[30,60,90] > return > > ss=[1,2,3] > test(ss) > print(ss) > test1(ss) > print(ss) > test2(ss) > print(ss) Your test2 function first mutates the caller's list by assigning alist[0]=3, then it rebinds the local name alist to be a new list. So the caller's list is now [3, 6, 9]. --Ned. From mok-kong.shen at t-online.de Mon Aug 14 16:02:30 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Mon, 14 Aug 2017 22:02:30 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> Message-ID: <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> Am 14.08.2017 um 21:53 schrieb Ned Batchelder: > On 8/14/17 3:21 PM, Mok-Kong Shen wrote: >> Am 14.08.2017 um 20:50 schrieb Ned Batchelder: >>> On 8/14/17 2:21 PM, Mok-Kong Shen wrote: >>>> I ran the attached program and got the following output: >>>> >>>> [1, 2, 3] >>>> [3, 6, 9] >>>> >>>> I don't understand why the modification doesn't work in the case of >>>> test() but does work in the case of test1(). >>>> >>>> Thanks for your help in advance. >>>> >>>> M. K. Shen >>>> >>>> ------------------------------------------------------------ >>>> >>>> def test(alist): >>>> alist=[3,6,9] >>>> return >>>> >>>> def test1(alist): >>>> alist[0],alist[1],alist[2]=3,6,9 >>>> return >>>> >>>> ss=[1,2,3] >>>> test(ss) >>>> print(ss) >>>> test1(ss) >>>> print(ss) >>> >>> This reassigns the name alist: alist = [3, 6, 9]. That changes the >>> local variable, but cannot affect the caller's variables. >>> >>> This leaves alist as the same object, but reassigns its elements, >>> mutating the list: alist[0] = 3 >>> >>> This talk has more details: https://nedbatchelder.com/text/names1.html >> >> I could more or less understand that in test() alist is interpreted as >> local but in the extended program below in test2() I first write the >> same as in test1(), after which I logically assume that the name alist >> is now known as global and then I write alist=[30,60,90] but that >> doesn't have any effect globally, since I get the output: >> >> [1, 2, 3] >> [3, 6, 9] >> [3, 6, 9] >> >> Could you please explain that? >> >> M. K. Shen >> --------------------------------------------------------- >> >> def test(alist): >> alist=[3,6,9] >> return >> >> def test1(alist): >> alist[0],alist[1],alist[2]=3,6,9 >> return >> >> def test2(alist): >> alist[0],alist[1],alist[2]=3,6,9 >> alist=[30,60,90] >> return >> >> ss=[1,2,3] >> test(ss) >> print(ss) >> test1(ss) >> print(ss) >> test2(ss) >> print(ss) > > Your test2 function first mutates the caller's list by assigning > alist[0]=3, then it rebinds the local name alist to be a new list. So > the caller's list is now [3, 6, 9]. Sorry for my poor knowledge. After the line alist[0]..., what is the status of the name alist? It's now a global name, right? So why in the line following that the name alist would suddenly be interpreted as local? I can't yet fully comprehend the logic behind that. M. K. Shen . From oliver.schoenborn at gmail.com Mon Aug 14 16:10:56 2017 From: oliver.schoenborn at gmail.com (oliver) Date: Mon, 14 Aug 2017 20:10:56 +0000 Subject: A question on modification of a list via a function invocation In-Reply-To: <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> Message-ID: It is not a global because accessing an item of a list does not change whether it is global or local. It would only be global if you declared it global via a "global" statement. Can you give an example, that would help determine the issue. On Mon, 14 Aug 2017 at 16:06 Mok-Kong Shen wrote: > Am 14.08.2017 um 21:53 schrieb Ned Batchelder: > > On 8/14/17 3:21 PM, Mok-Kong Shen wrote: > >> Am 14.08.2017 um 20:50 schrieb Ned Batchelder: > >>> On 8/14/17 2:21 PM, Mok-Kong Shen wrote: > >>>> I ran the attached program and got the following output: > >>>> > >>>> [1, 2, 3] > >>>> [3, 6, 9] > >>>> > >>>> I don't understand why the modification doesn't work in the case of > >>>> test() but does work in the case of test1(). > >>>> > >>>> Thanks for your help in advance. > >>>> > >>>> M. K. Shen > >>>> > >>>> ------------------------------------------------------------ > >>>> > >>>> def test(alist): > >>>> alist=[3,6,9] > >>>> return > >>>> > >>>> def test1(alist): > >>>> alist[0],alist[1],alist[2]=3,6,9 > >>>> return > >>>> > >>>> ss=[1,2,3] > >>>> test(ss) > >>>> print(ss) > >>>> test1(ss) > >>>> print(ss) > >>> > >>> This reassigns the name alist: alist = [3, 6, 9]. That changes the > >>> local variable, but cannot affect the caller's variables. > >>> > >>> This leaves alist as the same object, but reassigns its elements, > >>> mutating the list: alist[0] = 3 > >>> > >>> This talk has more details: https://nedbatchelder.com/text/names1.html > >> > >> I could more or less understand that in test() alist is interpreted as > >> local but in the extended program below in test2() I first write the > >> same as in test1(), after which I logically assume that the name alist > >> is now known as global and then I write alist=[30,60,90] but that > >> doesn't have any effect globally, since I get the output: > >> > >> [1, 2, 3] > >> [3, 6, 9] > >> [3, 6, 9] > >> > >> Could you please explain that? > >> > >> M. K. Shen > >> --------------------------------------------------------- > >> > >> def test(alist): > >> alist=[3,6,9] > >> return > >> > >> def test1(alist): > >> alist[0],alist[1],alist[2]=3,6,9 > >> return > >> > >> def test2(alist): > >> alist[0],alist[1],alist[2]=3,6,9 > >> alist=[30,60,90] > >> return > >> > >> ss=[1,2,3] > >> test(ss) > >> print(ss) > >> test1(ss) > >> print(ss) > >> test2(ss) > >> print(ss) > > > > Your test2 function first mutates the caller's list by assigning > > alist[0]=3, then it rebinds the local name alist to be a new list. So > > the caller's list is now [3, 6, 9]. > > Sorry for my poor knowledge. After the line alist[0]..., what is the > status of the name alist? It's now a global name, right? So why in the > line following that the name alist would suddenly be interpreted as > local? I can't yet fully comprehend the logic behind that. > > M. K. Shen > > > . > > -- > https://mail.python.org/mailman/listinfo/python-list > -- Oliver My StackOverflow contributions My CodeProject articles My Github projects My SourceForget.net projects From mok-kong.shen at t-online.de Mon Aug 14 16:18:46 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Mon, 14 Aug 2017 22:18:46 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> Message-ID: Am 14.08.2017 um 22:10 schrieb oliver: > It is not a global because accessing an item of a list does not change > whether it is global or local. It would only be global if you declared it > global via a "global" statement. Can you give an example, that would help > determine the issue. If without a global statement, a name is local, then alist[0]=3 should not work globally, if it works at all, in my layman's logic. M. K. Shen > > On Mon, 14 Aug 2017 at 16:06 Mok-Kong Shen > wrote: > >> Am 14.08.2017 um 21:53 schrieb Ned Batchelder: >>> On 8/14/17 3:21 PM, Mok-Kong Shen wrote: >>>> Am 14.08.2017 um 20:50 schrieb Ned Batchelder: >>>>> On 8/14/17 2:21 PM, Mok-Kong Shen wrote: >>>>>> I ran the attached program and got the following output: >>>>>> >>>>>> [1, 2, 3] >>>>>> [3, 6, 9] >>>>>> >>>>>> I don't understand why the modification doesn't work in the case of >>>>>> test() but does work in the case of test1(). >>>>>> >>>>>> Thanks for your help in advance. >>>>>> >>>>>> M. K. Shen >>>>>> >>>>>> ------------------------------------------------------------ >>>>>> >>>>>> def test(alist): >>>>>> alist=[3,6,9] >>>>>> return >>>>>> >>>>>> def test1(alist): >>>>>> alist[0],alist[1],alist[2]=3,6,9 >>>>>> return >>>>>> >>>>>> ss=[1,2,3] >>>>>> test(ss) >>>>>> print(ss) >>>>>> test1(ss) >>>>>> print(ss) >>>>> >>>>> This reassigns the name alist: alist = [3, 6, 9]. That changes the >>>>> local variable, but cannot affect the caller's variables. >>>>> >>>>> This leaves alist as the same object, but reassigns its elements, >>>>> mutating the list: alist[0] = 3 >>>>> >>>>> This talk has more details: https://nedbatchelder.com/text/names1.html >>>> >>>> I could more or less understand that in test() alist is interpreted as >>>> local but in the extended program below in test2() I first write the >>>> same as in test1(), after which I logically assume that the name alist >>>> is now known as global and then I write alist=[30,60,90] but that >>>> doesn't have any effect globally, since I get the output: >>>> >>>> [1, 2, 3] >>>> [3, 6, 9] >>>> [3, 6, 9] >>>> >>>> Could you please explain that? >>>> >>>> M. K. Shen >>>> --------------------------------------------------------- >>>> >>>> def test(alist): >>>> alist=[3,6,9] >>>> return >>>> >>>> def test1(alist): >>>> alist[0],alist[1],alist[2]=3,6,9 >>>> return >>>> >>>> def test2(alist): >>>> alist[0],alist[1],alist[2]=3,6,9 >>>> alist=[30,60,90] >>>> return >>>> >>>> ss=[1,2,3] >>>> test(ss) >>>> print(ss) >>>> test1(ss) >>>> print(ss) >>>> test2(ss) >>>> print(ss) >>> >>> Your test2 function first mutates the caller's list by assigning >>> alist[0]=3, then it rebinds the local name alist to be a new list. So >>> the caller's list is now [3, 6, 9]. >> >> Sorry for my poor knowledge. After the line alist[0]..., what is the >> status of the name alist? It's now a global name, right? So why in the >> line following that the name alist would suddenly be interpreted as >> local? I can't yet fully comprehend the logic behind that. >> >> M. K. Shen >> >> >> . >> >> -- >> https://mail.python.org/mailman/listinfo/python-list >> From jladasky at itu.edu Mon Aug 14 16:33:25 2017 From: jladasky at itu.edu (jladasky at itu.edu) Date: Mon, 14 Aug 2017 13:33:25 -0700 (PDT) Subject: why k means do not rectangle the red area drawn by harris corner? In-Reply-To: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> References: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> Message-ID: On Monday, August 14, 2017 at 12:30:21 PM UTC-7, Ho Yeung Lee wrote: > https://gist.github.com/hoyeunglee/df7e6cb9b76c576b26fd2bb2b26bfe2f > > sample image > https://drive.google.com/file/d/0Bxs_ao6uuBDUY09qM1JMWS1Ob0k/view?usp=sharing > > would like to rectangle bound the eye ,mouth corner etc > which detected by harris corner > > but using kmeans can not rectangle the red area drawn by harris corner Does your code run without errors? You appear to be asking more general question, about machine learning and image processing algorithms, than about Python. From greg.ewing at canterbury.ac.nz Mon Aug 14 18:26:55 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Tue, 15 Aug 2017 10:26:55 +1200 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: Ben Finney wrote: > That the comprehension > syntax *does not* necessarily connote a procedural loop, but instead can > quite reasonably be interpreted as its designer intended, a single > conceptual operation. To put it another way: Consider that a comprehension is an expression, and I think most people would agree that relying on order of evaluation in an expression is a very bad idea, since it hurts readability and is prone to subtle bugs. -- Greg From jobmattcon at gmail.com Mon Aug 14 18:27:39 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Mon, 14 Aug 2017 15:27:39 -0700 (PDT) Subject: why k means do not rectangle the red area drawn by harris corner? In-Reply-To: References: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> Message-ID: i would like to ask whether at line dd = dst>0.01*dst.max() and the part of code below from script, whether write wrong in array access or assignment testing1 = zip(*np.where(dd == 1)) locations = testing1 testing1 = [list((float(elem[0]),float(elem[1]))) for elem in testing1] centroids,_ = kmeans(testing1,10) row,col = vq(testing1,centroids) locationsgroup = {} keyone = len(locationsgroup)+1 for jj in range(0, len(row)): for ii in range(0, len(np.nonzero(row == jj)[0])): locationsgroup = addtogroupkey(locationsgroup, keyone, locations[np.nonzero(row == jj)[0][ii]]) keyone = len(locationsgroup)+1 #for ii in range(0, len(np.nonzero(row == jj)[0])): #locationsgroup = addtogroupkey(locationsgroup, keyone, locations[np.nonzero(row == jj)[0][ii]]) #keyone = len(locationsgroup)+1 colortolocation[eachcolor] = locationsgroup On Tuesday, August 15, 2017 at 4:33:51 AM UTC+8, jlad... at itu.edu wrote: > On Monday, August 14, 2017 at 12:30:21 PM UTC-7, Ho Yeung Lee wrote: > > https://gist.github.com/hoyeunglee/df7e6cb9b76c576b26fd2bb2b26bfe2f > > > > sample image > > https://drive.google.com/file/d/0Bxs_ao6uuBDUY09qM1JMWS1Ob0k/view?usp=sharing > > > > would like to rectangle bound the eye ,mouth corner etc > > which detected by harris corner > > > > but using kmeans can not rectangle the red area drawn by harris corner > > Does your code run without errors? You appear to be asking more general question, about machine learning and image processing algorithms, than about Python. From python at mrabarnett.plus.com Mon Aug 14 18:42:55 2017 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 14 Aug 2017 23:42:55 +0100 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> Message-ID: On 2017-08-14 20:21, Mok-Kong Shen wrote: [snip] > I could more or less understand that in test() alist is interpreted as > local but in the extended program below in test2() I first write the > same as in test1(), after which I logically assume that the name alist > is now known as global and then I write alist=[30,60,90] but that > doesn't have any effect globally, since I get the output: > > [1, 2, 3] > [3, 6, 9] > [3, 6, 9] > > Could you please explain that? > > M. K. Shen > --------------------------------------------------------- > > def test(alist): > alist=[3,6,9] > return > > def test1(alist): > alist[0],alist[1],alist[2]=3,6,9 > return > > def test2(alist): At entry, "alist" is a local name that refers to the list that was passed in: alist ---> [1,2,3] Now you change values in that list: > alist[0],alist[1],alist[2]=3,6,9 alist ---> [3,6,9] You've modified the list that was passed in. You then bind the local name "alist" to a new list. > alist=[30,60,90] alist ---> [30,60,90] # This is a new list. At exit, "alist" refers to a different list from the one that was passed in. > return > > ss=[1,2,3] > test(ss) > print(ss) > test1(ss) > print(ss) > test2(ss) > print(ss) > From zhilongch64 at gmail.com Mon Aug 14 18:48:02 2017 From: zhilongch64 at gmail.com (zhilongch64 at gmail.com) Date: Mon, 14 Aug 2017 15:48:02 -0700 (PDT) Subject: Solution Manual Test Bank for South-Western Federal Taxation 2018: Corporations, Partnerships, Estates and Trusts, 41st Edition by Hoffman In-Reply-To: <94e6cc3c-1dda-4cdf-9c6f-23b48d90e929@googlegroups.com> References: <94e6cc3c-1dda-4cdf-9c6f-23b48d90e929@googlegroups.com> Message-ID: <754bec77-8326-4030-b65c-947ffeee96d5@googlegroups.com> On Friday, June 30, 2017 at 3:03:05 PM UTC-5, Test Banks wrote: > Greetings, > > We do have Solution Manuals and Test Bank for SOUTH-WESTERN FEDERAL TAXATION 2018: CORPORATIONS, PARTNERSHIPS, ESTATES AND TRUSTS 41st EDITION BY HOFFMAN at reasonable price. You can get above mentioned resources by sending email to pro.fast(@)hotmail(dot)com > > Send your order queries at PRO.FAST(@)HOTMAIL(DOT)COM > > Below are details given for this book > > Book Name: SOUTH-WESTERN FEDERAL TAXATION 2018: CORPORATIONS, PARTNERSHIPS, ESTATES AND TRUSTS > Authors: William H. Hoffman, Jr. | James C. Young | William A. Raabe | David M. Maloney | Annette Nellen > Edition: 41st E > ISBN-10: 1337385948 > ISBN-13: 9781337385947 > Product Format: MS Word > Total Modules: 20 > > Please mention complete details for your book so we could send you sample accordingly. > > Best Regards, > > P.S : Please do not post your reply here. We do not monitor queries here. Simply send us an email directly to PRO.FAST (@) HOTMAIL (DOT) COM Do you have ebook book too. The ISBN is 9781337385947. Tell me the price. From zhilongch64 at gmail.com Mon Aug 14 18:59:20 2017 From: zhilongch64 at gmail.com (zhilongch64 at gmail.com) Date: Mon, 14 Aug 2017 15:59:20 -0700 (PDT) Subject: Solution Manual Test Bank for South-Western Federal Taxation 2018: Corporations, Partnerships, Estates and Trusts, 41st Edition by Hoffman In-Reply-To: <94e6cc3c-1dda-4cdf-9c6f-23b48d90e929@googlegroups.com> References: <94e6cc3c-1dda-4cdf-9c6f-23b48d90e929@googlegroups.com> Message-ID: <4c3f3251-02d5-4684-b6a4-66e96a1a513c@googlegroups.com> On Friday, June 30, 2017 at 3:03:05 PM UTC-5, Test Banks wrote: > Greetings, > > We do have Solution Manuals and Test Bank for SOUTH-WESTERN FEDERAL TAXATION 2018: CORPORATIONS, PARTNERSHIPS, ESTATES AND TRUSTS 41st EDITION BY HOFFMAN at reasonable price. You can get above mentioned resources by sending email to pro.fast(@)hotmail(dot)com > > Send your order queries at PRO.FAST(@)HOTMAIL(DOT)COM > > Below are details given for this book > > Book Name: SOUTH-WESTERN FEDERAL TAXATION 2018: CORPORATIONS, PARTNERSHIPS, ESTATES AND TRUSTS > Authors: William H. Hoffman, Jr. | James C. Young | William A. Raabe | David M. Maloney | Annette Nellen > Edition: 41st E > ISBN-10: 1337385948 > ISBN-13: 9781337385947 > Product Format: MS Word > Total Modules: 20 > > Please mention complete details for your book so we could send you sample accordingly. > > Best Regards, > > P.S : Please do not post your reply here. We do not monitor queries here. Simply send us an email directly to PRO.FAST (@) HOTMAIL (DOT) COM I think it is the book I am looking for just let me see the cover page. the isbn number is 9781337385947. From ben+python at benfinney.id.au Mon Aug 14 19:10:51 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Tue, 15 Aug 2017 09:10:51 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> Message-ID: <85wp65iw3o.fsf@benfinney.id.au> Steve D'Aprano writes: > On Mon, 14 Aug 2017 07:59 pm, Ben Finney wrote: > > You began by asking what people would expect syntax to mean. > > > > Then you expressed surprise that anyone would think a comprehension > > would be interpreted by the reader as a single operation. > > Yes, and I stand by that. In the face of the designer saying that's how the feature was intended to be interpreted by a reader, you *remain* surprised anyone could think that? I find it hard to believe you are denying facts to this extent. > Python list comprehensions are explicitly documented as being equivalent to a > loop, the syntax chosen uses the same keyword as a loop, the implementation > uses a loop, and when read as pseudo-code they explicitly claim to be > a loop. > So on what basis would anyone conclude that they aren't loops? Python's list comprehensions are explicitly drawn from set theory, the syntax chosen uses the same words mathematicians use for set operations. I'm not saying what you wrote above is incorrect. But it is *also* true what I wrote. Since this is a thread you began by asking how people would interpret some syntax, *both of these are relevant*, even if incompatible. > > The designer of that feature expressed that yes, the intention was > > that it be interpreted as a single conceptual operation, not a > > looping sequence of operations. > > What matters is how comprehensions actually *are*, not what Greg > intended. When it comes to the matter you actually raised ? how a person reading the syntax will interpret it ? implementation is barely at play. What matters much more is the connotations and baggage of language and syntax not in the Python implementation, but *in the reader's mind*. That's why it is an ongoing non sequitur that, when people honestly say what leads them to interpret the syntax a particular way, you then point to the Python implementation. > Greg's intention simply doesn't matter. List comprehensions in Python > are as they are documented and implemented, not as he intended them to > be. As a statement about what Python *will actually* do, of course that's true. But it's not what you asked, and your bafflement at getting answers not to the question you didn't ask, but instead to the question you did ask, is becoming quite strange. > People are free to interpret Python features any way they like, but we > don't have to treat them seriously if their interpretation doesn't > match the documented semantics of the feature. Then why ask people's interpretations at the start of this thread? The Python executable can be freely designed to interpret syntax any way its designers choose. But those are *choices*, and we can expect the designers to inform those choices from the existing connotations and baggage of language and syntax from outside and prior to Python ? and even from outside any programming languages. If the design of Python's semantics sufficiently violates an established interpretation of language or syntax, we don't have to treat it seriously and can rightly call it a design bug. -- \ ?Having sex with Rachel is like going to a concert. She yells a | `\ lot, and throws frisbees around the room; and when she wants | _o__) more, she lights a match.? ?Steven Wright | Ben Finney From ned at nedbatchelder.com Mon Aug 14 19:12:07 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Mon, 14 Aug 2017 19:12:07 -0400 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> Message-ID: <510defc1-14cf-80b7-0c73-a875a59f354f@nedbatchelder.com> On 8/14/17 4:18 PM, Mok-Kong Shen wrote: > Am 14.08.2017 um 22:10 schrieb oliver: >> It is not a global because accessing an item of a list does not change >> whether it is global or local. It would only be global if you >> declared it >> global via a "global" statement. Can you give an example, that would >> help >> determine the issue. > > If without a global statement, a name is local, then alist[0]=3 should > not work globally, if it works at all, in my layman's logic. Take a few moments to read or watch this: https://nedbatchelder.com/text/names1.html It answers precisely these questions. --Ned. > > M. K. Shen >> >> On Mon, 14 Aug 2017 at 16:06 Mok-Kong Shen >> wrote: >> >>> Am 14.08.2017 um 21:53 schrieb Ned Batchelder: >>>> On 8/14/17 3:21 PM, Mok-Kong Shen wrote: >>>>> Am 14.08.2017 um 20:50 schrieb Ned Batchelder: >>>>>> On 8/14/17 2:21 PM, Mok-Kong Shen wrote: >>>>>>> I ran the attached program and got the following output: >>>>>>> >>>>>>> [1, 2, 3] >>>>>>> [3, 6, 9] >>>>>>> >>>>>>> I don't understand why the modification doesn't work in the case of >>>>>>> test() but does work in the case of test1(). >>>>>>> >>>>>>> Thanks for your help in advance. >>>>>>> >>>>>>> M. K. Shen >>>>>>> >>>>>>> ------------------------------------------------------------ >>>>>>> >>>>>>> def test(alist): >>>>>>> alist=[3,6,9] >>>>>>> return >>>>>>> >>>>>>> def test1(alist): >>>>>>> alist[0],alist[1],alist[2]=3,6,9 >>>>>>> return >>>>>>> >>>>>>> ss=[1,2,3] >>>>>>> test(ss) >>>>>>> print(ss) >>>>>>> test1(ss) >>>>>>> print(ss) >>>>>> >>>>>> This reassigns the name alist: alist = [3, 6, 9]. That changes >>>>>> the >>>>>> local variable, but cannot affect the caller's variables. >>>>>> >>>>>> This leaves alist as the same object, but reassigns its elements, >>>>>> mutating the list: alist[0] = 3 >>>>>> >>>>>> This talk has more details: >>>>>> https://nedbatchelder.com/text/names1.html >>>>> >>>>> I could more or less understand that in test() alist is >>>>> interpreted as >>>>> local but in the extended program below in test2() I first write the >>>>> same as in test1(), after which I logically assume that the name >>>>> alist >>>>> is now known as global and then I write alist=[30,60,90] but that >>>>> doesn't have any effect globally, since I get the output: >>>>> >>>>> [1, 2, 3] >>>>> [3, 6, 9] >>>>> [3, 6, 9] >>>>> >>>>> Could you please explain that? >>>>> >>>>> M. K. Shen >>>>> --------------------------------------------------------- >>>>> >>>>> def test(alist): >>>>> alist=[3,6,9] >>>>> return >>>>> >>>>> def test1(alist): >>>>> alist[0],alist[1],alist[2]=3,6,9 >>>>> return >>>>> >>>>> def test2(alist): >>>>> alist[0],alist[1],alist[2]=3,6,9 >>>>> alist=[30,60,90] >>>>> return >>>>> >>>>> ss=[1,2,3] >>>>> test(ss) >>>>> print(ss) >>>>> test1(ss) >>>>> print(ss) >>>>> test2(ss) >>>>> print(ss) >>>> >>>> Your test2 function first mutates the caller's list by assigning >>>> alist[0]=3, then it rebinds the local name alist to be a new list. So >>>> the caller's list is now [3, 6, 9]. >>> >>> Sorry for my poor knowledge. After the line alist[0]..., what is the >>> status of the name alist? It's now a global name, right? So why in the >>> line following that the name alist would suddenly be interpreted as >>> local? I can't yet fully comprehend the logic behind that. >>> >>> M. K. Shen >>> >>> >>> . >>> >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >>> > From jobmattcon at gmail.com Mon Aug 14 19:40:55 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Mon, 14 Aug 2017 16:40:55 -0700 (PDT) Subject: why k means do not rectangle the red area drawn by harris corner? In-Reply-To: References: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> Message-ID: my code can run without error, you can try to download one of face from search keyword "face" and try this script On Tuesday, August 15, 2017 at 4:33:51 AM UTC+8, jlad... at itu.edu wrote: > On Monday, August 14, 2017 at 12:30:21 PM UTC-7, Ho Yeung Lee wrote: > > https://gist.github.com/hoyeunglee/df7e6cb9b76c576b26fd2bb2b26bfe2f > > > > sample image > > https://drive.google.com/file/d/0Bxs_ao6uuBDUY09qM1JMWS1Ob0k/view?usp=sharing > > > > would like to rectangle bound the eye ,mouth corner etc > > which detected by harris corner > > > > but using kmeans can not rectangle the red area drawn by harris corner > > Does your code run without errors? You appear to be asking more general question, about machine learning and image processing algorithms, than about Python. From jladasky at itu.edu Mon Aug 14 21:28:19 2017 From: jladasky at itu.edu (jladasky at itu.edu) Date: Mon, 14 Aug 2017 18:28:19 -0700 (PDT) Subject: why k means do not rectangle the red area drawn by harris corner? In-Reply-To: References: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> Message-ID: On Monday, August 14, 2017 at 4:41:23 PM UTC-7, Ho Yeung Lee wrote: > my code can run without error, > > you can try to download one of face from search keyword "face" > and try this script You're assuming a lot. From your code: from PIL import Image # Two lines removed import numpy as np import cv2 from pylab import plot,show from numpy import vstack,array from numpy.random import rand from scipy.cluster.vq import kmeans,vq from pywinauto.application import Application I count five third-party packages which are not part of the Python language. Many programmers won't have all of these packages installed. Many people won't have any of these packages installed. > > On Tuesday, August 15, 2017 at 4:33:51 AM UTC+8, jlad... at itu.edu wrote: > > On Monday, August 14, 2017 at 12:30:21 PM UTC-7, Ho Yeung Lee wrote: > > > https://gist.github.com/hoyeunglee/df7e6cb9b76c576b26fd2bb2b26bfe2f > > > > > > sample image > > > https://drive.google.com/file/d/0Bxs_ao6uuBDUY09qM1JMWS1Ob0k/view?usp=sharing > > > > > > would like to rectangle bound the eye ,mouth corner etc > > > which detected by harris corner > > > > > > but using kmeans can not rectangle the red area drawn by harris corner > > > > Does your code run without errors? You appear to be asking more general question, about machine learning and image processing algorithms, than about Python. From steve+python at pearwood.info Mon Aug 14 22:24:30 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 15 Aug 2017 12:24:30 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59925b60$0$1586$c3e8da3$5496439d@news.astraweb.com> On Tue, 15 Aug 2017 01:40 am, Chris Angelico wrote: [...] >> A Haskell list comprehension is not a loop at all. > > What if you don't take the first four, but instead take just the tenth > element? Will the preceding elements be calculated too, or do you have > a sparse list? Both. Or neither. The preceding elements aren't *calculated*, but they are *allocated* ready for when you need them: Prelude> let squares = [ x ** 2 | x <- [1 ..] ] :: [Float] Prelude> squares !! 10 121.0 Prelude> :print squares squares = (_t2::Float) : (_t3::Float) : (_t4::Float) : (_t5::Float) : (_t6::Float) : (_t7::Float) : (_t8::Float) : (_t9::Float) : (_t10::Float) : (_t11::Float) : 121.0 : (_t12::[Float]) Haskell lists are single-pointer linked lists. https://wiki.haskell.org/How_to_work_on_lists My understanding of it is that it will be implemented something like a linked list of thunks, followed by the evaluated element, followed by an infinite generator. In Python terms: (lambda x=1: x**2, (lambda x=2: x**2, (lambda x=3: x**2, ... # for brevity (lambda x=10: x**2, (121.0, ((x**2 for x in itertools.count(12)), None) ) ) ... ) ) ) or something more-or-less equivalent. It's quite clever, actually, in that it gives *pseudo* random-access with lazy evaluation. You can evaluate the Nth element without evaluating the earlier ones. But you can't do so without *storing* the previous ones, they have to be allocated, with only the actual evaluation being delayed. So its both less powerful and more powerful than Python's (x)range. Less powerful as: - there's no random access (you have to walk the linked list to get to the Nth element, touching each element in turn); - and you cannot access the Nth element without storing the previous N-1 elements. But more powerful in that, like a generator expression, it can take arbitrary expressions. Here's a more interesting example: Prelude> let squares = [ x ** 2 | x <- [1 ..] ] :: [Float] Prelude> let values = [a + 1 | a <- squares ] :: [Float] Prelude> values !! 4 26.0 Prelude> :print values values = (_t13::Float) : (_t14::Float) : (_t15::Float) : (_t16::Float) : 26.0 : (_t17::[Float]) Prelude> :print squares squares = (_t18::Float) : (_t19::Float) : (_t20::Float) : (_t21::Float) : 25.0 : (_t22::[Float]) So its lazy evaluation all the way down. I think the closest analogy in Python terms would be a generator expression with a cache. That's not *quite* the same, because Python is eagerly evaluated and Haskell is lazily evaluated, but the critical fact (which Ian seems to have completely missed) is that while evaluation can be delayed, touching each element *in order* from start to end cannot be. You cannot jump to an arbitrary index in Haskell. But one thing is sure: even if evaluation is delayed, before you can access element N, you have to access element N-1. Whether it is implemented via recursion, a while-loop, or an actual for-loop, it is still logically equivalent to a for-loop through the elements. In Haskell, you cannot get the last N elements of a list without allocating memory for the previous ones. Here's a Stackoverflow post about it: https://stackoverflow.com/questions/17252851/how-do-i-take-the-last-n-elements-of-a-list -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From orgnut at yahoo.com Mon Aug 14 23:25:15 2017 From: orgnut at yahoo.com (Larry Hudson) Date: Mon, 14 Aug 2017 20:25:15 -0700 Subject: A question on modification of a list via a function invocation In-Reply-To: <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> Message-ID: <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> On 08/14/2017 01:02 PM, Mok-Kong Shen wrote: > Am 14.08.2017 um 21:53 schrieb Ned Batchelder: [snip] >>> def test(alist): >>> alist=[3,6,9] >>> return >>> >>> def test1(alist): >>> alist[0],alist[1],alist[2]=3,6,9 >>> return >>> >>> def test2(alist): >>> alist[0],alist[1],alist[2]=3,6,9 >>> alist=[30,60,90] >>> return >>> >>> ss=[1,2,3] >>> test(ss) >>> print(ss) >>> test1(ss) >>> print(ss) >>> test2(ss) >>> print(ss) >> >> Your test2 function first mutates the caller's list by assigning >> alist[0]=3, then it rebinds the local name alist to be a new list. So >> the caller's list is now [3, 6, 9]. > > Sorry for my poor knowledge. After the line alist[0]..., what is the > status of the name alist? It's now a global name, right? So why in the > line following that the name alist would suddenly be interpreted as > local? I can't yet fully comprehend the logic behind that. > > M. K. Shen Here is my attempt to clarify the situation with some ascii graphics. (Well, not ascii, but utf-8 box-drawing characters ? I hope they come through ok. And, of curse, it won't display properly with a proportional font.) The left side is the program lines, and the right side tries to show the way Python implements the name binding to the data in memory. (But I abbreviated the long assignment line, alist[0],alist[1],alist[2]=3,6,9 to ) Program line Variable bound to memory =========== Initial assignment ============ ss = [1, 2, 3] ss ???> [1, 2, 3] =============== test() code =============== def test(alist): ss ???> [1, 2, 3] alist ?? --------------------------------------------- alist = [3, 6, 9] ss ???> [1, 2, 3] alist ???> [3, 6, 9] --------------------------------------------- return ss ???> [1, 2, 3] alist =============== test1() code ============== def test1(alist): ss ???> [1, 2, 3] alist ?? --------------------------------------------- ss ???> [3, 6, 9] alist ?? --------------------------------------------- return ss ???> [3, 6, 9] alist =============== test2() code ============== def test2(alist): ss ???> [1, 2, 3] alist ?? --------------------------------------------- ss ???> [3, 6, 9] alist ?? --------------------------------------------- alist = [30, 60, 90] ss ???> [3, 6, 9] alist ???> [30, 60, 90] --------------------------------------------- return ss ???> [3, 6, 9] alist -- -=- Larry -=- From no.email at nospam.invalid Mon Aug 14 23:26:12 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 14 Aug 2017 20:26:12 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <59925b60$0$1586$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87mv71a4vf.fsf@nightsong.com> Steve D'Aprano writes: > It's quite clever, actually, in that it gives *pseudo* random-access > with lazy evaluation. You can evaluate the Nth element without > evaluating the earlier ones. But you can't do so without *storing* the > previous ones, they have to be allocated, with only the actual > evaluation being delayed. Look at any of the memoization packages for ways around that. Or of course you could just write a function instead of a list... > In Haskell, you cannot get the last N elements of a list without > allocating memory for the previous ones. lastn n xxs@(x:xs) | length (take n xs) == n-1 = xxs | otherwise = lastn n xs main = print . lastn 5 $ [1..10000000] *Main> main [9999996,9999997,9999998,9999999,10000000] works for me. The 10000000 list nodes all get allocated, but are immediately freed, so only 5 cells have to be in memory at a time. In principle a fancy enough compiler optimization could get rid of all the allocation completely. From torriem at gmail.com Mon Aug 14 23:31:11 2017 From: torriem at gmail.com (Michael Torrie) Date: Mon, 14 Aug 2017 21:31:11 -0600 Subject: why k means do not rectangle the red area drawn by harris corner? In-Reply-To: References: <8a6f9493-ba27-460d-be3e-267fac102133@googlegroups.com> Message-ID: <51fbe355-bc43-58e0-1cf8-0f2dcdd62e38@gmail.com> On 08/14/2017 07:28 PM, jladasky at itu.edu wrote: > On Monday, August 14, 2017 at 4:41:23 PM UTC-7, Ho Yeung Lee wrote: >> my code can run without error, >> >> you can try to download one of face from search keyword "face" >> and try this script > > You're assuming a lot. From your code: > > from PIL import Image > # Two lines removed > import numpy as np > import cv2 > from pylab import plot,show > from numpy import vstack,array > from numpy.random import rand > from scipy.cluster.vq import kmeans,vq > from pywinauto.application import Application > > > I count five third-party packages which are not part of the Python language. Many programmers won't have all of these packages installed. Many people won't have any of these packages installed. I'm guessing many of these are part of the SciPy distribution. Perhaps he'd have better luck asking on the SciPy mailing list. I'm sure they have lists for discussion algorithms and image processing, as they are a scientific programming community. https://www.scipy.org/scipylib/mailing-lists.html From no.email at nospam.invalid Mon Aug 14 23:38:57 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 14 Aug 2017 20:38:57 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> <87zib2a70t.fsf@nightsong.com> <87valqmqgf.fsf@elektro.pacujo.net> Message-ID: <87inhpa4a6.fsf@nightsong.com> Marko Rauhamaa writes: > For the non-logicians in the audience, an "axiom schema" is a generator > pattern that produces an infinity of actual axioms. For non-logicians this is not worth worrying about: schemas are basically a technical hack to get around the inability of first-order logic to quantify over formulas. Naively most of us think of single axioms with second-order quantifiers, instead of schemas. For example, arithmetic induction goes something like: FORALL P. [ P(0) and P(n) -> P(n+1) ] where "FORALL P" means quantifying over all formulas P. Since in FOL we can only quantify over numbers and not formulas, we write down a separate axiom for each possible formula. Since there are infinitely many formulas, this is an infinite axiom schema. Historically (in "naive set theory") we didn't bother with any of this. We could write { S : S \not\in S } for the set of all sets that are not members of themselves. Is S a member of itself ("Russell's paradox")? Either way leads to contradiction. So the comprehension axiom schemas for set theory had to be designed to not allow formulas like that. From larry.martell at gmail.com Mon Aug 14 23:39:57 2017 From: larry.martell at gmail.com (Larry Martell) Date: Mon, 14 Aug 2017 23:39:57 -0400 Subject: cpython version In-Reply-To: References: Message-ID: On Sun, Aug 13, 2017 at 10:59 PM, Gilmeh Serda wrote: > On Sat, 12 Aug 2017 10:24:06 -0400, Larry Martell wrote: > >> now I have prospective client that refuses to run linux, even in a VM. >> So I am tying to get my app running on Windows Server 2016, piece by >> painful piece. > > I hope you charge them an arm and a leg for it! :) Both arms and both legs. From no.email at nospam.invalid Tue Aug 15 00:13:10 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 14 Aug 2017 21:13:10 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> <87zib2a70t.fsf@nightsong.com> <87valqmqgf.fsf@elektro.pacujo.net> <87inhpa4a6.fsf@nightsong.com> Message-ID: <87efsda2p5.fsf@nightsong.com> Paul Rubin writes: > FORALL P. [ P(0) and P(n) -> P(n+1) ] Sorry, that was supposed to say FORALL P. [ (P(0) and P(n) -> P(n+1)) -> forall n. P(n) ] FORALL quantifies over formulas and forall quantifies over numbers. Maybe something is still missing from the above ;-). From rustompmody at gmail.com Tue Aug 15 00:31:19 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Mon, 14 Aug 2017 21:31:19 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: <0e5f3c19-ab6d-43b6-81d6-65c821fd7cca@googlegroups.com> On Tuesday, August 15, 2017 at 3:57:22 AM UTC+5:30, Gregory Ewing wrote: > Ben Finney wrote: > > That the comprehension > > syntax *does not* necessarily connote a procedural loop, but instead can > > quite reasonably be interpreted as its designer intended, a single > > conceptual operation. > > To put it another way: Consider that a comprehension is an expression, A neat summary of the basis of this whole difference of opinion! JFTR: Haskell gets its list comprehensions from Miranda. Technically Haskell and Miranda are much the same in syntax, semantics etc (in this respect) However as to the informal discussion-terms around the same there is this difference: In Miranda the terms used were ?list comprehension? as well as ?ZF expression? (ZF standing for Zermelo, Fraenkel who formulated the comprehension axiom(s) ) with a slight preference for the latter. I have generally preferred ?ZF expression? because as I said earlier ?comprehension?, in this context, is meaningless (in English). Seeing this discussion, I feel the other part ? ?expression? ? which I never paid attention to so far! ? is probably as or more important. From rustompmody at gmail.com Tue Aug 15 00:54:22 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Mon, 14 Aug 2017 21:54:22 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: On Monday, August 14, 2017 at 10:35:22 PM UTC+5:30, Terry Reedy wrote: > On 8/14/2017 5:59 AM, Ben Finney wrote: > > > At what point will you accept the feedback: That the comprehension > > syntax *does not* necessarily connote a procedural loop, but instead can > > quite reasonably be interpreted as its designer intended, a single > > conceptual operation. > > In a world where functions have 'side-effects', which is to say, > implicit inputs and outputs, procedural order is necessary for > predictable outcomes. The 'single conception operation' is ambiguious. > > Suppose stdin contains "a\nb\nc\nd\ne\nf\ng\n". > What is the meaning of > [input(f"response{i}") for i in range(6)]? > In Python, the predictable result is > ['a', 'b', 'c', 'd', 'e', 'f'] > It would not be with some of Rustom Mody's 'equivalents'. > Or let L = . > This implementation of list reversal: [L.pop() for i in range(len(L))] In languages, especially those with a clearly separated lang-spec from specific implementation-spec (eg C99), there is a sharp distinction made between - undefined behaviour - unspecified behaviour - erroneous behaviour Roughly: - Erroneous means compiler/runtime should flag an error - Undefined means implementation can format your hard disk and clear your bank account https://stackoverflow.com/questions/18420753/unspecified-undefined-and-implementation-defined-behavior-wiki-for-c - Unspecified means not error but not spelled out My point of suggesting those alternative implementations is precisely to make your examples above fall squarely into unspecified category Note that this would square with the informal practice seen in places like this ML/NG where a noob asks a question using a comprehension such as the ones you've used and someone more experienced pipes up "Dont do that" > Do not functional languages define comprehensions in terms of recursion, > equivalent to for loops? At the risk of some over-simplification, the idea of functional languages is to move above behavior from unspecified to erroneous category. IMHO this is not in line with python's genus as an imperative dynamically typed language [In haskell, putchar, getchar etc exist and have monadic type. Which is a funny way of saying that the type system takes cognisance of and rigorously enforces the side-effecting nature of such functions. Which also means there are no side-effects; only effects, clearly flagged with the monadic type] From dieter at handshake.de Tue Aug 15 01:28:19 2017 From: dieter at handshake.de (dieter) Date: Tue, 15 Aug 2017 07:28:19 +0200 Subject: numpy not working any more References: <58f6ae18-3401-41db-b857-ee38544592d6@googlegroups.com> Message-ID: <87shgtv1qk.fsf@handshake.de> Poul Riis writes: > ... > For some time I have been using python 3.6.0 on a windows computer. > Suddenly, my numpy does not work any more. > This one-liner program: > import numpy as np > results in the long error message below. > ... > Traceback (most recent call last): > File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 16, in > from . import multiarray > ImportError: DLL load failed: Den angivne procedure blev ikke fundet. Apparently, the module "multiarry" is implemented in a separate DLL (= "Dynamically Loaded Library") and loading this DLL failed. There can be several reasons for such a failure, among others: * the DLL is missing * the DLL is corrupted * the DLL depends on something which is missing or corrupted * there is a version mismatch (e.g. between the DLL and the Python trying to load it) An initial step could be to try to reinstall "numpy" and see whether the problem goes away. From ian.g.kelly at gmail.com Tue Aug 15 02:05:21 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 15 Aug 2017 00:05:21 -0600 Subject: Proposed new syntax In-Reply-To: <59925b60$0$1586$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <59925b60$0$1586$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Mon, Aug 14, 2017 at 8:24 PM, Steve D'Aprano wrote: > I think the closest analogy in Python terms would be a generator expression with > a cache. That's not *quite* the same, because Python is eagerly evaluated and > Haskell is lazily evaluated, but the critical fact (which Ian seems to have > completely missed) is that while evaluation can be delayed, touching each > element *in order* from start to end cannot be. You cannot jump to an arbitrary > index in Haskell. > > But one thing is sure: even if evaluation is delayed, before you can access > element N, you have to access element N-1. Whether it is implemented via > recursion, a while-loop, or an actual for-loop, it is still logically > equivalent to a for-loop through the elements. I don't think that I've missed anything here. That the *implementation* uses some kind of recursive application does not make the *semantics* of the list comprehension logically equivalent to a for loop. This is about as close as you can get to a for loop with side effects in Haskell: Prelude Data.Traversable> forM [1..5] $ \n -> print $ n*n 1 4 9 16 25 [(),(),(),(),()] And here's taking the last element of a list comprehension that, according to you, should be "logically equivalent" to the above loop: Prelude Data.Traversable> [ print $ n*n | n <- [1..5] ] !! 4 25 Wait, where are the side effects of the first four elements that had to be recursed over to get to the last element? Clearly these are not logically equivalent. As I said, Haskell list comprehensions are not loops. From greg.ewing at canterbury.ac.nz Tue Aug 15 03:32:58 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Tue, 15 Aug 2017 19:32:58 +1200 Subject: Proposed new syntax In-Reply-To: <87inhpa4a6.fsf@nightsong.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <44eecb82-1fdc-4aea-9fe9-3a2126302f04@googlegroups.com> <87shgxw4gw.fsf@elektro.pacujo.net> <87k228wzev.fsf@elektro.pacujo.net> <87zib2a70t.fsf@nightsong.com> <87valqmqgf.fsf@elektro.pacujo.net> <87inhpa4a6.fsf@nightsong.com> Message-ID: Paul Rubin wrote: > Historically (in "naive set theory") we didn't bother with any of this. > We could write { S : S \not\in S } for the set of all sets that are not > members of themselves. Is S a member of itself ("Russell's paradox")? > Either way leads to contradiction. So the comprehension axiom schemas > for set theory had to be designed to not allow formulas like that. Personally I think mathematicians worry overly much about that. What it means is that not every predicate can be used to define a set. A manifestation of the same thing in computing is that not every program you can write down will terminate. But we don't warp our languages in an effort to make non-terminating programs impossible; we just accept them as a fact of life and move on. -- Greg From alister.ware at ntlworld.com Tue Aug 15 04:30:22 2017 From: alister.ware at ntlworld.com (alister) Date: Tue, 15 Aug 2017 08:30:22 GMT Subject: Solution Manual Test Bank for South-Western Federal Taxation 2018: Corporations, Partnerships, Estates and Trusts, 41st Edition by Hoffman References: <94e6cc3c-1dda-4cdf-9c6f-23b48d90e929@googlegroups.com> <754bec77-8326-4030-b65c-947ffeee96d5@googlegroups.com> Message-ID: On Mon, 14 Aug 2017 15:48:02 -0700, zhilongch64 wrote: Please do the whole world a big favour & NEVER reply to spam if no-one responded this heinous practice would die. -- I hate users you sound like a sysadmin already! From anthra.norell at bluewin.ch Tue Aug 15 04:42:39 2017 From: anthra.norell at bluewin.ch (Friedrich Rentsch) Date: Tue, 15 Aug 2017 10:42:39 +0200 Subject: Redirecting input of IDLE window In-Reply-To: References: Message-ID: <360c311a-51e6-1e73-9a9b-2ba8ffc6adb9@bluewin.ch> On 08/14/2017 10:47 AM, Friedrich Rentsch wrote: > Hi, > > I work interactively in an IDLE window most of the time and find > "help (...)" very useful to summarize things. The display comes up > directly (doesn't return a text, which I could edit, assign or store). > I suspect that there are ways to redirect the display, say to a file. > Thanks for suggestions. > > > Frederic > > Peter Otten's "mypager" works well. All suggestions provide a welcome opportunity to learn more about the inner workings. Thank you all for your responses. Frederic From wwwtomsworld at gmail.com Tue Aug 15 05:37:47 2017 From: wwwtomsworld at gmail.com (Alhassan Tom Alfa) Date: Tue, 15 Aug 2017 10:37:47 +0100 Subject: Application Error Message-ID: Dear Sir, I just downloaded Python on my PH Windows 10 PC but any time I tried to start the application it always give the following error message; Python.exe - Application Error The application was unable to start correctly (0xc000007b). Click Ok to close the application. How this error be corrected? I really need to use this application Thank you in anticipation for a quick response Best Regards, Tom Virus-free. www.avast.com <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> From tkolsa at gmail.com Tue Aug 15 05:52:42 2017 From: tkolsa at gmail.com (TKS) Date: Tue, 15 Aug 2017 11:52:42 +0200 Subject: Any advice on getting Pyscripter installed & working with Python on Windows 10 computer ? Message-ID: > > > Hi there, > > I am trying to assist my daughter with a school IT task to install Python > & Pyscripter on a Windows 10 notebook. (64 bit system) > > It seems no version of Pyscripter will work - it fails to complete the > installation & ends with an error ("Python could not be properly > initialised, we must quit"). > I have tried using 32 & 64 bit versions for both & alternating options, > but same error comes up. > > Can you offer any suggestions on how to get this working ? > > Thank you. > ?TK. > > ? > > From steve+python at pearwood.info Tue Aug 15 07:32:51 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 15 Aug 2017 21:32:51 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <59925b60$0$1586$c3e8da3$5496439d@news.astraweb.com> <87mv71a4vf.fsf@nightsong.com> Message-ID: <5992dbe5$0$1600$c3e8da3$5496439d@news.astraweb.com> On Tue, 15 Aug 2017 01:26 pm, Paul Rubin wrote: > Steve D'Aprano writes: [...] >> In Haskell, you cannot get the last N elements of a list without >> allocating memory for the previous ones. > > lastn n xxs@(x:xs) > | length (take n xs) == n-1 = xxs > | otherwise = lastn n xs > > main = print . lastn 5 $ [1..10000000] > > *Main> main > [9999996,9999997,9999998,9999999,10000000] > > works for me. Right. Did you read the Stackoverflow page I linked to? They all pretty much say the same thing, although most of the given solutions use `drop`. Sorry if my wording was unclear. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Tue Aug 15 08:18:14 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 15 Aug 2017 22:18:14 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: <5992e688$0$1601$c3e8da3$5496439d@news.astraweb.com> On Tue, 15 Aug 2017 02:54 pm, Rustom Mody wrote: > On Monday, August 14, 2017 at 10:35:22 PM UTC+5:30, Terry Reedy wrote: [...] >> Suppose stdin contains "a\nb\nc\nd\ne\nf\ng\n". >> What is the meaning of >> [input(f"response{i}") for i in range(6)]? >> In Python, the predictable result is >> ['a', 'b', 'c', 'd', 'e', 'f'] >> It would not be with some of Rustom Mody's 'equivalents'. Indeed. Terry has hit the nail on the head here. Python's documented semantics is predictable and deterministic, and the documented semantics of comprehensions are explicitly based on sequential for-loops. To continue to insist, in contradiction to the documentation, that list comps might legitimately operate in arbitrary order is simply irrational. If they behaved as Rustom is insisting they might, it would be a bug in the implementation. >> Or let L = . >> This implementation of list reversal: [L.pop() for i in range(len(L))] > > In languages, especially those with a clearly separated lang-spec from > specific implementation-spec (eg C99), there is a sharp distinction made > between - undefined behaviour > - unspecified behaviour > - erroneous behaviour > > > Roughly: > - Erroneous means compiler/runtime should flag an error > - Undefined means implementation can format your hard disk and clear your bank > account In *some* languages, not all, undefined means the implementation can format your hard disk. Those languages include C (and perhaps C++). I don't know of any other languages which are so hostile to the developer (and their end users) as to specify such abominable behaviour and claim it is a feature. (There may be others, I just don't know them.) In general, undefined and unspecified are synonymous. > https://stackoverflow.com/questions/18420753/unspecified-undefined-and-implementation-defined-behavior-wiki-for-c > - Unspecified means not error but not spelled out > > My point of suggesting those alternative implementations is precisely > to make your examples above fall squarely into unspecified category Terry's examples don't demonstrate unspecified behaviour. The order of execution is completely specified. See the links to the docs I have already posted. > Note that this would square with the informal practice seen in places like > this ML/NG where a noob asks a question using a comprehension such as the > ones you've used and someone more experienced pipes up "Dont do that" Don't do that *in production code.* [print(x, y) for x in values for y in others] is a good way of learning how to read list comprehensions. You're making the classic logical error of affirming the consequent: https://en.wikipedia.org/wiki/Affirming_the_consequent we should avoid code with unspecified behaviour we should avoid this code, therefore it must have unspecified behaviour Just because code showing unspecified behaviour should be avoided, doesn't mean that all code that should be avoided has unspecified behaviour. There are plenty of reasons for avoiding certain misuses of comprehensions that have nothing to do with unspecified behaviour. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rustompmody at gmail.com Tue Aug 15 08:37:17 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Tue, 15 Aug 2017 05:37:17 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: <5992e688$0$1601$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5992e688$0$1601$c3e8da3$5496439d@news.astraweb.com> Message-ID: <8cef0399-4779-4695-9eee-0ef047aed70f@googlegroups.com> On Tuesday, August 15, 2017 at 5:48:43 PM UTC+5:30, Steve D'Aprano wrote: > On Tue, 15 Aug 2017 02:54 pm, Rustom Mody wrote: > > > On Monday, August 14, 2017 at 10:35:22 PM UTC+5:30, Terry Reedy wrote: > [...] > >> Suppose stdin contains "a\nb\nc\nd\ne\nf\ng\n". > >> What is the meaning of > >> [input(f"response{i}") for i in range(6)]? > >> In Python, the predictable result is > >> ['a', 'b', 'c', 'd', 'e', 'f'] > >> It would not be with some of Rustom Mody's 'equivalents'. > > Indeed. Terry has hit the nail on the head here. Python's documented semantics > is predictable and deterministic, and the documented semantics of > comprehensions are explicitly based on sequential for-loops. > > To continue to insist, in contradiction to the documentation, that list comps > might legitimately operate in arbitrary order is simply irrational. If they > behaved as Rustom is insisting they might, it would be a bug in the > implementation. I know that list-comps behave like the l2r-pass-doing-appends as SPECIFIED in the docs. In my view the IMPLEMENTATION is correct wrt that specification Whereas the SPECIFICATION, in being over-specific is wrong In the same way that if someone explaining C were to say that the '+' operator is (the SAME AS) ADD x86 instructions and then proves that case by showing gcc -S's output. From bgailer at gmail.com Tue Aug 15 10:31:49 2017 From: bgailer at gmail.com (Bob Gailer) Date: Tue, 15 Aug 2017 10:31:49 -0400 Subject: Application Error In-Reply-To: References: Message-ID: On Aug 15, 2017 9:50 AM, "Alhassan Tom Alfa" wrote: > > Dear Sir, > > I just downloaded Python Exactly what did you download? Where did you download it from? There are 32 bit versions and 64-bit versions. Did you download the one corresponding to your computer? Normally when you download python You are downloading an installer. Did you run the installer? on my PH What is pH? Windows 10 PC but any time I tried to > start the application When you say application are you referring to python or some Python program? Exactly what are you doing to run the application? Be as specific as possible. it always give the following error message; > > Python.exe - Application Error > The application was unable to start correctly (0xc000007b). Click Ok to > close the application. Personally I have never heard of this error. Have you tried to Google it? The comments above are my own comments they reflect my own experience there may be others on this list who will give you a better answer. > > How this error be corrected? I really need to use this application We are all volunteers who choose to help others with questions. Expressions of urgency usually don't motivate us. So in the future just ask a question. > > Thank you in anticipation for a quick response > > Best Regards, > > Tom > > < https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=icon > > Virus-free. > www.avast.com > < https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail&utm_term=link > > <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> > -- > https://mail.python.org/mailman/listinfo/python-list From ian.g.kelly at gmail.com Tue Aug 15 10:46:32 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 15 Aug 2017 08:46:32 -0600 Subject: Application Error In-Reply-To: References: Message-ID: On Tue, Aug 15, 2017 at 3:37 AM, Alhassan Tom Alfa wrote: > Dear Sir, > > I just downloaded Python on my PH Windows 10 PC but any time I tried to > start the application it always give the following error message; > > Python.exe - Application Error > The application was unable to start correctly (0xc000007b). Click Ok to > close the application. > > How this error be corrected? I really need to use this application https://stackoverflow.com/questions/20650596/cannot-open-python-error-0xc000007b From oddeveneven at gmail.com Tue Aug 15 11:56:27 2017 From: oddeveneven at gmail.com (Evan Aad) Date: Tue, 15 Aug 2017 18:56:27 +0300 Subject: Python's method-resolution algorithm: An implementation question Message-ID: According to the description of Python's method resolution order (mro) (https://www.python.org/download/releases/2.3/mro/), a.k.a. C3 linearization (see Wikipedia), the algorithm can be described as follows: "the linearization of C is the sum of C plus the merge of the linearizations of the parents and the list of the parents." Symbolically, the algorithm is defined recursively thus: L(O) = L(C) = + merge(L(B1),..., L(Bn), ) where * O is the class from which every class inherits. * C is a class that inherits directly from B1, ..., Bn, in this order. * < and > are list delimiters. * + is the list-concatenation operator. * 'merge' merges its list arguments into a single list with no repetitions in the manner described in the next paragraph. Consider the head of the first list, i.e L(B1)[0]: if it is a good head, i.e. if it is not in the proper tail of any of the other lists, add it to the linearization of C, and remove it from all the lists in the merge. Otherwise, consider the head of the next list, etc. Repeat until no more classes, or no good heads. In the latter case, it is impossible to construct the merge. Why is the list of parents given as an argument to 'merge'? Will the algorithm produce different results if this argument is omitted? From priisdk at gmail.com Tue Aug 15 12:23:00 2017 From: priisdk at gmail.com (Poul Riis) Date: Tue, 15 Aug 2017 09:23:00 -0700 (PDT) Subject: numpy not working any more In-Reply-To: References: <58f6ae18-3401-41db-b857-ee38544592d6@googlegroups.com> <87shgtv1qk.fsf@handshake.de> Message-ID: <1e7951b6-f2f3-4501-b1dd-e8ce88397f29@googlegroups.com> Den tirsdag den 15. august 2017 kl. 07.29.05 UTC+2 skrev dieter: > Poul Riis writes: > > ... > > For some time I have been using python 3.6.0 on a windows computer. > > Suddenly, my numpy does not work any more. > > This one-liner program: > > import numpy as np > > results in the long error message below. > > ... > > Traceback (most recent call last): > > File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 16, in > > from . import multiarray > > ImportError: DLL load failed: Den angivne procedure blev ikke fundet. > > Apparently, the module "multiarry" is implemented in a separate > DLL (= "Dynamically Loaded Library") and loading this DLL failed. > > There can be several reasons for such a failure, among others: > > * the DLL is missing > > * the DLL is corrupted > > * the DLL depends on something which is missing or corrupted > > * there is a version mismatch (e.g. between the DLL and the Python > trying to load it) > > > An initial step could be to try to reinstall "numpy" and > see whether the problem goes away. I have reinstalled numpy several times - doesn't help. From breamoreboy at gmail.com Tue Aug 15 13:18:48 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Tue, 15 Aug 2017 10:18:48 -0700 (PDT) Subject: numpy not working any more In-Reply-To: <1e7951b6-f2f3-4501-b1dd-e8ce88397f29@googlegroups.com> References: <58f6ae18-3401-41db-b857-ee38544592d6@googlegroups.com> <87shgtv1qk.fsf@handshake.de> <1e7951b6-f2f3-4501-b1dd-e8ce88397f29@googlegroups.com> Message-ID: <9ef7a283-d0a3-476b-92ad-59d4feb370f2@googlegroups.com> On Tuesday, August 15, 2017 at 5:23:29 PM UTC+1, Poul Riis wrote: > Den tirsdag den 15. august 2017 kl. 07.29.05 UTC+2 skrev dieter: > > Poul Riis writes: > > > ... > > > For some time I have been using python 3.6.0 on a windows computer. > > > Suddenly, my numpy does not work any more. > > > This one-liner program: > > > import numpy as np > > > results in the long error message below. > > > ... > > > Traceback (most recent call last): > > > File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 16, in > > > from . import multiarray > > > ImportError: DLL load failed: Den angivne procedure blev ikke fundet. > > > > Apparently, the module "multiarry" is implemented in a separate > > DLL (= "Dynamically Loaded Library") and loading this DLL failed. > > > > There can be several reasons for such a failure, among others: > > > > * the DLL is missing > > > > * the DLL is corrupted > > > > * the DLL depends on something which is missing or corrupted > > > > * there is a version mismatch (e.g. between the DLL and the Python > > trying to load it) > > > > > > An initial step could be to try to reinstall "numpy" and > > see whether the problem goes away. > > I have reinstalled numpy several times - doesn't help. The short answer is you need to upgrade Python, not numpy. For the long answer please see https://stackoverflow.com/questions/44537131/numpy-library-importerror-dll-load-failed-the-specified-procedure-could-not-be which in turn refers to https://bugs.python.org/issue29943. Kindest regards. Mark Lawrence. From steve+python at pearwood.info Tue Aug 15 14:05:56 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 16 Aug 2017 04:05:56 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> Message-ID: <59933807$0$1611$c3e8da3$5496439d@news.astraweb.com> On Tue, 15 Aug 2017 08:26 am, Gregory Ewing wrote: > Ben Finney wrote: >> That the comprehension >> syntax *does not* necessarily connote a procedural loop, but instead can >> quite reasonably be interpreted as its designer intended, a single >> conceptual operation. > > To put it another way: Consider that a comprehension is an > expression, and I think most people would agree that relying > on order of evaluation in an expression is a very bad idea, > since it hurts readability and is prone to subtle bugs. So you've stopped arguing that list comprehensions don't have a defined order of evaluation, and are now arguing that code which relies on that order of evaluation is hard to reason about? I suppose that's progress :-) I take issue with your statement that relying on order of evaluation is always "a very bad idea". Order of evaluation in Python is well-defined, and we frequently rely on it. There is nothing wrong with writing code like: x = y + 1/z x is not None and x > 1 a, b = b, a while x in foo or x not in bar and similar. And especially now that print is a regular function instead of a statement, it is incredibly useful to stick a print or two in the middle of an expression for debugging. You can't use that trick everywhere, but it is especially useful in generator expressions as a way of seeing when its called and yields a value: (print('generator', x) or expression for x in something) for example. But really, the argument that you seem to be making: # paraphrase, not an actual quote "Comprehensions might actually have well-defined semantics in terms of for-loops, just as they are documented to have, but we should pretend that they don't because some really complicated expressions with side-effects can be confusing or buggy." seems pretty dubious to me. As they say, "A man's got to know his limitations." If you program code that is as complicated as you can understand, you won't be clever enough to debug it when it goes wrong. That applies whether we're talking about order of evaluation, basic arithmetic, threads, async programming, functional idioms, levels of abstraction or spaghetti code. That makes a good argument for writing conservative code that is the simplest thing that will work (for some definition of "work"). It's not an argument for treating the semantics of code as different from what those semantics actually are. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From fabiofz at gmail.com Tue Aug 15 14:12:08 2017 From: fabiofz at gmail.com (Fabio Zadrozny) Date: Tue, 15 Aug 2017 15:12:08 -0300 Subject: PyDev 5.9.2 released Message-ID: PyDev 5.9.2 Release Highlights - *Important* PyDev now requires Java 8 and Eclipse 4.6 (Neon) onwards. - PyDev 5.2.0 is the last release supporting Eclipse 4.5 (Mars). - *Debugger* - Integrated speedups for Python 3.6 which use the new Python hook which allows the debugger to add breakpoints through bytecode manipulation. - Some critical fixes related to issues in the latest debugger (#PyDev-837, #PyDev-838, #PyDev-817). - Added support for having isort as the engine for import sorting. - Fixed issue on text search with *Lucene* when the user had another plugin which also used lucene (*#PyDev-826*). - From this version onwards, PyDev is built with a proper certificate (previous versions used a self-signed certificate). - Google App Engine templates now working out of the box (patch by *Mat Booth*). - Optimization in editor highlighting when dealing with huge files. - Some bugfixes in pytest integration. - *cv2* added to forced builtins by default for working with OpenCV. - Fixed issue when parsing empty f-string. What is PyDev? PyDev is an open-source Python IDE on top of Eclipse for Python, Jython and IronPython development. It comes with goodies such as code completion, syntax highlighting, syntax analysis, code analysis, refactor, debug, interactive console, etc. Details on PyDev: http://pydev.org Details on its development: http://pydev.blogspot.com What is LiClipse? LiClipse is a PyDev standalone with goodies such as support for Multiple cursors, theming, TextMate bundles and a number of other languages such as Django Templates, Jinja2, Kivy Language, Mako Templates, Html, Javascript, etc. It's also a commercial counterpart which helps supporting the development of PyDev. Details on LiClipse: http://www.liclipse.com/ Cheers, -- Fabio Zadrozny ------------------------------ Software Developer LiClipse http://www.liclipse.com PyDev - Python Development Environment for Eclipse http://pydev.org http://pydev.blogspot.com PyVmMonitor - Python Profiler http://www.pyvmmonitor.com/ From ian.g.kelly at gmail.com Tue Aug 15 14:44:09 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 15 Aug 2017 12:44:09 -0600 Subject: Python's method-resolution algorithm: An implementation question In-Reply-To: References: Message-ID: On Tue, Aug 15, 2017 at 9:56 AM, Evan Aad wrote: > According to the description of Python's method resolution order (mro) > (https://www.python.org/download/releases/2.3/mro/), a.k.a. C3 > linearization (see Wikipedia), the algorithm can be described as > follows: > > "the linearization of C is the sum of C plus the merge of the > linearizations of the parents and the list of the parents." > > Symbolically, the algorithm is defined recursively thus: > > L(O) = > L(C) = + merge(L(B1),..., L(Bn), ) > > where > > * O is the class from which every class inherits. > * C is a class that inherits directly from B1, ..., Bn, in this order. > * < and > are list delimiters. > * + is the list-concatenation operator. > * 'merge' merges its list arguments into a single list with no > repetitions in the manner described in the next paragraph. > > Consider the head of the first list, i.e L(B1)[0]: if it is a good > head, i.e. if it is not in the proper tail of any of the other lists, > add it to the linearization of C, and remove it from all the lists in > the merge. Otherwise, consider the head of the next list, etc. Repeat > until no more classes, or no good heads. In the latter case, it is > impossible to construct the merge. > > > > Why is the list of parents given as an argument to > 'merge'? Will the algorithm produce different results if this argument > is omitted? It ensures that the parents are linearized in that order. Without that list, it would be possible for B2 to appear before B1 in the MRO of C. From orgnut at yahoo.com Tue Aug 15 14:47:34 2017 From: orgnut at yahoo.com (Larry Hudson) Date: Tue, 15 Aug 2017 11:47:34 -0700 Subject: A question on modification of a list via a function invocation In-Reply-To: <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> Message-ID: On 08/14/2017 08:25 PM, Larry Hudson wrote: [snip] > Here is my attempt to clarify the situation with some ascii graphics. > (Well, not ascii, but utf-8 box-drawing characters ? I hope they come through ok. > And, of curse, it won't display properly with a proportional font.) > > The left side is the program lines, and the right side tries to show the way Python implements > the name binding to the data in memory. (But I abbreviated the long assignment line, > alist[0],alist[1],alist[2]=3,6,9 to ) > > Program line Variable bound to memory > > =========== Initial assignment ============ > > ss = [1, 2, 3] ss ???> [1, 2, 3] > > =============== test() code =============== > > def test(alist): ss ???> [1, 2, 3] > alist ?? > --------------------------------------------- > alist = [3, 6, 9] ss ???> [1, 2, 3] > alist ???> [3, 6, 9] > --------------------------------------------- > return ss ???> [1, 2, 3] > alist > > =============== test1() code ============== > def test1(alist): ss ???> [1, 2, 3] > alist ?? > --------------------------------------------- > ss ???> [3, 6, 9] > alist ?? > --------------------------------------------- > return ss ???> [3, 6, 9] > alist > > =============== test2() code ============== > def test2(alist): ss ???> [1, 2, 3] > alist ?? > --------------------------------------------- > ss ???> [3, 6, 9] > alist ?? > --------------------------------------------- > alist = [30, 60, 90] ss ???> [3, 6, 9] > alist ???> [30, 60, 90] > --------------------------------------------- > return ss ???> [3, 6, 9] > alist > This needs a minor clarification to the test1 example, plus I want to emphasize that the assignment here is through the alist variable. =============== test1() code ============== def test1(alist): ss ???> [1, 2, 3] alist ?? --------------------------------------------- ss ???> [3, 6, 9] alist ?? --------------------------------------------- return ss ???> [3, 6, 9] alist There is nothing to garbage collect here. -- -=- Larry -=- From oddeveneven at gmail.com Tue Aug 15 14:57:03 2017 From: oddeveneven at gmail.com (Evan Aad) Date: Tue, 15 Aug 2017 21:57:03 +0300 Subject: Python's method-resolution algorithm: An implementation question Message-ID: I don't see how, since the L(B*)'s are listed in order in the argument list: L(B1), L(B2), ..., and each L(B*) starts with B*: L(B1) = , L(B2) = , ... Could you please give a counter-example? On Tue, Aug 15, 2017 at 9:44 PM, Ian Kelly wrote: > > On Tue, Aug 15, 2017 at 9:56 AM, Evan Aad wrote: > > According to the description of Python's method resolution order (mro) > > (https://www.python.org/download/releases/2.3/mro/), a.k.a. C3 > > linearization (see Wikipedia), the algorithm can be described as > > follows: > > > > "the linearization of C is the sum of C plus the merge of the > > linearizations of the parents and the list of the parents." > > > > Symbolically, the algorithm is defined recursively thus: > > > > L(O) = > > L(C) = + merge(L(B1),..., L(Bn), ) > > > > where > > > > * O is the class from which every class inherits. > > * C is a class that inherits directly from B1, ..., Bn, in this order. > > * < and > are list delimiters. > > * + is the list-concatenation operator. > > * 'merge' merges its list arguments into a single list with no > > repetitions in the manner described in the next paragraph. > > > > Consider the head of the first list, i.e L(B1)[0]: if it is a good > > head, i.e. if it is not in the proper tail of any of the other lists, > > add it to the linearization of C, and remove it from all the lists in > > the merge. Otherwise, consider the head of the next list, etc. Repeat > > until no more classes, or no good heads. In the latter case, it is > > impossible to construct the merge. > > > > > > > > Why is the list of parents given as an argument to > > 'merge'? Will the algorithm produce different results if this argument > > is omitted? > > It ensures that the parents are linearized in that order. Without that > list, it would be possible for B2 to appear before B1 in the MRO of C. > -- > https://mail.python.org/mailman/listinfo/python-list From priisdk at gmail.com Tue Aug 15 15:12:55 2017 From: priisdk at gmail.com (Poul Riis) Date: Tue, 15 Aug 2017 12:12:55 -0700 (PDT) Subject: numpy not working any more In-Reply-To: <9ef7a283-d0a3-476b-92ad-59d4feb370f2@googlegroups.com> References: <58f6ae18-3401-41db-b857-ee38544592d6@googlegroups.com> <87shgtv1qk.fsf@handshake.de> <1e7951b6-f2f3-4501-b1dd-e8ce88397f29@googlegroups.com> <9ef7a283-d0a3-476b-92ad-59d4feb370f2@googlegroups.com> Message-ID: Den tirsdag den 15. august 2017 kl. 19.19.15 UTC+2 skrev bream... at gmail.com: > On Tuesday, August 15, 2017 at 5:23:29 PM UTC+1, Poul Riis wrote: > > Den tirsdag den 15. august 2017 kl. 07.29.05 UTC+2 skrev dieter: > > > Poul Riis writes: > > > > ... > > > > For some time I have been using python 3.6.0 on a windows computer. > > > > Suddenly, my numpy does not work any more. > > > > This one-liner program: > > > > import numpy as np > > > > results in the long error message below. > > > > ... > > > > Traceback (most recent call last): > > > > File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 16, in > > > > from . import multiarray > > > > ImportError: DLL load failed: Den angivne procedure blev ikke fundet. > > > > > > Apparently, the module "multiarry" is implemented in a separate > > > DLL (= "Dynamically Loaded Library") and loading this DLL failed. > > > > > > There can be several reasons for such a failure, among others: > > > > > > * the DLL is missing > > > > > > * the DLL is corrupted > > > > > > * the DLL depends on something which is missing or corrupted > > > > > > * there is a version mismatch (e.g. between the DLL and the Python > > > trying to load it) > > > > > > > > > An initial step could be to try to reinstall "numpy" and > > > see whether the problem goes away. > > > > I have reinstalled numpy several times - doesn't help. > > The short answer is you need to upgrade Python, not numpy. > > For the long answer please see https://stackoverflow.com/questions/44537131/numpy-library-importerror-dll-load-failed-the-specified-procedure-could-not-be which in turn refers to https://bugs.python.org/issue29943. > > Kindest regards. > > Mark Lawrence. I mentioned in my original question that I have tried Python 3.6.2 and that it indeed had no problems with numpy but that it on the other hand gave rize to another problem, namely failing installation of vtk (pip says 'Couldn't find a version that satisfies the requirement vtk'. Poul Riis From fred at bristle.com Tue Aug 15 15:13:25 2017 From: fred at bristle.com (Fred Stluka) Date: Tue, 15 Aug 2017 15:13:25 -0400 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> Message-ID: <28c8fce9-7ba2-a6e1-cba1-ee4813ae7bcf@bristle.com> > Here is my attempt to clarify the situation with some ascii graphics. > (Well, not ascii, but utf-8 box-drawing characters ? I hope they come > through ok. > And, of curse, it won't display properly with a proportional font.) Here's a VERY useful tool for understanding/explaining/drawing such code snippets: - http://pythontutor.com At the "Edit code" link, you can type/paste your own Python statements and have the tool single-step though them. At each step, it draws the data structures with values, links to other data structures, etc. A great Python visualization tool! Enjoy! --Fred ------------------------------------------------------------------------ Fred Stluka -- mailto:fred at bristle.com -- http://bristle.com/~fred/ Bristle Software, Inc -- http://bristle.com -- Glad to be of service! Open Source: Without walls and fences, we need no Windows or Gates. ------------------------------------------------------------------------ From ian.g.kelly at gmail.com Tue Aug 15 15:41:32 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 15 Aug 2017 13:41:32 -0600 Subject: Python's method-resolution algorithm: An implementation question In-Reply-To: References: Message-ID: On Tue, Aug 15, 2017 at 12:57 PM, Evan Aad wrote: > I don't see how, since the L(B*)'s are listed in order in the argument > list: L(B1), L(B2), ..., and each L(B*) starts with B*: L(B1) = ...>, L(B2) = , ... > > Could you please give a counter-example? Sure. merge(, ) -> vs: merge(, , ) -> TypeError Or in Python: >>> class A1: pass >>> class A2: pass >>> class B1(A1): pass >>> class B2(A2, B1): pass >>> class C(B1, B2): pass Traceback (most recent call last): File "", line 1, in TypeError: Cannot create a consistent method resolution order (MRO) for bases B1, B2 From breamoreboy at gmail.com Tue Aug 15 15:49:57 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Tue, 15 Aug 2017 12:49:57 -0700 (PDT) Subject: numpy not working any more In-Reply-To: References: <58f6ae18-3401-41db-b857-ee38544592d6@googlegroups.com> <87shgtv1qk.fsf@handshake.de> <1e7951b6-f2f3-4501-b1dd-e8ce88397f29@googlegroups.com> <9ef7a283-d0a3-476b-92ad-59d4feb370f2@googlegroups.com> Message-ID: On Tuesday, August 15, 2017 at 8:13:19 PM UTC+1, Poul Riis wrote: > Den tirsdag den 15. august 2017 kl. 19.19.15 UTC+2 skrev bream... at gmail.com: > > On Tuesday, August 15, 2017 at 5:23:29 PM UTC+1, Poul Riis wrote: > > > Den tirsdag den 15. august 2017 kl. 07.29.05 UTC+2 skrev dieter: > > > > Poul Riis writes: > > > > > ... > > > > > For some time I have been using python 3.6.0 on a windows computer. > > > > > Suddenly, my numpy does not work any more. > > > > > This one-liner program: > > > > > import numpy as np > > > > > results in the long error message below. > > > > > ... > > > > > Traceback (most recent call last): > > > > > File "C:\Users\pr\AppData\Local\Programs\Python\Python36\lib\site-packages\numpy\core\__init__.py", line 16, in > > > > > from . import multiarray > > > > > ImportError: DLL load failed: Den angivne procedure blev ikke fundet. > > > > > > > > Apparently, the module "multiarry" is implemented in a separate > > > > DLL (= "Dynamically Loaded Library") and loading this DLL failed. > > > > > > > > There can be several reasons for such a failure, among others: > > > > > > > > * the DLL is missing > > > > > > > > * the DLL is corrupted > > > > > > > > * the DLL depends on something which is missing or corrupted > > > > > > > > * there is a version mismatch (e.g. between the DLL and the Python > > > > trying to load it) > > > > > > > > > > > > An initial step could be to try to reinstall "numpy" and > > > > see whether the problem goes away. > > > > > > I have reinstalled numpy several times - doesn't help. > > > > The short answer is you need to upgrade Python, not numpy. > > > > For the long answer please see https://stackoverflow.com/questions/44537131/numpy-library-importerror-dll-load-failed-the-specified-procedure-could-not-be which in turn refers to https://bugs.python.org/issue29943. > > > > Kindest regards. > > > > Mark Lawrence. > > I mentioned in my original question that I have tried Python 3.6.2 and that it indeed had no problems with numpy but that it on the other hand gave rize to another problem, namely failing installation of vtk (pip says 'Couldn't find a version that satisfies the requirement vtk'. > > Poul Riis Pip won't know anything about VTK, you have to download it yourself from http://www.vtk.org/. Kindest regards. Mark Lawrence. From greg.ewing at canterbury.ac.nz Tue Aug 15 18:59:31 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Wed, 16 Aug 2017 10:59:31 +1200 Subject: Proposed new syntax In-Reply-To: <59933807$0$1611$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <59933807$0$1611$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > I take issue with your statement that relying on order of evaluation is always > "a very bad idea". Perhaps what I should say is that relying on side effects in an expression occurring in a particular order is a bad idea. Boolean operators are a well-understood special case that doesn't extend to other expression elements. If you saw x = foo(y) + bar(z) you wouldn't immediately assume it relied critically on foo being called before bar -- would you? > And especially now that print is a regular function instead of a > statement, it is incredibly useful to stick a print or two in the middle of an > expression for debugging. That's fine as a temporary hack, but I would never use that for something the program needs to do as part of its normal operation. > # paraphrase, not an actual quote > "Comprehensions might actually have well-defined semantics in terms > of for-loops, just as they are documented to have, but we should > pretend that they don't because some really complicated expressions > with side-effects can be confusing or buggy." That's pretty much it, except I would delete "really complicated". Any reliance on side effects in an expression is confusing and bug-prone, IMO. The whole reason to write something as a comprehension is because you want to express it declaratively. You're saying "this is the list I want, I don't care how you compute it." Likewise, the reader should be able to read it as "this is the list produced, and you *don't have to care* how it gets computed." Introducing procedural elements such as "while" into a comprehension messes that up, because suddenly the reader *does* have to care about details of how it gets computed. And those details can be tricky. We've already seen how a subtle error can creep in when you get a "while" and an "if" in the wrong order! -- Greg From ben+python at benfinney.id.au Tue Aug 15 19:30:30 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 16 Aug 2017 09:30:30 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <59933807$0$1611$c3e8da3$5496439d@news.astraweb.com> Message-ID: <85shgsif3d.fsf@benfinney.id.au> Gregory Ewing writes: > The whole reason to write something as a comprehension is because you > want to express it declaratively. You're saying "this is the list I > want, I don't care how you compute it." That's certainly a strong reason for my choosing comprehension expressions: when I don't want to write a sequence of statements in a loop, an expression communicates the intent (?this is one expression with one output; think of it as one operation?). > Likewise, the reader should be able to read it as "this is the list > produced, and you *don't have to care* how it gets computed." So I find the ?while? proposed addition to be counter to that purpose, and describe it as confounding the ability of the reader to reason about the expression. > Introducing procedural elements such as "while" into a comprehension > messes that up, because suddenly the reader *does* have to care about > details of how it gets computed. Thanks for stating it so well, Greg. -- \ ?The good thing about science is that it's true whether or not | `\ you believe in it.? ?Neil deGrasse Tyson, 2011-02-04 | _o__) | Ben Finney From oddeveneven at gmail.com Tue Aug 15 22:23:36 2017 From: oddeveneven at gmail.com (Evan Aad) Date: Wed, 16 Aug 2017 05:23:36 +0300 Subject: Python's method-resolution algorithm: An implementation question Message-ID: Thanks! On Tue, Aug 15, 2017 at 10:41 PM, Ian Kelly wrote: > > On Tue, Aug 15, 2017 at 12:57 PM, Evan Aad wrote: > > I don't see how, since the L(B*)'s are listed in order in the argument > > list: L(B1), L(B2), ..., and each L(B*) starts with B*: L(B1) = > ...>, L(B2) = , ... > > > > Could you please give a counter-example? > > Sure. > > merge(, ) -> > > vs: > > merge(, , ) -> TypeError > > Or in Python: > > >>> class A1: pass > >>> class A2: pass > >>> class B1(A1): pass > >>> class B2(A2, B1): pass > >>> class C(B1, B2): pass > Traceback (most recent call last): > File "", line 1, in > TypeError: Cannot create a consistent method resolution order (MRO) > for bases B1, B2 > -- > https://mail.python.org/mailman/listinfo/python-list From joel.goldstick at gmail.com Wed Aug 16 07:17:05 2017 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Wed, 16 Aug 2017 07:17:05 -0400 Subject: A small quiz question In-Reply-To: References: Message-ID: On Wed, Aug 16, 2017 at 7:06 AM, Stefan Ram wrote: > I wrote my first Python quiz question! > > It goes like this: > > Can you predict (without trying it out) what the Python > console will output after the following three lines have > been entered? > > def f(i): print(i); return i; > > f(4)**f(1)**f(2) > > > -- > https://mail.python.org/mailman/listinfo/python-list > That's a nice problem for order evaluation. I guessed wrong. -- Joel Goldstick http://joelgoldstick.com/blog http://cc-baseballstats.info/stats/birthdays From steve+python at pearwood.info Wed Aug 16 07:44:44 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 16 Aug 2017 21:44:44 +1000 Subject: A small quiz question References: Message-ID: <5994302e$0$1593$c3e8da3$5496439d@news.astraweb.com> On Wed, 16 Aug 2017 09:06 pm, Stefan Ram wrote: > I wrote my first Python quiz question! > > It goes like this: > > Can you predict (without trying it out) what the Python > console will output after the following three lines have > been entered? > > def f(i): print(i); return i; > > f(4)**f(1)**f(2) My initial prediction was: 4 1 2 16 which is embarrassing. Fortunately my supper arrived in the nick of time to distract me from hitting Send, just long enough to remember that 1*1 is 1, not 2. So how about: 4 1 2 4 Unless its a syntax error... I can't remember if the REPL allows multiple semi-colon separated statements after a colon declaration. I know it gets mad at this: py> def a(): pass; def b(): pass File "", line 1 def a(): pass; def b(): pass ^ SyntaxError: invalid syntax So my wild guess is that this is a trick question and the actual answer is that its a SyntaxError. Otherwise, I'm sticking with 4 1 2 4 -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From breamoreboy at gmail.com Wed Aug 16 08:29:42 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Wed, 16 Aug 2017 05:29:42 -0700 (PDT) Subject: A small quiz question In-Reply-To: <5994302e$0$1593$c3e8da3$5496439d@news.astraweb.com> References: <5994302e$0$1593$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Wednesday, August 16, 2017 at 12:45:13 PM UTC+1, Steve D'Aprano wrote: > On Wed, 16 Aug 2017 09:06 pm, Stefan Ram wrote: > > > I wrote my first Python quiz question! > > > > It goes like this: > > > > Can you predict (without trying it out) what the Python > > console will output after the following three lines have > > been entered? > > > > def f(i): print(i); return i; > > > > f(4)**f(1)**f(2) > > My initial prediction was: > > > 4 > 1 > 2 > 16 > > > which is embarrassing. Fortunately my supper arrived in the nick of time > to distract me from hitting Send, just long enough to remember that 1*1 > is 1, not 2. > > So how about: > > 4 > 1 > 2 > 4 > > Unless its a syntax error... I can't remember if the REPL allows multiple > semi-colon separated statements after a colon declaration. I know it gets mad > at this: > > py> def a(): pass; def b(): pass > File "", line 1 > def a(): pass; def b(): pass > ^ > SyntaxError: invalid syntax > > > So my wild guess is that this is a trick question and the actual answer is that > its a SyntaxError. > > Otherwise, I'm sticking with > > 4 > 1 > 2 > 4 > > > > -- > Steve > ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure > enough, things got worse. How do you expect to get four lines of output from the three function calls? Kindest regards. Mark Lawrence. From steve+python at pearwood.info Wed Aug 16 09:32:08 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 16 Aug 2017 23:32:08 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> Message-ID: <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> On Tue, 15 Aug 2017 09:10 am, Ben Finney wrote: > Steve D'Aprano writes: > >> On Mon, 14 Aug 2017 07:59 pm, Ben Finney wrote: >> > You began by asking what people would expect syntax to mean. >> > >> > Then you expressed surprise that anyone would think a comprehension >> > would be interpreted by the reader as a single operation. >> >> Yes, and I stand by that. > > In the face of the designer saying that's how the feature was intended > to be interpreted by a reader, you *remain* surprised anyone could think > that? Yes. What the designer intended matters not a whit, what matters is what was actually designed. Whatever Greg intended, it didn't even last long enough to make it into the PEP, let alone the language. As I asked Greg earlier: If he wanted declarative semantics, why didn't he argue for declarative syntax like "select...where", instead of choosing procedural syntax which matches the actual procedural semantics given? In order to think of list comps as declarative, you have to: - ignore the PEP; - ignore the documentation; - ignore the actual behaviour; - ignore the syntax. That's a lot of reality to ignore. That's why I was surprised at your attitude that list comps could reasonably be interpreted as a single operation. To do so requires ignoring everything we know about list comprehensions in Python. The same doesn't apply to map(), at least in Python 2. I think it is completely reasonable for somebody to imagine that map() operated as a single operation. They would be wrong, of course, but not egregiously wrong. There's no PEP to contradict it, the documentation is consistent with map being an atomic operation: https://docs.python.org/2/library/functions.html#map the name is the same as the functional "map", which in purely functional languages is intended to be read as a mathematical operation which takes a function and a list and returns a new list. There may be subtle aspects of map in Python 2 which reveal that it is not actually a single conceptual operation (side-effects, of course, and the fact that you can interrupt it with Ctrl-C) but they are subtle and it is reasonable for somebody to miss them, or to argue that they are mere accidents of implementation. But comprehensions? You can't even write a comprehension without being reminded that they are designed as an expression form of for-loops! That's why I was, and remain, perplexed that you could ignore the documentation and the behaviour of comprehensions and believe something so egregiously wrong about them. > I find it hard to believe you are denying facts to this extent. I don't know what facts you think I'm ignoring. >> Python list comprehensions are explicitly documented as being equivalent to a >> loop, the syntax chosen uses the same keyword as a loop, the implementation >> uses a loop, and when read as pseudo-code they explicitly claim to be >> a loop. >> So on what basis would anyone conclude that they aren't loops? > > Python's list comprehensions are explicitly drawn from set theory, the > syntax chosen uses the same words mathematicians use for set operations. No they don't. Set builder notation doesn't use words at all, it uses symbols: {n+1 | n ? {1, 2, 3}} which if we were to translate into words would be: "the set of n plus one, such that n is an element of the set 1, 2 and 3". That's not even close to the same words as Python's comprehensions. Aside: The interesting thing about sets in mathematics is that they're unordered, unless it is useful for them to be thought of as ordered, in which case they're taken as ordered. E.g. when talking about arithmetic or geometric sequences, the unordered set of integers is taken as an ordered set, with no change in notation or language. [...] >> Greg's intention simply doesn't matter. List comprehensions in Python >> are as they are documented and implemented, not as he intended them to >> be. > > As a statement about what Python *will actually* do, of course that's > true. > > But it's not what you asked, and your bafflement at getting answers not > to the question you didn't ask, but instead to the question you did ask, > is becoming quite strange. I don't understand this. You seem to be implying that the answer to the question: "What do you think Python will do if you execute a list comprehension?" is best answered by predicting that Python will do something that you know it actually won't do. I can't believe you mean it that way, so I'm more perplexed than ever. >> People are free to interpret Python features any way they like, but we >> don't have to treat them seriously if their interpretation doesn't >> match the documented semantics of the feature. > > Then why ask people's interpretations at the start of this thread? Because I wanted to know what their interpretations are, and not being omniscient the only way to do so is to ask. At no point did I promise that I wouldn't question their answers, if they made no sense to me. > The Python executable can be freely designed to interpret syntax any way > its designers choose. But those are *choices*, and we can expect the > designers to inform those choices from the existing connotations and > baggage of language and syntax from outside and prior to Python ? and > even from outside any programming languages. > > If the design of Python's semantics sufficiently violates an established > interpretation of language or syntax, we don't have to treat it > seriously and can rightly call it a design bug. Of course you can. There are millions of programmers who claim that: - significant indentation is a design bug; - dynamic typing is a design bug; - everything about Unicode is a design bug, and we should all just use ASCII; - exceptions are a design bug; - early evaluation of function default arguments is a design bug; - late evaluation of function default arguments is a design bug; to mention just a few. But we really haven't established that Python's comprehension semantics violates any widely established programming language semantics. I may take that to another thread :-) -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ben.usenet at bsb.me.uk Wed Aug 16 09:38:47 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Wed, 16 Aug 2017 14:38:47 +0100 Subject: A small quiz question References: Message-ID: <87r2wbmy3c.fsf@bsb.me.uk> ram at zedat.fu-berlin.de (Stefan Ram) writes: > I wrote my first Python quiz question! > > It goes like this: > > Can you predict (without trying it out) what the Python > console will output after the following three lines have > been entered? > > def f(i): print(i); return i; > > f(4)**f(1)**f(2) Does Python actually specify what the output will be? It's going to end with 4 (the result from the REPL) and 4, 1 and 2 will appear on the lines before, but is the order they appear specified? -- Ben. From marco.buttu at gmail.com Wed Aug 16 09:48:58 2017 From: marco.buttu at gmail.com (Marco Buttu) Date: Wed, 16 Aug 2017 15:48:58 +0200 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59944D4A.7060607@oa-cagliari.inaf.it> On 10/08/2017 16:28, Steve D'Aprano wrote: > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] [1, 2, 3] > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] [1, 2, 3, 4, 5] -- Marco Buttu INAF-Osservatorio Astronomico di Cagliari Via della Scienza n. 5, 09047 Selargius (CA) Phone: 070 711 80 217 Email: mbuttu at oa-cagliari.inaf.it From steve+python at pearwood.info Wed Aug 16 09:51:43 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 16 Aug 2017 23:51:43 +1000 Subject: A small quiz question References: <5994302e$0$1593$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59944df0$0$1610$c3e8da3$5496439d@news.astraweb.com> On Wed, 16 Aug 2017 10:29 pm, breamoreboy at gmail.com wrote: > How do you expect to get four lines of output from the three function calls? In the REPL (the interactive interpreter) the result of evaluating the line is printed. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From jeanmichel at sequans.com Wed Aug 16 09:53:14 2017 From: jeanmichel at sequans.com (jmp) Date: Wed, 16 Aug 2017 15:53:14 +0200 Subject: Proposed new syntax In-Reply-To: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 08/10/2017 04:28 PM, Steve D'Aprano wrote: > Every few years, the following syntax comes up for discussion, with some people > saying it isn't obvious what it would do, and others disagreeing and saying > that it is obvious. So I thought I'd do an informal survey. > > What would you expect this syntax to return? > > [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] > > > For comparison, what would you expect this to return? (Without actually trying > it, thank you.) > > [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] > > > > How about these? > > [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] > > [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] > > > > Thanks for your comments! > [1,2,3] [1,2,3,4,5] SyntaxError("Have you tried Perl ?") SyntaxError("Have you tried Perl ?") I really would not want to deal with 3 and 4. jm From steve+python at pearwood.info Wed Aug 16 09:58:13 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 16 Aug 2017 23:58:13 +1000 Subject: A small quiz question References: <87r2wbmy3c.fsf@bsb.me.uk> Message-ID: <59944f76$0$1611$c3e8da3$5496439d@news.astraweb.com> On Wed, 16 Aug 2017 11:38 pm, Ben Bacarisse wrote: > ram at zedat.fu-berlin.de (Stefan Ram) writes: > >> I wrote my first Python quiz question! >> >> It goes like this: >> >> Can you predict (without trying it out) what the Python >> console will output after the following three lines have >> been entered? >> >> def f(i): print(i); return i; >> >> f(4)**f(1)**f(2) > > Does Python actually specify what the output will be? It's going to end > with 4 (the result from the REPL) and 4, 1 and 2 will appear on the > lines before, but is the order they appear specified? https://docs.python.org/3/reference/expressions.html#evaluation-order -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From skip.montanaro at gmail.com Wed Aug 16 09:58:18 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Wed, 16 Aug 2017 08:58:18 -0500 Subject: Automatic segmenting of large Kafka messages? Message-ID: When using Apache Kafka, the maximum message size can be defined in the configuration. If you have a lot of similarly sized messages, you can probably make a good estimate of a max message size. When the message sizes are highly variable, that's less certain. This presentation from an engineer at LinkedIn: https://www.slideshare.net/JiangjieQin/handle-large-messages-in-apache-kafka-58692297 describes a Kafka message segmentation facility they created. I poked around looking for an implementation of this concept, but came up short. Before I go off an reimplement the wheel, does anyone know if there is something out there already? I'd be using it with Dana Powers' Kafka package: https://pypi.python.org/pypi/kafka/1.3.4.1 Thx, Skip From breamoreboy at gmail.com Wed Aug 16 10:13:50 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Wed, 16 Aug 2017 07:13:50 -0700 (PDT) Subject: A small quiz question In-Reply-To: <59944df0$0$1610$c3e8da3$5496439d@news.astraweb.com> References: <5994302e$0$1593$c3e8da3$5496439d@news.astraweb.com> <59944df0$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: <92e97180-79e9-47e3-92be-658978fee445@googlegroups.com> On Wednesday, August 16, 2017 at 2:52:09 PM UTC+1, Steve D'Aprano wrote: > On Wed, 16 Aug 2017 10:29 pm, breamoreboy wrote: > > > How do you expect to get four lines of output from the three function calls? > > In the REPL (the interactive interpreter) the result of evaluating the line is > printed. > > -- > Steve > ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure > enough, things got worse. *face palm* but of course. Kindest regards. Mark Lawrence. From ben+python at benfinney.id.au Wed Aug 16 10:28:10 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 17 Aug 2017 00:28:10 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: <85mv6zio3p.fsf@benfinney.id.au> Steve D'Aprano writes: > If he wanted declarative semantics, why didn't he argue for > declarative syntax like "select...where", instead of choosing > procedural syntax which matches the actual procedural semantics given? The syntax ?f(foo) for foo in bar if baz(foo)? is nicely declarative. > In order to think of list comps as declarative, you have to: > > - ignore the PEP; > - ignore the documentation; > - ignore the actual behaviour; > - ignore the syntax. > > That's a lot of reality to ignore. Python's list comprehensions behave as I expect that syntax to behave, from the declarative, single-conceptual-operation expression model. I'm not ignoring the behaviour or syntax. The PEP and documentation, I will admit to ignoring (or at least have forgotten since I first read them, now that I've got Python's actual behaviour working with an widely known mental model). The Python behaviour and mental model fit fine together, so I just keep programming on that basis. > That's why I was surprised at your attitude that list comps could > reasonably be interpreted as a single operation. To do so requires > ignoring everything we know about list comprehensions in Python. I hope that clarifies. Everything about how Python's list comprehension behaves, at a Python language level, supports the mental model of a list comprehension as a single conceptual operation. Does Python's behaviour *also* support the mental model of ?it's like a for loop?? Yes. Python supports multiple mental models, that should be no surprise. > But comprehensions? You can't even write a comprehension without being > reminded that they are designed as an expression form of for-loops! I'm reminded of a set operation. It works just fine that way. > > [?] your bafflement at getting answers not to the question you > > didn't ask, but instead to the question you did ask, is becoming > > quite strange. > > I don't understand this. You seem to be implying that the answer to > the question: > > "What do you think Python will do if you execute a list > comprehension?" You didn't ask about what it *will do*, you asked about syntax that Python does not yet support (a ?while? keyword in a list comprehension). The correct answer to ?What do you think Python will do if you execute an expression with an invalid keyword in it?? is ?Python will raise a SyntaxError?. Indeed, you got just such an answer, and it was an answer to the wrong question as you rightly pointed out at the time. Instead, you asked the much more interesting question: With the ?while? keyword in the expression, what do you think Python *would do* if it supported such an expression? So you're asking us not what Python *will in fact* do with that syntax (today, it will raise an error). You're asking us what *the proposed syntax would mean* if Python supported it. > is best answered by predicting that Python will do something that you > know it actually won't do. You're asking something very similar. Because this is *proposed* syntax, presently not valid Python, you're asking us to speculate about some putative future Python, based on our mental models of Python semantics. > But we really haven't established that Python's comprehension > semantics violates any widely established programming language > semantics. Python's comprehension semantics do not violate those widely established semantics, so you can stop waiting for anyone to try establishing that. I'm responding to the proposal by pointing out that, unlike today's Python, the proposed behaviour would violate those semantics. -- \ ?It is seldom that liberty of any kind is lost all at once.? | `\ ?David Hume | _o__) | Ben Finney From steve+python at pearwood.info Wed Aug 16 10:53:42 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 00:53:42 +1000 Subject: Cross-language comparison: function map and similar Message-ID: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Over in another thread, we've been talking about comprehensions and their similarities and differences from the functional map() operation. Reminder: map(chr, [65, 66, 67, 68]) will return ['A', 'B', 'C']. My questions for those who know languages apart from Python: Are there language implementations which evaluate the result of map() (or its equivalent) in some order other than the obvious left-to-right first-to-last sequential order? Is that order guaranteed by the language, or is it an implementation detail? Standard library functions implementing an explicitly "parallel map" or "threaded map" are also relevant. (Less interested in third-party libraries, unless they're practically a standard for the language in question.) E.g. given the map above, Blub language might promise to evaluate chr(65), chr(66), chr(67) and chr(68) in parallel if your computer has four cores. Or some Blub language implementation may unroll the above map to the equivalent of this pseudo-code: array = [None, None, None, None] array[3] = chr(68) array[2] = chr(67) array[1] = chr(66) array[0] = chr(65) I'm not terribly interested in hypothetical "Blub language doesn't specify evaluation order, so some implementation could do this". I'm more interested in actual concrete examples of mapping implementations which don't operate in the obvious first-to-last order. For example, Fortran has "do concurrent": do concurrent(i = 1:n) a(i) = a(i+m)+b(i) end do which tells the compiler that it can run the iterations in any order, or parallelize them and run them in parallel across threads, etc: https://www.hpcwire.com/2015/04/06/compilers-and-more-the-past-present-and-future-of-parallel-loops/ Wikipedia mentions a few specialised parallel processing languages which have equivalent forms of parallel map: https://en.wikipedia.org/wiki/Map_%28parallel_pattern%29 Wolfram Language (Mathematica?) has a parallel map: http://reference.wolfram.com/language/ref/ParallelMap.html as does Clojure: https://clojuredocs.org/clojure.core/pmap Any others? I'm especially interested in cases of languages where their regular map() function is performed in parallel, or out of order, *without* the performance hit that the Clojure docs warn about: "Only useful for computationally intensive functions where the time of f dominates the coordination overhead." -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 16 11:39:21 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 01:39:21 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> Message-ID: <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 12:28 am, Ben Finney wrote: > Steve D'Aprano writes: > >> If he wanted declarative semantics, why didn't he argue for >> declarative syntax like "select...where", instead of choosing >> procedural syntax which matches the actual procedural semantics given? > > The syntax ?f(foo) for foo in bar if baz(foo)? is nicely declarative. Do you consider: for foo in bar: if baz(foo): f(foo) # append to a list, or print, or yield, as needed declarative? My understanding of "declarative" agrees with Wikipedia: "In computer science, declarative programming is a programming paradigm ... that expresses the logic of a computation without describing its control flow." https://en.wikipedia.org/wiki/Declarative_programming For-loops are a classic example of explicitly specifying control flow, so I'm surprised that you seem to think they are declarative. SQL's SELECT ... WHERE is one of the canonical examples of declarative programming: SELECT * FROM Book WHERE price > 100.00 returns matching books (those with a price over 100) in arbitrary order (unless you specify the "ORDER BY" clause). But more importantly than the order of results, the order of data accesses is not specified by the SELECT statement. Instead, the SQL compiler generates a "query plan" that specifies how to access the data: https://en.wikipedia.org/wiki/Query_plan independently of the programmer. (Although many databases offer additional tools for manually fine-tuning the query plan.) If instead we wrote: for row in Book: if row.price > 100: print(row) # for example I think that is specifying the control flow, and therefore not declarative. Do you agree? [...] > I'm responding to the proposal by pointing out that, unlike today's > Python, the proposed behaviour would violate those semantics. In what way? Do you feel the same way about itertools.takewhile? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 16 11:40:53 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 01:40:53 +1000 Subject: Cross-language comparison: function map and similar References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59946786$0$1610$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 12:53 am, Steve D'Aprano wrote: > map(chr, [65, 66, 67, 68]) > > will return ['A', 'B', 'C']. Of course I meant ['A', 'B', 'C', 'D']. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rustompmody at gmail.com Wed Aug 16 13:17:33 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Wed, 16 Aug 2017 10:17:33 -0700 (PDT) Subject: Cross-language comparison: function map and similar In-Reply-To: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: <7af4421e-bfa3-4bfc-86d4-7c2f3b457451@googlegroups.com> On Wednesday, August 16, 2017 at 8:24:46 PM UTC+5:30, Steve D'Aprano wrote: > Over in another thread, we've been talking about comprehensions and their > similarities and differences from the functional map() operation. > > Reminder: > > map(chr, [65, 66, 67, 68]) > > will return ['A', 'B', 'C']. > > My questions for those who know languages apart from Python: > > Are there language implementations which evaluate the result of map() (or its > equivalent) in some order other than the obvious left-to-right first-to-last > sequential order? Is that order guaranteed by the language, or is it an > implementation detail? There are dozens of parallel/concurrent languages: https://en.wikipedia.org/wiki/List_of_concurrent_and_parallel_programming_languages > > Standard library functions implementing an explicitly "parallel map" > or "threaded map" are also relevant. Here's the peach (parallel-each) 'adverb in Q/K http://code.kx.com/wiki/Reference/peach In more mainstream languages: parallel map in Julia https://docs.julialang.org/en/latest/manual/parallel-computing Haskell's parmap et al: http://chimera.labs.oreilly.com/books/1230000000929/ch03.html#sec_par-kmeans-perf From steve+python at pearwood.info Wed Aug 16 13:18:31 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 03:18:31 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59947e69$0$1614$c3e8da3$5496439d@news.astraweb.com> On Wed, 16 Aug 2017 11:53 pm, jmp wrote: > On 08/10/2017 04:28 PM, Steve D'Aprano wrote: >> Every few years, the following syntax comes up for discussion, with some >> people saying it isn't obvious what it would do, and others disagreeing and >> saying that it is obvious. So I thought I'd do an informal survey. >> >> What would you expect this syntax to return? >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) while x < 5] >> >> >> For comparison, what would you expect this to return? (Without actually >> trying it, thank you.) >> >> [x + 1 for x in (0, 1, 2, 999, 3, 4) if x < 5] >> >> >> >> How about these? >> >> [x + y for x in (0, 1, 2, 999, 3, 4) while x < 5 for y in (100, 200)] >> >> [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] >> >> >> >> Thanks for your comments! >> > > [1,2,3] > [1,2,3,4,5] > SyntaxError("Have you tried Perl ?") > SyntaxError("Have you tried Perl ?") > > I really would not want to deal with 3 and 4. :-) #4 is actually valid syntax right now, and has been since Python 2.2. py> [x + y for x in (0, 1, 2, 999, 3, 4) if x < 5 for y in (100, 200)] [100, 200, 101, 201, 102, 202, 103, 203, 104, 204] It is equivalent to: for x in (0, 1, 2, 999, 3, 4): if x < 5: for y in (100, 200): x + y # collect into the list -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ian.g.kelly at gmail.com Wed Aug 16 13:28:20 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 16 Aug 2017 11:28:20 -0600 Subject: A small quiz question In-Reply-To: References: Message-ID: On Wed, Aug 16, 2017 at 6:51 AM, Dennis Lee Bieber wrote: > On 16 Aug 2017 11:06:26 GMT, ram at zedat.fu-berlin.de (Stefan Ram) declaimed > the following: > >> I wrote my first Python quiz question! >> >> It goes like this: >> >> Can you predict (without trying it out) what the Python >> console will output after the following three lines have >> been entered? >> >>def f(i): print(i); return i; >> >>f(4)**f(1)**f(2) >> > > As a first guess > > 2 > 1 > 4 > > 4 > > since in many languages, exponentiation associates right to left I thought the same thing but figured there was no reason to eval f(2) before f(1), so I came up with 1 2 4 4 which is also wrong. From best_lay at yahoo.com Wed Aug 16 13:57:16 2017 From: best_lay at yahoo.com (Wildman) Date: Wed, 16 Aug 2017 12:57:16 -0500 Subject: Request Help With Gdk.Display Message-ID: I am working on a program for the Linux platform that reports system information. The program reports screen information, number of monitors, resolution of each one and the total resolution. It does it using a couple of external utils, Xrandr and Xdpyinfo. It is my goal to replace the existing code with a python solution without depending on the external programs. With the help of a code snippet I found, I came up with this but it only reports the resolution of the primary monitor... #! /usr/bin/env python3 import gi gi.require_version('Gdk', '3.0') from gi.repository import Gdk display = Gdk.Display.get_default() pm = display.get_primary_monitor() geo = pm.get_geometry() w = geo.width h = geo.height print(w,h) I know that the number of monitors can be obtained by using... mc = Gdk.Display.get_n_monitors(display) Then to get each monitor, this can be used... monitor = Gdk.Display.get_monitor(display, monitor_num) My problem is that I can't find any information on how "monitor_num" is obtained. The only thing I have been able to find out is that it is an integer. Can anybody point me in the right direction? Much appreciated. -- GNU/Linux user #557453 May the Source be with you. From tjreedy at udel.edu Wed Aug 16 14:07:17 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 16 Aug 2017 14:07:17 -0400 Subject: Cross-language comparison: function map and similar In-Reply-To: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/16/2017 10:53 AM, Steve D'Aprano wrote: > Over in another thread, we've been talking about comprehensions and their > similarities and differences from the functional map() operation. > Reminder: > map(chr, [65, 66, 67, 68]) > will return ['A', 'B', 'C']. The comprehension 'while' proposal is for future Python 3. Asking your while question the restricted context of Python 2 encouraged the restricted list-based or concrete-collection-based thinking about comprehensions that you got in some of the answers. The above snipper is only true for Python-2 . In Python 3, >>> oracle = map(chr, [65, 66, 67, 68]) >>> oracle >>> next(oracle) 'A' >>> next(oracle) 'B' >>> next(oracle) 'C' When oracle is asked for the next value, it asks base_oracle = iter(iterable) for a value. If base_oracle gives one, oracle gives func(value). If base_iterable raises StopIteration, so does oracle. This process is inherently sequential. It remains so with multiple input iterables. >>> next(oracle) 'D' >>> next(oracle) Traceback (most recent call last): File "", line 1, in next(oracle) StopIteration Even in pre-2.2 Python, map's input was not restricted to being a list, but could be any 'sequence'. From 2.0 doc: "The list arguments may be *any kind of sequence*" [emphasis added]. I am rather sure that in this context, a 'sequence' was merely something that could be indexed and that a pre-defined length was not required. This means that map could use the old iterator protocol. So 'sequence' meant 'iterator' in current terms. The old spelling of 'next(iterator)' was 'iterator[i]' where i is 0 for the first request for an object and incremented thereafter. The 'sequence' was free to ignore i when generating the return object. It could also use external input. > My questions for those who know languages apart from Python: > > Are there language implementations which evaluate the result of map() (or its > equivalent) in some order other than the obvious left-to-right first-to-last > sequential order? If map's collection input is unbounded, as with Python, a right-to-left or completely parallel order is not possible. If the input oracle creates objects on demand, as Python allows, then doing anything other that applying func as objects are made available requires internal storage. Asking an oracle for millions of objects when only the first few are needed, is foolish. Storing millions or billions of objects all at once when there are only needed one at a time is also foolish. Which is why map and filter were changed in Python 3. -- Terry Jan Reedy From python at mrabarnett.plus.com Wed Aug 16 14:11:16 2017 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 16 Aug 2017 19:11:16 +0100 Subject: Request Help With Gdk.Display In-Reply-To: References: Message-ID: <4b697335-2707-e030-1904-697f18a88bd1@mrabarnett.plus.com> On 2017-08-16 18:57, Wildman via Python-list wrote: > I am working on a program for the Linux platform that > reports system information. The program reports screen > information, number of monitors, resolution of each one > and the total resolution. It does it using a couple of > external utils, Xrandr and Xdpyinfo. It is my goal to > replace the existing code with a python solution without > depending on the external programs. > > With the help of a code snippet I found, I came up with > this but it only reports the resolution of the primary > monitor... > > #! /usr/bin/env python3 > > import gi > gi.require_version('Gdk', '3.0') > from gi.repository import Gdk > > display = Gdk.Display.get_default() > pm = display.get_primary_monitor() > geo = pm.get_geometry() > w = geo.width > h = geo.height > print(w,h) > > > I know that the number of monitors can be obtained by > using... > > mc = Gdk.Display.get_n_monitors(display) > > Then to get each monitor, this can be used... > > monitor = Gdk.Display.get_monitor(display, monitor_num) > > My problem is that I can't find any information on how > "monitor_num" is obtained. The only thing I have been > able to find out is that it is an integer. Can anybody > point me in the right direction? Much appreciated. > If get_n_monitors tells you how many monitors there are, isn't monitor_num just an index (0, 1, 2, ...)? From marko at pacujo.net Wed Aug 16 14:22:51 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 16 Aug 2017 21:22:51 +0300 Subject: A small quiz question References: Message-ID: <87378r5q4k.fsf@elektro.pacujo.net> Ian Kelly : > On Wed, Aug 16, 2017 at 6:51 AM, Dennis Lee Bieber > wrote: >>>def f(i): print(i); return i; >>> >>>f(4)**f(1)**f(2) >>> >> >> As a first guess >> >> 2 >> 1 >> 4 >> >> 4 >> >> since in many languages, exponentiation associates right to left > > I thought the same thing but figured there was no reason to eval f(2) > before f(1), so I came up with > > 1 > 2 > 4 > 4 > > which is also wrong. Python evaluates expressions from left to right. Marko From best_lay at yahoo.com Wed Aug 16 15:33:27 2017 From: best_lay at yahoo.com (Wildman) Date: Wed, 16 Aug 2017 14:33:27 -0500 Subject: Request Help With Gdk.Display References: <4b697335-2707-e030-1904-697f18a88bd1@mrabarnett.plus.com> Message-ID: On Wed, 16 Aug 2017 19:11:16 +0100, MRAB wrote: > On 2017-08-16 18:57, Wildman via Python-list wrote: >> I am working on a program for the Linux platform that >> reports system information. The program reports screen >> information, number of monitors, resolution of each one >> and the total resolution. It does it using a couple of >> external utils, Xrandr and Xdpyinfo. It is my goal to >> replace the existing code with a python solution without >> depending on the external programs. >> >> With the help of a code snippet I found, I came up with >> this but it only reports the resolution of the primary >> monitor... >> >> #! /usr/bin/env python3 >> >> import gi >> gi.require_version('Gdk', '3.0') >> from gi.repository import Gdk >> >> display = Gdk.Display.get_default() >> pm = display.get_primary_monitor() >> geo = pm.get_geometry() >> w = geo.width >> h = geo.height >> print(w,h) >> >> >> I know that the number of monitors can be obtained by >> using... >> >> mc = Gdk.Display.get_n_monitors(display) >> >> Then to get each monitor, this can be used... >> >> monitor = Gdk.Display.get_monitor(display, monitor_num) >> >> My problem is that I can't find any information on how >> "monitor_num" is obtained. The only thing I have been >> able to find out is that it is an integer. Can anybody >> point me in the right direction? Much appreciated. >> > If get_n_monitors tells you how many monitors there are, isn't > monitor_num just an index (0, 1, 2, ...)? I don't know. The documentation doesn't say. That is something I can test that I hadn't thought of. I hope you are right. It would be nice if it was that simple. Thanks. -- GNU/Linux user #557453 The cow died so I don't need your bull! From mok-kong.shen at t-online.de Wed Aug 16 17:06:49 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Wed, 16 Aug 2017 23:06:49 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> Message-ID: <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> Am 15.08.2017 um 20:47 schrieb Larry Hudson: [snip] >> =============== test2() code ============== >> def test2(alist): ss ???> [1, 2, 3] >> alist ?? >> --------------------------------------------- >> ss ???> [3, 6, 9] >> alist ?? >> --------------------------------------------- >> alist = [30, 60, 90] ss ???> [3, 6, 9] >> alist ???> [30, 60, 90] [snip] The above shows that with , i.e. assigning single values to individual members of alist (with alist[0]=3 etc.) is "principally" different from assigning a whole list to alist (with alist=[30,60,90]). The first operation doesn't affect the connection between ss and alist, while the second separates the connection between ss and alist, as your diagram above clearly indicates. Isn't this kind of convention/rule something that appears to be not quite natural/"logical" to the common users (non-experts)? M. K. Shen From ned at nedbatchelder.com Wed Aug 16 17:20:31 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Wed, 16 Aug 2017 17:20:31 -0400 Subject: A question on modification of a list via a function invocation In-Reply-To: <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> Message-ID: <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> On 8/16/17 5:06 PM, Mok-Kong Shen wrote: > Am 15.08.2017 um 20:47 schrieb Larry Hudson: > [snip] >>> =============== test2() code ============== >>> def test2(alist): ss ???> [1, 2, 3] >>> alist ?? >>> --------------------------------------------- >>> ss ???> [3, 6, 9] >>> alist ?? >>> --------------------------------------------- >>> alist = [30, 60, 90] ss ???> [3, 6, 9] >>> alist ???> [30, 60, 90] > [snip] > > The above shows that with , i.e. assigning single values to > individual members of alist (with alist[0]=3 etc.) is "principally" > different from assigning a whole list to alist (with alist=[30,60,90]). > The first operation doesn't affect the connection between ss and alist, > while the second separates the connection between ss and alist, as your > diagram above clearly indicates. > > Isn't this kind of convention/rule something that appears to be not > quite natural/"logical" to the common users (non-experts)? This kind of question comes up frequently, so you are right, it needs to be learned. But this is true of nearly everything about programming languages, isn't it? Did you take a look at https://nedbatchelder.com/text/names1.html ? It's the best way I know to explain the principles at work here. --Ned. From ben.usenet at bsb.me.uk Wed Aug 16 17:37:05 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Wed, 16 Aug 2017 22:37:05 +0100 Subject: A small quiz question References: <87r2wbmy3c.fsf@bsb.me.uk> <59944f76$0$1611$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87wp63kxdq.fsf@bsb.me.uk> Steve D'Aprano writes: > On Wed, 16 Aug 2017 11:38 pm, Ben Bacarisse wrote: > >> ram at zedat.fu-berlin.de (Stefan Ram) writes: >> >>> I wrote my first Python quiz question! >>> >>> It goes like this: >>> >>> Can you predict (without trying it out) what the Python >>> console will output after the following three lines have >>> been entered? >>> >>> def f(i): print(i); return i; >>> >>> f(4)**f(1)**f(2) >> >> Does Python actually specify what the output will be? It's going to end >> with 4 (the result from the REPL) and 4, 1 and 2 will appear on the >> lines before, but is the order they appear specified? > > https://docs.python.org/3/reference/expressions.html#evaluation-order Thanks. -- Ben. From kevaday123 at gmail.com Wed Aug 16 17:47:26 2017 From: kevaday123 at gmail.com (Kevi Aday (Katch22)) Date: Wed, 16 Aug 2017 17:47:26 -0400 Subject: Default .py program and Edit with IDLE problem Message-ID: <5994bd71.d86e240a.a76fc.516e@mx.google.com> Hello, I installed python 3.6.2 for making running and editing programs. Later on I installed python 2.7 because a program that I downloaded only works with that. Later I deleted the program. I then wanted to run a program from cmd but it was giving me all kinds of errors I didn?t used to get. I thought the problem was being caused by python 2.7 and I didn?t even need it anymore so I uninstalled it. After I uninstalled it, all my .py files? icons disappeared and when I right clicked on it the ?Edit with IDLE? disappeared. I tried all kinds of things like repairing python, editing the registry, etc. but I just can?t fix the problem and this has never happened to me and its really bugging me. Please help. A Python fan From best_lay at yahoo.com Wed Aug 16 18:13:41 2017 From: best_lay at yahoo.com (Wildman) Date: Wed, 16 Aug 2017 17:13:41 -0500 Subject: Request Help With Gdk.Display References: <4b697335-2707-e030-1904-697f18a88bd1@mrabarnett.plus.com> Message-ID: On Wed, 16 Aug 2017 14:33:27 -0500, Wildman wrote: > On Wed, 16 Aug 2017 19:11:16 +0100, MRAB wrote: > >> On 2017-08-16 18:57, Wildman via Python-list wrote: >>> I am working on a program for the Linux platform that >>> reports system information. The program reports screen >>> information, number of monitors, resolution of each one >>> and the total resolution. It does it using a couple of >>> external utils, Xrandr and Xdpyinfo. It is my goal to >>> replace the existing code with a python solution without >>> depending on the external programs. >>> >>> With the help of a code snippet I found, I came up with >>> this but it only reports the resolution of the primary >>> monitor... >>> >>> #! /usr/bin/env python3 >>> >>> import gi >>> gi.require_version('Gdk', '3.0') >>> from gi.repository import Gdk >>> >>> display = Gdk.Display.get_default() >>> pm = display.get_primary_monitor() >>> geo = pm.get_geometry() >>> w = geo.width >>> h = geo.height >>> print(w,h) >>> >>> >>> I know that the number of monitors can be obtained by >>> using... >>> >>> mc = Gdk.Display.get_n_monitors(display) >>> >>> Then to get each monitor, this can be used... >>> >>> monitor = Gdk.Display.get_monitor(display, monitor_num) >>> >>> My problem is that I can't find any information on how >>> "monitor_num" is obtained. The only thing I have been >>> able to find out is that it is an integer. Can anybody >>> point me in the right direction? Much appreciated. >>> >> If get_n_monitors tells you how many monitors there are, isn't >> monitor_num just an index (0, 1, 2, ...)? > > I don't know. The documentation doesn't say. That is > something I can test that I hadn't thought of. I hope > you are right. It would be nice if it was that simple. > Thanks. In case anyone is interested that was the answer. Thanks again MRAB. -- GNU/Linux user #557453 The cow died so I don't need your bull! From cs at cskk.id.au Wed Aug 16 18:26:35 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 17 Aug 2017 08:26:35 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> References: <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> Message-ID: <20170816222635.GA2160@cskk.homeip.net> On 16Aug2017 23:06, Mok-Kong Shen wrote: >Am 15.08.2017 um 20:47 schrieb Larry Hudson: >[snip] >>>=============== test2() code ============== >>>def test2(alist): ss ???> [1, 2, 3] >>> alist ?? >>>--------------------------------------------- >>> ss ???> [3, 6, 9] >>> alist ?? >>>--------------------------------------------- >>> alist = [30, 60, 90] ss ???> [3, 6, 9] >>> alist ???> [30, 60, 90] >[snip] > >The above shows that with , i.e. assigning single values to >individual members of alist (with alist[0]=3 etc.) is "principally" >different from assigning a whole list to alist (with alist=[30,60,90]). >The first operation doesn't affect the connection between ss and alist, >while the second separates the connection between ss and alist, as your >diagram above clearly indicates. > >Isn't this kind of convention/rule something that appears to be not >quite natural/"logical" to the common users (non-experts)? Well, it may not seem natural, but it is consistent. Larry's excellent diagrams have glossed over the lower level of array assignment for clarity. Observe: alist = [1,2,3] This causes "alist" to refer to the list object [1,2,3]. But a list is itself a compound object with references to its elements. So where Larry drew: alist ???> [1,2,3] a more complete diagram looks like this: alist ???> [ ???> 0, ???> 1, ???> 2 ] so that when you write: alist[1] = 9 You're dropped the reference to the value 1, and replaced it with a reference to the value 9: alist ???> [ ???> 0, ???> 9, ???> 2 ] So you can see that "alist" is a variable name - all python variables are references to values. So "alist[1]" is also effectively a variable name. What one would call an "lvalue" in the C programming language: a term that may appear on the left of an assignment statement. So they are not funcamentally different activity - what has changed is how you describe the reference which is being modified. Consider an object: class C: def __init__(self, v0): self.x = v0 o = C(1) o2 = C(9) o.x = 9 o = o2 Here we've made an object with an attribute "x". We make a first instance with x=1, _bound_ to the name "o". We make another with x=9, bound to the name "o2". Then: o.x = 9 changes the reference within the first object to refer to the value 9 instead of the value 1. It does not change what the name "o" refers to. Versus: o = o2 which changes which object the name "o" refers to ("is bound to"): it now refers to the second object we made. This is exactly analogous to the array example, but using objects. The notation eg "alist[1]" or "o.x" is just what you need to say to designate which reference you are changing. Cheers, Cameron Simpson (formerly cs at zip.com.au) From mok-kong.shen at t-online.de Wed Aug 16 18:29:30 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Thu, 17 Aug 2017 00:29:30 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> Message-ID: <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Am 16.08.2017 um 23:20 schrieb Ned Batchelder: > On 8/16/17 5:06 PM, Mok-Kong Shen wrote: >> Am 15.08.2017 um 20:47 schrieb Larry Hudson: >> [snip] >>>> =============== test2() code ============== >>>> def test2(alist): ss ???> [1, 2, 3] >>>> alist ?? >>>> --------------------------------------------- >>>> ss ???> [3, 6, 9] >>>> alist ?? >>>> --------------------------------------------- >>>> alist = [30, 60, 90] ss ???> [3, 6, 9] >>>> alist ???> [30, 60, 90] >> [snip] >> >> The above shows that with , i.e. assigning single values to >> individual members of alist (with alist[0]=3 etc.) is "principally" >> different from assigning a whole list to alist (with alist=[30,60,90]). >> The first operation doesn't affect the connection between ss and alist, >> while the second separates the connection between ss and alist, as your >> diagram above clearly indicates. >> >> Isn't this kind of convention/rule something that appears to be not >> quite natural/"logical" to the common users (non-experts)? > > This kind of question comes up frequently, so you are right, it needs to > be learned. But this is true of nearly everything about programming > languages, isn't it? Did you take a look at > https://nedbatchelder.com/text/names1.html ? It's the best way I know > to explain the principles at work here. I looked at your web page but I don't see at which place in it the issue that I deem to be not natural/"logical" above are (anyway concretely) explained. I apologize, if I have overlooked. I have earlier learned some other (older) programming languages. For these the formal parameters are either "by reference" or "by value". In the first case, any modification of the formal parameter inside a function affects the corresponding actual parameter of a function call, while in the second case a copy of the actual parameter is passed into the function so that any modification of the formal parameter inside the function has no effect at all outside. This is extremely clear-cut in comparison to Python, isn't it? Anyway, while any new user of a programming language certainly can be expected to take good efforts to learn a lot of new stuffs, I suppose it's good for any practical programming language to minimize the cases of surprises for those that come from other programming languages. M. K. Shen From rosuav at gmail.com Wed Aug 16 18:39:50 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Aug 2017 08:39:50 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen wrote: > I have earlier learned some other (older) programming languages. For > these the formal parameters are either "by reference" or "by value". > In the first case, any modification of the formal parameter inside > a function affects the corresponding actual parameter of a function > call, while in the second case a copy of the actual parameter is > passed into the function so that any modification of the formal > parameter inside the function has no effect at all outside. This is > extremely clear-cut in comparison to Python, isn't it? Anyway, while > any new user of a programming language certainly can be expected to > take good efforts to learn a lot of new stuffs, I suppose it's good > for any practical programming language to minimize the cases of > surprises for those that come from other programming languages. Python has a data model that is neither of the above, but it's simpler in that you have one pattern for everything. Whether you're looking at function parameters, return values, assignment, loops, function definitions, or anything else, the model is exactly the same. And that model is: objects exist independently of names, and names refer to objects. If you do "x = y", you're saying "figure out which object 'y' means, and make the name 'x' refer to it". If you do "x[1] = y", you're saying "figure out which object 'y' means, and tell the object that 'x' means that it should make [1] refer to that object". So if you have multiple names referring to the same object, any change you ask that object to do will be seen by every other name that also refers to it - because it's all about the object. ChrisA From cannedham284 at hotmail.com Wed Aug 16 18:44:40 2017 From: cannedham284 at hotmail.com (Ben Iannitelli) Date: Wed, 16 Aug 2017 22:44:40 +0000 Subject: Default .py program and Edit with IDLE problem In-Reply-To: <5994bd71.d86e240a.a76fc.516e@mx.google.com> References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> Message-ID: Hi Kevi, Just to clarify your situation: 1. Which operating system? 2. You still have all of the .py files that you yourself wrote? Sincerely, -Ben I. -- https://mail.python.org/mailman/listinfo/python-list Python-list Info Page mail.python.org This mailing list is a general discussion list for the Python programming language. Please note that for those who prefer, this list is mirrored to the Usenet ... From flebber.crue at gmail.com Wed Aug 16 18:48:57 2017 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 16 Aug 2017 15:48:57 -0700 (PDT) Subject: Why is my class undefined? Message-ID: Morning I haven't ventured into classes much before. When trying to follow some examples and create my own classes in a jupyter notebook I receive an error that the class is undefined. So I created for practise a frog class class frog(object): def __init__(self, ftype, word): self.ftype = ftype self.word = ftype def jump(self): """ Make frog jump """ return "I am jumping" if __name__ == "__main__": tree_frog = frog("Tree Frog", "Ribbitt") print(frog.ftype) print(frog.word) I receive this error NameError Traceback (most recent call last) in () ----> 1 class frog(object): 2 3 def __init__(self, ftype, word): 4 self.ftype = ftype 5 self.word = ftype in frog() 12 13 if __name__ == "__main__": ---> 14 tree_frog = frog("Tree Frog", "Ribbitt") 15 print(frog.ftype) 16 print(frog.word) NameError: name 'frog' is not defined what exactly am I doing wrong? Cheers Sayth From ian.g.kelly at gmail.com Wed Aug 16 19:02:50 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 16 Aug 2017 17:02:50 -0600 Subject: Why is my class undefined? In-Reply-To: References: Message-ID: On Wed, Aug 16, 2017 at 4:48 PM, Sayth Renshaw wrote: > Morning > > I haven't ventured into classes much before. When trying to follow some examples and create my own classes in a jupyter notebook I receive an error that the class is undefined. > > So I created for practise a frog class > > class frog(object): > > def __init__(self, ftype, word): > self.ftype = ftype > self.word = ftype > > def jump(self): > """ > Make frog jump > """ > return "I am jumping" > > if __name__ == "__main__": > tree_frog = frog("Tree Frog", "Ribbitt") > print(frog.ftype) > print(frog.word) > > > I receive this error > > NameError Traceback (most recent call last) > in () > ----> 1 class frog(object): > 2 > 3 def __init__(self, ftype, word): > 4 self.ftype = ftype > 5 self.word = ftype > > in frog() > 12 > 13 if __name__ == "__main__": > ---> 14 tree_frog = frog("Tree Frog", "Ribbitt") > 15 print(frog.ftype) > 16 print(frog.word) > > NameError: name 'frog' is not defined > > what exactly am I doing wrong? The if __name__ == "__main__" block is inside the class declaration block, so at the point that it runs the class has not been created yet. Try removing the indentation to place it after the class block instead. From lists at mostrom.pp.se Wed Aug 16 19:03:35 2017 From: lists at mostrom.pp.se (Jan Erik =?utf-8?q?Mostr=C3=B6m?=) Date: Thu, 17 Aug 2017 01:03:35 +0200 Subject: Why is my class undefined? In-Reply-To: References: Message-ID: On 17 Aug 2017, at 0:48, Sayth Renshaw wrote: > what exactly am I doing wrong? Outdent the if-statement = jem From mok-kong.shen at t-online.de Wed Aug 16 19:03:37 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Thu, 17 Aug 2017 01:03:37 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> Am 17.08.2017 um 00:39 schrieb Chris Angelico: > On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen > wrote: >> I have earlier learned some other (older) programming languages. For >> these the formal parameters are either "by reference" or "by value". >> In the first case, any modification of the formal parameter inside >> a function affects the corresponding actual parameter of a function >> call, while in the second case a copy of the actual parameter is >> passed into the function so that any modification of the formal >> parameter inside the function has no effect at all outside. This is >> extremely clear-cut in comparison to Python, isn't it? Anyway, while >> any new user of a programming language certainly can be expected to >> take good efforts to learn a lot of new stuffs, I suppose it's good >> for any practical programming language to minimize the cases of >> surprises for those that come from other programming languages. > > Python has a data model that is neither of the above, but it's simpler > in that you have one pattern for everything. Whether you're looking at > function parameters, return values, assignment, loops, function > definitions, or anything else, the model is exactly the same. And that > model is: objects exist independently of names, and names refer to > objects. If you do "x = y", you're saying "figure out which object 'y' > means, and make the name 'x' refer to it". If you do "x[1] = y", > you're saying "figure out which object 'y' means, and tell the object > that 'x' means that it should make [1] refer to that object". So if > you have multiple names referring to the same object, any change you > ask that object to do will be seen by every other name that also > refers to it - because it's all about the object. I may have misunderstood you. But I don't think what you wrote above would explain why the program below produces the output: [1, 2, 3] [3, 6, 9] M. K. Shen ----------------------------------------------------- def test2(alist): alist[0],alist[1],alist[2]=3,6,9 alist=[30,60,90] return def test3(alist): alist=[30,60,90] alist[0],alist[1],alist[2]=3,6,9 return ss=[1,2,3] test3(ss) print(ss) test2(ss) print(ss) From ian.g.kelly at gmail.com Wed Aug 16 19:29:17 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 16 Aug 2017 17:29:17 -0600 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: On Wed, Aug 16, 2017 at 5:03 PM, Stefan Ram wrote: > Chris Angelico writes: >>objects exist independently of names > > When the object ?Example()? loses its name below, > it loses its existence. > > class Example(object): > ... def __init__(self): > ... print( 'initialized' ) > ... def __del__(self): > ... print( 'deleted' ) > ... >>>> a = Example() > initialized >>>> a = 2 > deleted Try: >>> class Example(object): ... def __init__(self): ... print('initialized') ... def __del__(self): ... print('deleted') ... >>> a = Example() initialized >>> b = [a] >>> a = 2 >>> The object no longer has a name, but it still exists. From ben+python at benfinney.id.au Wed Aug 16 19:32:15 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 17 Aug 2017 09:32:15 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: <85inhnhyww.fsf@benfinney.id.au> Steve D'Aprano writes: > On Thu, 17 Aug 2017 12:28 am, Ben Finney wrote: > > > Steve D'Aprano writes: > > > >> If he wanted declarative semantics, why didn't he argue for > >> declarative syntax like "select...where", instead of choosing > >> procedural syntax which matches the actual procedural semantics given? > > > > The syntax ?f(foo) for foo in bar if baz(foo)? is nicely declarative. > > Do you consider [a Python ?for? loop] declarative? No, that is a syntax that can only mean iteration over the *distinct statements* in the block. > My understanding of "declarative" agrees with Wikipedia: Thanks. Mine does too. > For-loops are a classic example of explicitly specifying control flow, > so I'm surprised that you seem to think they are declarative. The Python for loop syntax specifies control flow. The Python list comprehension syntax does not specify control flow. The expression ?f(foo) for foo in bar if baz(foo)? is not expressing control flow, it is expressing a single conceptual operation. A collection goes in, a single conceptual operation is performed, a collection goes out. The control flow is not specified. > SQL's SELECT ... WHERE is one of the canonical examples of declarative > programming: > > SELECT * > FROM Book > WHERE price > 100.00 > > returns matching books (those with a price over 100) in arbitrary > order (unless you specify the "ORDER BY" clause). But more importantly > than the order of results, the order of data accesses is not specified > by the SELECT statement. Nor is the order of data accesses specified by Python's comprehension syntax. In both cases, of course, implementations *do* perform smaller-grained operations in a specific control flow. You'll even find that order of operations described in the documentation, for SQL implementations and for Python, respectively. > for row in Book: > if row.price > 100: > print(row) # for example > > I think that is specifying the control flow, and therefore not > declarative. Do you agree? Yes, I agree. > [...] > > I'm responding to the proposal by pointing out that, unlike today's > > Python, the proposed behaviour would violate those semantics. > > In what way? By inserting a semantic of iteration over multiple operations, into what is otherwise an expression with declarative semantics. > Do you feel the same way about itertools.takewhile? The functions in the ?itertools? module are not expressing a declarative single operation; they are expressing an iteration of multiple operations. List comprehensions, in their syntax, strongly connote a single declarative operation. This makes them different from iteration syntax. -- \ ?Shepherds ? look after their sheep so they can, first, fleece | `\ them and second, turn them into meat. That's much more like the | _o__) priesthood as I know it.? ?Christopher Hitchens, 2008-10-29 | Ben Finney From cs at cskk.id.au Wed Aug 16 19:58:29 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 17 Aug 2017 09:58:29 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> References: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> Message-ID: <20170816235829.GA54664@cskk.homeip.net> On 17Aug2017 01:03, Mok-Kong Shen wrote: >Am 17.08.2017 um 00:39 schrieb Chris Angelico: >>On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen >> wrote: >>Chris wrote: >>objects exist independently of names, and names refer to >>objects. If you do "x = y", you're saying "figure out which object 'y' >>means, and make the name 'x' refer to it". If you do "x[1] = y", >>you're saying "figure out which object 'y' means, and tell the object >>that 'x' means that it should make [1] refer to that object". So if >>you have multiple names referring to the same object, any change you >>ask that object to do will be seen by every other name that also >>refers to it - because it's all about the object. > >I may have misunderstood you. But I don't think what you wrote >above would explain why the program below produces the output: > >[1, 2, 3] >[3, 6, 9] > >M. K. Shen >----------------------------------------------------- > >def test2(alist): > alist[0],alist[1],alist[2]=3,6,9 > alist=[30,60,90] > return This is because "alist" in the function test2 is a _local_ variable. It is a reference to the same list whose reference was passed to the function. So: alist[0],alist[1],alist[2]=3,6,9 This modifies the references within that list. alist=[30,60,90] This makes the local name "alist" refer to a shiny new list [30,60,90], totally unrelated to the list whose reference was first passed in. Importantly, in the main program "ss" still refers to the original list, which now has references to the values 3, 6 and 9 in it. >def test3(alist): > alist=[30,60,90] > alist[0],alist[1],alist[2]=3,6,9 > return This code first points "alist" to a new, unrelated, list. Then modifies the references inside that list. Put different values in this function (by using the same values as in test2 you can see whether changes came from one or the other) eg use 5,6,7 or something. >ss=[1,2,3] >test3(ss) >print(ss) >test2(ss) >print(ss) So test3 first discards its reference to the [1,2,3] list, then modifies an unrelate new list. So "ss" is unchanged, still holding [1,2,3]. Then test modifies the original list (affecting what "ss" holds) and then points its local "alist" at something else (another shiny new list). But that doesn't change what "ss" refers to, so it now has [3,6,9]. Cheers, Cameron Simpson (formerly cs at zip.com.au) From ned at nedbatchelder.com Wed Aug 16 20:14:01 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Wed, 16 Aug 2017 20:14:01 -0400 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen wrote: > Anyway, while > any new user of a programming language certainly can be expected to > take good efforts to learn a lot of new stuffs, I suppose it's good > for any practical programming language to minimize the cases of > surprises for those that come from other programming languages. Which other languages? Should Python's functions act like C functions, or like Haskell functions? Should Python's strings act like C strings, or Ruby strings? Should Python's syntax be like C syntax, or like Lisp syntax? If languages can't be different from each other, then there's no point in having different languages. I agree that gratuitous differences are, well, gratuitous, but the name/value data model of Python is not some trivial detail that we could change to match some other language: it's a fundamental part of what makes Python what it is. For some reason, students have been taught that things can be either call-by-reference or call-by-value. But those are not the only two possibilities, and neither completely describes how Python works. Learn Python for what it is. --Ned. From rosuav at gmail.com Wed Aug 16 20:35:19 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Aug 2017 10:35:19 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> Message-ID: On Thu, Aug 17, 2017 at 9:03 AM, Mok-Kong Shen wrote: > Am 17.08.2017 um 00:39 schrieb Chris Angelico: >> >> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen >> wrote: >>> >>> I have earlier learned some other (older) programming languages. For >>> these the formal parameters are either "by reference" or "by value". >>> In the first case, any modification of the formal parameter inside >>> a function affects the corresponding actual parameter of a function >>> call, while in the second case a copy of the actual parameter is >>> passed into the function so that any modification of the formal >>> parameter inside the function has no effect at all outside. This is >>> extremely clear-cut in comparison to Python, isn't it? Anyway, while >>> any new user of a programming language certainly can be expected to >>> take good efforts to learn a lot of new stuffs, I suppose it's good >>> for any practical programming language to minimize the cases of >>> surprises for those that come from other programming languages. >> >> >> Python has a data model that is neither of the above, but it's simpler >> in that you have one pattern for everything. Whether you're looking at >> function parameters, return values, assignment, loops, function >> definitions, or anything else, the model is exactly the same. And that >> model is: objects exist independently of names, and names refer to >> objects. If you do "x = y", you're saying "figure out which object 'y' >> means, and make the name 'x' refer to it". If you do "x[1] = y", >> you're saying "figure out which object 'y' means, and tell the object >> that 'x' means that it should make [1] refer to that object". So if >> you have multiple names referring to the same object, any change you >> ask that object to do will be seen by every other name that also >> refers to it - because it's all about the object. > > > I may have misunderstood you. But I don't think what you wrote > above would explain why the program below produces the output: > > [1, 2, 3] > [3, 6, 9] > > M. K. Shen > ----------------------------------------------------- > > def test2(alist): > alist[0],alist[1],alist[2]=3,6,9 > alist=[30,60,90] > return > > def test3(alist): > alist=[30,60,90] > alist[0],alist[1],alist[2]=3,6,9 > return > > ss=[1,2,3] > test3(ss) > print(ss) > test2(ss) > print(ss) It does. Go through it step by step. Think about objects and names, not about variables. Also, please keep things on the list - thanks! :) ChrisA From steve+python at pearwood.info Wed Aug 16 20:41:13 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 10:41:13 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote: > I have earlier learned some other (older) programming languages. For > these the formal parameters are either "by reference" or "by value". By reference and by value are not the only two conventions. Perhaps if you go back to the 1950s you might be able to argue that "reference" and "value" are the only two conventions, but alternatives have existed for many decades, since *at least* 1960 when Algol introduced "call by name". Python's evaluation strategy has existed for at least 43 years since Barbara Liskov named the calling convention used by CLU "call by sharing" in 1974. (It actually is much older than CLU, it goes back all the way to Lisp.) https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing > In the first case, any modification of the formal parameter Technically, you cannot modify the formal parameter, because the formal parameter is just a name unbound to any value. It's just the label in the function definition. You need to have actually passed a value as argument to the function before there is anything to modify. > inside > a function affects the corresponding actual parameter of a function > call, while in the second case a copy of the actual parameter is > passed into the function so that any modification of the formal > parameter inside the function has no effect at all outside. This is > extremely clear-cut in comparison to Python, isn't it? Python (and Ruby, Scheme, Ocaml, etc) are very clear-cut too. Just different. This may help: http://import-that.dreamwidth.org/1130.html > Anyway, while > any new user of a programming language certainly can be expected to > take good efforts to learn a lot of new stuffs, I suppose it's good > for any practical programming language to minimize the cases of > surprises for those that come from other programming languages. Indeed. And call by value is surprising: why should passing a giant array of a million values make a copy of the array just because I pass it to a function? And call by reference is even more surprising: if I assign a value to a local name inside a function, why should it modify names in the caller's namespace? Python's evaluation strategy is the least surprising of all the calling strategies I've used. -- Steven D'Aprano ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From mok-kong.shen at t-online.de Wed Aug 16 20:49:23 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Thu, 17 Aug 2017 02:49:23 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> <20170816235829.GA54664@cskk.homeip.net> Message-ID: <50046f8d-2f14-1de4-4f3c-feab0ac8da32@t-online.de> Am 17.08.2017 um 01:58 schrieb Cameron Simpson: > On 17Aug2017 01:03, Mok-Kong Shen wrote: >> Am 17.08.2017 um 00:39 schrieb Chris Angelico: >>> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen >>> wrote: >>> Chris wrote: >>> objects exist independently of names, and names refer to >>> objects. If you do "x = y", you're saying "figure out which object 'y' >>> means, and make the name 'x' refer to it". If you do "x[1] = y", >>> you're saying "figure out which object 'y' means, and tell the object >>> that 'x' means that it should make [1] refer to that object". So if >>> you have multiple names referring to the same object, any change you >>> ask that object to do will be seen by every other name that also >>> refers to it - because it's all about the object. >> >> I may have misunderstood you. But I don't think what you wrote >> above would explain why the program below produces the output: >> >> [1, 2, 3] >> [3, 6, 9] >> >> M. K. Shen >> ----------------------------------------------------- >> >> def test2(alist): >> alist[0],alist[1],alist[2]=3,6,9 >> alist=[30,60,90] >> return > > This is because "alist" in the function test2 is a _local_ variable. It > is a reference to the same list whose reference was passed to the function. > > So: > > alist[0],alist[1],alist[2]=3,6,9 > > This modifies the references within that list. > > alist=[30,60,90] > > This makes the local name "alist" refer to a shiny new list [30,60,90], > totally unrelated to the list whose reference was first passed in. > Importantly, in the main program "ss" still refers to the original list, > which now has references to the values 3, 6 and 9 in it. > >> def test3(alist): >> alist=[30,60,90] >> alist[0],alist[1],alist[2]=3,6,9 >> return > > This code first points "alist" to a new, unrelated, list. Then modifies > the references inside that list. Put different values in this function > (by using the same values as in test2 you can see whether changes came > from one or the other) eg use 5,6,7 or something. > >> ss=[1,2,3] >> test3(ss) >> print(ss) >> test2(ss) >> print(ss) > > So test3 first discards its reference to the [1,2,3] list, then modifies > an unrelate new list. So "ss" is unchanged, still holding [1,2,3]. > > Then test modifies the original list (affecting what "ss" holds) and > then points its local "alist" at something else (another shiny new > list). But that doesn't change what "ss" refers to, so it now has [3,6,9]. I don't yet understand. Why (by which rule of the language reference) should "alist=[30,60,90]" mean discarding the name's reference to the [1,2,3] list? What I conjecture is that in test2 the assignment "alist[0], ..." can only have a proper meaning according to the syntacs of Python if alist is meant to be the global alist. But then, since now the name alist is known to be global, why then in the next line of test2 the name is suddenly interpreted to be local? (Which rule of the language reference says that?) That's what I currently continue to wonder. M. K. Shen M. K. Shen to From mok-kong.shen at t-online.de Wed Aug 16 20:49:23 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Thu, 17 Aug 2017 02:49:23 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> <20170816235829.GA54664@cskk.homeip.net> Message-ID: <50046f8d-2f14-1de4-4f3c-feab0ac8da32@t-online.de> Am 17.08.2017 um 01:58 schrieb Cameron Simpson: > On 17Aug2017 01:03, Mok-Kong Shen wrote: >> Am 17.08.2017 um 00:39 schrieb Chris Angelico: >>> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen >>> wrote: >>> Chris wrote: >>> objects exist independently of names, and names refer to >>> objects. If you do "x = y", you're saying "figure out which object 'y' >>> means, and make the name 'x' refer to it". If you do "x[1] = y", >>> you're saying "figure out which object 'y' means, and tell the object >>> that 'x' means that it should make [1] refer to that object". So if >>> you have multiple names referring to the same object, any change you >>> ask that object to do will be seen by every other name that also >>> refers to it - because it's all about the object. >> >> I may have misunderstood you. But I don't think what you wrote >> above would explain why the program below produces the output: >> >> [1, 2, 3] >> [3, 6, 9] >> >> M. K. Shen >> ----------------------------------------------------- >> >> def test2(alist): >> alist[0],alist[1],alist[2]=3,6,9 >> alist=[30,60,90] >> return > > This is because "alist" in the function test2 is a _local_ variable. It > is a reference to the same list whose reference was passed to the function. > > So: > > alist[0],alist[1],alist[2]=3,6,9 > > This modifies the references within that list. > > alist=[30,60,90] > > This makes the local name "alist" refer to a shiny new list [30,60,90], > totally unrelated to the list whose reference was first passed in. > Importantly, in the main program "ss" still refers to the original list, > which now has references to the values 3, 6 and 9 in it. > >> def test3(alist): >> alist=[30,60,90] >> alist[0],alist[1],alist[2]=3,6,9 >> return > > This code first points "alist" to a new, unrelated, list. Then modifies > the references inside that list. Put different values in this function > (by using the same values as in test2 you can see whether changes came > from one or the other) eg use 5,6,7 or something. > >> ss=[1,2,3] >> test3(ss) >> print(ss) >> test2(ss) >> print(ss) > > So test3 first discards its reference to the [1,2,3] list, then modifies > an unrelate new list. So "ss" is unchanged, still holding [1,2,3]. > > Then test modifies the original list (affecting what "ss" holds) and > then points its local "alist" at something else (another shiny new > list). But that doesn't change what "ss" refers to, so it now has [3,6,9]. I don't yet understand. Why (by which rule of the language reference) should "alist=[30,60,90]" mean discarding the name's reference to the [1,2,3] list? What I conjecture is that in test2 the assignment "alist[0], ..." can only have a proper meaning according to the syntacs of Python if alist is meant to be the global alist. But then, since now the name alist is known to be global, why then in the next line of test2 the name is suddenly interpreted to be local? (Which rule of the language reference says that?) That's what I currently continue to wonder. M. K. Shen M. K. Shen to From ben+python at benfinney.id.au Wed Aug 16 20:56:51 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 17 Aug 2017 10:56:51 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> Message-ID: <858tijhuzw.fsf@benfinney.id.au> Steve D'Aprano writes: > On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote: > > > I have earlier learned some other (older) programming languages. For > > these the formal parameters are either "by reference" or "by value". > > By reference and by value are not the only two conventions. > > Perhaps if you go back to the 1950s you might be able to argue that > "reference" and "value" are the only two conventions, but alternatives > have existed for many decades, since *at least* 1960 when Algol > introduced "call by name". Indeed. I have had a lot of success helping people, who come to Python with the baggage of that false dichotomy, by using Fredrik Lundh's term ?call by object? to describe the Python argument-pass semantics. Python?s model is neither ?call by value? nor ?call by reference? (because any attempt to use those terms for Python requires you to use non-standard definitions of the words ?-value? and ?-reference?). The most accurate description is CLU?s ?call by object? or ?call by sharing?. Or, if you prefer, ?call by object reference?. > This may help: > > http://import-that.dreamwidth.org/1130.html That's a good one too, thank you for writing it. I just wish Dreamwidth would present a URL with a slug derived from the article title, so that it was easier to search the URLs in my history :-) -- \ ?Some people have a problem, and they think ?I know, I'll use | `\ Perl!?. Now they have some number of problems but they're not | _o__) sure whether it's a string or an integer.? ?Benno Rice, 2011 | Ben Finney From flebber.crue at gmail.com Wed Aug 16 21:02:48 2017 From: flebber.crue at gmail.com (Sayth Renshaw) Date: Wed, 16 Aug 2017 18:02:48 -0700 (PDT) Subject: Why is my class undefined? In-Reply-To: References: Message-ID: On Thursday, 17 August 2017 09:03:59 UTC+10, Ian wrote: wrote: > > Morning > > > > I haven't ventured into classes much before. When trying to follow some examples and create my own classes in a jupyter notebook I receive an error that the class is undefined. > > > > So I created for practise a frog class > > > > class frog(object): > > > > def __init__(self, ftype, word): > > self.ftype = ftype > > self.word = ftype > > > > def jump(self): > > """ > > Make frog jump > > """ > > return "I am jumping" > > > > if __name__ == "__main__": > > tree_frog = frog("Tree Frog", "Ribbitt") > > print(frog.ftype) > > print(frog.word) > > > > > > I receive this error > > > > NameError Traceback (most recent call last) > > in () > > ----> 1 class frog(object): > > 2 > > 3 def __init__(self, ftype, word): > > 4 self.ftype = ftype > > 5 self.word = ftype > > > > in frog() > > 12 > > 13 if __name__ == "__main__": > > ---> 14 tree_frog = frog("Tree Frog", "Ribbitt") > > 15 print(frog.ftype) > > 16 print(frog.word) > > > > NameError: name 'frog' is not defined > > > > what exactly am I doing wrong? > > The if __name__ == "__main__" block is inside the class declaration > block, so at the point that it runs the class has not been created > yet. Try removing the indentation to place it after the class block > instead. Thank you that had me bugged I just couldn't see it. Cheers Sayth From steve+python at pearwood.info Wed Aug 16 21:03:26 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 11:03:26 +1000 Subject: A small quiz question References: <87378r5q4k.fsf@elektro.pacujo.net> Message-ID: <5994eb5f$0$1593$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 09:12 am, Dennis Lee Bieber wrote: > I suppose, the two in combination imply that the calls to "f()" occur > first in left to right, but then the "**" are applied to the returned > values right to left -- rather than having the calls performed in the > exponentiation order. Standard mathematical convention is for exponentiation to be performed from right to left: 2**3**2 should be evaluated as 2**(3**2) = 512 rather than (2**3)**2 = 64. This is more obvious in the standard formatted mathematical notation where each subsequent index is higher and smaller than the previous, indicating that 2 is being raised to the power of 3 squared, rather than 2 cubed being squared. See, for example, the comment here: http://mathworld.wolfram.com/PowerTower.html where z^z^z is an abbreviation for z^(z^z) (about a third of the way down the page). So Python agrees with the usual maths convention here. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ben+python at benfinney.id.au Wed Aug 16 21:05:50 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 17 Aug 2017 11:05:50 +1000 Subject: A question on modification of a list via a function invocation References: <7aeaf5f7-4c97-6cd1-aa2f-6901c162f152@t-online.de> <20170816235829.GA54664@cskk.homeip.net> <50046f8d-2f14-1de4-4f3c-feab0ac8da32@t-online.de> Message-ID: <854lt7hukx.fsf@benfinney.id.au> Mok-Kong Shen writes: > I don't yet understand. Why (by which rule of the language reference) > should "alist=[30,60,90]" mean discarding the name's reference to the > [1,2,3] list? I think I understand that question, but I find it surprising. What is your expectation of the following code? foo = "spam" foo = "beans" print(foo) What should ?foo? be bound to after the second assignment? Your question seems to imply you expect that the ?foo? reference would be bound to *both* of ?"spam"? and ?"beans"?, somehow. Is that right? How would that work? To answer the question: The semantics of an assignment statement are at in the Python language reference. Assignment statements are used to (re)bind names to values [?] If the target is an identifier (name): [?] The name is rebound if it was already bound. A reference (a name is one kind of reference) can be bound to exactly one object at any time. > But then, since now the name alist is known to be global, why then in > the next line of test2 the name is suddenly interpreted to be local? The same section of the language reference discusses that. In brief: The fact that the first use of a name, in the current scope, is an assignment, means that the name is implicitly within that scope. -- \ ?Pinky, are you pondering what I'm pondering?? ?Uh, I think so, | `\ Brain, but we'll never get a monkey to use dental floss.? | _o__) ?_Pinky and The Brain_ | Ben Finney From mok-kong.shen at t-online.de Wed Aug 16 21:18:31 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Thu, 17 Aug 2017 03:18:31 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> Message-ID: Am 17.08.2017 um 02:41 schrieb Steve D'Aprano: > On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote: > >> I have earlier learned some other (older) programming languages. For >> these the formal parameters are either "by reference" or "by value". > > By reference and by value are not the only two conventions. > > Perhaps if you go back to the 1950s you might be able to argue that "reference" > and "value" are the only two conventions, but alternatives have existed for > many decades, since *at least* 1960 when Algol introduced "call by name". > > Python's evaluation strategy has existed for at least 43 years since Barbara > Liskov named the calling convention used by CLU "call by sharing" in 1974. > > (It actually is much older than CLU, it goes back all the way to Lisp.) > > https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing > > >> In the first case, any modification of the formal parameter > > Technically, you cannot modify the formal parameter, because the formal > parameter is just a name unbound to any value. It's just the label in the > function definition. You need to have actually passed a value as argument to > the function before there is anything to modify. > >> inside >> a function affects the corresponding actual parameter of a function >> call, while in the second case a copy of the actual parameter is >> passed into the function so that any modification of the formal >> parameter inside the function has no effect at all outside. This is >> extremely clear-cut in comparison to Python, isn't it? > > Python (and Ruby, Scheme, Ocaml, etc) are very clear-cut too. Just different. > > This may help: > > http://import-that.dreamwidth.org/1130.html > > >> Anyway, while >> any new user of a programming language certainly can be expected to >> take good efforts to learn a lot of new stuffs, I suppose it's good >> for any practical programming language to minimize the cases of >> surprises for those that come from other programming languages. > > Indeed. And call by value is surprising: why should passing a giant array of a > million values make a copy of the array just because I pass it to a function? > > And call by reference is even more surprising: if I assign a value to a local > name inside a function, why should it modify names in the caller's namespace? > > Python's evaluation strategy is the least surprising of all the calling > strategies I've used. Sorry for my poor capacity to comprehend. I read in the web page you cited: "In Python, the parameters to a function or method are always local to that function or method. Any assignments to local variables inside the function only affect the local variable, not the caller's variable." But then why in my test2 the global list does get modified? (Would alist[0]=3 etc. be "in-place modification" while alist=[30,60,90] is deemed not an "in-place modification"? If yes, where is that term clearly defined? (That term is new for me.) M. K. Shen M. K. Shen M. K. From steve+python at pearwood.info Wed Aug 16 21:40:33 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 11:40:33 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 10:14 am, Ned Batchelder wrote: > the name/value data model of > Python is not some trivial detail that we could change to match some > other language: it's a fundamental part of what makes Python what it is. It is also an evaluation model which matches nearly all of the most popular languages of the last two decades, including Java[1], Ruby, (I think) PHP, and Javascript. > For some reason, students have been taught that things can be either > call-by-reference or call-by-value. But those are not the only two > possibilities, and neither completely describes how Python works. > > Learn Python for what it is. > > --Ned. Indeed. The insistence on this false dichotomy of call by value versus by reference puzzles me, since alternatives go back to one of earliest, and most influential, programming languages: Lisp. Algol, another early and hugely influential language, used call by name. Its like there was an entire generation of cooks and chefs who insisted that there are only two ways of cooking food: steaming, and barbecuing, and came up with elaborate rationalisations for why frying, roasting, boiling etc are actually one of the two. [1] Despite the obnoxious insistence of Java experts that it is "pass by value", where the value they are talking about is not the actual value, but some hidden, implementation-dependent pointer or reference to the value: http://javadude.com/articles/passbyvalue.htm In the words of the Effbot Fredrik well, I guess you can, in theory, value an artificial number assigned to an object as much as the object itself. "Joe, I think our son might be lost in the woods" "Don't worry, I have his social security number" http://www.effbot.org/zone/call-by-object.htm It absolutely astonishes me how the Java community abuse the term "call by value" in this way, despite the confusion it causes, and despite knowing the correct answer. Scott Stanchfield actually does know what is going on. Despite the inflammatory title of his post, and the outright false comment right at the start: "Java is strictly pass-by-value, exactly as in C." deep in the article linked above, he comes clean and writes: "A correct statement would be /Object references are passed by value/." [emphasis /.../ in original] But the objects themselves are not, as would be required by pass-by-value semantics. So he knows that the values, the objects themselves, are not copied when you pass them to a function. Only the invisible references to the objects are copied, but they are not the values anyone cares about. The example he shows has precisely the same behaviour as the equivalent Python code. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From mok-kong.shen at t-online.de Wed Aug 16 21:43:55 2017 From: mok-kong.shen at t-online.de (Mok-Kong Shen) Date: Thu, 17 Aug 2017 03:43:55 +0200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: <41929f5f-e671-9189-9a1a-2571865cb379@t-online.de> Am 17.08.2017 um 02:14 schrieb Ned Batchelder: > On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen wrote: >> Anyway, while >> any new user of a programming language certainly can be expected to >> take good efforts to learn a lot of new stuffs, I suppose it's good >> for any practical programming language to minimize the cases of >> surprises for those that come from other programming languages. > Which other languages? Should Python's functions act like C functions, > or like Haskell functions? Should Python's strings act like C strings, > or Ruby strings? Should Python's syntax be like C syntax, or like Lisp > syntax? If languages can't be different from each other, then there's no > point in having different languages. I agree that gratuitous > differences are, well, gratuitous, but the name/value data model of > Python is not some trivial detail that we could change to match some > other language: it's a fundamental part of what makes Python what it is. > > For some reason, students have been taught that things can be either > call-by-reference or call-by-value. But those are not the only two > possibilities, and neither completely describes how Python works. > > Learn Python for what it is. Your last sentence is fine and certainly to be accepted. Is there a good document with which one could well use to resolve problems like the present one? (Earlier I learned a few programming languages from their ISO standard documents, which was not easy but later turned out to be quite profitable.) M. K. Shen expect that there be a good documen From cs at cskk.id.au Wed Aug 16 21:44:43 2017 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 17 Aug 2017 11:44:43 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: <50046f8d-2f14-1de4-4f3c-feab0ac8da32@t-online.de> References: <50046f8d-2f14-1de4-4f3c-feab0ac8da32@t-online.de> Message-ID: <20170817014443.GA89469@cskk.homeip.net> On 17Aug2017 02:49, Mok-Kong Shen wrote: >I don't yet understand. Why (by which rule of the language reference) >should "alist=[30,60,90]" mean discarding the name's reference to the >[1,2,3] list? Section 7.2: Simple statements: Assignment Statements. It says: An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right. So this: alist=[30,60,90] "evaluates the expression list" (that is the [30,60,90]) and assigns it. So this creates a new list object [30,60,90]. This is independent of whatever is/was in "alist". Then the reference to that is assigned to the name "alist". Since a name references to a single object, necessarily the reference to what "alist" previously refered is discarded. So before this statement, both "ss" and "alist" referered to the list [1,2,3]. After the statement "ss" has not been changed, and still refers to the [1,2,3] list. But "alist" now points to the new list which was created by the right hand side of the assignment statement i.e. the new [30,60,90] list. You might try inserting some print statements in your code. print("ss = %s:%r, alist = %s:%r" % (id(ss), ss, id(alist), alist)) after every statement in your code to see these changes. The id() function returns Python's internal object id for each existing object - this is unique at any given time. If two names refer to the same object, the same id will be printed. So this will let you see directly when the names start pointing at different objects. You can also go: print("alist[0] = %s:%r" % (id(alist[0]), alist[0])) to see the internal things within lists and so forth. >What I conjecture is that in test2 the assignment >"alist[0], ..." can only have a proper meaning according to the syntacs >of Python if alist is meant to be the global alist. There is no "global alist". >But then, since >now the name alist is known to be global, why then in the next line of >test2 the name is suddenly interpreted to be local? There are two reasons for this. Firstly, "alist" is a function parameter. That is a local name, always. Also, every python function definition is inspected for assignment statements. Any assignment statement "x = ..." causes the name "x" to be a local variable. This is important, because it provided _reliable_ and predictable behaviour. >(Which rule of >the language reference says that?) That's what I currently continue to >wonder. 4.2. Naming and Binding. 4.2.1 starts "Names refer to objects. Names are introduced by name binding operations. The following constructs bind names: formal parameters to functions, ...". So a function parameter is a name binding. Then "if a name is bound in a block, it is a local variable of that block, unless declared as nonlocal or global." ("nonlocal" and "global" are explicit statements.) So a function parameter, which is a binding, causes that name to be local to the function. Regarding the inspection side of things to which i alluded to earlier, under "4.2.2. Resolution of names" it says "If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations." Cheers, Cameron Simpson (formerly cs at zip.com.au) From steve+python at pearwood.info Wed Aug 16 21:47:27 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 11:47:27 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5994f5b0$0$1596$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 11:07 am, Stefan Ram wrote: > Steve D'Aprano writes: >>On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote: >>>In the first case, any modification of the formal parameter >>Technically, you cannot modify the formal parameter, because the formal >>parameter is just a name unbound to any value. It's just the label in the >>function definition. You need to have actually passed a value as argument to >>the function before there is anything to modify. > > So, when an argument is actually passed, then the parameter > can be modified? It seems Mok-Kong Shen was writing about > this case. I would say that the argument is modified. https://docs.python.org/3/faq/programming.html#faq-argument-vs-parameter "Parameters are defined by the names that appear in a function definition, whereas arguments are the values actually passed to a function when calling it." See also: https://docs.python.org/3/glossary.html#term-parameter https://docs.python.org/3/glossary.html#term-argument -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From kryptxy at protonmail.com Wed Aug 16 23:13:27 2017 From: kryptxy at protonmail.com (Kryptxy) Date: Wed, 16 Aug 2017 23:13:27 -0400 Subject: Need some help managing project and making it a little simple (pretty messed up code) Message-ID: <-gUInp2uHyJ6_ZRpbyiJNbn7sHu2cI7TmCiEw4KZXE5qCn_xgouliuQOeL_uVLuGP7lBIe15hG3ge2JoNd9C8a-0U2T2voYY4wxFxnjx6zc=@protonmail.com> Hello, I am new to python. While learning python, I began a side project. Its a command-line search program. Here: https://github.com/kryptxy/torrench The project is becoming a little difficult to manage, and before it becomes more complex, I'd like to sort it out a little and make it more managable and readable. As of now, I haven't used any OOP concepts (no classes) bc while I was learning, I didn't reach the OOP part, and then spent too much time on the project (and that's probably the part I want help with). Now however, I do know about classes and basics about OOP. But, I am unable to understand how I should begin structuring the project (updating code according to OOP). If someone could have a look? Could really use some suggestions/ideas. Also, can someone point me to some (small) project where something similar is being implemented? (as in sharing similar project-structure). They can be really helpful. I did have a look at youtube-dl source. Not helpful. Seemed too complex. Hope for some positive response. Thank you. From steve+python at pearwood.info Wed Aug 16 23:23:05 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 13:23:05 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> <5994f5b0$0$1596$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59950c1b$0$1601$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 12:24 pm, Stefan Ram wrote: > Steve D'Aprano writes: >>On Thu, 17 Aug 2017 11:07 am, Stefan Ram wrote: >>>So, when an argument is actually passed, then the parameter >>>can be modified? It seems Mok-Kong Shen was writing about >>>this case. >>I would say that the argument is modified. > > I was thinking along these lines: > >>>> def function( parameter ): > ... parameter = parameter + 1 > ... print( parameter ) > ... >>>> argument = 4 >>>> function( argument ) > 5 >>>> argument > 4 Okay, you are talking about the *local variable* called "parameter". We can: - mutate the *object* bound to that local variable; - re-bind (reassign) a different object to that local variable. I was talking about the *name* (an identifier) in the function declaration, a literal piece of text appearing in your source code. In that sense, we can't do anything to the parameter until the function is called and an argument is passed in. I see now that both ways of looking at this have some validity. The FAQ helps a bit: Parameters are defined by the names that appear in a function definition, whereas arguments are the values actually passed to a function when calling it. https://docs.python.org/3/faq/programming.html#faq-argument-vs-parameter so in your example the argument is certainly the int 4, the parameter is the name (the identifier) in the function declaration, but how do we refer to the local variable inside the function? Is it the parameter (an identifier) or an argument (an object) or something else? I think the terminology is inconsistent. For example, here: https://chortle.ccsu.edu/java5/Notes/chap34A/ch34A_3.html "formal parameter" is defined as the *identifier* but later on the same page seems to use it to refer to the *local variable*. I think that if we are talking about the local variable when we say "parameter", it is okay to talk about it being re-bound, but if we're talking about the identifier, it is not. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From no.email at nospam.invalid Thu Aug 17 00:44:05 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Wed, 16 Aug 2017 21:44:05 -0700 Subject: Cross-language comparison: function map and similar References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87efsarega.fsf@nightsong.com> Steve D'Aprano writes: > Are there language implementations which evaluate the result of map() > (or its equivalent) in some order other than the obvious left-to-right > first-to-last sequential order? Is that order guaranteed by the > language, or is it an implementation detail? Haskell just gives back an unevaluated thunk. The elements are evaluated in whatever order you happen to use them in. Since the evaluation isn't supposed to have observable side effects, there's no way to tell the order. There are also parallel versions (Control.Parallel.Strategies.parMap etc.) and an extension that recognizes "racing stripes" on the square brackets to make list comprehensions run faster: foo = [| sqrt(x) | x <- [1.0 .. 1000.0] |] parallelizes the calculation and offloads it to a GPU or other vector processor. You might also like this old post https://donsbot.wordpress.com/2007/11/29/use-those-extra-cores-and-beat-c-today-parallel-haskell-redux/ "map" is conceptually the lifting of a function from a given type, to the type under the action of some functor. For historical reasons map only works on lists while fmap works on arbitrary functors, but they are in principle the same thing. Depending on what the functor does, the whole concept of left-to-right order might be meaningless. From marko at pacujo.net Thu Aug 17 01:29:47 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 17 Aug 2017 08:29:47 +0300 Subject: A small quiz question References: <87378r5q4k.fsf@elektro.pacujo.net> Message-ID: <87r2wa4v90.fsf@elektro.pacujo.net> Dennis Lee Bieber : > I suppose, the two in combination imply that the calls to "f()" > occur first in left to right, but then the "**" are applied to the > returned values right to left -- rather than having the calls > performed in the exponentiation order. Yes, and parentheses, operator precedence or expressions as arguments to functions don't affect the evaluation order. Marko From dieter at handshake.de Thu Aug 17 01:39:02 2017 From: dieter at handshake.de (dieter) Date: Thu, 17 Aug 2017 07:39:02 +0200 Subject: Default .py program and Edit with IDLE problem References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> Message-ID: <87fucqkb2h.fsf@handshake.de> "Kevi Aday (Katch22)" writes: > I installed python 3.6.2 for making running and editing programs. Later on I installed python 2.7 > because a program that I downloaded only works with that. Later I deleted the program. I then wanted to run a > program from cmd but it was giving me all kinds of errors I didn?t used to get. I thought the > problem was being caused by python 2.7 and I didn?t even need it anymore so I uninstalled it. > After I uninstalled it, all my .py files? icons disappeared and when I right clicked on it the ?Edit with IDLE? disappeared. > I tried all kinds of things like repairing python, editing the registry, etc. but I just can?t fix the problem and this > has never happened to me and its really bugging me. Please help. This is obviously a Windows problem. I am no Windows expert but I think this is what happens: both Python 3 as well as Python 2 are using the same Windows configuration resources (i.e. the same resource names) (at least partially). Then, it becomes problematic to install both Python 3 as well as Python 2 in the same Windows system as one version overrides (some of) the other's configuration resources. When you uninstall Python, it likely tries to clean up the Windows configuration - and it is apparently not prepared for the case that is has (partially) overridden another Python version. As a next step, I would try to uninstall and then install again Python 3. From pavol.lisy at gmail.com Thu Aug 17 01:54:23 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Thu, 17 Aug 2017 07:54:23 +0200 Subject: Cross-language comparison: function map and similar In-Reply-To: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/16/17, Steve D'Aprano wrote: > Over in another thread, we've been talking about comprehensions and their > similarities and differences from the functional map() operation. > > Reminder: > > map(chr, [65, 66, 67, 68]) > > will return ['A', 'B', 'C']. > > My questions for those who know languages apart from Python: > > Are there language implementations which evaluate the result of map() (or > its > equivalent) in some order other than the obvious left-to-right first-to-last > sequential order? Is that order guaranteed by the language, or is it an > implementation detail? Is it guaranteed in python? Or future version could implement map with something like subscriptability "propagation"? >>>range(1_000_000_000_000_000_000)[-1] 9999999999999999 >>> map(lambda a:a+1,range(1_000_000_000_000_000_000))[-1] TypeError: 'map' object is not subscriptable From marko at pacujo.net Thu Aug 17 01:54:58 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 17 Aug 2017 08:54:58 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> <85inhnhyww.fsf@benfinney.id.au> Message-ID: <87mv6y4u31.fsf@elektro.pacujo.net> Ben Finney : > The Python list comprehension syntax does not specify control flow. I understand your point, but how do you know your statement is true? I didn't check this, but I would imagine the list comprehension: [ f(x) for x in I if c(x) ] was defined as syntactic sugar for: list(f(x) for x in I if c(x)) where f(x) for x in I if c(x) has heavily iterative semantics. > List comprehensions, in their syntax, strongly connote a single > declarative operation. This makes them different from iteration > syntax. Except for side effects, you get the same result whichever way you imagine it. As a side not, I have found it rather confusing that I have to say: [ (x, y) for x in range(5) for y in range(x) ] instead of: [ (x, y) for y in range(x) for x in range(5) ] After all, you must say: [ ((x, y) for y in range(x)) for x in range(5) ] which, admittedly, means a different thing. Marko From dieter at handshake.de Thu Aug 17 02:08:18 2017 From: dieter at handshake.de (dieter) Date: Thu, 17 Aug 2017 08:08:18 +0200 Subject: Need some help managing project and making it a little simple (pretty messed up code) References: <-gUInp2uHyJ6_ZRpbyiJNbn7sHu2cI7TmCiEw4KZXE5qCn_xgouliuQOeL_uVLuGP7lBIe15hG3ge2JoNd9C8a-0U2T2voYY4wxFxnjx6zc=@protonmail.com> Message-ID: <87bmnek9pp.fsf@handshake.de> Kryptxy via Python-list writes: > ... > I am new to python. While learning python, I began a side project. Its a command-line search program. > ... > But, I am unable to understand how I should begin structuring the project (updating code according to OOP). If someone could have a look? Could really use some suggestions/ideas. Manageing larger projects is in general helped by some kind of modularization: you split the whole implementation into different parts which have high internal and low external interaction. While the total complexity increases, you have often a chance to concentrate on a part only and this part is far less complex the the whole. OOP is just one kind of modularization. Not all problems can make high use of OOP modularization. For OOP friendly problems, you can easily identify objects. They have state and functions operating on this state (those functions are called "method"s). The state is mostly relevant only for the object internally and less (if at all) for the external world. In your case, the search service itself might be an object. And the queries might be objects. To gain something, you must have interesting operations on those objects - operations that manipulate a mostly irrelevant (but fairly complex) internal state. > Also, can someone point me to some (small) project where something similar is being implemented? You might have a look at "Products.AdvancedQuery" (--> "PyPI"). Download its source; you will find a documentation in the folder "Products/AdvancedQuery/doc/". It models queries as objects and the relevant operations are query constructors. You (likely) will not be able to "run" it. It depends on a search service called "ZCatalog" (part of the web application framework "Zope"). This search service, too, is implemented by an object. To use it, you would need "Zope". But you can download the source (--> "PyPI"; its name is "Products.ZCatalog") and look at the interface description in "Products.ZCatalog.interfaces.py" to learn about the "ZCatalog" methods. This file also contains a good documentation (via so called "docstring"s). Interfaces are a general way to document the relevant parts of objects/classes for "external use". They are heavily used by "Zope". From orgnut at yahoo.com Thu Aug 17 03:18:09 2017 From: orgnut at yahoo.com (Larry Hudson) Date: Thu, 17 Aug 2017 00:18:09 -0700 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: On 08/16/2017 03:39 PM, Chris Angelico wrote: > On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen > wrote: >> I have earlier learned some other (older) programming languages. For >> these the formal parameters are either "by reference" or "by value". >> In the first case, any modification of the formal parameter inside >> a function affects the corresponding actual parameter of a function >> call, while in the second case a copy of the actual parameter is >> passed into the function so that any modification of the formal >> parameter inside the function has no effect at all outside. This is >> extremely clear-cut in comparison to Python, isn't it? Anyway, while >> any new user of a programming language certainly can be expected to >> take good efforts to learn a lot of new stuffs, I suppose it's good >> for any practical programming language to minimize the cases of >> surprises for those that come from other programming languages. > > Python has a data model that is neither of the above, but it's simpler > in that you have one pattern for everything. Whether you're looking at > function parameters, return values, assignment, loops, function > definitions, or anything else, the model is exactly the same. And that > model is: objects exist independently of names, and names refer to > objects. If you do "x = y", you're saying "figure out which object 'y' > means, and make the name 'x' refer to it". If you do "x[1] = y", > you're saying "figure out which object 'y' means, and tell the object > that 'x' means that it should make [1] refer to that object". So if > you have multiple names referring to the same object, any change you > ask that object to do will be seen by every other name that also > refers to it - because it's all about the object. > > ChrisA > Here's another explanation, same concepts just stated differently, perhaps giving a different perspective. In a "traditional" programming language, variables are created/assigned by: Setting aside a chunk of memory to hold the data and associating the variable name with that memory. And since this chunk is a fixed size, the data type that can be stored there is also fixed at that time as well. This is static typing. Assignment is done by storing the new data in that memory location, overwriting what was already there. But it has to be the proper data type so it doesn't overrun the memory allocated for it. Python does it in the opposite order: The data is stored in memory (or already exists) and the variable name is associated with that memory. Python calls this name binding. It is possible, and common, that this memory (data) has multiple names bound to it. Assignment is done by associating the name to a different data value (memory location). This data may be newly created or it can be previously existing data. (The old data may or may not be 'garbage collected' ? depending on other factors.) A key point here is that the name has no memory size/data type itself and can be bound to ANY data ? this is dynamic typing. Where things get confusing is when we consider mutable/immutable data. If it is immutable (unchangeable: ints, floats, strings, tuples...) the _practical_ result is that although the implementation details are different, the result of running the program is the same. But for mutable data (changeable IN PLACE: lists, dictionaries...) the results can be surprising from the viewpoint of other languages. Since this (mutable) data can have multiple variable names bound to it, changing the value(s) through ANY of the names changes this data for ALL of the names bound to it. The OP said... >> I suppose it's good >> for any practical programming language to minimize the cases of >> surprises for those that come from other programming languages. I see your point, but it's irrelevant. Part of learning any new language is to learn where/how the new language handles things differently from your previous experience. You MUST learn the new ways and forget (or at least modify) your previous knowledge. It's simply a necessary part of learning a new language. Expect it and live with it! I hope this description gives you another viewpoint to consider. Good luck on your journey to becoming a Pythonista! -- -=- Larry -=- From rosuav at gmail.com Thu Aug 17 04:06:24 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Aug 2017 18:06:24 +1000 Subject: Cross-language comparison: function map and similar In-Reply-To: References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 17, 2017 at 3:54 PM, Pavol Lisy wrote: > On 8/16/17, Steve D'Aprano wrote: >> Over in another thread, we've been talking about comprehensions and their >> similarities and differences from the functional map() operation. >> >> Reminder: >> >> map(chr, [65, 66, 67, 68]) >> >> will return ['A', 'B', 'C']. >> >> My questions for those who know languages apart from Python: >> >> Are there language implementations which evaluate the result of map() (or >> its >> equivalent) in some order other than the obvious left-to-right first-to-last >> sequential order? Is that order guaranteed by the language, or is it an >> implementation detail? > > Is it guaranteed in python? Or future version could implement map with > something like subscriptability "propagation"? > >>>>range(1_000_000_000_000_000_000)[-1] > 9999999999999999 > >>>> map(lambda a:a+1,range(1_000_000_000_000_000_000))[-1] > TypeError: 'map' object is not subscriptable I think it is, partly because of the behaviour of map with additional arguments. If you want something subscriptable, you probably don't want an iterable, but a mapping type (it's no coincidence that the words are similar). The Python map() function expects a function and one or more iterables, and returns an iterator; but if you instead give it a function and a (subscriptable) collections, you could have it be a collection. (I'm not sure what to do about multiple collections. I guess you'd do something similar to map() - if any subcollection raises, Map raises. Not implemented here though.) class Map(dict): def __init__(self, func, coll): self.func, self.coll = func, coll def __missing__(self, key): self[key] = self.func(self.coll[key]) return self[key] This has the same subscripting semantics as the underlying collection, and will cache any result it sees. But watch out! It can't know about subscript aliasing, and will treat a key of -1 as completely different from any positive subscript. It also doesn't iterate the same way as the underlying collection does: >>> spam = Map(print, range(10)) >>> list(spam) [] Without knowing exactly what kind of "thing" you're mapping over, it's impossible to get everything right. ChrisA From orgnut at yahoo.com Thu Aug 17 04:25:12 2017 From: orgnut at yahoo.com (Larry Hudson) Date: Thu, 17 Aug 2017 01:25:12 -0700 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: On 08/17/2017 12:18 AM, Larry Hudson wrote: > On 08/16/2017 03:39 PM, Chris Angelico wrote: >> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen ... Oops, I replied to Chris's post, but it was meant for the OP. I should have replied to Mok-Kong Shen's post instead. My bad. Sorry for the confusion, Chris. -- -=- Larry -=- From rosuav at gmail.com Thu Aug 17 04:27:30 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 17 Aug 2017 18:27:30 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: On Thu, Aug 17, 2017 at 6:25 PM, Larry Hudson via Python-list wrote: > On 08/17/2017 12:18 AM, Larry Hudson wrote: >> >> On 08/16/2017 03:39 PM, Chris Angelico wrote: >>> >>> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen > > ... > Oops, I replied to Chris's post, but it was meant for the OP. I should have > replied to Mok-Kong Shen's post instead. My bad. Sorry for the confusion, > Chris. > > No harm, no foul. The tone of your text made it clear who you were addressing. ChrisA From breamoreboy at gmail.com Thu Aug 17 04:31:40 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Thu, 17 Aug 2017 01:31:40 -0700 (PDT) Subject: The tragic tale of the deadlocking Python queue Message-ID: I found it interesting, possibly some of you may feel the same way so here it is https://codewithoutrules.com/2017/08/16/concurrency-python/ Kindest regards. Mark Lawrence. From alister.ware at ntlworld.com Thu Aug 17 07:25:09 2017 From: alister.ware at ntlworld.com (alister) Date: Thu, 17 Aug 2017 11:25:09 GMT Subject: Why is my class undefined? References: Message-ID: On Wed, 16 Aug 2017 18:02:48 -0700, Sayth Renshaw wrote: > On Thursday, 17 August 2017 09:03:59 UTC+10, Ian wrote: > wrote: >> > Morning >> > >> > I haven't ventured into classes much before. When trying to follow >> > some examples and create my own classes in a jupyter notebook I >> > receive an error that the class is undefined. >> > >> > So I created for practise a frog class >> > >> > class frog(object): >> > >> > def __init__(self, ftype, word): >> > self.ftype = ftype self.word = ftype >> > >> > def jump(self): >> > """ >> > Make frog jump """ >> > return "I am jumping" >> > >> > if __name__ == "__main__": >> > tree_frog = frog("Tree Frog", "Ribbitt") >> > print(frog.ftype) >> > print(frog.word) >> > >> > >> > I receive this error >> > >> > NameError Traceback (most recent call >> > last) >> > in () >> > ----> 1 class frog(object): >> > 2 >> > 3 def __init__(self, ftype, word): >> > 4 self.ftype = ftype 5 self.word = ftype >> > >> > in frog() >> > 12 13 if __name__ == "__main__": >> > ---> 14 tree_frog = frog("Tree Frog", "Ribbitt") >> > 15 print(frog.ftype) >> > 16 print(frog.word) >> > >> > NameError: name 'frog' is not defined >> > >> > what exactly am I doing wrong? >> >> The if __name__ == "__main__" block is inside the class declaration >> block, so at the point that it runs the class has not been created yet. >> Try removing the indentation to place it after the class block instead. > > Thank you that had me bugged I just couldn't see it. > > Cheers > > Sayth I think you shod also print tree_frog.type not frog.type you create the object tree_frog which is of type frog. Although not a fault it is also recommended that classes have a capital first letter to make them more visible* * this is imply style guidance & not compulsory see pep8 for more detail when you feel ready for it. -- who gives a shit about US law anyone living in the US. From greg.ewing at canterbury.ac.nz Thu Aug 17 08:21:16 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Fri, 18 Aug 2017 00:21:16 +1200 Subject: Proposed new syntax In-Reply-To: <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > If he wanted declarative semantics, why didn't he argue for declarative syntax > like "select...where", instead of choosing procedural syntax which matches the > actual procedural semantics given? I don't agree that the word "for" necessarily implies proceduralness. -- Greg From steve+python at pearwood.info Thu Aug 17 08:23:10 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 17 Aug 2017 22:23:10 +1000 Subject: A question on modification of a list via a function invocation References: <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> Message-ID: <59958ab1$0$1589$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 10:02 pm, Stefan Ram wrote: > ram at zedat.fu-berlin.de (Stefan Ram) writes: >>Python uses a reference-counting memory reclaimer, so the >>reference count of the OEBEA now is 2. > > IIRC, the reference-counting memory reclaimer (RCMC) is not > required by the language specification. The language > specification allows other kinds of memory management. But a > certain widespread Python implementation uses an RCMC as its > default way to manage memory. CPython uses *two* garbage collectors, a reference counter, plus a second one which runs periodically to collect unused object cycles which can't be collected by the ref counter. You can enable or disable the second one using the gc module. You are correct that reference counting is not required by the language. Jython uses the JRE's native garbage collector, and IronPython uses the .Net CLR's garbage collector. One major difference between their GC's and CPython's is that objects in Jython and IronPython can be moved in memory. PyPy can be built with different sorts of garbage collectors, mostly experimental. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From greg.ewing at canterbury.ac.nz Thu Aug 17 08:47:45 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Fri, 18 Aug 2017 00:47:45 +1200 Subject: Proposed new syntax In-Reply-To: <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > Do you consider: > > for foo in bar: > if baz(foo): > f(foo) # append to a list, or print, or yield, as needed > > declarative? No. But the reason for that is not because it has the word "for" in it. The reason is that it's made up of statements. Statements are procedural, expressions are declarative. > SQL's SELECT ... WHERE is one of the canonical examples of declarative > programming: Despite the fact that "select" is a verb in English. :-) -- Greg From rustompmody at gmail.com Thu Aug 17 08:55:42 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 17 Aug 2017 05:55:42 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thursday, August 17, 2017 at 5:51:45 PM UTC+5:30, Gregory Ewing wrote: > Steve D'Aprano wrote: > > If he wanted declarative semantics, why didn't he argue for declarative syntax > > like "select...where", instead of choosing procedural syntax which matches the > > actual procedural semantics given? > > I don't agree that the word "for" necessarily implies proceduralness. Thou blasphemer! Prepare to be anathematized!! From rustompmody at gmail.com Thu Aug 17 09:19:10 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 17 Aug 2017 06:19:10 -0700 (PDT) Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> Message-ID: <7b67047d-7d59-4856-9fd4-5824f0608aff@googlegroups.com> On Thursday, August 17, 2017 at 6:49:19 AM UTC+5:30, Mok-Kong Shen wrote: > Am 17.08.2017 um 02:41 schrieb Steve D'Aprano: > > On Thu, 17 Aug 2017 08:29 am, Mok-Kong Shen wrote: > > > >> I have earlier learned some other (older) programming languages. For > >> these the formal parameters are either "by reference" or "by value". > > > > By reference and by value are not the only two conventions. > > > > Perhaps if you go back to the 1950s you might be able to argue that "reference" > > and "value" are the only two conventions, but alternatives have existed for > > many decades, since *at least* 1960 when Algol introduced "call by name". > > > > Python's evaluation strategy has existed for at least 43 years since Barbara > > Liskov named the calling convention used by CLU "call by sharing" in 1974. > > > > (It actually is much older than CLU, it goes back all the way to Lisp.) > > > > https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing > > > > > >> In the first case, any modification of the formal parameter > > > > Technically, you cannot modify the formal parameter, because the formal > > parameter is just a name unbound to any value. It's just the label in the > > function definition. You need to have actually passed a value as argument to > > the function before there is anything to modify. > > > >> inside > >> a function affects the corresponding actual parameter of a function > >> call, while in the second case a copy of the actual parameter is > >> passed into the function so that any modification of the formal > >> parameter inside the function has no effect at all outside. This is > >> extremely clear-cut in comparison to Python, isn't it? > > > > Python (and Ruby, Scheme, Ocaml, etc) are very clear-cut too. Just different. > > > > This may help: > > > > http://import-that.dreamwidth.org/1130.html > > > > > >> Anyway, while > >> any new user of a programming language certainly can be expected to > >> take good efforts to learn a lot of new stuffs, I suppose it's good > >> for any practical programming language to minimize the cases of > >> surprises for those that come from other programming languages. > > > > Indeed. And call by value is surprising: why should passing a giant array of a > > million values make a copy of the array just because I pass it to a function? > > > > And call by reference is even more surprising: if I assign a value to a local > > name inside a function, why should it modify names in the caller's namespace? > > > > Python's evaluation strategy is the least surprising of all the calling > > strategies I've used. > > Sorry for my poor capacity to comprehend. I read in the web page you > cited: "In Python, the parameters to a function or method are always > local to that function or method. Any assignments to local variables > inside the function only affect the local variable, not the caller's > variable." But then why in my test2 the global list does get modified? > (Would alist[0]=3 etc. be "in-place modification" while alist=[30,60,90] > is deemed not an "in-place modification"? If yes, where is that term > clearly defined? (That term is new for me.) Let me offer you a non-standard (in the python world) view on the subject. The fact that you are confused is good? it is in fact confusing! What is called ?call-by-object? or ?call-by-sharing? etc is really an acknowledgement of the fact that parameter passing in the OO world along with permissible mutation of data-structures is inherently leaky Since this covers the large majority of modern languages, people wonder: ?Seriously?! Can ALL these languages be WRONG?? Well? They are not wrong. Some things leak? Leakage is a fact of life https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/ is written from a slightly different viewpoint but it applies here as well And the best/only way you can come to grips with this is to understand the pointer-patterns of linked data-structures This is a bit of a delicate matter? You dont need to know about machine addresses or allocation But you do need to understand that the graphical or topological structure of b and c are different even if printing them shows no difference >>> a = [1,2] >>> b = [a,a] >>> c = [[1,2],[1,2]] From ben.usenet at bsb.me.uk Thu Aug 17 09:37:43 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Thu, 17 Aug 2017 14:37:43 +0100 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87fucqjowo.fsf@bsb.me.uk> Steve D'Aprano writes: > On Thu, 17 Aug 2017 10:14 am, Ned Batchelder wrote: >> For some reason, students have been taught that things can be either >> call-by-reference or call-by-value. But those are not the only two >> possibilities, and neither completely describes how Python works. That's obviously a crying shame when it happens, but I don't think it's universally true. Neither my experience as a student nor as a teacher bear this out. > Indeed. The insistence on this false dichotomy of call by value versus by > reference puzzles me, since alternatives go back to one of earliest, and most > influential, programming languages: Lisp. Algol, another early and hugely > influential language, used call by name. > > Its like there was an entire generation of cooks and chefs who insisted that > there are only two ways of cooking food: steaming, and barbecuing, and came up > with elaborate rationalisations for why frying, roasting, boiling etc are > actually one of the two. Obviously it's better (as Ned also said) to learn a language using its own terms, but sometimes it can help to make the jump from one language to another to think about it in other, less specific, jargon. What goes wrong when someone thinks of Python as passing by value but the value of an expression is an object reference? (I'd rather avoid the term "reference" altogether and talk, instead, about an object's identity, but Python already uses that term.) I know you address this exact question in relation to Java (sorry, I cut it because I'm not commenting on it) but I don't know Java at all, and I only know Python as a casual user so I can't evaluate how well the arguments carry over. -- Ben. From rosuav at gmail.com Thu Aug 17 10:21:35 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 00:21:35 +1000 Subject: The tragic tale of the deadlocking Python queue In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 6:31 PM, wrote: > I found it interesting, possibly some of you may feel the same way so here it is https://codewithoutrules.com/2017/08/16/concurrency-python/ Starts out with a false premise. """ Writing programs with concurrency, programs with multiple threads, is hard. Without threads code is linear: line 2 is executed after line 1, with nothing happening in between. Add in threads, and now changes can happen behind your back. """ With nothing happening in between. Except for (asynchronous) signal handlers, cyclic garbage collection, and a whole lot of other things that can already happen in between otherwise-adjacent pieces of code. And that's without even considering that other processes in the system are doing things. Edit: Oh, turns out the author knows this. Okay then. Criticism withdrawn. The fact remains, though, that most of the problems listed come from improper use of mutable global state. The article would be a lot more factual (but a lot shorter and less emotive) if it just stuck to its main point, which is about how __del__ is asynchronous. Okay, so we get down to one thing: locks acquired in __del__ are dangerous. And I'd say that yes, they really should be. The hard problem is not "how can we make a re-entrant queue", but "how can we avoid the use of locks inside __del__". The solution, in my opinion, is not to use queues with ResourceWarning (which might mean handling ResourceWarning specially, or handling all warnings differently). Concurrent programming is not as hard as a lot of people make out. It's just an extension of otherwise well-known good programming habits like being careful of mutable global state. The only difference is that, with single-threaded code, you have all these implicit locks around your functions, so you can pretend that things are atomic when they're not. ChrisA From marko at pacujo.net Thu Aug 17 10:42:58 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 17 Aug 2017 17:42:58 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87pobutfv1.fsf@elektro.pacujo.net> Gregory Ewing : > I don't agree that the word "for" necessarily implies proceduralness. Programming languages stole the word from math, where it is nonprocedural. Really, "for" is just a preposition. In Algol, for example, proceduralness was not in the word "for" but in "do": for p := 1 step 1 until n do for q := 1 step 1 until m do if abs(a[p, q]) > y then begin y := abs(a[p, q]); i := p; k := q end Pascal is similar: for i:= 1 to 10 do writeln(i); As is sh: for i in *.py; do mv "$i" "$i.bak" done Common lisp uses "do" as well: (setq a-vector (vector 1 nil 3 nil)) (do ((i 0 (+ i 1)) ;Sets every null element of a-vector to zero. (n (array-dimension a-vector 0))) ((= i n)) (when (null (aref a-vector i)) (setf (aref a-vector i) 0))) => NIL I guess we have C to blame for the redefinition of the word "for" in programmers' minds. Marko From rustompmody at gmail.com Thu Aug 17 10:48:30 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 17 Aug 2017 07:48:30 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: <87pobutfv1.fsf@elektro.pacujo.net> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <87pobutfv1.fsf@elektro.pacujo.net> Message-ID: <8e3efe26-2d12-496d-bdb9-8deac16fac58@googlegroups.com> On Thursday, August 17, 2017 at 8:13:24 PM UTC+5:30, Marko Rauhamaa wrote: > Gregory Ewing : > > I don't agree that the word "for" necessarily implies proceduralness. > > Programming languages stole the word from math, where it is > nonprocedural. > > Really, "for" is just a preposition. In Algol, for example, > proceduralness was not in the word "for" but in "do": > > for p := 1 step 1 until n do > for q := 1 step 1 until m do > if abs(a[p, q]) > y then > begin y := abs(a[p, q]); > i := p; k := q > end > > > > Pascal is similar: > > for i:= 1 to 10 do writeln(i); > > > > As is sh: > > for i in *.py; do > mv "$i" "$i.bak" > done > > Common lisp uses "do" as well: > > (setq a-vector (vector 1 nil 3 nil)) > (do ((i 0 (+ i 1)) ;Sets every null element of a-vector to zero. > (n (array-dimension a-vector 0))) > ((= i n)) > (when (null (aref a-vector i)) > (setf (aref a-vector i) 0))) => NIL > > htm> > > I guess we have C to blame for the redefinition of the word "for" in > programmers' minds. And C?s for is just a while with a ?finally? clause for its inner block From tjreedy at udel.edu Thu Aug 17 11:11:00 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 17 Aug 2017 11:11:00 -0400 Subject: The tragic tale of the deadlocking Python queue In-Reply-To: References: Message-ID: On 8/17/2017 4:31 AM, breamoreboy at gmail.com wrote: > I found it interesting, possibly some of you may feel the same way so here it is https://codewithoutrules.com/2017/08/16/concurrency-python/ The intro ends with "Weep when you read the response of Python?s maintainers!", referring to https://bugs.python.org/issue14976. The issue was originally about signals, threads, and Queue's, which Itamar admits "don't interact well". The solution to that was to document "Don't do this.". Followup: When Itamar posted, yesterday, a clear demonstration that there is a bug in other, more reasonable code, the response has been to reopen the issue, with a plan to rewrite in C using (somewhat ironically) the (somewhat hated) GIL as a lock. -- Terry Jan Reedy From lew.pitcher at digitalfreehold.ca Thu Aug 17 11:11:29 2017 From: lew.pitcher at digitalfreehold.ca (Lew Pitcher) Date: Thu, 17 Aug 2017 11:11:29 -0400 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <87pobutfv1.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > Gregory Ewing : >> I don't agree that the word "for" necessarily implies proceduralness. > > Programming languages stole the word from math, where it is > nonprocedural. > > Really, "for" is just a preposition. In Algol, for example, > proceduralness was not in the word "for" but in "do": [snip] > I guess we have C to blame for the redefinition of the word "for" in > programmers' minds. Sorry, but that use of "for" was part of the programmer's lexicon well before the invention of C. Computer languages have inherited and used it since (at least) 1948. Dartmouth BASIC (1964) had "FOR" FOR I=1 TO 10 ALGOL-60 (1960) had "for" for i:=1 step 1 until 10 ALGOL-58 (1958) had "for" for i:=1(1)10 Superplan (1948) had "fur" (German for the English word "for") F?r k=1(1)10 : -- Lew Pitcher "In Skills, We Trust" PGP public key available upon request From pavol.lisy at gmail.com Thu Aug 17 15:19:02 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Thu, 17 Aug 2017 21:19:02 +0200 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/17/17, Gregory Ewing wrote: > Steve D'Aprano wrote: >> If he wanted declarative semantics, why didn't he argue for declarative >> syntax >> like "select...where", instead of choosing procedural syntax which matches >> the >> actual procedural semantics given? > > I don't agree that the word "for" necessarily implies proceduralness. With this logic (I humbly think that) word "while" neither necessarilly implies proceduralness. From saurabh.chaturvedi63 at gmail.com Thu Aug 17 15:39:36 2017 From: saurabh.chaturvedi63 at gmail.com (Sam Chats) Date: Thu, 17 Aug 2017 19:39:36 +0000 (UTC) Subject: Synchronization Primitives in Python Message-ID: A good introductory article on synchronizing threads in Python: https://hackernoon.com/synchronization-primitives-in-python-564f89fee732 From marko at pacujo.net Thu Aug 17 16:20:55 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 17 Aug 2017 23:20:55 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87a82y3pzs.fsf@elektro.pacujo.net> Pavol Lisy : > On 8/17/17, Gregory Ewing wrote: >> I don't agree that the word "for" necessarily implies proceduralness. > > With this logic (I humbly think that) word "while" neither > necessarilly implies proceduralness. I don't see the logic. Here's a random page from an algebra textbook: A sequence {a[n]} is called *bounded* if there is some real number b, a *bound*, such that |a[n]| ? b for all n. Z = {(a) ? ?**? | a[n] = 0 for all but finitely many n } On another one: = 0 if i ? j, and = 1 for each i And: For every value a of the variable x, there are at most n points of S whose x-coordinate is a. Marko From ian.g.kelly at gmail.com Thu Aug 17 16:28:04 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 14:28:04 -0600 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 17, 2017 at 1:19 PM, Pavol Lisy wrote: > On 8/17/17, Gregory Ewing wrote: >> Steve D'Aprano wrote: >>> If he wanted declarative semantics, why didn't he argue for declarative >>> syntax >>> like "select...where", instead of choosing procedural syntax which matches >>> the >>> actual procedural semantics given? >> >> I don't agree that the word "for" necessarily implies proceduralness. > > With this logic (I humbly think that) word "while" neither > necessarilly implies proceduralness. "while" implies a condition that is currently true and may at some point stop being true. To me, that sequentiality does imply proceduralness. "for", to quote from Merriam-Webster, indicates "equivalence in exchange". A precise definition seems hard to nail down, but there's no such implication there. From jfong at ms4.hinet.net Thu Aug 17 20:03:53 2017 From: jfong at ms4.hinet.net (jfong at ms4.hinet.net) Date: Thu, 17 Aug 2017 17:03:53 -0700 (PDT) Subject: Call a class A method from a class B instance? Do I miss something? Message-ID: I study some codes of a tutorial about tkinter (https://github.com/daleathan/widget-tour-py3) and can't figure out how it works. Below is the codes from its two major files: ---------------------------- # file infrastructure.py ... ... class callit: def __init__(self, function, *args ): self.f = function self.args = args def __call__(self, *ignored): self.f(*self.args) ... ------------------------ # file widget.py ... from infrastructure import * ... class DemoMainWindow(Frame): ... def _fill_textarea(self): ... # bind events self.text.tag_bind(tag, '', callit(self.demoenter_callback, tag) ) ... def demoenter_callback(self, tag): ... self.text.configure(cursor='hand2') ... ---------------------- My question is that the object which was left by callit(self.demoenter_callback, tag) is a callit instance, and the method it calls is a DemoMainWindow's method. How it is possible? Best Regards, Jach Fong From nagle at animats.com Thu Aug 17 20:14:13 2017 From: nagle at animats.com (John Nagle) Date: Thu, 17 Aug 2017 17:14:13 -0700 Subject: What extended ASCII character set uses 0x9D? Message-ID: I'm cleaning up some data which has text description fields from multiple sources. Some are are in UTF-8. Some are in WINDOWS-1252. And some are in some other character set. So I have to examine and sanity check each field in a database dump, deciding which character set best represents what's there. Here's a hard case: g1 = bytearray(b'\\"Perfect Gift Idea\\"\x9d Each time') g1.decode("utf8") UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9d in position 21: invalid start byte g1.decode("windows-1252") UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 21: character maps to 0x9d is unmapped in "windows-1252", according to https://en.wikipedia.org/wiki/Windows-1252 So the Python codec isn't wrong here. Trying "latin-1" g1.decode("latin-1") '\\"Perfect Gift Idea\\"\x9d Each time' That just converts 0x9d in the input to 0x9d in Unicode. That's "Operating System Command" (the "Windows" key?) That's clearly wrong; some kind of quote was intended. Any ideas? John Nagle From rosuav at gmail.com Thu Aug 17 20:27:34 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 10:27:34 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Fri, Aug 18, 2017 at 10:14 AM, John Nagle wrote: > I'm cleaning up some data which has text description fields from > multiple sources. Some are are in UTF-8. Some are in WINDOWS-1252. > And some are in some other character set. So I have to examine and > sanity check each field in a database dump, deciding which character > set best represents what's there. > > Here's a hard case: > > g1 = bytearray(b'\\"Perfect Gift Idea\\"\x9d Each time') > > g1.decode("utf8") > UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9d in position 21: > invalid start byte > > g1.decode("windows-1252") > UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 21: > character maps to > > 0x9d is unmapped in "windows-1252", according to > > https://en.wikipedia.org/wiki/Windows-1252 > > So the Python codec isn't wrong here. > > Trying "latin-1" > > g1.decode("latin-1") > '\\"Perfect Gift Idea\\"\x9d Each time' > > That just converts 0x9d in the input to 0x9d in Unicode. > That's "Operating System Command" (the "Windows" key?) > That's clearly wrong; some kind of quote was intended. > Any ideas? Another possibility is that it's some kind of dash or ellipsis or something, but I can't find anything that does. (You already have quote characters in there.) The nearest I can actually find is: >>> b'\\"Perfect Gift Idea\\"\x9d Each time'.decode("1256") '\\"Perfect Gift Idea\\"\u200c Each time' >>> unicodedata.name("\u200c") 'ZERO WIDTH NON-JOINER' which, honestly, doesn't make a lot of sense either. :( ChrisA From nagle at animats.com Thu Aug 17 20:30:28 2017 From: nagle at animats.com (John Nagle) Date: Thu, 17 Aug 2017 17:30:28 -0700 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On 08/17/2017 05:14 PM, John Nagle wrote: > I'm cleaning up some data which has text description fields from > multiple sources. A few more cases: bytearray(b'miguel \xe3\x81ngel santos') bytearray(b'lidija kmeti\xe4\x8d') bytearray(b'\xe5\x81ukasz zmywaczyk') bytearray(b'M\x81\x81\xfcnster') bytearray(b'ji\xe5\x99\xe3\xad urban\xe4\x8d\xe3\xadk') bytearray(b'\xe4\xbdubom\xe3\xadr mi\xe4\x8dko') bytearray(b'petr urban\xe4\x8d\xe3\xadk') 0x9d is the most common; that occurs in English text. The others seem to be in some Eastern European character set. Understand, there's no metadata available to disambiguate this. What I have is a big CSV file in which different character sets are mixed. Each field has a uniform character set, so I need character set detection on a per-field basis. John Nagle From ian.g.kelly at gmail.com Thu Aug 17 20:38:52 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 18:38:52 -0600 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 6:27 PM, Chris Angelico wrote: > On Fri, Aug 18, 2017 at 10:14 AM, John Nagle wrote: >> I'm cleaning up some data which has text description fields from >> multiple sources. Some are are in UTF-8. Some are in WINDOWS-1252. >> And some are in some other character set. So I have to examine and >> sanity check each field in a database dump, deciding which character >> set best represents what's there. >> >> Here's a hard case: >> >> g1 = bytearray(b'\\"Perfect Gift Idea\\"\x9d Each time') >> >> g1.decode("utf8") >> UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9d in position 21: >> invalid start byte >> >> g1.decode("windows-1252") >> UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 21: >> character maps to >> >> 0x9d is unmapped in "windows-1252", according to >> >> https://en.wikipedia.org/wiki/Windows-1252 >> >> So the Python codec isn't wrong here. >> >> Trying "latin-1" >> >> g1.decode("latin-1") >> '\\"Perfect Gift Idea\\"\x9d Each time' >> >> That just converts 0x9d in the input to 0x9d in Unicode. >> That's "Operating System Command" (the "Windows" key?) >> That's clearly wrong; some kind of quote was intended. >> Any ideas? > > Another possibility is that it's some kind of dash or ellipsis or > something, but I can't find anything that does. (You already have > quote characters in there.) The nearest I can actually find is: > >>>> b'\\"Perfect Gift Idea\\"\x9d Each time'.decode("1256") > '\\"Perfect Gift Idea\\"\u200c Each time' >>>> unicodedata.name("\u200c") > 'ZERO WIDTH NON-JOINER' > > which, honestly, doesn't make a lot of sense either. :( In CP437 it's ? which makes some sense in the "gift idea" context. But then I'd expect a number to appear with it. It could also just be junk data. From steve+python at pearwood.info Thu Aug 17 20:49:50 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 10:49:50 +1000 Subject: Cross-language comparison: function map and similar References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: <599639b0$0$1606$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 03:54 pm, Pavol Lisy wrote: > Is it guaranteed in python? Or future version could implement map with > something like subscriptability "propagation"? > >>>>range(1_000_000_000_000_000_000)[-1] > 9999999999999999 > >>>> map(lambda a:a+1,range(1_000_000_000_000_000_000))[-1] > TypeError: 'map' object is not subscriptable I don't recognise the term "subscriptability propagation". Given a suitable deprecation period, or another backwards-incompatible release like Python 3, anything is possible. But some things are very unlikely, such as another backwards-incompatible release, or map supporting indexing. Python's map() now returns an iterator, which means it must yield items one by one, in order. Because it is an iterator, in general it cannot know what the next item will be until it evaluates it. Unlike range, it cannot jump ahead In principle we could have map() return a magic iterator that delegated indexing to the underlying sequence, but that's not part of the iterator API and the benefit seems small. So, possible but unlikely. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ian.g.kelly at gmail.com Thu Aug 17 20:52:08 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 18:52:08 -0600 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 6:30 PM, John Nagle wrote: > A few more cases: > > bytearray(b'miguel \xe3\x81ngel santos') If that were b'\xc3\x81' it would be ? in UTF-8 which would fit the rest of the name. > bytearray(b'\xe5\x81ukasz zmywaczyk') If that were b'\xc5\x81' it would be ? in UTF-8 which would fit the rest of the name. I suspect the others contain similar errors. I don't know if it's the result of some form of Mojibake or maybe just transcription errors. From rosuav at gmail.com Thu Aug 17 20:53:58 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 10:53:58 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Fri, Aug 18, 2017 at 10:30 AM, John Nagle wrote: > On 08/17/2017 05:14 PM, John Nagle wrote: >> I'm cleaning up some data which has text description fields from >> multiple sources. > A few more cases: > > bytearray(b'\xe5\x81ukasz zmywaczyk') This one has to be Polish, and the first character should be the letter ? U+0141 or ? U+0142. In UTF-8, U+0141 becomes C5 81, which is very similar to the E5 81 that you have. So here's an insane theory: something attempted to lower-case the byte stream as if it were ASCII. If you ignore the high bit, 0xC5 looks like 0x45 or "E", which lower-cases by having 32 added to it, yielding 0xE5. Reversing this transformation yields sane data for several of your strings - they then decode as UTF-8: miguel ?ngel santos lidija kmeti? ?ukasz zmywaczyk ji?? urban??k ?ubom?r mi?ko petr urban??k That doesn't work for everything, though. The 0x81 0x81 and 0x9d ones are still a puzzle. ChrisA From ian.g.kelly at gmail.com Thu Aug 17 20:54:29 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 18:54:29 -0600 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 6:52 PM, Ian Kelly wrote: > On Thu, Aug 17, 2017 at 6:30 PM, John Nagle wrote: >> A few more cases: >> >> bytearray(b'miguel \xe3\x81ngel santos') > > If that were b'\xc3\x81' it would be ? in UTF-8 which would fit the > rest of the name. > >> bytearray(b'\xe5\x81ukasz zmywaczyk') > > If that were b'\xc5\x81' it would be ? in UTF-8 which would fit the > rest of the name. > > I suspect the others contain similar errors. I don't know if it's the > result of some form of Mojibake or maybe just transcription errors. Oh shit, I think know what happened. In ASCII you can lower-case letters by just adding 32 (0x20) to them. Somebody tried to do that here and fucked up the encoding. That's why all the ASCII letters in the strings are lower-case while these ones aren't. From rosuav at gmail.com Thu Aug 17 21:02:59 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 11:02:59 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Fri, Aug 18, 2017 at 10:54 AM, Ian Kelly wrote: > On Thu, Aug 17, 2017 at 6:52 PM, Ian Kelly wrote: >> On Thu, Aug 17, 2017 at 6:30 PM, John Nagle wrote: >>> A few more cases: >>> >>> bytearray(b'miguel \xe3\x81ngel santos') >> >> If that were b'\xc3\x81' it would be ? in UTF-8 which would fit the >> rest of the name. >> >>> bytearray(b'\xe5\x81ukasz zmywaczyk') >> >> If that were b'\xc5\x81' it would be ? in UTF-8 which would fit the >> rest of the name. >> >> I suspect the others contain similar errors. I don't know if it's the >> result of some form of Mojibake or maybe just transcription errors. > > Oh shit, I think know what happened. In ASCII you can lower-case > letters by just adding 32 (0x20) to them. Somebody tried to do that > here and fucked up the encoding. That's why all the ASCII letters in > the strings are lower-case while these ones aren't. That applies to some, but not all. > bytearray(b'M\x81\x81\xfcnster') This should be M?nster, which is a U+00FC. You have 81 81 FC. I don't know of any encoding that does this, but it looks indicative - and it's not the lower-casing. And the 0x9d doesn't either, but maybe that's some relation to 0x2d which is an ASCII hyphen? ChrisA From ian.g.kelly at gmail.com Thu Aug 17 21:06:08 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 19:06:08 -0600 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 6:53 PM, Chris Angelico wrote: > That doesn't work for everything, though. The 0x81 0x81 and 0x9d ones > are still a puzzle. I'm fairly sure that b'M\x81\x81\xfcnster' is 'M?nster'. It decodes to that in Latin-1 if you remove the \x81 bytes. The question then is what those extra bytes are doing there. I suspect that they and 0x9d are just non-printing junk control bytes from the C1 set that got inserted into the character stream somehow. From ben.usenet at bsb.me.uk Thu Aug 17 21:07:11 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 18 Aug 2017 02:07:11 +0100 Subject: What extended ASCII character set uses 0x9D? References: Message-ID: <87a82xiszk.fsf@bsb.me.uk> John Nagle writes: > I'm cleaning up some data which has text description fields from > multiple sources. Some are are in UTF-8. Some are in WINDOWS-1252. > And some are in some other character set. So I have to examine and > sanity check each field in a database dump, deciding which character > set best represents what's there. > > Here's a hard case: > > g1 = bytearray(b'\\"Perfect Gift Idea\\"\x9d Each time') > > g1.decode("utf8") > UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9d in position 21: invalid start byte > > g1.decode("windows-1252") > UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 21: character maps to > > 0x9d is unmapped in "windows-1252", according to > > https://en.wikipedia.org/wiki/Windows-1252 > > So the Python codec isn't wrong here. > > Trying "latin-1" > > g1.decode("latin-1") > '\\"Perfect Gift Idea\\"\x9d Each time' > > That just converts 0x9d in the input to 0x9d in Unicode. > That's "Operating System Command" (the "Windows" key?) > That's clearly wrong; some kind of quote was intended. > Any ideas? I wrote a little shell script to try every encoding known to iconv and the two most likely intended characters seem to be cedilla (if someone mistook it for a comma) and a zero width non-joiner. The former mainly comes from IBM character sets and the latter from IBM and MS character sets (WINDOWS-1256 for example). Neither seems very plausible so I'm betting on an error! -- Ben. From steve+python at pearwood.info Thu Aug 17 21:13:07 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 11:13:07 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59963f24$0$1618$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 10:47 pm, Gregory Ewing wrote: > Steve D'Aprano wrote: >> Do you consider: >> >> for foo in bar: >> if baz(foo): >> f(foo) # append to a list, or print, or yield, as needed >> >> declarative? > > No. But the reason for that is not because it has the word > "for" in it. The reason is that it's made up of statements. > Statements are procedural, expressions are declarative. Not necessarily. If we can't agree on definitions for procedural and declarative, I'm not sure that this conversation is going to go anywhere. But the established definition is that: - in procedural code (although possibly "imperative" may be a better term) you have to explicitly control the flow of program state yourself - in declarative code you don't, you state the desired outcome and the interpreter is free to choose its own execution flow to meet that outcome. Whether your code is made of statements or expressions or both is not relevant. You can have declarative statements, if the interpreter is free to perform them in any order. Within a single language, it is common to have both procedural and declarative statements. E.g. in Python for statements are clearly procedural flow control. But "import" can be read as a declarative statement: "Load this module, I don't care how you do it or where you have to search or what order you do the searching, so long as you load this module." Arguably its not *really* declarative, because we can implicitly control the search order by manipulating sys.modules and sys.path and a few other ways. But that's splitting hairs -- by that standard, SQL SELECT isn't declarative either, because databases often give you a way to fine-tune the query plan. >> SQL's SELECT ... WHERE is one of the canonical examples of declarative >> programming: > > Despite the fact that "select" is a verb in English. :-) "Select" isn't flow control. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From python at mrabarnett.plus.com Thu Aug 17 21:21:35 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 18 Aug 2017 02:21:35 +0100 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On 2017-08-18 01:14, John Nagle wrote: > I'm cleaning up some data which has text description fields from > multiple sources. Some are are in UTF-8. Some are in WINDOWS-1252. > And some are in some other character set. So I have to examine and > sanity check each field in a database dump, deciding which character > set best represents what's there. > > Here's a hard case: > > g1 = bytearray(b'\\"Perfect Gift Idea\\"\x9d Each time') > > g1.decode("utf8") > UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9d in position > 21: invalid start byte > > g1.decode("windows-1252") > UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position > 21: character maps to > > 0x9d is unmapped in "windows-1252", according to > > https://en.wikipedia.org/wiki/Windows-1252 > > So the Python codec isn't wrong here. > > Trying "latin-1" > > g1.decode("latin-1") > '\\"Perfect Gift Idea\\"\x9d Each time' > > That just converts 0x9d in the input to 0x9d in Unicode. > That's "Operating System Command" (the "Windows" key?) > That's clearly wrong; some kind of quote was intended. > Any ideas? > It's preceded by something in quotes, so it might be ? (trademark symbol, '\u2122') or something similar. No idea which encoding that would be, though. From rosuav at gmail.com Thu Aug 17 21:25:58 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 11:25:58 +1000 Subject: Proposed new syntax In-Reply-To: <59963f24$0$1618$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> <59963f24$0$1618$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 18, 2017 at 11:13 AM, Steve D'Aprano wrote: > Within a single language, it is common to have both procedural and declarative > statements. E.g. in Python for statements are clearly procedural flow control. > But "import" can be read as a declarative statement: > > "Load this module, I don't care how you do it or where you have to search or > what order you do the searching, so long as you load this module." > > Arguably its not *really* declarative, because we can implicitly control the > search order by manipulating sys.modules and sys.path and a few other ways. But > that's splitting hairs -- by that standard, SQL SELECT isn't declarative > either, because databases often give you a way to fine-tune the query plan. One way to figure out whether it's declarative or imperative is to consider whether it would be legal for (a) a different Python implementation, or (b) a different version of the same Python implementation, to achieve the same goal in a different way. An import statement is definitely somewhat declarative, because you can *externally* change the mechanics of the command. (For instance, activating a virtual environment, or otherwise messing with PYTHONPATH.) ChrisA From python at mrabarnett.plus.com Thu Aug 17 22:15:54 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 18 Aug 2017 03:15:54 +0100 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: <34eb2198-7cff-20f0-30d5-4a3e75fc1051@mrabarnett.plus.com> On 2017-08-18 01:53, Chris Angelico wrote: > On Fri, Aug 18, 2017 at 10:30 AM, John Nagle wrote: >> On 08/17/2017 05:14 PM, John Nagle wrote: >>> I'm cleaning up some data which has text description fields from >>> multiple sources. >> A few more cases: >> >> bytearray(b'\xe5\x81ukasz zmywaczyk') > > This one has to be Polish, and the first character should be the > letter ? U+0141 or ? U+0142. In UTF-8, U+0141 becomes C5 81, which is > very similar to the E5 81 that you have. > > So here's an insane theory: something attempted to lower-case the byte > stream as if it were ASCII. If you ignore the high bit, 0xC5 looks > like 0x45 or "E", which lower-cases by having 32 added to it, yielding > 0xE5. Reversing this transformation yields sane data for several of > your strings - they then decode as UTF-8: > > miguel ?ngel santos I think that's: miguel ?ngel santos > lidija kmeti? > ?ukasz zmywaczyk > ji?? urban??k > ?ubom?r mi?ko > petr urban??k > > That doesn't work for everything, though. The 0x81 0x81 and 0x9d ones > are still a puzzle. > From ian.g.kelly at gmail.com Thu Aug 17 22:23:48 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 20:23:48 -0600 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: <34eb2198-7cff-20f0-30d5-4a3e75fc1051@mrabarnett.plus.com> References: <34eb2198-7cff-20f0-30d5-4a3e75fc1051@mrabarnett.plus.com> Message-ID: On Thu, Aug 17, 2017 at 8:15 PM, MRAB wrote: > On 2017-08-18 01:53, Chris Angelico wrote: >> So here's an insane theory: something attempted to lower-case the byte >> stream as if it were ASCII. If you ignore the high bit, 0xC5 looks >> like 0x45 or "E", which lower-cases by having 32 added to it, yielding >> 0xE5. Reversing this transformation yields sane data for several of >> your strings - they then decode as UTF-8: >> >> miguel ?ngel santos > > > I think that's: > > miguel ?ngel santos It would be if it had been lower-cased correctly. The UTF-8 for ? is \xc3\xa1, not \xe3x81 (ironically the add-32 method still works in this particular case; it was just added to the wrong byte). From python at mrabarnett.plus.com Thu Aug 17 22:24:27 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 18 Aug 2017 03:24:27 +0100 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On 2017-08-18 01:30, John Nagle wrote: > On 08/17/2017 05:14 PM, John Nagle wrote: > > I'm cleaning up some data which has text description fields from > > multiple sources. > A few more cases: > > bytearray(b'miguel \xe3\x81ngel santos') > bytearray(b'lidija kmeti\xe4\x8d') > bytearray(b'\xe5\x81ukasz zmywaczyk') > bytearray(b'M\x81\x81\xfcnster') I suspect that it's b'M\xc3\xbcnster', i.e. 'M?nster'.encode('utf'8') > bytearray(b'ji\xe5\x99\xe3\xad urban\xe4\x8d\xe3\xadk') > bytearray(b'\xe4\xbdubom\xe3\xadr mi\xe4\x8dko') > bytearray(b'petr urban\xe4\x8d\xe3\xadk') > > 0x9d is the most common; that occurs in English text. The others > seem to be in some Eastern European character set. > > Understand, there's no metadata available to disambiguate this. What I > have is a big CSV file in which different character sets are mixed. > Each field has a uniform character set, so I need character set > detection on a per-field basis. > From ian.g.kelly at gmail.com Thu Aug 17 22:40:38 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 20:40:38 -0600 Subject: Call a class A method from a class B instance? Do I miss something? In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 6:03 PM, wrote: > I study some codes of a tutorial about tkinter (https://github.com/daleathan/widget-tour-py3) and can't figure out how it works. > > Below is the codes from its two major files: > ---------------------------- > # file infrastructure.py > ... > ... > class callit: > def __init__(self, function, *args ): > self.f = function > > self.args = args > > > def __call__(self, *ignored): > self.f(*self.args) > > ... > > ------------------------ > # file widget.py > ... > from infrastructure import * > ... > class DemoMainWindow(Frame): > ... > def _fill_textarea(self): > ... > # bind events > self.text.tag_bind(tag, '', > > callit(self.demoenter_callback, tag) ) > ... > > def demoenter_callback(self, tag): > ... > self.text.configure(cursor='hand2') > ... > > ---------------------- > My question is that the object which was left by callit(self.demoenter_callback, tag) is a callit instance, and the method it calls is a DemoMainWindow's method. > How it is possible? Methods are just functions with a bit of magic [1] that binds the self argument to them. DemoMainWindow.demoenter_callback is an unbound method object (although in Python 3, it's just an ordinary function). When self.demoenter_callback is evaluated, the result is not the same unbound method object. Instead you get a different *bound* method object, which binds the self argument to the DemoMainWindow instance. The important point is that this binding happens when self.demoenter_callback is evaluated, not when the method is called. This bound method object gets passed to the callit object, which saves it as self.f. Later, it calls self.f() which calls the method that is still bound to the same DemoMainWindow instance. Note that evaluating self.f does not *rebind* the method object. Bound method objects never get rebound; they are only created from unbound methods. So when self.f() is called the bound DemoMainWindow instance is used as the value of the self argument. The fact that it was actually called from a method of callit doesn't matter. [1] This magic is called the descriptor protocol, and if you want to play with it you can use it to create your own method types! This is a topic usually presented to intermediate-level Python programmers. From steve+python at pearwood.info Thu Aug 17 23:07:18 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 13:07:18 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> <7b67047d-7d59-4856-9fd4-5824f0608aff@googlegroups.com> Message-ID: <599659e8$0$1620$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 11:19 pm, Rustom Mody wrote: > What is called ?call-by-object? or ?call-by-sharing? etc is really an > acknowledgement of the fact that parameter passing in the OO world along with > permissible mutation of data-structures is inherently leaky Leaky of *what*? What do you think the abstraction is that is leaky? Call by value leaks. The abstraction is that the argument received by the function is independent from the value you pass in. But the leak happens when you pass an array with a billion items, and the compiler makes a copy of the entire array, and you wonder why you run out of memory. Call by reference leaks. The abstraction is that the argument received by the function is the argument you pass to the function. Not just the same, in the sense of equal, but one-and-the-same. As in, "me myself and I" all refer to the same person. But the leak happens when you try to pass a literal or a constant or the result of an expression, rather than a variable, and the compiler says "Uh uh, you can't do that!" So what abstraction do you think call by object sharing is making, and in what way does it leak? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rantingrickjohnson at gmail.com Thu Aug 17 23:42:39 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Thu, 17 Aug 2017 20:42:39 -0700 (PDT) Subject: Call a class A method from a class B instance? Do I miss something? In-Reply-To: References: Message-ID: jf... at ms4.hinet.net wrote: > I study some codes of a tutorial about tkinter > > [snip code] > > My question is that the object which was left by > callit(self.demoenter_callback, tag) is a callit instance, > and the method it calls is a DemoMainWindow's method. How > it is possible? Why would it _not_ be possible? Functions are first class objects, after all. Google it. All the code is doing here is passing around a function reference and argument list like a baton in a foot race. No real magic here, just a lot of academic smoke and mirrors really. Or maybe this is more like a rat maze? Or a hot potato? Opinions may vary... But short of obfuscation for the _sake_ of obfuscation, i don't understand what the tutorial author is intending to teach you here. Sheesh, the same goal could be achieved much more clearly by wrapping the argument-laden callback in an anonymous function or using a functools.partial, as the _true_goal_ here is to avoid premature execution of the argument-laden callback. I absolutely detest superfluity! -- >>> import this From nagle at animats.com Thu Aug 17 23:46:35 2017 From: nagle at animats.com (John Nagle) Date: Thu, 17 Aug 2017 20:46:35 -0700 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On 08/17/2017 05:53 PM, Chris Angelico wrote:> On Fri, Aug 18, 2017 at 10:30 AM, John Nagle wrote: >> On 08/17/2017 05:14 PM, John Nagle wrote: >>> I'm cleaning up some data which has text description fields from >>> multiple sources. >> A few more cases: >> >> bytearray(b'\xe5\x81ukasz zmywaczyk') > > This one has to be Polish, and the first character should be the > letter ? U+0141 or ? U+0142. In UTF-8, U+0141 becomes C5 81, which is > very similar to the E5 81 that you have. > > So here's an insane theory: something attempted to lower-case the byte > stream as if it were ASCII. If you ignore the high bit, 0xC5 looks > like 0x45 or "E", which lower-cases by having 32 added to it, yielding > 0xE5. Reversing this transformation yields sane data for several of > your strings - they then decode as UTF-8: > > miguel ?ngel santos > lidija kmeti? > ?ukasz zmywaczyk > ji?? urban??k > ?ubom?r mi?ko > petr urban??k I think you're right for those. I'm working from a MySQL dump of supposedly LATIN-1 data, but LATIN-1 will accept anything. I've found UTF-8 and Windows-2152 in there. It's quite possble that someone lower-cased UTF-8 stored in a LATIN-1 field. There are lots of questions on the web which complain about getting a Python decode error on 0x9d, and the usual answer is "Use Latin-1". But that doesn't really decode properly, it just doesn't generate an exception. > That doesn't work for everything, though. The 0x81 0x81 and 0x9d ones > are still a puzzle. The 0x9d thing seems unrelated to the Polish names thing. 0x9d shows up in the middle of English text that's otherwise ASCII. Is this something that can appear as a result of cutting and pasting from Microsoft Word? I'd like to get 0x9d right, because it comes up a lot. The Polish name thing is rare. There's only about a dozen of those in 400MB of database dump. There are hundreds of 0x9d hits. Here's some more 0x9d usage, each from a different data item: Guitar Pro, JamPlay, RedBana\\\'s Audition,\x9d Doppleganger\x99s The Lounge\x9d or Heatwave Interactive\x99s Platinum Life Country,\\" for example \\"I\\\'ve seen the bull run in Pamplona, Spain\x9d.\\" Everything Netwise Depot is a \\"One Stop Web Shop\\"\x9d that provides sustainable \\"green\\"\x9d living are looking for a \\"Do It for Me\\"\x9d solution This has me puzzled. It's often, but not always after a close quote. "TM" or "(R)" might make sense, but what non-Unicode character set has those. And "green"(tm) makes no sense. John Nagle From steve+python at pearwood.info Fri Aug 18 00:39:31 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 14:39:31 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <87pobutfv1.fsf@elektro.pacujo.net> Message-ID: <59966f85$0$1621$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 01:11 am, Lew Pitcher wrote: > Marko Rauhamaa wrote: >> I guess we have C to blame for the redefinition of the word "for" in >> programmers' minds. > > Sorry, but that use of "for" was part of the programmer's lexicon well > before the invention of C. Computer languages have inherited and used it > since (at least) 1948. That can't be right! Programming wasn't invented until 1972, when C sprung forth, fully formed and perfect, with no predecessors, from the mind of Dennis Ritchie! *wink* I wish people knew more about the history of programming. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 18 01:05:03 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 15:05:03 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 06:28 am, Ian Kelly wrote: > On Thu, Aug 17, 2017 at 1:19 PM, Pavol Lisy wrote: >> On 8/17/17, Gregory Ewing wrote: >>> Steve D'Aprano wrote: >>>> If he wanted declarative semantics, why didn't he argue for declarative >>>> syntax >>>> like "select...where", instead of choosing procedural syntax which matches >>>> the >>>> actual procedural semantics given? >>> >>> I don't agree that the word "for" necessarily implies proceduralness. >> >> With this logic (I humbly think that) word "while" neither >> necessarilly implies proceduralness. > > "while" implies a condition that is currently true and may at some > point stop being true. To me, that sequentiality does imply > proceduralness. For loops and comprehensions (in Python) are inherently procedural, so it's a good match. If you want to ignore the documented semantics of Python comprehensions, their fundamental similarities to generator expressions, and their actual behaviour, in order to say that they aren't procedural, that's okay, it a free planet. (Sometimes.) But if you do that, then logically you must also allow that "while" is likewise not procedural. Otherwise you're just showing a double-standard. [Aside: comprehensions are also functional in the sense that they return a result (unlike a loop, which is imperative) but not in the sense that the order of execution is unspecified.] > "for", to quote from Merriam-Webster, indicates "equivalence in > exchange". A precise definition seems hard to nail down, but there's > no such implication there. Webster 1913 includes well over a dozen definitions for the word "for", so I'm sure that Merrian-Webster would be similar. I don't know why you cherry picked that one definition out of so many. I think this is more appropriate: 8. Indicating the space or time through which an action or state extends; hence, during; in or through the space or time of. "for x in seq" indicates that x extends through the space of seq, in a manner of speaking. Or for something more recent, and more relevant, how about foldoc, the Free On-line Dictionary of Computing? for loop for A loop construct found in many procedural languages which repeatedly executes some instructions while a condition is true. [examples snipped] The for loop is an alternative way of writing a while loop that is convenient because the loop control logic is collected in a single place. It is also closely related to the repeat loop. Sounds pretty definitively procedural to me. But as Lewis Carrol wrote: ?When I use a word, Humpty Dumpty said, in a rather scornful tone, it means just what I choose it to mean, neither more nor less. The question is, said Alice, whether you can make words mean so many different things. The question is, said Humpty Dumpty, which is to be master ? that?s all.? Of course we can choose any definition or meaning we like for the word "for" in comprehensions, and insist that it doesn't actually mean what the "for" in for-statement means. We're the master of language, not language of us! But if we can do that, we can likewise do the same for "while". You can't have it both ways: (1) if we can ignore the proceduralness of "for", then we can ignore the proceduralness of "while" and put it in a comprehension; (2) if we *cannot* ignore the proceduralness of "while", then we likewise cannot ignore the proceduralness of "for", therefore comprehensions are fundamentally procedural and that objection against "while" is neutered. There may be other objections against "while", but any that revolve around the declarativeness or non-proceduralness of comprehensions are logically invalid. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 18 01:09:37 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 15:09:37 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> Message-ID: <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 11:37 pm, Ben Bacarisse wrote: > What goes wrong when someone thinks of Python as passing by value but > the value of an expression is an object reference? Lots. Because even if people *think* about call by value where the value is an invisible reference to the actual value, that's not how they talk, because it's too hard. Look at Scott Stanchfield's extremely influential post. It is *not* called: "Java is call by value where the value is an invisible object reference, dammit!" http://javadude.com/articles/passbyvalue.htm and consequently people who don't read or understand the *entire* post in full take away the lesson that "Java is call by value, dammit!" So how do we distinguish between languages like Java and Python and those like C and Pascal which *genuinely* are call by value, and do exhibit call by value semantics? For example, in Pascal, if you declare an array parameter without specifying it as "var", the compiler will copy the entire array. Java does not do that. Python does not do that. C doesn't treat arrays as first class values, so you can't pass an array as argument. You can only pass a pointer to the start of the array. But you can declare arbitrarily big structs, and they are copied when you pass them to functions. Java objects are not. Despite Scott's insistence that Java is exactly the same as C, it isn't. If we claim that Python is call by value, without specifying the proviso "if you consider the value to be the invisible reference to the actual value" every time, we risk misleading others into wrongly inferring that Python is "call by value" and you shouldn't pass big lists to functions because then they will be copied and that's inefficient. Or people will be confused by the behaviour of Python, and decide that maybe it is only call by value when you pass an immutable object like a string or int, and is call by reference when you pass a mutable object like a list or dict. Many people have done that. Imagine this conversation: * * * "I was reviewing your code, and in module spam.py I don't understand what value the x variable has." "I don't know. It's something implementation dependent." "What do you mean?" "It depends on the interpreter. In CPython the value will be a pointer. Something like an address 0x1234abcd." "But Python doesn't have pointers." "Okay, call it a reference then. Whatever the implementation uses to point to objects." "I don't care about the Python implementation, I want to know the value of x." "I told you. It's some unknown and unknowable reference or pointer to an object." "Okay. Given x=1, what's the value of x?" "How do I know? It depends on the implementation. Something like 0x93a80f16 I guess. Why do you care about the value?" * * * Obviously this isn't going to happen. Nobody actually thinks like this. Given x=1, we all agree that the value of x is 1, not some invisible, unknown, unknowable, implementation-dependent reference. Instead they have to juggle two mutually contradictory meanings of value in their head, and try to guess which one is meant at any point. Sometimes the value of x is 1, and sometimes it is the invisible reference, and because that is usually implied rather than explicit, there's always room for confusion and misunderstanding. This whole thing is unnecessary. It is no easier to learn that: "Python is call by value, where the value is an invisible object reference" than it is to learn that: "Python is call by object sharing". Either way, you have to learn what it means, otherwise it might as well be gobbledygook: "Python is whargle bargle by wazit, where the wazit is fizzbit wacker p'toing". The terminology has been around for forty years. It was invented by Barbara Liskov, one of the pioneers of OOP, the same person responsible for the Liskov Substitution Principle. So its not like it is some obscure term invented by "just some guy on the internet". -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ian.g.kelly at gmail.com Fri Aug 18 01:12:06 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 23:12:06 -0600 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Thu, Aug 17, 2017 at 9:46 PM, John Nagle wrote: > The 0x9d thing seems unrelated to the Polish names thing. 0x9d > shows up in the middle of English text that's otherwise ASCII. > Is this something that can appear as a result of cutting and > pasting from Microsoft Word? > > I'd like to get 0x9d right, because it comes up a lot. The > Polish name thing is rare. There's only about a dozen of those > in 400MB of database dump. There are hundreds of 0x9d hits. > > Here's some more 0x9d usage, each from a different data item: > > > Guitar Pro, JamPlay, RedBana\\\'s Audition,\x9d Doppleganger\x99s The > Lounge\x9d or Heatwave Interactive\x99s Platinum Life Country,\\" This one seems like a good hint since \x99 here looks like it should be an apostrophe. But what character set has an apostrophe there? The best I can come up with is that 0xE2 0x80 0x99 is "right single quotation mark" in UTF-8. Also known as the "smart apostrophe", so it could have been entered by a word processor. The problem is that if that's what it is, then two out of the three bytes are outright missing. If the same thing happened to \x9d then who knows what's missing from it? One possibility is that it's the same two bytes. That would make it 0xE2 0x80 0x9D which is "right double quotation mark". Since it keeps appearing after ending double quotes that seems plausible, although one has to wonder why it appears *in addition to* the ASCII double quotes. > This has me puzzled. It's often, but not always after a close quote. > "TM" or "(R)" might make sense, but what non-Unicode character set > has those. And "green"(tm) makes no sense. CP-1252 has ? at \x99, perhaps coincidentally. CP-1252 and Latin-1 both have ? at \xae. From steve+python at pearwood.info Fri Aug 18 01:25:53 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 18 Aug 2017 15:25:53 +1000 Subject: What extended ASCII character set uses 0x9D? References: Message-ID: <59967a63$0$22141$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 10:14 am, John Nagle wrote: > I'm cleaning up some data which has text description fields from > multiple sources. Some are are in UTF-8. Some are in WINDOWS-1252. > And some are in some other character set. So I have to examine and > sanity check each field in a database dump, deciding which character > set best represents what's there. > > Here's a hard case: > > g1 = bytearray(b'\\"Perfect Gift Idea\\"\x9d Each time') py> unicodedata.name('\x9d'.decode('macroman')) 'LATIN SMALL LETTER U WITH GRAVE' Doesn't seem too likely. This may help: http://i18nqa.com/debug/bug-double-conversion.html There's always the possibility that it's just junk, or moji-bake from some other source, so it might not be anything sensible in any extended ASCII character set. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From ian.g.kelly at gmail.com Fri Aug 18 01:34:32 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 17 Aug 2017 23:34:32 -0600 Subject: Proposed new syntax In-Reply-To: <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 17, 2017 at 11:05 PM, Steve D'Aprano wrote: > On Fri, 18 Aug 2017 06:28 am, Ian Kelly wrote: >> "while" implies a condition that is currently true and may at some >> point stop being true. To me, that sequentiality does imply >> proceduralness. > > For loops and comprehensions (in Python) are inherently procedural, so it's a > good match. If you want to ignore the documented semantics of Python > comprehensions, their fundamental similarities to generator expressions, and > their actual behaviour, in order to say that they aren't procedural, that's > okay, it a free planet. (Sometimes.) > > But if you do that, then logically you must also allow that "while" is likewise > not procedural. Otherwise you're just showing a double-standard. I explained my logic here. You say that logically "while" is likewise not procedural, but you didn't explain what that logic is, so I have no idea what you're referring to. >> "for", to quote from Merriam-Webster, indicates "equivalence in >> exchange". A precise definition seems hard to nail down, but there's >> no such implication there. > > > Webster 1913 includes well over a dozen definitions for the word "for", so I'm > sure that Merrian-Webster would be similar. I don't know why you cherry picked > that one definition out of so many. "For" in the loop sense takes the meaning that it has in "for each" (hence why we sometimes call it a for-each loop). This is the only one that makes sense to me in that context. > I think this is more appropriate: > > 8. Indicating the space or time through which an action or > state extends; hence, during; in or through the space or > time of. The example phrase for that one is "gone for two days". I don't see how you can possibly interpret this in the sense of a for-each loop. > "for x in seq" indicates that x extends through the space of seq, in a manner of > speaking. No, given the definition above, it would indicate that something extends through the space of x. Again, this makes zero sense to me. > Or for something more recent, and more relevant, how about foldoc, the Free > On-line Dictionary of Computing? Completely misses the point of consulting the dictionary in the first place. We were discussing the implications of the use of the English definition. A technical computing definition is irrelevant. > But if we can do that, we can likewise do the same for "while". Okay, I'm waiting. What is your proposed "non-procedural" definition of "while"? > You can't have it both ways: > > (1) if we can ignore the proceduralness of "for", then we can ignore the > proceduralness of "while" and put it in a comprehension; > > (2) if we *cannot* ignore the proceduralness of "while", then we likewise cannot > ignore the proceduralness of "for", therefore comprehensions are fundamentally > procedural and that objection against "while" is neutered. This claim is absurd. They're *different words* with different definitions and entirely different connotations. They're not even the same part of speech. You might as well be saying that if we can ignore that "swim" is a color, then we can also ignore that "red" is a color. From pavol.lisy at gmail.com Fri Aug 18 01:56:56 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Fri, 18 Aug 2017 07:56:56 +0200 Subject: Proposed new syntax In-Reply-To: <87a82y3pzs.fsf@elektro.pacujo.net> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <85fuczjaws.fsf@benfinney.id.au> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <87a82y3pzs.fsf@elektro.pacujo.net> Message-ID: On 8/17/17, Marko Rauhamaa wrote: > Pavol Lisy : > >> On 8/17/17, Gregory Ewing wrote: >>> I don't agree that the word "for" necessarily implies proceduralness. >> >> With this logic (I humbly think that) word "while" neither >> necessarilly implies proceduralness. > > I don't see the logic. > > Here's a random page from an algebra textbook: > > A sequence {a[n]} is called *bounded* if there is some real number b, > a *bound*, such that |a[n]| ? b for all n. > > > Z = {(a) ? ?**? | a[n] = 0 for all but finitely many n } > > On another one: > > = 0 if i ? j, and = 1 for each i > > > And: > > For every value a of the variable x, there are at most n points of S > whose x-coordinate is a. > > > Marko > -- > https://mail.python.org/mailman/listinfo/python-list I meant while "implemented" like this (N is set of natural numbers) -> { n ? N | condition(m) for all m <= n } or more correctly: { n ? N | condition(m) for all m ? { o ? N | o <= n } } From no.email at nospam.invalid Fri Aug 18 02:16:00 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 17 Aug 2017 23:16:00 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> Message-ID: <871so9qu3j.fsf@nightsong.com> Steve D'Aprano writes: > For loops and comprehensions (in Python) are inherently procedural, Sure, and floating point arithmetic is inherently imprecise and doesn't follow the associative laws for either addition or multiplication. There are times when we have to be aware of those details. Usually, though, we want to act as if they represent the mathematical reals, and we read Python statements involving floats as if they were mathematical statements involving reals. When possible, we write in a style where this doesn't cause problems, use double precision to decrease rounding errors in long calculations, etc. Similarly we occasionally have to be aware of the procedural nature of Python list comprehensions, but most of the time we think of them in terms of the mathematical abstraction they are designed to resemble. From nagle at animats.com Fri Aug 18 02:24:58 2017 From: nagle at animats.com (John Nagle) Date: Thu, 17 Aug 2017 23:24:58 -0700 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On 08/17/2017 10:12 PM, Ian Kelly wrote: >> Here's some more 0x9d usage, each from a different data item: >> >> >> Guitar Pro, JamPlay, RedBana\\\'s Audition,\x9d Doppleganger\x99s The >> Lounge\x9d or Heatwave Interactive\x99s Platinum Life Country,\\" > > This one seems like a good hint since \x99 here looks like it should > be an apostrophe. But what character set has an apostrophe there? The > best I can come up with is that 0xE2 0x80 0x99 is "right single > quotation mark" in UTF-8. Also known as the "smart apostrophe", so it > could have been entered by a word processor. > > The problem is that if that's what it is, then two out of the three > bytes are outright missing. If the same thing happened to \x9d then > who knows what's missing from it? > > One possibility is that it's the same two bytes. That would make it > 0xE2 0x80 0x9D which is "right double quotation mark". Since it keeps > appearing after ending double quotes that seems plausible, although > one has to wonder why it appears *in addition to* the ASCII double > quotes. I was wondering if it was a signal to some word processor to apply smart quote handling. >> This has me puzzled. It's often, but not always after a close quote. >> "TM" or "(R)" might make sense, but what non-Unicode character set >> has those. And "green"(tm) makes no sense. > > CP-1252 has ? at \x99, perhaps coincidentally. CP-1252 and Latin-1 > both have ? at \xae. That's helpful. All those text snippets failed Windows-1252 decoding, though, because 0x9d isn't in Windows-1252. I'm coming around to the idea that some of these snippets have been previously mis-converted, which is why they make no sense. Since, as someone pointed out, there was UTF-8 which had been run through an ASCII-type lower casing algorithm, that's a reasonable assumption. Thanks for looking at this, everyone. If a string won't parse as either UTF-8 or Windows-1252, I'm just going to convert the bogus stuff to the Unicode replacement character. I might remove 0x9d chars, since that never seems to affect readability. John Nagle From rosuav at gmail.com Fri Aug 18 02:31:29 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 16:31:29 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On Fri, Aug 18, 2017 at 4:24 PM, John Nagle wrote: > I'm coming around to the idea that some of these snippets > have been previously mis-converted, which is why they make no sense. > Since, as someone pointed out, there was UTF-8 which had been > run through an ASCII-type lower casing algorithm, that's a reasonable > assumption. Thanks for looking at this, everyone. If a string won't > parse as either UTF-8 or Windows-1252, I'm just going to convert the > bogus stuff to the Unicode replacement character. I might remove > 0x9d chars, since that never seems to affect readability. That sounds like a good plan. Unless you can pin down a single coherent encoding (even a broken one, like "UTF-8, then add 32 to everything between 0xC1 and 0xDA"), all you have is decoding individual strings. There just isn't enough context to do anything smarter than flipping unparseable bytes to U+FFFD. ChrisA From no.email at nospam.invalid Fri Aug 18 02:38:21 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 17 Aug 2017 23:38:21 -0700 Subject: What extended ASCII character set uses 0x9D? References: Message-ID: <87wp61pehu.fsf@nightsong.com> John Nagle writes: > Since, as someone pointed out, there was UTF-8 which had been > run through an ASCII-type lower casing algorithm I spent a few minutes figuring out if some of the mysterious 0x81's could be from ASCII-lower-casing some Unicode combining characters, but the numbers didn't seem to work out. Might still be worth looking for in some other cases. From rosuav at gmail.com Fri Aug 18 02:49:26 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 16:49:26 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: <87wp61pehu.fsf@nightsong.com> References: <87wp61pehu.fsf@nightsong.com> Message-ID: On Fri, Aug 18, 2017 at 4:38 PM, Paul Rubin wrote: > John Nagle writes: >> Since, as someone pointed out, there was UTF-8 which had been >> run through an ASCII-type lower casing algorithm > > I spent a few minutes figuring out if some of the mysterious 0x81's > could be from ASCII-lower-casing some Unicode combining characters, but > the numbers didn't seem to work out. Might still be worth looking for > in some other cases. They can't be from anything like that. Lower-casing in ASCII consists of adding 32 (or setting the fifth bit) on certain byte/character values. Subtracting 32 from 0x81 gives 0x61 which is lower-case letter 'a'; the fifth bit isn't set in 0x81. So there's no way that UTF-8 + dumb lowercasing could give you 0x81. ChrisA From marko at pacujo.net Fri Aug 18 02:55:07 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 18 Aug 2017 09:55:07 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> Message-ID: <87shgp2wms.fsf@elektro.pacujo.net> Paul Rubin : > Steve D'Aprano writes: >> For loops and comprehensions (in Python) are inherently procedural, > > Sure, and floating point arithmetic is inherently imprecise and > doesn't follow the associative laws for either addition or > multiplication. There are times when we have to be aware of those > details. Usually, though, we want to act as if they represent the > mathematical reals, and we read Python statements involving floats as > if they were mathematical statements involving reals. Nothing prevents you from using Python's comprehensions that declarative way. The question is, is it bad style?or even an error?to rely on the execution order of the comprehension loops? Is a Python implementation allowed to parallelize or otherwise reorder the evaluation loop? Unfortunately, the spec is rather vague: they are computed via a set of looping and filtering instructions [...] the elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached. Thus, the scholastic debate may rage on. > Similarly we occasionally have to be aware of the procedural nature of > Python list comprehensions, but most of the time we think of them in > terms of the mathematical abstraction they are designed to resemble. I understand your concern. With the introduction of a "while" in the syntax, the beautiful illusion would be shattered. However, I think the concept of a generator expression is more fundamental in Pythonic thinking. Also, since Python has chosen to specify the precize execution order in: { f(g(), h()) * k() : z() } I would think comprehensions would be put in a similar straitjacket. Marko From marko at pacujo.net Fri Aug 18 02:57:06 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 18 Aug 2017 09:57:06 +0300 Subject: What extended ASCII character set uses 0x9D? References: <87wp61pehu.fsf@nightsong.com> Message-ID: <87o9rd2wjh.fsf@elektro.pacujo.net> Chris Angelico : > On Fri, Aug 18, 2017 at 4:38 PM, Paul Rubin wrote: >> John Nagle writes: >>> Since, as someone pointed out, there was UTF-8 which had been >>> run through an ASCII-type lower casing algorithm >> >> I spent a few minutes figuring out if some of the mysterious 0x81's >> could be from ASCII-lower-casing some Unicode combining characters, >> but the numbers didn't seem to work out. Might still be worth looking >> for in some other cases. > > They can't be from anything like that. Lower-casing in ASCII consists > of adding 32 (or setting the fifth bit) on certain byte/character > values. How about lower-casing? Marko From rosuav at gmail.com Fri Aug 18 03:06:36 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 17:06:36 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: <87o9rd2wjh.fsf@elektro.pacujo.net> References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 18, 2017 at 4:57 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Fri, Aug 18, 2017 at 4:38 PM, Paul Rubin wrote: >>> John Nagle writes: >>>> Since, as someone pointed out, there was UTF-8 which had been >>>> run through an ASCII-type lower casing algorithm >>> >>> I spent a few minutes figuring out if some of the mysterious 0x81's >>> could be from ASCII-lower-casing some Unicode combining characters, >>> but the numbers didn't seem to work out. Might still be worth looking >>> for in some other cases. >> >> They can't be from anything like that. Lower-casing in ASCII consists >> of adding 32 (or setting the fifth bit) on certain byte/character >> values. > > How about lower-casing? Huh? ChrisA From marko at pacujo.net Fri Aug 18 03:11:48 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 18 Aug 2017 10:11:48 +0300 Subject: What extended ASCII character set uses 0x9D? References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> Message-ID: <87efs92vuz.fsf@elektro.pacujo.net> Chris Angelico : > On Fri, Aug 18, 2017 at 4:57 PM, Marko Rauhamaa wrote: >> Chris Angelico : >> >>> On Fri, Aug 18, 2017 at 4:38 PM, Paul Rubin wrote: >>>> John Nagle writes: >>>>> Since, as someone pointed out, there was UTF-8 which had been >>>>> run through an ASCII-type lower casing algorithm >>>> >>>> I spent a few minutes figuring out if some of the mysterious 0x81's >>>> could be from ASCII-lower-casing some Unicode combining characters, >>>> but the numbers didn't seem to work out. Might still be worth looking >>>> for in some other cases. >>> >>> They can't be from anything like that. Lower-casing in ASCII consists >>> of adding 32 (or setting the fifth bit) on certain byte/character >>> values. >> >> How about lower-casing? > > Huh? s/lower/upper/ Marko From jfong at ms4.hinet.net Fri Aug 18 03:22:04 2017 From: jfong at ms4.hinet.net (jfong at ms4.hinet.net) Date: Fri, 18 Aug 2017 00:22:04 -0700 (PDT) Subject: Call a class A method from a class B instance? Do I miss something? In-Reply-To: References: Message-ID: Ian? 2017?8?18???? UTC+8??10?41?44???? > On Thu, Aug 17, 2017 at 6:03 PM, wrote: > > I study some codes of a tutorial about tkinter (https://github.com/daleathan/widget-tour-py3) and can't figure out how it works. > > > > Below is the codes from its two major files: > > ---------------------------- > > # file infrastructure.py > > ... > > ... > > class callit: > > def __init__(self, function, *args ): > > self.f = function > > > > self.args = args > > > > > > def __call__(self, *ignored): > > self.f(*self.args) > > > > ... > > > > ------------------------ > > # file widget.py > > ... > > from infrastructure import * > > ... > > class DemoMainWindow(Frame): > > ... > > def _fill_textarea(self): > > ... > > # bind events > > self.text.tag_bind(tag, '', > > > > callit(self.demoenter_callback, tag) ) > > ... > > > > def demoenter_callback(self, tag): > > ... > > self.text.configure(cursor='hand2') > > ... > > > > ---------------------- > > My question is that the object which was left by callit(self.demoenter_callback, tag) is a callit instance, and the method it calls is a DemoMainWindow's method. > > How it is possible? > > Methods are just functions with a bit of magic [1] that binds the self > argument to them. > > DemoMainWindow.demoenter_callback is an unbound method object > (although in Python 3, it's just an ordinary function). When > self.demoenter_callback is evaluated, the result is not the same > unbound method object. Instead you get a different *bound* method > object, which binds the self argument to the DemoMainWindow instance. > The important point is that this binding happens when > self.demoenter_callback is evaluated, not when the method is called. > > This bound method object gets passed to the callit object, which saves > it as self.f. Later, it calls self.f() which calls the method that is > still bound to the same DemoMainWindow instance. Note that evaluating > self.f does not *rebind* the method object. Bound method objects never > get rebound; they are only created from unbound methods. > > So when self.f() is called the bound DemoMainWindow instance is used > as the value of the self argument. The fact that it was actually > called from a method of callit doesn't matter. > > [1] This magic is called the descriptor protocol, and if you want to > play with it you can use it to create your own method types! This is a > topic usually presented to intermediate-level Python programmers. Thank you for your explaination about the bound/unbound method. I had read them in various document many times before but never pay attention to it becasue it seems didn't matter much in real world coding. >The important point is that this binding happens when >self.demoenter_callback is evaluated, not when the method is called. All I had learned about the "self" argument is that it's a hidden argument and was passed as the first argument at the time when method was called, never though it can be used to "bind" a method alone. It's completely new to me. >So when self.f() is called the bound DemoMainWindow instance is used >as the value of the self argument. The fact that it was actually >called from a method of callit doesn't matter. It seems there is a hard homework waiting for me. Any hint? --Jach From jfong at ms4.hinet.net Fri Aug 18 03:25:20 2017 From: jfong at ms4.hinet.net (jfong at ms4.hinet.net) Date: Fri, 18 Aug 2017 00:25:20 -0700 (PDT) Subject: Call a class A method from a class B instance? Do I miss something? In-Reply-To: References: Message-ID: Rick Johnson at 2017/8/18 UTC+8 AM 11:43:06 wrote: > jf... at ms4.hinet.net wrote: > > I study some codes of a tutorial about tkinter > > > > [snip code] > > > > My question is that the object which was left by > > callit(self.demoenter_callback, tag) is a callit instance, > > and the method it calls is a DemoMainWindow's method. How > > it is possible? > > Why would it _not_ be possible? Functions are first class > objects, after all. Google it. > > All the code is doing here is passing around a function > reference and argument list like a baton in a foot race. No > real magic here, just a lot of academic smoke and mirrors > really. Or maybe this is more like a rat maze? Or a hot > potato? Opinions may vary... > > But short of obfuscation for the _sake_ of obfuscation, i > don't understand what the tutorial author is intending to > teach you here. Sheesh, the same goal could be achieved much > more clearly by wrapping the argument-laden callback in an > anonymous function or using a functools.partial, as the > _true_goal_ here is to avoid premature execution of the > argument-laden callback. > > I absolutely detest superfluity! > > -- According to the explanation above Ian had done, this method was already bound by "self". To set my mind ease, I follow your suggestion and implement a closure to replace the class: def callit(function, *args): def inner(*ignored): return function(*args) return inner or even a lambda to get rid of callit: lambda *ignored, a=tag: self.demoenter_callback(a) I didn't try functools.partial but I think it will work too. Thanks for your point of view. --Jach From rosuav at gmail.com Fri Aug 18 03:25:35 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 17:25:35 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: <87efs92vuz.fsf@elektro.pacujo.net> References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 18, 2017 at 5:11 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Fri, Aug 18, 2017 at 4:57 PM, Marko Rauhamaa wrote: >>> Chris Angelico : >>> >>>> On Fri, Aug 18, 2017 at 4:38 PM, Paul Rubin wrote: >>>>> John Nagle writes: >>>>>> Since, as someone pointed out, there was UTF-8 which had been >>>>>> run through an ASCII-type lower casing algorithm >>>>> >>>>> I spent a few minutes figuring out if some of the mysterious 0x81's >>>>> could be from ASCII-lower-casing some Unicode combining characters, >>>>> but the numbers didn't seem to work out. Might still be worth looking >>>>> for in some other cases. >>>> >>>> They can't be from anything like that. Lower-casing in ASCII consists >>>> of adding 32 (or setting the fifth bit) on certain byte/character >>>> values. >>> >>> How about lower-casing? >> >> Huh? > > s/lower/upper/ Ohh. We have no evidence that uppercasing is going on here, and a naive ASCII upper-casing wouldn't produce 0x81 either - if it did, it would also convert 0x21 ("!") into 0x01 (SOH, a control character). So this one's still a mystery. ChrisA From no.email at nospam.invalid Fri Aug 18 03:36:22 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Fri, 18 Aug 2017 00:36:22 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> <87shgp2wms.fsf@elektro.pacujo.net> Message-ID: <87mv6xgweh.fsf@nightsong.com> Marko Rauhamaa writes: > The question is, is it bad style?or even an error?to rely on the > execution order of the comprehension loops? Bad style: IMO, yes, most of the time. I've made use of it at particular times. If it's done in an obscure way it at least deserves a code commment. Error: no, I think the language spec is clear. It's not like the situation of people depending on reference counting to free resources predictably. Use the 'with' statement for that. > Is a Python implementation allowed to parallelize or otherwise reorder > the evaluation loop? No. From marko at pacujo.net Fri Aug 18 03:39:34 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Fri, 18 Aug 2017 10:39:34 +0300 Subject: What extended ASCII character set uses 0x9D? References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> Message-ID: <8760dl2ukp.fsf@elektro.pacujo.net> Chris Angelico : > Ohh. We have no evidence that uppercasing is going on here, and a > naive ASCII upper-casing wouldn't produce 0x81 either - if it did, it > would also convert 0x21 ("!") into 0x01 (SOH, a control character). So > this one's still a mystery. BTW, I was reading up on the history of ASCII control characters. Quite fascinating. For example, have you ever wondered why DEL is the odd control character out at the code point 127? The reason turns out to be paper punch tape. By backstepping and punching a DEL over the previous ASCII character you can "rub out" the character. (I got interested in the control characters after reading the sad spec RFC 7464.) Marko From rosuav at gmail.com Fri Aug 18 03:45:52 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 18 Aug 2017 17:45:52 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: <8760dl2ukp.fsf@elektro.pacujo.net> References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> <8760dl2ukp.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 18, 2017 at 5:39 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> Ohh. We have no evidence that uppercasing is going on here, and a >> naive ASCII upper-casing wouldn't produce 0x81 either - if it did, it >> would also convert 0x21 ("!") into 0x01 (SOH, a control character). So >> this one's still a mystery. > > BTW, I was reading up on the history of ASCII control characters. Quite > fascinating. > > For example, have you ever wondered why DEL is the odd control character > out at the code point 127? The reason turns out to be paper punch tape. > By backstepping and punching a DEL over the previous ASCII character you > can "rub out" the character. Yeah. Bvvvvvvvp, no more character there :) I'm not old enough to have actually worked with those technologies (although I do have a punched card somewhere around, being used as a bookmark), but a lot of them have influenced the standards that we still use, so it's well worth studying the history! ChrisA From python at mrabarnett.plus.com Fri Aug 18 05:58:15 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 18 Aug 2017 10:58:15 +0100 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: <85636751-5f7d-f120-c8e2-58737c59d394@mrabarnett.plus.com> On 2017-08-18 04:46, John Nagle wrote: > On 08/17/2017 05:53 PM, Chris Angelico wrote:> On Fri, Aug 18, 2017 at > 10:30 AM, John Nagle wrote: > >> On 08/17/2017 05:14 PM, John Nagle wrote: > >>> I'm cleaning up some data which has text description fields from > >>> multiple sources. > >> A few more cases: > >> > >> bytearray(b'\xe5\x81ukasz zmywaczyk') > > > > This one has to be Polish, and the first character should be the > > letter ? U+0141 or ? U+0142. In UTF-8, U+0141 becomes C5 81, which is > > very similar to the E5 81 that you have. > > > > So here's an insane theory: something attempted to lower-case the byte > > stream as if it were ASCII. If you ignore the high bit, 0xC5 looks > > like 0x45 or "E", which lower-cases by having 32 added to it, yielding > > 0xE5. Reversing this transformation yields sane data for several of > > your strings - they then decode as UTF-8: > > > > miguel ?ngel santos > > lidija kmeti? > > ?ukasz zmywaczyk > > ji?? urban??k > > ?ubom?r mi?ko > > petr urban??k > > I think you're right for those. I'm working from a MySQL dump of > supposedly LATIN-1 data, but LATIN-1 will accept anything. I've > found UTF-8 and Windows-2152 in there. It's quite possble that someone > lower-cased UTF-8 stored in a LATIN-1 field. There are lots of > questions on the web which complain about getting a Python decode error > on 0x9d, and the usual answer is "Use Latin-1". But that doesn't really > decode properly, it just doesn't generate an exception. > > > That doesn't work for everything, though. The 0x81 0x81 and 0x9d ones > > are still a puzzle. > > The 0x9d thing seems unrelated to the Polish names thing. 0x9d > shows up in the middle of English text that's otherwise ASCII. > Is this something that can appear as a result of cutting and > pasting from Microsoft Word? > > I'd like to get 0x9d right, because it comes up a lot. The > Polish name thing is rare. There's only about a dozen of those > in 400MB of database dump. There are hundreds of 0x9d hits. > > Here's some more 0x9d usage, each from a different data item: > > > Guitar Pro, JamPlay, RedBana\\\'s Audition,\x9d Doppleganger\x99s The > Lounge\x9d or Heatwave Interactive\x99s Platinum Life Country,\\" > > for example \\"I\\\'ve seen the bull run in Pamplona, Spain\x9d.\\" > Everything > > Netwise Depot is a \\"One Stop Web Shop\\"\x9d that provides > > sustainable \\"green\\"\x9d living > > are looking for a \\"Do It for Me\\"\x9d solution > > > This has me puzzled. It's often, but not always after a close quote. > "TM" or "(R)" might make sense, but what non-Unicode character set > has those. And "green"(tm) makes no sense. > I googled for """Netwise Depot is a""" and found this page: https://www.crunchbase.com/organization/netwise-depot#/entity It has the text: Netwise Depot is a "One Stop Web Shop"? that provides a holistic solution Put that through the ascii function and you get: 'Netwise Depot is a "One Stop Web Shop"\x9d that provides a holistic solution' OK. Try another one. Google for """Guitar Pro, JamPlay, RedBana""": https://www.crunchbase.com/organization/the-rights-workshop#/entity""" Look familiar? That page has: Guitar Pro, JamPlay, RedBana's Audition, Doppleganger?s Is that where the data comes from? From rustompmody at gmail.com Fri Aug 18 08:36:12 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Fri, 18 Aug 2017 05:36:12 -0700 (PDT) Subject: A question on modification of a list via a function invocation In-Reply-To: <599659e8$0$1620$c3e8da3$5496439d@news.astraweb.com> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> <7b67047d-7d59-4856-9fd4-5824f0608aff@googlegroups.com> <599659e8$0$1620$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Friday, August 18, 2017 at 8:37:43 AM UTC+5:30, Steve D'Aprano wrote: > On Thu, 17 Aug 2017 11:19 pm, Rustom Mody wrote: > > > What is called ?call-by-object? or ?call-by-sharing? etc is really an > > acknowledgement of the fact that parameter passing in the OO world along with > > permissible mutation of data-structures is inherently leaky > > > Leaky of *what*? > > What do you think the abstraction is that is leaky? > > Call by value leaks. The abstraction is that the argument received by the > function is independent from the value you pass in. But the leak happens when > you pass an array with a billion items, and the compiler makes a copy of the > entire array, and you wonder why you run out of memory. > > Call by reference leaks. The abstraction is that the argument received by the > function is the argument you pass to the function. Not just the same, in the > sense of equal, but one-and-the-same. As in, "me myself and I" all refer to the > same person. But the leak happens when you try to pass a literal or a constant > or the result of an expression, rather than a variable, and the compiler > says "Uh uh, you can't do that!" > > So what abstraction do you think call by object sharing is making, and in what > way does it leak? Data Dependency ? also called coupling ? is generally considered to be deleterious to software quality | The presence of pointers causes complex data-dependence | relationships. Because of pointers and aliasing, it may not be possible to | identify unambiguously the variable that is actually defined (resp., used) at a | statement containing a definition (resp., use). https://www.cc.gatech.edu/~orso/papers/orso.sinha.harrold.IWPC01.pdf Python removes the frank pointers of C (like) languages It does nothing about aliasing Sharing-by-object is nothing more than the diginification of aliasing From rustompmody at gmail.com Fri Aug 18 09:46:58 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Fri, 18 Aug 2017 06:46:58 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: There is code and there are machines There are Turing machines and Universal Turing machines There are programs and there are programming languages There are (il)legal programs and best/worst (software engineering) practices As best as I can see most of us are talking of the respective latters above while Steven insists on taking this whole discussion exclusively in terms of the formers Picked up some quotes from the thread above and ALLCAPSed the phrases that would hopefully show the difference Paul writes > Sure, and floating point arithmetic is inherently imprecise and > doesn't follow the associative laws for either addition or > multiplication. There are times when we have to be aware of those > details. Usually, though, WE WANT TO ACT AS IF they represent the > mathematical reals, and we read Python statements involving floats as > if they were mathematical statements involving reals. Marko Rauhamaa writes: > Nothing prevents you from using Python's comprehensions that declarative > way. THE QUESTION IS, IS IT BAD STYLE?OR EVEN AN ERROR?to rely on the > execution order of the comprehension loops? Is a Python implementation > allowed to parallelize or otherwise reorder the evaluation loop? Greg Ewing writes: > Perhaps what I should say is that relying on side effects in > an expression occurring in a particular order IS A BAD IDEA. (not wrong) Ben Finney writes: At what point will you accept the feedback: That the comprehension syntax *does not* necessarily CONNOTE (not denote) a procedural loop, but instead can quite REASONABLY (not guaranteedly/necessarily) be interpreted as its designer intended, a single conceptual operation. I just want to emphasise that (for myself) Ive no quarrel with the current semantics My issue is that the tutorial introduces comprehensions backwards, as though they are a macro for the for-loop https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions Compare the well-known haskell tutorial http://learnyouahaskell.com/starting-out whose comprehension intro starts: | If you've ever taken a course in mathematics, you've probably run into set | comprehensions. They're normally used for building more specific sets out of | general sets. A basic comprehension for a set that contains the first ten even | natural numbers is | S = {2?x | x ? ?, x ? 10} Analogous thing shown at ghci prompt: | ghci> [x*2 | x <- [1..10]] | [2,4,6,8,10,12,14,16,18,20] From ben.usenet at bsb.me.uk Fri Aug 18 10:04:37 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 18 Aug 2017 15:04:37 +0100 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87y3qhgefe.fsf@bsb.me.uk> Steve D'Aprano writes: > On Thu, 17 Aug 2017 11:37 pm, Ben Bacarisse wrote: > >> What goes wrong when someone thinks of Python as passing by value but >> the value of an expression is an object reference? This seems to be a hot-button topic so I'd like to try to cool it off a bit. To in that spirit I'll point out that I'm not advocating teaching "the wrong way to think about things", I'm asking if that model, universally applied, actually leads to misunderstanding Python. > Lots. > > Because even if people *think* about call by value where the value is an > invisible reference to the actual value, that's not how they talk, because it's > too hard. People will drop the word reference (I prefer identity) on occasion but then they are always going to take shortcuts. > Look at Scott Stanchfield's extremely influential post. It is *not* > called: > > "Java is call by value where the value is an invisible object reference, > dammit!" > > http://javadude.com/articles/passbyvalue.htm > > and consequently people who don't read or understand the *entire* post in full > take away the lesson that > > "Java is call by value, dammit!" I don't think this is a fair point. You will run out of ideas if they are to be avoided because some people will get the wrong idea when reading part of a description of that idea applied to some other language. > So how do we distinguish between languages like Java and Python and > those like C and Pascal which *genuinely* are call by value, and do > exhibit call by value semantics? For example, in Pascal, if you > declare an array parameter without specifying it as "var", the > compiler will copy the entire array. Java does not do that. Python > does not do that. Well, I know how I do that but you are not a fan of that view. I found it a helpful view because it covers a lot more than just argument passing by saying something about the set of values that Python expressions manipulate. It may be wrong in some case (hence my question) but I don't think I've been led astray by it (so far!). > C doesn't treat arrays as first class values, so you can't pass an array as > argument. You can only pass a pointer to the start of the array. But you can > declare arbitrarily big structs, and they are copied when you pass them to > functions. Java objects are not. Despite Scott's insistence that Java is > exactly the same as C, it isn't. I'm not here to defend someone else's incorrect statements! Clearly C is not the same as Java. Equally clearly, C only passes arguments by value (I have no idea about Java). > If we claim that Python is call by value, without specifying the > proviso "if you consider the value to be the invisible reference to > the actual value" every time, we risk misleading others into wrongly > inferring that Python is "call by value" and you shouldn't pass big > lists to functions because then they will be copied and that's > inefficient. True, though I obviously take issue with using a particularly long-winded phrase. See later for how Liskov does it with one short word. The core of the idea is actually what the value-set of Python programs is -- the passing by value just drops out of that. Talking about object identities (or references) is not so very cumbersome. You have to talk about *something* like that explain the language, don't you? > Or people will be confused by the behaviour of Python, and decide that maybe it > is only call by value when you pass an immutable object like a string or int, > and is call by reference when you pass a mutable object like a list or dict. > Many people have done that. I'm not a fan of this notion that an idea is bad because it goes wrong when people don't understand it. I don't think any description of Python's semantics can avoid that trap. > Imagine this conversation: > > * * * > > "I was reviewing your code, and in module spam.py I don't understand what value > the x variable has." > > "I don't know. It's something implementation dependent." > > "What do you mean?" > > "It depends on the interpreter. In CPython the value will be a pointer. > Something like an address 0x1234abcd." > > "But Python doesn't have pointers." > > "Okay, call it a reference then. Whatever the implementation uses to point to > objects." > > "I don't care about the Python implementation, I want to know the value of x." > > "I told you. It's some unknown and unknowable reference or pointer to an > object." > > "Okay. Given x=1, what's the value of x?" > > "How do I know? It depends on the implementation. Something like 0x93a80f16 I > guess. Why do you care about the value?" > > > * * * > > Obviously this isn't going to happen. Nobody actually thinks like > this. No, I should hope not! > Given > x=1, we all agree that the value of x is 1, not some invisible, unknown, > unknowable, implementation-dependent reference. > > Instead they have to juggle two mutually contradictory meanings of value in > their head, and try to guess which one is meant at any point. Sometimes the > value of x is 1, and sometimes it is the invisible reference, and because that > is usually implied rather than explicit, there's always room for confusion and > misunderstanding. > > This whole thing is unnecessary. It is no easier to learn that: > > "Python is call by value, where the value is an invisible object reference" > > than it is to learn that: > > "Python is call by object sharing". I'm not advocating the former because I want to say more than just what values get passed, and the latter does not explain some other cases that confuse people new to the language such as x = [[1]] y = x x[0][0] = 42 I find that keeping in mind (despite the odd shortcut I may make) that all these values really just /refer/ to objects helps me. > Either way, you have to learn what it means, otherwise it might as well be > gobbledygook: > > "Python is whargle bargle by wazit, where the wazit is fizzbit wacker p'toing". > > > The terminology has been around for forty years. It was invented by > Barbara Liskov, one of the pioneers of OOP, the same person > responsible for the Liskov Substitution Principle. So its not like it > is some obscure term invented by "just some guy on the internet". Yes I know. I had the pleasure of talking programming languages with her once -- scary bright person! Liskov on CLU: x := e causes x to refer to the object obtained by evaluating expression e. Not the "refer". That's all it takes. The value of x is not the object, x /refers/ to the object. And on calling: ... arguments are passed "by object"; the (pointer to the) object resulting from evaluating the actual argument expression is assigned to the formal. (Thus passing a parameter is just doing an assignment to the formal.) I think this is true of Python too. If so, I'd be tempted to define passing "as if by assignment" (as it's done in the C standard) and make the semantics of assignment the basic feature that needs to be described. Finally, from the Python tutorial[1] "... arguments are passed using call by value (where the value is always an object reference, not the value of the object)." Maybe I got it from there and generalised a little. I would not want to see that remark removed (because, if that's where I got it from, it helped me), but maybe it is now doomed. [1] https://docs.python.org/3/tutorial/controlflow.html#defining-functions -- Ben. From grant.b.edwards at gmail.com Fri Aug 18 10:23:07 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 18 Aug 2017 14:23:07 +0000 (UTC) Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> Message-ID: On 2017-08-17, Ben Bacarisse wrote: > What goes wrong when someone thinks of Python as passing by value but > the value of an expression is an object reference? What usually goes wrong is that people don't combined that thinking with an understanding of what the "=" operator does. -- Grant Edwards grant.b.edwards Yow! HUMAN REPLICAS are at inserted into VATS of gmail.com NUTRITIONAL YEAST ... From rosuav at gmail.com Fri Aug 18 10:59:36 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 19 Aug 2017 00:59:36 +1000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 18, 2017 at 11:46 PM, Rustom Mody wrote: > Compare the well-known haskell tutorial > http://learnyouahaskell.com/starting-out > whose comprehension intro starts: > > | If you've ever taken a course in mathematics, you've probably run into set > | comprehensions. They're normally used for building more specific sets out of > | general sets. A basic comprehension for a set that contains the first ten even | natural numbers is > > | S = {2?x | x ? ?, x ? 10} > > Analogous thing shown at ghci prompt: > > | ghci> [x*2 | x <- [1..10]] > | [2,4,6,8,10,12,14,16,18,20] And what if you HAVEN'T taken a course in mathematics? What use is this then? How would you teach this to a non-mathematician? Pretty much everyone, at some point in their lives, will follow a set of written instructions. Most commonly, a recipe for some sort of food. It consists of a set of ingredients and a sequence of commands. This translates well into a classic imperative style - for instance: Ingredients. 100 g flour 250 g butter 1 egg Method. 1. Sift the flour. 2. Put flour into mixing bowl. 3. Serve with caramel sauce. 4. Stir for 2 minutes. 5. Remove egg. 6. Rub the flour until sifted. 7. Stir for 2 minutes. 8. Fold the butter into the mixing bowl. 9. Pour contents of the mixing bowl into the baking dish. Serves 1. You might recognize that this is a part of a recipe for Fibonacci numbers [1], but aside from a few tricky instructions like "remove egg", it's no worse than a recipe for chocolate ripple cake [2]: Ingredients 300g Chocolate Ripple biscuits 600mL thickened cream (for whipping) 1tsp vanilla essence Sugar (?some?) 6-12 Lindor balls (to taste) Rectangular plate/dish to work on (about the size of the packet of biscuits) Directions 1. Collect ingredients. Read all the instructions and comprehend them. 2. Open the packet of chocolate biscuits. Find a broken one and eat it. 3. Taste a Lindor ball. 4. Whip the cream in a jug with plenty of room. 5. Add some sugar to the cream. If you have chocolate-flavoured sugar, use it. ... etc ... Anyone who's worked with this kind of recipe will have no difficulty understanding the concept of imperative code. # Ingredients import math num = 42 # Mixing bowl guess = 1 # Method while not done: guess = num / guess if guess hasn't changed: done is True print num to the screen And apart from a small matter of syntax and a need to break down the concept "hasn't changed" into another variable and a comparison, this is valid Python code. Valid *imperative* code. It's the one thing that practically everyone, not just those elite few who actually comprehend higher mathematics, can easily grok. ChrisA [1] http://www.dangermouse.net/esoteric/chef_fib.html [2] http://rosuav.github.io/shed/ChocRippleCake From rosuav at gmail.com Fri Aug 18 11:02:57 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 19 Aug 2017 01:02:57 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> Message-ID: On Sat, Aug 19, 2017 at 12:43 AM, Stefan Ram wrote: > Ben Bacarisse writes: >>Steve D'Aprano writes: >>>"Java is call by value, dammit!" >>I don't think this is a fair point. You will run out of ideas if they >>are to be avoided because some people will get the wrong idea when >>reading part of a description of that idea applied to some other language. > > You are trying to cool off the topic. An expression such as > "da...t!" should be avoided in a cold topic. But otherwise, > "Java is call by value." is just fine. > > The rest has nothing to do with calls, but with expressions. > > What happens in Java (Python and JavaScript are similar), > when this piece of code is executed? > > { final java.lang.Object object = new java.lang.Object(); > java.lang.System.out.println( object ); } > > In C terms, the value of ?new java.lang.Object()? is an > address. The evaluation of ?object? in the next lines yields > an address. This address then is passed to println. > > Python and JavaScript both want to be "higher-level" in this > regard and avoid words such as "address", they use other > means of description. Java is in between: it speaks of the > addresses, but calls them "references". It doesn't matter. What happens, in any sane language, is that the object gets printed out. (In C, you'd have to somehow tell the println function that it's getting an object. In C++, that would be handled by operator overloading in cout, or somesuch.) You aren't printing out the object's address - you're printing out the object. You pass the object, not the address of the object. Details of memory locations etc are important if you care about the implementation, but that's all. In the same way that "x = 1" means that x now has the value of 1, your code snippet is going to print the value of the new object, one way or another. ChrisA From rosuav at gmail.com Fri Aug 18 12:00:14 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 19 Aug 2017 02:00:14 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> Message-ID: On Sat, Aug 19, 2017 at 1:42 AM, Stefan Ram wrote: > Chris Angelico writes: >>On Sat, Aug 19, 2017 at 12:43 AM, Stefan Ram wrote: >>>{ final java.lang.Object object = new java.lang.Object(); >>> java.lang.System.out.println( object ); } > ... >> You pass the >>object, not the address of the object. > > Yes, it's true, sometimes you can see it this way. But then, > one can also look at > > public final class Main > { > private static void method( final java.lang.Object parameter ) > { if( parameter == null ) > java.lang.System.out.println( "Not received any object." ); } > > public static void main( final java.lang.String[] args ) > { > method( java.lang.Math.random() > 0.5 ? args : null ); }} > > Here the parameter contains an object only with a probability > of 50 %. How do you call that which is passed otherwise? Wrong. Your parameter always contains an object. Sometimes that object is an array, sometimes that object is null. Null is not the absence of an object, any more than zero is the absence of a number, or black is the absence of an image. > So, when one is writing ?"abc".length()?, by /the language > reference/, ?"abc"? is a "reference to an object", and not an > object. > > Your description might be appropriate for Python, but it > cannot describe completely the behavior of the example Java > program given above and it does not use the terms as the > Java Language Reference is using them. Yes, it's a reference to an object. But you are printing out the object itself. Names refer to objects; objects get manipulated. > And when you speak of objects, then after > >>>> class example( object ): > ... def __init__( self ): > ... self.v = 1; > ... >>>> example = example() >>>> a = example >>>> b = example >>>> a.v = 2 >>>> b.v > 2 > > you should say that the variables ?a? and ?b? now contain > the same object. I /can/ accept this, but some people cannot > accept the idea of the same object being in two places > (variables). (Yes, I know that one usually uses the idea of > "binding" to mitigate this.) The names a and b now refer to the same object. Or are bound to the same object. Either way. ChrisA From rosuav at gmail.com Fri Aug 18 13:28:33 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 19 Aug 2017 03:28:33 +1000 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> Message-ID: On Sat, Aug 19, 2017 at 2:06 AM, Stefan Ram wrote: > Chris Angelico writes: >>Wrong. Your parameter always contains an object. Sometimes that object >>is an array, sometimes that object is null. Null is not the absence of >>an object, any more than zero is the absence of a number, or black is >>the absence of an image. > > ?The reference values (often just references) are > pointers to these objects, and a special null reference, > which refers to no object.? > > The Java Language Specification 8, section 4.3.1 > > (Maybe your are thinking of Python's ?None?, > which is something different than Java's ?null?.) I'm thinking of the abstract concept of a "value". Java differentiates between "reference values" and "primitive values", where numbers and strings are not reference values. The point of the above sentence is that "null" is a special kind of reference value, as opposed to being a kind of primitive value. But whether something is a reference or primitive type, it's still a "value" in the abstract sense, and can be passed as a parameter to a function. Python simplifies things a lot here. Every value is an object. None is an object, 42 is an object, "spam" is an object, [1,2,3] is an object, and dict is an object. "Value" and "object" become virtually interchangeable. But even in Java, where some things are objects and some are not, they are still all values. So I was slightly wrong in my terminology (I said "object" when it would have been more accurate to say "value"), but I stand by the gist of what I said there. ChrisA From random832 at fastmail.com Fri Aug 18 13:32:24 2017 From: random832 at fastmail.com (Random832) Date: Fri, 18 Aug 2017 13:32:24 -0400 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: <8760dl2ukp.fsf@elektro.pacujo.net> References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> <8760dl2ukp.fsf@elektro.pacujo.net> Message-ID: <1503077544.2675028.1077816016.77F2586D@webmail.messagingengine.com> On Fri, Aug 18, 2017, at 03:39, Marko Rauhamaa wrote: > BTW, I was reading up on the history of ASCII control characters. Quite > fascinating. > > For example, have you ever wondered why DEL is the odd control character > out at the code point 127? The reason turns out to be paper punch tape. > By backstepping and punching a DEL over the previous ASCII character you > can "rub out" the character. I assume this is also why teletypes used even parity - so 0xFF can be used as DEL on characters that had any parity. From ben.usenet at bsb.me.uk Fri Aug 18 16:27:31 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 18 Aug 2017 21:27:31 +0100 Subject: A question on modification of a list via a function invocation References: <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> Message-ID: <8760dkhb9o.fsf@bsb.me.uk> ram at zedat.fu-berlin.de (Stefan Ram) writes: > Ben Bacarisse writes: >>Steve D'Aprano writes: >>>"Java is call by value, dammit!" >>I don't think this is a fair point. You will run out of ideas if they >>are to be avoided because some people will get the wrong idea when >>reading part of a description of that idea applied to some other language. > > You are trying to cool off the topic. An expression such as > "da...t!" should be avoided in a cold topic. But otherwise, > "Java is call by value." is just fine. I didn't say it. -- Ben. From piet-l at vanoostrum.org Fri Aug 18 17:04:49 2017 From: piet-l at vanoostrum.org (Piet van Oostrum) Date: Fri, 18 Aug 2017 23:04:49 +0200 Subject: What extended ASCII character set uses 0x9D? References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> <8760dl2ukp.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa writes: > Chris Angelico : > >> Ohh. We have no evidence that uppercasing is going on here, and a >> naive ASCII upper-casing wouldn't produce 0x81 either - if it did, it >> would also convert 0x21 ("!") into 0x01 (SOH, a control character). So >> this one's still a mystery. > > BTW, I was reading up on the history of ASCII control characters. Quite > fascinating. > > For example, have you ever wondered why DEL is the odd control character > out at the code point 127? The reason turns out to be paper punch tape. > By backstepping and punching a DEL over the previous ASCII character you > can "rub out" the character. > Sure, I have done that many times. Years ago. -- Piet van Oostrum WWW: http://piet.vanoostrum.org/ PGP key: [8DAE142BE17999C4] From nagle at animats.com Fri Aug 18 17:42:49 2017 From: nagle at animats.com (John Nagle) Date: Fri, 18 Aug 2017 14:42:49 -0700 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: On 08/17/2017 05:53 PM, Chris Angelico wrote: > On Fri, Aug 18, 2017 at 10:30 AM, John Nagle wrote: >> On 08/17/2017 05:14 PM, John Nagle wrote: >>> I'm cleaning up some data which has text description fields from >>> multiple sources. >> A few more cases: >> >> bytearray(b'\xe5\x81ukasz zmywaczyk') > > This one has to be Polish, and the first character should be the > letter ? U+0141 or ? U+0142. In UTF-8, U+0141 becomes C5 81, which is > very similar to the E5 81 that you have. > > So here's an insane theory: something attempted to lower-case the byte > stream as if it were ASCII. If you ignore the high bit, 0xC5 looks > like 0x45 or "E", which lower-cases by having 32 added to it, yielding > 0xE5. Reversing this transformation yields sane data for several of > your strings - they then decode as UTF-8: > > miguel ?ngel santos > lidija kmeti? > ?ukasz zmywaczyk > ji?? urban??k > ?ubom?r mi?ko > petr urban??k You're exactly right. The database has columns "name" and "normalized name". Normalizing the name was done by forcing it to lower case as if in ASCII, even for UTF-8. That resulted in errors like KACMAZLAR MEKAN?K -> kacmazlar mekan??k Anita Cal?ados -> anita cal??ados Felfria Resor f?r att Koh Lanta -> felfria resor f??r att koh lanta The "name" field is OK; it's just the "normalized name" field that is sometimes garbaged. Now that I know this, and have properly captured the "name" field in UTF-8 where appropriate, I can regenerate the "normalized name" field. MySQL/MariaDB know how to lower-case UTF-8 properly. Clean data at last. Thanks. The database, by the way, is a historical snapshot of startup funding, from Crunchbase. John Nagle From ethan at stoneleaf.us Fri Aug 18 18:50:47 2017 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 18 Aug 2017 15:50:47 -0700 Subject: pip requirements file In-Reply-To: <5988AE24.2000204@stoneleaf.us> References: <5985309E.1070405@stoneleaf.us> <598533E5.6000101@stoneleaf.us> <5988AE24.2000204@stoneleaf.us> Message-ID: <59976F47.4080002@stoneleaf.us> On 08/07/2017 11:15 AM, Ethan Furman wrote: > Light finally turned on. If requirements.txt has all my installed requirements, that would include any dependencies > actually needed; so I specify --no-dependencies, then dependencies not listed in the requirements.txt file will not be > installed. As a follow-up: I tried it, and it worked! :) Oh, and the flag name is --no-deps . -- ~Ethan~ From steve+python at pearwood.info Fri Aug 18 20:16:45 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 19 Aug 2017 10:16:45 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <598d447b$0$1614$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <85mv6zio3p.fsf@benfinney.id.au> <5994672b$0$1610$c3e8da3$5496439d@news.astraweb.com> <85inhnhyww.fsf@benfinney.id.au> <87mv6y4u31.fsf@elektro.pacujo.net> Message-ID: <59978370$0$1602$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 03:54 pm, Marko Rauhamaa wrote: > Ben Finney : > >> The Python list comprehension syntax does not specify control flow. > > I understand your point, but how do you know your statement is true? > > I didn't check this, but I would imagine the list comprehension: > > [ f(x) for x in I if c(x) ] > > was defined as syntactic sugar for: > > list(f(x) for x in I if c(x)) Not originally. List comprehensions were added to Python in version 2.0, before generator expressions. (Generator expressions only made it into the language in version 2.4.) But right from 2.0, they have been explicitly defined as equivalent to for loops: https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Doc/whatsnew/2.0.rst#list-comprehensions In Python 3, it would make sense for list/set/dict comprehensions to be thin wrappers around generator expressions, but I don't know if they share implementations that way or have separate "copy and paste" implementations. I can't find where they are implemented. This does leave a *tiny* bit of wriggle-room: the implementation (in C, say, or some other language) doesn't have to use a for-loop. It could use recursion, or a while-loop, or it might unroll the loop into a long series of imperative statements, or use GOTO to emulate looping. So long as the Python semantics remain the same, and the elements are generated in the same order. > where > > f(x) for x in I if c(x) > > has heavily iterative semantics. Indeed. For loops are one of the cardinal examples of iteration. It isn't a coincidence that generator expressions and comprehensions use the same syntax. Whatever implementation is used, the semantics must be the same as the equivalent for loop procedural code. For example: from io import StringIO myfile = StringIO('Is this the room for an argument?') values = [myfile.read(1) for i in range(33)] assert values == list('Is this the room for an argument?') Python is not free to generate the results in some other order. >> List comprehensions, in their syntax, strongly connote a single >> declarative operation. This makes them different from iteration >> syntax. > > Except for side effects, you get the same result whichever way you > imagine it. That's not correct, as the example of reading from a file demonstrates. > As a side not, I have found it rather confusing that I have to say: > > [ (x, y) for x in range(5) for y in range(x) ] > > instead of: > > [ (x, y) for y in range(x) for x in range(5) ] That doesn't work because x isn't defined when you call range(x). > After all, you must say: > > [ ((x, y) for y in range(x)) for x in range(5) ] > > which, admittedly, means a different thing. Indeed. Completely different. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 18 20:22:25 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 19 Aug 2017 10:22:25 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994e62c$0$1603$c3e8da3$5496439d@news.astraweb.com> <7b67047d-7d59-4856-9fd4-5824f0608aff@googlegroups.com> <599659e8$0$1620$c3e8da3$5496439d@news.astraweb.com> Message-ID: <599784c3$0$1602$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 10:36 pm, Rustom Mody wrote: >> So what abstraction do you think call by object sharing is making, and in >> what way does it leak? > > Data Dependency ? also called coupling ? is generally considered to be > deleterious to software quality Excessive coupling. You cannot avoid some coupling, nor would you want to. The whole purpose of programming is to couple your input and your output. But yes, excessive and inappropriate coupling between parts of your code that shouldn't be coupled is THE big evil in software development. > Python removes the frank pointers of C (like) languages > It does nothing about aliasing Doesn't it? > Sharing-by-object is nothing more than the diginification of aliasing Is it? How so? In any case, I have to repeat my question since you didn't answer it. What abstraction do you think call by object sharing is making, and in what way does it leak? You made a statement that it is a leaky abstraction, not that it is insufficiently vigorous in rooting out coupling branch and stem. That's a separate criticism. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 18 20:25:29 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 19 Aug 2017 10:25:29 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5997857b$0$1602$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 11:46 pm, Rustom Mody wrote: > My issue is that the tutorial introduces comprehensions backwards, as though > they are a macro for the for-loop Python doesn't have macros as such, but if it did, that would be a good way to describe comprehensions. Another way would be to say that comprehensions are syntactic sugar for a for-loop and accumulator. You say "as though they are", but that's exactly the point -- that is precisely what they are. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Fri Aug 18 20:40:04 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 19 Aug 2017 10:40:04 +1000 Subject: A question on modification of a list via a function invocation References: <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> Message-ID: <599788e7$0$1619$c3e8da3$5496439d@news.astraweb.com> On Sat, 19 Aug 2017 12:43 am, Stefan Ram wrote: > Ben Bacarisse writes: >>Steve D'Aprano writes: >>>"Java is call by value, dammit!" >>I don't think this is a fair point. You will run out of ideas if they >>are to be avoided because some people will get the wrong idea when >>reading part of a description of that idea applied to some other language. > > You are trying to cool off the topic. An expression such as > "da...t!" should be avoided in a cold topic. But otherwise, > "Java is call by value." is just fine. Apart from being technically wrong and deeply misleading, yes it is fine. And "Java is call by value, dammit!" is not my words, it is (almost) the actual title of the piece by Scott Stanchfield. http://javadude.com/articles/passbyvalue.htm (I made a mistake: Scott calls it "Pass-by-Value".) The precise, exact, copy-and-paste title used by Scott for his essay is: Java is Pass-by-Value, Dammit! -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Sat Aug 19 00:15:22 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 19 Aug 2017 14:15:22 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> On Sat, 19 Aug 2017 12:59 am, Chris Angelico wrote: > On Fri, Aug 18, 2017 at 11:46 PM, Rustom Mody wrote: >> Compare the well-known haskell tutorial >> http://learnyouahaskell.com/starting-out >> whose comprehension intro starts: >> >> | If you've ever taken a course in mathematics, you've probably run into set >> | comprehensions. They're normally used for building more specific sets out >> | of general sets. A basic comprehension for a set that contains the first >> | ten even | natural numbers is >> >> | S = {2?x | x ? ?, x ? 10} For the record, this is not the best example to give, since the Natural numbers ? are not well-defined. Some people include 0, and some do not, so there's a slight ambiguity to the above. http://mathworld.wolfram.com/NaturalNumber.html Despite that nit-pick, set builder notation is very common in maths, but not universal. It is taught in secondary education (high school) in Australia, but not to all students. >> Analogous thing shown at ghci prompt: >> >> | ghci> [x*2 | x <- [1..10]] >> | [2,4,6,8,10,12,14,16,18,20] > > And what if you HAVEN'T taken a course in mathematics? What use is > this then? How would you teach this to a non-mathematician? Speaking as someone who *has* taken a course of mathematics or two, I find that Rustom's insistence in coming back to the fundamentals of set theory and the Zermelo?Fraenkel axioms is not terribly helpful. Even among professional mathematicians. Z-F and the axiom of choice and related matters are extremely specialised and abstract fields of little interest to the average working mathematician. In my experience, they're of more interest to philosophers and dilettantes than actual mathematicians, outside of the minority working in that specific field. Yes yes, it is absolutely fundamental to mathematics, just as quantum mechanics is absolutely fundamental to an understanding of matter. How many bridge builders care about quantum mechanics? Python is not Haskell and makes no pretence at being mathematically sound[1]. The Zen of Python sets forth some of the design principles in the language, and "mathematical purity" is not one of them. The opposite, in fact: "practicality beats purity." To answer your (Chris') question: When I teach comprehension syntax, I always mention set builder notation and say "you may have been taught this is school". I don't think I have ever come across someone who both *was* taught it and *remembers* so, but I'll keep trying. For those who don't understand set builder notation (so far, everyone I've tried to teach comps to) I explain them in terms of for loops. In fact, even if you do understand set builder notation, for more complex examples with "if" clauses and multiple "for" loops, I maintain that you have to think of it in terms of loops to understand it. I am extremely skeptical that anyone could look at a comprehension like: [expr for x in A for y in B if P for z in C if Q for w in D for v in E if R] and understand it *without* converting it to nested loops. > Pretty much everyone, at some point in their lives, will follow a set > of written instructions. Most commonly, a recipe for some sort of > food. It consists of a set of ingredients and a sequence of commands. > This translates well into a classic imperative style Indeed. People find imperative (recipe) algorithms easy to follow, and pure functional reasoning hard. I'm glad that functional programming is fashionable again, and hope that people will learn good habits from it, but I think that mathematical purity is not necessary or even helpful in the majority of programming tasks. I expect that languages like Haskell, like Scheme and Lisp, will be greatly influential but remain niche languages themselves. [1] Assuming that mathematics actually is sound, which thanks to G?del we know is unprovable. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Sat Aug 19 01:42:04 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 19 Aug 2017 15:42:04 +1000 Subject: Proposed new syntax In-Reply-To: <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sat, Aug 19, 2017 at 2:15 PM, Steve D'Aprano wrote: > Indeed. People find imperative (recipe) algorithms easy to follow, and pure > functional reasoning hard. I'm glad that functional programming is fashionable > again, and hope that people will learn good habits from it, but I think that > mathematical purity is not necessary or even helpful in the majority of > programming tasks. > > I expect that languages like Haskell, like Scheme and Lisp, will be greatly > influential but remain niche languages themselves. Agreed. Functional programming languages teach us about recursion, immutability, declarative programming styles, etc, all of which are incredibly useful. I don't particularly enjoy writing Scheme code (only ever done it because of Lilypond), but I think I'm a better programmer for having gotten my head around it. > > [1] Assuming that mathematics actually is sound, which thanks to G?del we know > is unprovable. Harmony in audio signals is based on frequency ratios. Therefore sound is mathematics, and by the reflexive principle of equality, mathematics is sound. Sorry, G?del, I just proved it. ChrisA From owenberry12 at gmail.com Sat Aug 19 01:50:59 2017 From: owenberry12 at gmail.com (Owen Berry) Date: Sat, 19 Aug 2017 01:50:59 -0400 Subject: No subject Message-ID: I'm new to python and having trouble with the most basic step. I have tried to install python (Web-based installer) on my home pc to mess around and attempt to develop a program. when I install the launcher it is fine but when I try and open the file it launches a modify setup window. I have no clue how to fix this issue and start using the actual program. how do I go about fixing this issue? any information would be greatly valued. Thank you [image: Inline image 2] Modify [image: Inline image 3] Next [image: Inline image 4] Install [image: Inline image 5] From rantingrickjohnson at gmail.com Sat Aug 19 05:43:43 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sat, 19 Aug 2017 02:43:43 -0700 (PDT) Subject: Default .py program and Edit with IDLE problem In-Reply-To: References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> Message-ID: <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> On Wednesday, August 16, 2017 at 4:55:17 PM UTC-5, Kevi Aday (Katch22) wrote: > I installed python 3.6.2 for making running and editing > programs. Later on I installed python 2.7 because a program > that I downloaded only works with that. Later I deleted the > program. I then wanted to run a program from cmd but it was > giving me all kinds of errors What kind of errors? You should have copy/pasted the exception messages here. > I thought the problem was being caused by python 2.7 and I > didn?t even need it anymore so I uninstalled it. After I > uninstalled it, all my .py files? icons disappeared and > when I right clicked on it the ?Edit with IDLE? > disappeared. I tried all kinds of things like repairing > python, Don't waste your time with that stupid "repair option". What does an uninstall and reinstall process take these days... all of two minutes? > editing the registry, etc. Oh boy... The first rule of troubleshooting is always to apply the simplist fix first, then start walking up the "staircase of complexity" until you find a solution. Something specific and esoteric as editing the registry is very near the top of the staircase. In this case, the "easy fix" is a quick and painless uninstall+reinstall. One of the core philosophical principals of Python is: "In the face of ambiguity, refuse the temptation to guess", and while uninstall+reinstall may indeed seem like a drastic measure, it is the most practical solution for this kind of problem. > but I just can?t fix the problem and this has never > happened to me and its really bugging me. Please help. (1) Uninstall all versions of Python on your machine. (2) Install Python 3, and be sure to check the box that says (I'm paraphrasing here): "Make this my default installation" All better now? -- rr >>> import this # The path to enlightenment begins here... From rantingrickjohnson at gmail.com Sat Aug 19 06:07:07 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sat, 19 Aug 2017 03:07:07 -0700 (PDT) Subject: A question on modification of a list via a function invocation In-Reply-To: <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> Message-ID: <445fb28d-45f9-4d96-8775-95380ae73302@googlegroups.com> On Wednesday, August 16, 2017 at 4:07:14 PM UTC-5, Mok-Kong Shen wrote: > The above shows that with , i.e. assigning > single values to individual members of alist (with > alist[0]=3 etc.) is "principally" different from assigning > a whole list to alist (with alist=[30,60,90]). The first > operation doesn't affect the connection between ss and > alist, while the second separates the connection between ss > and alist, as your diagram above clearly indicates. And why is that so difficult for you to understand? It has always seemed perfectly logical to me... [A thought experiment] Consider automobiles as an example. Automobiles are constructed in factories, and they are machines that are made of many subcomponents, but we reference the entire "conglomeration of subcomponents" (a "car") as single unit, and each unit is given a serial number (aka: "Vehicle Identification Number"). Now image one day your car is wrecked, and your mechanic replaces a few (or all) of the subcomponents with new subcomponents... would he also modify the VIN? Of course not! Because the subcomponents do not define the vehicle. If we want a new vehicle, then we request one from the factory. So when you do this: car = [1,2,3] You are requesting a _new_ car from the factory. But when you do this: car[0] = 10 car[1] = 20 car[2] = 30 ... You are merely changing out subcomponents of an _existing_ car. And even if you exchange every component, the car will never be a "factory new" car. > Isn't this kind of convention/rule something that appears > to be not quite natural/"logical" to the common users (non- > experts)? No. From rosuav at gmail.com Sat Aug 19 06:38:50 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 19 Aug 2017 20:38:50 +1000 Subject: Default .py program and Edit with IDLE problem In-Reply-To: <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> Message-ID: On Sat, Aug 19, 2017 at 7:43 PM, Rick Johnson wrote: > Don't waste your time with that stupid "repair option". What > does an uninstall and reinstall process take these days... > all of two minutes? > > Oh boy... The first rule of troubleshooting is always to > apply the simplist fix first, then start walking up the > "staircase of complexity" until you find a solution. > Something specific and esoteric as editing the registry is > very near the top of the staircase. In this case, the "easy > fix" is a quick and painless uninstall+reinstall. One of the > core philosophical principals of Python is: "In the face of > ambiguity, refuse the temptation to guess", and while > uninstall+reinstall may indeed seem like a drastic measure, > it is the most practical solution for this kind of problem. I'm not sure how "refuse to guess" translates into "wipe it out and start over". I *never* recommend uninstall/reinstall as a first measure. It's a stupid idea unless you actually know that it's going to help. ChrisA From steve+python at pearwood.info Sat Aug 19 06:59:16 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sat, 19 Aug 2017 20:59:16 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <445fb28d-45f9-4d96-8775-95380ae73302@googlegroups.com> Message-ID: <59981a06$0$1606$c3e8da3$5496439d@news.astraweb.com> On Sat, 19 Aug 2017 08:07 pm, Rick Johnson wrote: > And why is that so difficult for you to understand? It has > always seemed perfectly logical to me... > > [A thought experiment] > Consider automobiles as an example. Automobiles are > constructed in factories, and they are machines that are > made of many subcomponents, but we reference the entire > "conglomeration of subcomponents" (a "car") as single unit, > and each unit is given a serial number (aka: "Vehicle > Identification Number"). Now image one day your car is > wrecked, and your mechanic replaces a few (or all) of the > subcomponents with new subcomponents... would he also modify > the VIN? Of course not! Because the subcomponents do not > define the vehicle. If we want a new vehicle, then we > request one from the factory. I'm not sure that the VIN defines the vehicle exactly... I wouldn't want to try driving a VIN without the rest of the vehicle. The mileage is terrible... Quoting Fredrik Lundh: well, I guess you can, in theory, value an artificial number assigned to an object as much as the object itself. "Joe, I think our son might be lost in the woods" "Don't worry, I have his social security number" but putting that aside, your car analogy glosses over a genuine paradox here. Consider that in my family, one of our most precious heirlooms is the axe of my great-great-great grandfather, which we have passed down from eldest son to eldest son for generations. The axe is now almost 200 years old. Of course, occasionally the handle has broken and we've had to replace it, and from time to time the axe head itself was so worn out that it had to be replaced, but apart from those repairs the axe is the same one that my great-great-great grandfather used almost two centuries ago. https://plato.stanford.edu/entries/identity-time/ -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rantingrickjohnson at gmail.com Sat Aug 19 10:11:28 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sat, 19 Aug 2017 07:11:28 -0700 (PDT) Subject: Default .py program and Edit with IDLE problem In-Reply-To: References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> Message-ID: <13950da3-cf56-45b9-bdc0-5f043c750be6@googlegroups.com> On Saturday, August 19, 2017 at 5:39:19 AM UTC-5, Chris Angelico wrote: > I'm not sure how "refuse to guess" translates into "wipe it > out and start over". I *never* recommend > uninstall/reinstall as a first measure. It's a stupid idea > unless you actually know that it's going to help. No, what's stupid is spending hours running down non-issues because you'd rather take random guesses than choose the easy, practical solution. I suppose if your library includes many third-party add-ons, the rebuild process could be more than a few minutes, but that's the very reason i have elected to keep my dependancy pool small. For instance, if i need a GUI, i opt for the stdlib module Tkinter first. Sure, Tkinter is a very basic library, and sometimes you have to roll your own widgets (while rolling your eyes!), but if it gets the job done, who cares! "Practicality beats purity!" In the end, even if i'm forced to extend a builtin library to get some missing functionality, my efficiency is increased because (1) i don't need to corral a herd of third party dependencies for distribution or rebuilds, and (2) I don't need to keep up with the latest changes in multiple dependencies (which can drastically affect my existing interfaces and APIs down-stream). If your goal is to be a hoarding "dependancy herder", then have fun with that! Meanwhile, i'll be focusing on new features and functionality. My software design philosophy is to be lean and mean. If we don't moderate ourselves, cruft has a way of piling up very quickly. From breamoreboy at gmail.com Sat Aug 19 10:43:10 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Sat, 19 Aug 2017 07:43:10 -0700 (PDT) Subject: A question on modification of a list via a function invocation In-Reply-To: <59981a06$0$1606$c3e8da3$5496439d@news.astraweb.com> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <445fb28d-45f9-4d96-8775-95380ae73302@googlegroups.com> <59981a06$0$1606$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Saturday, August 19, 2017 at 11:59:41 AM UTC+1, Steve D'Aprano wrote: > Consider that in my family, one of our most precious heirlooms is the axe of my > great-great-great grandfather, which we have passed down from eldest son to > eldest son for generations. > > The axe is now almost 200 years old. Of course, occasionally the handle has > broken and we've had to replace it, and from time to time the axe head itself > was so worn out that it had to be replaced, but apart from those repairs the > axe is the same one that my great-great-great grandfather used almost two > centuries ago. > > https://plato.stanford.edu/entries/identity-time/ > > -- > Steve > ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure > enough, things got worse. Rather like Trigger's roadsweeping broom https://www.youtube.com/watch?v=s1VNNbSYdt0 Kindest regards. Mark Lawrence. From rantingrickjohnson at gmail.com Sat Aug 19 10:51:23 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sat, 19 Aug 2017 07:51:23 -0700 (PDT) Subject: A question on modification of a list via a function invocation In-Reply-To: <59981a06$0$1606$c3e8da3$5496439d@news.astraweb.com> References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <445fb28d-45f9-4d96-8775-95380ae73302@googlegroups.com> <59981a06$0$1606$c3e8da3$5496439d@news.astraweb.com> Message-ID: <4ab450c1-77a9-4061-aa48-641e03d2d7c5@googlegroups.com> Steve D'Aprano wrote: > I'm not sure that the VIN defines the vehicle exactly... I > wouldn't want to try driving a VIN without the rest of the > vehicle. The mileage is terrible... Quoting Fredrik Lundh: > well, I guess you can, in theory, value an artificial > number assigned to an object as much as the object itself. > "Joe, I think our son might be lost in the woods" "Don't > worry, I have his social security number" While i'll admit your story is quite funny, it's not relevant to my example. > but putting that aside, your car analogy glosses over a > genuine paradox here. Consider that in my family, one of > our most precious heirlooms is the axe of my great-great- > great grandfather, which we have passed down from eldest > son to eldest son for generations. The axe is now almost > 200 years old. Of course, occasionally the handle has > broken and we've had to replace it, and from time to time > the axe head itself was so worn out that it had to be > replaced, but apart from those repairs the axe is the same > one that my great-great-great grandfather used almost two > centuries ago. No it isn't. You're conflating the "history of the axe" with the "physical axe" itself -- two distinct and unrelatable concepts -- one tangible, and one not. Generally, an axe consists of a handle and a blade, and if you replace the blade and the handle, you have a whole new axe. The axe you _now_ hold is merely a symbolic representation of the physical object that your great-great- great... deep breath... grandpappy held in his hand many centuries ago, and neither love nor nostalgia can overcome the reality that your axe, and the axe of your, urm, "distant relative", is not the same object anymore. Unfortunately, while my "car example" did correctly mirror many of the aspects of Python lists, i admit it was clumsily of me to conflate "components" with "contents". And although components can be added and removed (like contents), the adding and removing of these components do affect the overall "identity" of the car object, in a way that say, groceries in the back seat or passengers would not. So for that reason, it fails. With that in mind, a "basket full of apples" would be a better representation of lists, as the basket is not defined by its content. For instance, apples can be added, or taken away, or even oranges can be placed inside, but it will always be a unique basket. A unique object. And how the basket is referenced, in this reguard, is inconsequential. And whether we choose to uniquely identify the basket by say, placing a serial number on it or giving it a friendly name like: "Mr. Weaves", it will always be a unique object, regardless of content. From greg.ewing at canterbury.ac.nz Sat Aug 19 11:17:38 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Sun, 20 Aug 2017 03:17:38 +1200 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: Message-ID: Ian Kelly wrote: > One possibility is that it's the same two bytes. That would make it > 0xE2 0x80 0x9D which is "right double quotation mark". Since it keeps > appearing after ending double quotes that seems plausible, although > one has to wonder why it appears *in addition to* the ASCII double > quotes. Maybe something tried to replace right double quote marks with ascii double quotes, but got it wrong by only replacing 2 bytes instead of 3. -- Greg From steve+python at pearwood.info Sat Aug 19 11:56:14 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sun, 20 Aug 2017 01:56:14 +1000 Subject: Default .py program and Edit with IDLE problem References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> <13950da3-cf56-45b9-bdc0-5f043c750be6@googlegroups.com> Message-ID: <59985f9f$0$1621$c3e8da3$5496439d@news.astraweb.com> On Sun, 20 Aug 2017 12:11 am, Rick Johnson wrote: > On Saturday, August 19, 2017 at 5:39:19 AM UTC-5, Chris Angelico wrote: >> I'm not sure how "refuse to guess" translates into "wipe it >> out and start over". I *never* recommend >> uninstall/reinstall as a first measure. It's a stupid idea >> unless you actually know that it's going to help. > > No, what's stupid is spending hours running down non-issues > because you'd rather take random guesses than choose the > easy, practical solution. Assuming that it is the solution, which it often isn't. Just in recent months, there have been a spate of posts from people with problems on Windows, invariably ending with some plaintive cry of: "I've uninstalled and reinstalled again and again and it didn't help!" I must admit I don't remember the solution because, not being a Windows guy I didn't care that much, but if you care you can search the archives. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rantingrickjohnson at gmail.com Sat Aug 19 13:13:40 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sat, 19 Aug 2017 10:13:40 -0700 (PDT) Subject: Default .py program and Edit with IDLE problem In-Reply-To: <59985f9f$0$1621$c3e8da3$5496439d@news.astraweb.com> References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> <13950da3-cf56-45b9-bdc0-5f043c750be6@googlegroups.com> <59985f9f$0$1621$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > Rick Johnson wrote: > > Chris Angelico wrote: > > > I'm not sure how "refuse to guess" translates into "wipe > > > it out and start over". I *never* recommend > > > uninstall/reinstall as a first measure. It's a stupid > > > idea unless you actually know that it's going to help. > > > > No, what's stupid is spending hours running down non- > > issues because you'd rather take random guesses than > > choose the easy, practical solution. > > Assuming that it is the solution, which it often isn't. > Just in recent months, there have been a spate of posts > from people with problems on Windows, invariably ending > with some plaintive cry of: "I've uninstalled and > reinstalled again and again and it didn't help!" And remind me again, what's the definition of insanity? ;-) > I must admit I don't remember the solution because, not > being a Windows guy I didn't care that much, but if you > care you can search the archives. My solution for a Python3 that won't install would be to revert back to the Python2.x line. Like HTML tables, older features can be less buggy and suffer less compatibility issues in the wild (at least for a time). Being that Python3 is still cutting its teeth in the middle of constant churn, i await Python4. And i sure hope Python4 will be a little more stable. I think too many features have been added too quickly. For instance, the type-hints thing is a major shift from the founding philosophy, and one of my greatest pet peeves. From alister.ware at ntlworld.com Sat Aug 19 13:15:06 2017 From: alister.ware at ntlworld.com (alister) Date: Sat, 19 Aug 2017 17:15:06 GMT Subject: Default .py program and Edit with IDLE problem References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> <13950da3-cf56-45b9-bdc0-5f043c750be6@googlegroups.com> <59985f9f$0$1621$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sun, 20 Aug 2017 01:56:14 +1000, Steve D'Aprano wrote: > On Sun, 20 Aug 2017 12:11 am, Rick Johnson wrote: > >> On Saturday, August 19, 2017 at 5:39:19 AM UTC-5, Chris Angelico wrote: >>> I'm not sure how "refuse to guess" translates into "wipe it out and >>> start over". I *never* recommend uninstall/reinstall as a first >>> measure. It's a stupid idea unless you actually know that it's going >>> to help. >> >> No, what's stupid is spending hours running down non-issues because >> you'd rather take random guesses than choose the easy, practical >> solution. > > Assuming that it is the solution, which it often isn't. > > Just in recent months, there have been a spate of posts from people with > problems on Windows, invariably ending with some plaintive cry of: > > "I've uninstalled and reinstalled again and again and it didn't help!" > > I must admit I don't remember the solution because, not being a Windows > guy I didn't care that much, but if you care you can search the > archives. I think to a point I have to agree with rick, windows installers can be flaky and time is money. if something does not work after installation (& does not gibe any clues as to why) a quick install (reboot) & re install is work a try & probably has a 25-50% success rate. however you are also correct in that if this does not work there is nothing to be gained by repeating the process & further investigation as to what is causing the issue is needed. one approach I have found useful in the past is to try to start the program (what ever it is) from the command line - something that windows users have all but forgotten exists. -- The trouble is that things *never* get better, they just stay the same, only more so. (Eric) From rantingrickjohnson at gmail.com Sat Aug 19 14:03:28 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Sat, 19 Aug 2017 11:03:28 -0700 (PDT) Subject: Default .py program and Edit with IDLE problem In-Reply-To: References: <5994bd71.d86e240a.a76fc.516e@mx.google.com> <624cfa09-a86a-4f74-87de-88aced9a89b7@googlegroups.com> <13950da3-cf56-45b9-bdc0-5f043c750be6@googlegroups.com> <59985f9f$0$1621$c3e8da3$5496439d@news.astraweb.com> Message-ID: <6a139635-e2d9-43bf-a58c-a004d04ed413@googlegroups.com> alister wrote: > Steve D'Aprano wrote: > > Rick Johnson wrote: [...] > I think to a point I have to agree with rick, Well, alister, i'll take what i can get around here. :-) > windows installers can be flaky and time is money. Indeed. > if something does not work after installation (& does not > gibe any clues as to why) a quick install (reboot) & re > install is work a try & probably has a 25-50% success rate. Well, part of the problem here is that OP failed to provide the necessary information. Ssorry OP, but i gotta call you out on this one! First of all, the OP made it sound as though the Python3 install was working all fine-and-dandy until Python2 was installed, then some command-line hackery became problematic with "some errors i didn't used to get" --- whatever that means... Then after uninstalling Python2, the OP reports some weird OS specific behavior about icons disappearing and missing commands from the Windows Contextual Menu. Okay, the later issue would seem to indicate that the system file associations related to Python had been deleted and that the Python 2.x uninstaller, being unaware that the Python3 would hang around for a while longer, did its normal "hey, i'm the last fella here, so i'll clean up the empty beer cans and pizza boxess before i go" routine, by removing python related commands from the context menu (and gawd know what else!). The clue that could solve this whole mystery would be specific information about these "strange errors"... (1) Were these python exception messages? (2) Were they Windows error messages? (3) Perhaps the flux capacitor failed to produce the expected 1.21 GigaWatts? Great Scott!!! With such limited information, all we can do is guess here. But in my experience, with Python on windoze at least, the installers can be, as you said, flaky. Especially when you have multiple versions on the same machine and you forget to select the little "Make-This-My-Default-Python" box. But of course, that won't help when you do the uninstall later, because there's no "Use-VersionXY-As-My-Default-Python" for the uninstaller. It's a one-way street with no U-Turns allowed. From bgailer at gmail.com Sat Aug 19 15:42:57 2017 From: bgailer at gmail.com (Bob Gailer) Date: Sat, 19 Aug 2017 15:42:57 -0400 Subject: No subject In-Reply-To: References: Message-ID: Unfortunately the images did not come through, since this is a text-only email list. I suggest you put your images on an online resource such as Photobucket and post the links in your email. Unfortunately your description of the problem is not very precise. Obviously the images would help. Terms like installing the launcher and open the file don't help. Please get the images online send us the links and be more verbose in your explanation. On Aug 19, 2017 1:52 PM, "Owen Berry" wrote: > I'm new to python and having trouble with the most basic step. I have tried > to install python (Web-based installer) on my home pc to mess around and > attempt to develop a program. when I install the launcher it is fine but > when I try and open the file it launches a modify setup window. I have no > clue how to fix this issue and start using the actual program. how do I go > about fixing this issue? any information would be greatly valued. > > Thank you > > > > > [image: Inline image 2] > > Modify > [image: Inline image 3] > > Next > [image: Inline image 4] > > Install > [image: Inline image 5] > -- > https://mail.python.org/mailman/listinfo/python-list > From steve+python at pearwood.info Sat Aug 19 20:35:07 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sun, 20 Aug 2017 10:35:07 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: <5998d93d$0$1609$c3e8da3$5496439d@news.astraweb.com> On Sat, 19 Aug 2017 03:42 pm, Chris Angelico wrote: >> [1] Assuming that mathematics actually is sound, which thanks to G?del we >> [know >> is unprovable. > > Harmony in audio signals is based on frequency ratios. Therefore sound > is mathematics, and by the reflexive principle of equality, > mathematics is sound. Sorry, G?del, I just proved it. All prime numbers are odd. The primes 3, 5, 7, 11, 13, ... are not divisible by two, which makes them odd numbers. The prime 2 is unique in being the only prime which is divisible by two, which makes it the oddest prime of all. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From jobmattcon at gmail.com Sat Aug 19 20:58:11 2017 From: jobmattcon at gmail.com (Ho Yeung Lee) Date: Sat, 19 Aug 2017 17:58:11 -0700 (PDT) Subject: how to create root with treelib? Message-ID: <3ea125e1-029d-4a23-8d06-bf082d181d19@googlegroups.com> http://treelib.readthedocs.io/en/latest/examples.html tree = Tree() #create root tree.create_node((0,0), "root") result = [aa[0]] previousnode = (0,0) >>> #create root ... tree.create_node((0,0), "root") Traceback (most recent call last): File "", line 2, in File "C:\Python27\lib\site-packages\treelib\node.py", line 142, in __repr__ "tag=%r" % self.tag, TypeError: not all arguments converted during string formatting From python at mrabarnett.plus.com Sat Aug 19 21:40:51 2017 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 20 Aug 2017 02:40:51 +0100 Subject: how to create root with treelib? In-Reply-To: <3ea125e1-029d-4a23-8d06-bf082d181d19@googlegroups.com> References: <3ea125e1-029d-4a23-8d06-bf082d181d19@googlegroups.com> Message-ID: On 2017-08-20 01:58, Ho Yeung Lee wrote: > http://treelib.readthedocs.io/en/latest/examples.html > > tree = Tree() > #create root > tree.create_node((0,0), "root") > result = [aa[0]] > previousnode = (0,0) > >>>> #create root > ... tree.create_node((0,0), "root") > Traceback (most recent call last): > File "", line 2, in > File "C:\Python27\lib\site-packages\treelib\node.py", line 142, in __repr__ > "tag=%r" % self.tag, > TypeError: not all arguments converted during string formatting > You should probably report that as a bug. From rustompmody at gmail.com Sun Aug 20 00:28:04 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Sat, 19 Aug 2017 21:28:04 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Saturday, August 19, 2017 at 9:45:48 AM UTC+5:30, Steve D'Aprano wrote: > On Sat, 19 Aug 2017 12:59 am, Chris Angelico wrote: > > > On Fri, Aug 18, 2017 at 11:46 PM, Rustom Mody wrote: > >> Compare the well-known haskell tutorial > >> http://learnyouahaskell.com/starting-out > >> whose comprehension intro starts: > >> > >> | If you've ever taken a course in mathematics, you've probably run into set > >> | comprehensions. They're normally used for building more specific sets out > >> | of general sets. A basic comprehension for a set that contains the first > >> | ten even | natural numbers is > >> > >> | S = {2?x | x ? ?, x ? 10} > > For the record, this is not the best example to give, since the Natural numbers > ? are not well-defined. Some people include 0, and some do not, so there's a > slight ambiguity to the above. > > http://mathworld.wolfram.com/NaturalNumber.html > > Despite that nit-pick, set builder notation is very common in maths, but not > universal. It is taught in secondary education (high school) in Australia, but > not to all students. There's more than just a nit-pick wrong with that expression Here?s an actual Haskell run Prelude> [x*2 | x <- [1..], x <= 10] [2,4,6,8,10,12,14,16,18,20^CInterrupted. Prelude> ie after ??,20? instead of printing a ']' and giving back the "Prelude>" prompt it hangs? searching in the entire set of integers > 10? for an integer <= 10 (!!) ?until a Control-C is given What?s the conclusion?? Take your pick: - Functional programming is stupid - Haskell is not all that intelligent - Halting problem is unsolvable - Converting the borderline uncomputable notion of set builder /comprehensions into the computational framework of programming is fraught with trouble - Sets are a harder data-structure from computational pov than lists - ?? > > > > >> Analogous thing shown at ghci prompt: > >> > >> | ghci> [x*2 | x <- [1..10]] > >> | [2,4,6,8,10,12,14,16,18,20] So not really analogous! [Its the first time I am reading that article/book? just searched a standard Haskell tutorial source and posted it] > > > > And what if you HAVEN'T taken a course in mathematics? What use is > > this then? How would you teach this to a non-mathematician? > > Speaking as someone who *has* taken a course of mathematics or two, I find that > Rustom's insistence in coming back to the fundamentals of set theory and the > Zermelo?Fraenkel axioms is not terribly helpful. Even among professional > mathematicians. Z-F and the axiom of choice and related matters are extremely > specialised and abstract fields of little interest to the average working > mathematician. Dunno where you got that My reference to Zermelo-Fraenkel was entirely from the point of tracing the history, not to say that the logic-studies of a 100 years ago has any relevance to today Specifically the term 'comprehension' used today as a programming construct traces somewhat tenuously to an axiom that Zermelo/Fraenkel formulated in the 1920s Lives today in python in the fact that the russel-set gives a straightforward syntax error and nothing more grandly profound >>> R = {x if x not in x} File "", line 1 R = {x if x not in x} ^ SyntaxError: invalid syntax >>> ie the first element of a comprehension must be a 'for' not Almost? Unfortunately python muddies the discussion by overloading predicate 'in' and generator 'in'. So following follows the stricture above but still does not work ? >>> R = {x for x not in x} File "", line 1 R = {x for x not in x} ^ SyntaxError: invalid syntax >>> > > In my experience, they're of more interest to philosophers and dilettantes than > actual mathematicians, outside of the minority working in that specific field. > > Yes yes, it is absolutely fundamental to mathematics, just as quantum mechanics > is absolutely fundamental to an understanding of matter. How many bridge > builders care about quantum mechanics? > > Python is not Haskell and makes no pretence at being mathematically sound[1]. > The Zen of Python sets forth some of the design principles in the language, > and "mathematical purity" is not one of them. > > The opposite, in fact: "practicality beats purity." > > To answer your (Chris') question: Strawman argument as usual! For myself, thanks to Peter's clarification that 'comprehension' is best thought of as 'comprise', I am now going to teach to my students: ?Comprehension is a misspelling of comprision? [Comprehensivesion would be more tolerable semantically than comprehension but hurts mouth and eyes!] > > When I teach comprehension syntax, I always mention set builder notation and > say "you may have been taught this is school". I don't think I have ever come > across someone who both *was* taught it and *remembers* so, but I'll keep > trying. For those who don't understand set builder notation (so far, everyone > I've tried to teach comps to) I explain them in terms of for loops. > > In fact, even if you do understand set builder notation, for more complex > examples with "if" clauses and multiple "for" loops, I maintain that you have > to think of it in terms of loops to understand it. I am extremely skeptical > that anyone could look at a comprehension like: > > [expr for x in A for y in B if P for z in C if Q for w in D for v in E if R] > > and understand it *without* converting it to nested loops. > > > > Pretty much everyone, at some point in their lives, will follow a set > > of written instructions. Most commonly, a recipe for some sort of > > food. It consists of a set of ingredients and a sequence of commands. > > This translates well into a classic imperative style > > Indeed. People find imperative (recipe) algorithms easy to follow, and pure > functional reasoning hard. I'm glad that functional programming is fashionable > again, and hope that people will learn good habits from it, but I think that > mathematical purity is not necessary or even helpful in the majority of > programming tasks. I had a good friend in school who loved to play the flute. And when he played everyone around suffered He knew they suffered; he did not know why One day he asked me: ?Please teach me music!? ?uh? I dont know?flute? ?No No! You know music! Please teach me!? So I went to the piano and (tried) to show him? ?See (hear) this?? Middle-C + upper-C C + G C + E C + C# I was hoping to show him that musical proximity and physical proximity are not the same I was hoping to show him that? all C's are the 'same' C + G is consonant as is C + E; but C+E is more 'interesting' C+ C# is unpleasant etc I never reached that far! He gave me a funny look; I asked : ?What happened?? ?To me they all sound the same? (?!?!) So if Chris can answer how to teach music to a tone-deaf person, I can consider how to answer the question of how to teach programming to a math-challenged one Hint: >>> import operator >>> dir(operator) ['__abs__', '__add__', '__and__', '__concat__', '__contains__', '__delitem__', '__delslice__', '__div__', '__doc__', '__eq__', '__floordiv__', '__ge__', '__getitem__', '__getslice__', '__gt__', '__iadd__', '__iand__', '__iconcat__', '__idiv__', '__ifloordiv__', '__ilshift__', '__imod__', '__imul__', '__index__', '__inv__', '__invert__', '__ior__', '__ipow__', '__irepeat__', '__irshift__', '__isub__', '__itruediv__', '__ixor__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__name__', '__ne__', '__neg__', '__not__', '__or__', '__package__', '__pos__', '__pow__', '__repeat__', '__rshift__', '__setitem__', '__setslice__', '__sub__', '__truediv__', '__xor__', '_compare_digest', 'abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 'delitem', 'delslice', 'div', 'eq', 'floordiv', 'ge', 'getitem', 'getslice', 'gt', 'iadd', 'iand', 'iconcat', 'idiv', 'ifloordiv', 'ilshift', 'imod', 'imul', 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irepeat', 'irshift', 'isCallable', 'isMappingType', 'isNumberType', 'isSequenceType', 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'repeat', 'rshift', 'sequenceIncludes', 'setitem', 'setslice', 'sub', 'truediv', 'truth', 'xor'] Do tell me how many of these are unrelated to math! From no.email at nospam.invalid Sun Aug 20 01:29:57 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Sat, 19 Aug 2017 22:29:57 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87h8x2lsbu.fsf@nightsong.com> Rustom Mody writes: > Specifically the term 'comprehension' used today as a programming construct > traces somewhat tenuously to an axiom that Zermelo/Fraenkel formulated > in the 1920s I thought went back to Frege. Also, it appears in Zermelo set theory Z. ZF is Z with the Axiom of Replacement added, but Z was somewhat earlier than ZF. From rosuav at gmail.com Sun Aug 20 01:30:41 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 20 Aug 2017 15:30:41 +1000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Sun, Aug 20, 2017 at 2:28 PM, Rustom Mody wrote: > So if Chris can answer how to teach music to a tone-deaf person, I can > consider how to answer the question of how to teach programming to a math-challenged one You don't HAVE to understand math to be a programmer. Plenty of math-challenged people can cook. See my earlier example of recipes. ChrisA From steve+python at pearwood.info Sun Aug 20 02:33:20 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Sun, 20 Aug 2017 16:33:20 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59992d32$0$1603$c3e8da3$5496439d@news.astraweb.com> On Sun, 20 Aug 2017 02:28 pm, Rustom Mody wrote: >> >> | S = {2?x | x ? ?, x ? 10} [...] > There's more than just a nit-pick wrong with that expression The expression is fine. It is a mathematical expression, not Haskell code, so your example of Haskell code is irrelevant to judging maths notation. > Here?s an actual Haskell run > > Prelude> [x*2 | x <- [1..], x <= 10] > [2,4,6,8,10,12,14,16,18,20^CInterrupted. > Prelude> > > ie after ??,20? instead of printing a ']' and giving back the "Prelude>" > prompt it hangs? searching in the entire set of integers > 10? > for an integer <= 10 (!!) > ?until a Control-C is given If only Haskell supported the Clojure syntax: (for [x (range 1) :while (<= x 10)] x*2) (I may have got the order of x and 10 backwards, I haven't tested the above in a Clojure interpreter.) http://clojuredocs.org/clojure.core/for > What?s the conclusion?? Take your pick: > - Functional programming is stupid > - Haskell is not all that intelligent > - Halting problem is unsolvable > - Converting the borderline uncomputable notion of set builder /comprehensions > into the computational framework of programming is fraught with trouble > - Sets are a harder data-structure from computational pov than lists > - ?? None of the above. How about...? - abstract mathematics is not programming. [...] > Lives today in python in the fact that the russel-set gives a straightforward > syntax error and nothing more grandly profound > >>>> R = {x if x not in x} > File "", line 1 > R = {x if x not in x} > ^ > SyntaxError: invalid syntax Rustom, please write 100 times on the blackboard, "I cannot mechanically translate abstract maths notation into programming languages without understanding the semantics of both." Thank you. All you have demonstrated is that mechanically translating abstract maths notation into Python code without considering the semantics of either is, in general, doomed to fail. > Strawman argument as usual! If I had a dollar for every time somebody misused "strawman argument" to mean "a valid argument against my position that I cannot counter", I'd be able to afford to purchase a small island in the Pacific. Such as New Zealand. > For myself, thanks to Peter's clarification that 'comprehension' is best > thought of as 'comprise', I am now going to teach to my students: > ?Comprehension is a misspelling of comprision? Only if you wish to mislead your students. "How do you know that, Herr Doktor Professor Mody?" "Oh, some random person on the internet gave me his guess as to the etymology of the word, I made up my own word 'comprision', and put 2 and 2 together to get 7. Any other questions?" Comprehension is not a misspelling of anything, and I don't think Peter is correct. According to the OED, the etymology of "comprehension" comes from French compr?hension or Latin comprehensio, to seize. Comprise is also derived from the same words, but independently. Both are first attested to in the late Middle Ages. By the way, this was discussed in detail at least once before: http://code.activestate.com/lists/python-list/123564/ -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From stephanh42 at gmail.com.invalid Sun Aug 20 02:56:47 2017 From: stephanh42 at gmail.com.invalid (Stephan Houben) Date: 20 Aug 2017 06:56:47 GMT Subject: Cross-language comparison: function map and similar References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: Op 2017-08-16, Steve D'Aprano schreef : > Are there language implementations which evaluate the result of map() > (or its equivalent) in some order other than the obvious left-to-right > first-to-last sequential order? Is that order guaranteed by the > language, or is it an implementation detail? > > Standard library functions implementing an explicitly "parallel map" > or "threaded map" are also relevant. (Less interested in third-party > libraries, unless they're practically a standard for the language in > question.) C++17 has such a facility in its standard library. std::transform (and many other functions operating on sequences, but you asked for a map() equivalent) takes an optional "execution_policy" parameter which indicates if the operation should be run sequentially (the default) or can be parallellized. See: http://en.cppreference.com/w/cpp/algorithm/transform Stephan From jfong at ms4.hinet.net Sun Aug 20 04:48:59 2017 From: jfong at ms4.hinet.net (jfong at ms4.hinet.net) Date: Sun, 20 Aug 2017 01:48:59 -0700 (PDT) Subject: Ask for help about a tkinter problem Message-ID: <942ccec3-7998-401d-b750-97a2efe50802@googlegroups.com> I am running a tkinter tutor downloaded from web, https://github.com/daleathan/widget-tour-py3. there are two files involved: -------------------- #file button.py from tkinter import * from tkinter.ttk import * import infrastructure ... class ButtonsDemoWindow( infrastructure.DemoWindow ): ... def __init__( self ): ... ... for c in ('Peach Puff', 'Light Blue', 'Sea Green', 'Yellow' ): b = Button(self.frame, text=c) b['command'] = infrastructure.callit( self.callback, c ) b.pack( side=TOP, expand=YES, pady=2 ) def callback(self, color): self.frame['background']=color def runDemo(): ButtonsDemoWindow() ---------------------- #file infrastructure.py ... class DemoWindow( Toplevel ): ... ... class callit: def __init__(self, function, *args ): self.f = function self.args = args def __call__(self, *ignored): self.f( *self.args) -------------------- I run it under the DOS box: D:\Works\Python\widget-tour-py3-master>python Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import button >>> button.runDemo() after the window shows up, I pressed one of the buttons and get the error below: >>> Exception in Tkinter callback Traceback (most recent call last): File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__ return self.func(*args) File "D:\Works\Python\widget-tour-py3-master\infrastructure.py", line 216, in __call__ self.f( *self.args) File "D:\Works\Python\widget-tour-py3-master\button.py", line 39, in callback self.frame['background']=color File "C:\Python34\lib\tkinter\__init__.py", line 1331, in __setitem__ self.configure({key: value}) File "C:\Python34\lib\tkinter\__init__.py", line 1324, in configure return self._configure('configure', cnf, kw) File "C:\Python34\lib\tkinter\__init__.py", line 1315, in _configure self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) _tkinter.TclError: unknown option "-background" When I looked into the file tkinter\__init__.py, I found there is codes which add conditionally a '-' onto the original cnf argument: 1305 def _configure(self, cmd, cnf, kw): 1306 """Internal function.""" ... ... 1313 if isinstance(cnf, str): 1314 return self._getconfigure1(_flatten((self._w, cmd, '-'+cnf))) Is it the reason this exception raised? Why is that? Best Regards, Jach Fong From __peter__ at web.de Sun Aug 20 05:51:40 2017 From: __peter__ at web.de (Peter Otten) Date: Sun, 20 Aug 2017 11:51:40 +0200 Subject: Ask for help about a tkinter problem References: <942ccec3-7998-401d-b750-97a2efe50802@googlegroups.com> Message-ID: jfong at ms4.hinet.net wrote: > I am running a tkinter tutor downloaded from web, > https://github.com/daleathan/widget-tour-py3. there are two files > involved: > > -------------------- > #file button.py > > from tkinter import * > from tkinter.ttk import * > import infrastructure > ... > class ButtonsDemoWindow( infrastructure.DemoWindow ): > ... > def __init__( self ): > ... > ... > for c in ('Peach Puff', 'Light Blue', 'Sea Green', 'Yellow' ): > b = Button(self.frame, text=c) > b['command'] = infrastructure.callit( self.callback, c ) > b.pack( side=TOP, expand=YES, pady=2 ) > > def callback(self, color): > self.frame['background']=color > > def runDemo(): > ButtonsDemoWindow() > > ---------------------- > #file infrastructure.py > ... > class DemoWindow( Toplevel ): > ... > ... > class callit: > def __init__(self, function, *args ): > self.f = function > self.args = args > > def __call__(self, *ignored): > self.f( *self.args) > > -------------------- > I run it under the DOS box: > > D:\Works\Python\widget-tour-py3-master>python > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 > 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or > "license" for more information. > >>> import button > >>> button.runDemo() > > after the window shows up, I pressed one of the buttons and get the error > below: > >>>> Exception in Tkinter callback > Traceback (most recent call last): > File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__ > return self.func(*args) > File "D:\Works\Python\widget-tour-py3-master\infrastructure.py", line > 216, in __call__ > self.f( *self.args) > File "D:\Works\Python\widget-tour-py3-master\button.py", line 39, in > callback > self.frame['background']=color > File "C:\Python34\lib\tkinter\__init__.py", line 1331, in __setitem__ > self.configure({key: value}) > File "C:\Python34\lib\tkinter\__init__.py", line 1324, in configure > return self._configure('configure', cnf, kw) > File "C:\Python34\lib\tkinter\__init__.py", line 1315, in _configure > self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) > _tkinter.TclError: unknown option "-background" > > > When I looked into the file tkinter\__init__.py, I found there is codes > which add conditionally a '-' onto the original cnf argument: That is just a peculiarity of TCL; a "-" is added to the option by the Python wrapper before passing it along > 1305 def _configure(self, cmd, cnf, kw): > 1306 """Internal function.""" > ... > ... > 1313 if isinstance(cnf, str): > 1314 return self._getconfigure1(_flatten((self._w, cmd, > '-'+cnf))) > > Is it the reason this exception raised? Why is that? I can confirm the problem. It looks like the bug was introduced when the example was converted from stock tkinter to the new ttk widget set. While frame["background"] = color works when frame is a tkinter.Frame widget the newer tkinter.ttk.Frame widget uses "styles" to configure its appearance. I have not used that new feature, but with the help of http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-style-layer.html and some trial and error I modified the example to use a style: $ diff -u button.py button_fixed.py --- button.py 2017-08-20 11:44:33.841839812 +0200 +++ button_fixed.py 2017-08-20 11:44:04.032426163 +0200 @@ -25,7 +25,9 @@ infrastructure.DemoWindow.__init__(self, intro, 'button.py' ) - self.frame=Frame(self) + self.style = Style(self) + self.frame=Frame(self, style="foo.TFrame") + self.frame.pack(expand=YES, fill=BOTH ) for c in ('Peach Puff', 'Light Blue', 'Sea Green', 'Yellow' ): @@ -36,7 +38,7 @@ def callback(self, color): - self.frame['background']=color + self.style.configure("foo.TFrame", background=color) def runDemo(): $ However, I'm not sure if this is the canonical way to write it... From jfong at ms4.hinet.net Sun Aug 20 20:28:46 2017 From: jfong at ms4.hinet.net (jfong at ms4.hinet.net) Date: Sun, 20 Aug 2017 17:28:46 -0700 (PDT) Subject: Ask for help about a tkinter problem In-Reply-To: References: <942ccec3-7998-401d-b750-97a2efe50802@googlegroups.com> Message-ID: <8cfd7c3f-651b-44c0-b07b-17f32769b31e@googlegroups.com> Peter Otten at 2017/8/20 UTC+8 PM 5:52:24 wrote: > jfong at ms4.hinet.net wrote: > > > I am running a tkinter tutor downloaded from web, > > https://github.com/daleathan/widget-tour-py3. there are two files > > involved: > > > > -------------------- > > #file button.py > > > > from tkinter import * > > from tkinter.ttk import * > > import infrastructure > > ... > > class ButtonsDemoWindow( infrastructure.DemoWindow ): > > ... > > def __init__( self ): > > ... > > ... > > for c in ('Peach Puff', 'Light Blue', 'Sea Green', 'Yellow' ): > > b = Button(self.frame, text=c) > > b['command'] = infrastructure.callit( self.callback, c ) > > b.pack( side=TOP, expand=YES, pady=2 ) > > > > def callback(self, color): > > self.frame['background']=color > > > > def runDemo(): > > ButtonsDemoWindow() > > > > ---------------------- > > #file infrastructure.py > > ... > > class DemoWindow( Toplevel ): > > ... > > ... > > class callit: > > def __init__(self, function, *args ): > > self.f = function > > self.args = args > > > > def __call__(self, *ignored): > > self.f( *self.args) > > > > -------------------- > > I run it under the DOS box: > > > > D:\Works\Python\widget-tour-py3-master>python > > Python 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 > > 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or > > "license" for more information. > > >>> import button > > >>> button.runDemo() > > > > after the window shows up, I pressed one of the buttons and get the error > > below: > > > >>>> Exception in Tkinter callback > > Traceback (most recent call last): > > File "C:\Python34\lib\tkinter\__init__.py", line 1538, in __call__ > > return self.func(*args) > > File "D:\Works\Python\widget-tour-py3-master\infrastructure.py", line > > 216, in __call__ > > self.f( *self.args) > > File "D:\Works\Python\widget-tour-py3-master\button.py", line 39, in > > callback > > self.frame['background']=color > > File "C:\Python34\lib\tkinter\__init__.py", line 1331, in __setitem__ > > self.configure({key: value}) > > File "C:\Python34\lib\tkinter\__init__.py", line 1324, in configure > > return self._configure('configure', cnf, kw) > > File "C:\Python34\lib\tkinter\__init__.py", line 1315, in _configure > > self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) > > _tkinter.TclError: unknown option "-background" > > > > > > When I looked into the file tkinter\__init__.py, I found there is codes > > which add conditionally a '-' onto the original cnf argument: > > That is just a peculiarity of TCL; a "-" is added to the option by the > Python wrapper before passing it along > > > 1305 def _configure(self, cmd, cnf, kw): > > 1306 """Internal function.""" > > ... > > ... > > 1313 if isinstance(cnf, str): > > 1314 return self._getconfigure1(_flatten((self._w, cmd, > > '-'+cnf))) > > > > Is it the reason this exception raised? Why is that? > > I can confirm the problem. It looks like the bug was introduced when the > example was converted from stock tkinter to the new ttk widget set. > > While > > frame["background"] = color > > works when frame is a tkinter.Frame widget the newer tkinter.ttk.Frame > widget uses "styles" to configure its appearance. > > I have not used that new feature, but with the help of > > http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/ttk-style-layer.html > > and some trial and error I modified the example to use a style: > > $ diff -u button.py button_fixed.py > --- button.py 2017-08-20 11:44:33.841839812 +0200 > +++ button_fixed.py 2017-08-20 11:44:04.032426163 +0200 > @@ -25,7 +25,9 @@ > > infrastructure.DemoWindow.__init__(self, intro, 'button.py' ) > > - self.frame=Frame(self) > + self.style = Style(self) > + self.frame=Frame(self, style="foo.TFrame") > + > self.frame.pack(expand=YES, fill=BOTH ) > for c in ('Peach Puff', 'Light Blue', > 'Sea Green', 'Yellow' ): > @@ -36,7 +38,7 @@ > > > def callback(self, color): > - self.frame['background']=color > + self.style.configure("foo.TFrame", background=color) > > > def runDemo(): > $ > > However, I'm not sure if this is the canonical way to write it... Thank you for your answer. I try not to use the ttk by comment the line "from tkinter.ttk import *", and also try your "Style" modification codes, both work:-) > That is just a peculiarity of TCL; a "-" is added to the option by the > Python wrapper before passing it along This extra "-" confuses people when showing up in the Traceback info. Can't figure out why the author want to do this. --Jach From steve+python at pearwood.info Sun Aug 20 22:00:38 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 21 Aug 2017 12:00:38 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> <87shgp2wms.fsf@elektro.pacujo.net> Message-ID: <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 04:55 pm, Marko Rauhamaa wrote: > Is a Python implementation > allowed to parallelize or otherwise reorder the evaluation loop? No. I initially was going to just say "Read the PEP, read the What's New from 2.0, read the docs, notice the deliberate use of the same terminology as for-loops and the similarity to generator expression syntax", but in fact there's a simple demonstration for why list comps are not free to reorder the evaluation. from io import StringIO # simulate reading from a file myfile = StringIO('Is this the room for an argument?') values = [myfile.read(1) for i in range(33)] print(''.join(values)) For all the talk of how people read list comps declaratively without caring about the order the values are computed, if the above code snippet printed: 'nmoe sIsta ret hhna fto?mri rugo' instead of the expected 'Is this the room for an argument?', I believe that we would all agree that behaviour a bug. Perhaps not so much *here*, where we've paid for the full hour[1], but if it happened to us in real-life code, certainly. [1] "I'm sorry, I'm not allowed to argue unless you've paid." -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From python at mrabarnett.plus.com Sun Aug 20 22:12:55 2017 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 21 Aug 2017 03:12:55 +0100 Subject: Ask for help about a tkinter problem In-Reply-To: <8cfd7c3f-651b-44c0-b07b-17f32769b31e@googlegroups.com> References: <942ccec3-7998-401d-b750-97a2efe50802@googlegroups.com> <8cfd7c3f-651b-44c0-b07b-17f32769b31e@googlegroups.com> Message-ID: <3d58740b-3251-de99-506d-0fb271712bd4@mrabarnett.plus.com> On 2017-08-21 01:28, jfong at ms4.hinet.net wrote: > Peter Otten at 2017/8/20 UTC+8 PM 5:52:24 wrote: [snip] >> That is just a peculiarity of TCL; a "-" is added to the option by the >> Python wrapper before passing it along > > This extra "-" confuses people when showing up in the Traceback info. Can't figure out why the author want to do this. > To clarify what Peter said, tkinter is a GUI library written in the Tcl programming language. The 'tkinter' module in Python's standard library is just a wrapper around that library. The Perl and Ruby programming languages also have wrappers. The "-" is added because the Tcl language requires it. From python at mrabarnett.plus.com Sun Aug 20 22:19:47 2017 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 21 Aug 2017 03:19:47 +0100 Subject: Proposed new syntax In-Reply-To: <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> <87shgp2wms.fsf@elektro.pacujo.net> <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 2017-08-21 03:00, Steve D'Aprano wrote: > On Fri, 18 Aug 2017 04:55 pm, Marko Rauhamaa wrote: > >> Is a Python implementation >> allowed to parallelize or otherwise reorder the evaluation loop? > > No. > [snip] Well, I suppose an implementation _could_ parallelise, or whatever, _provided that_ it gave the same result. From rosuav at gmail.com Sun Aug 20 22:33:15 2017 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 21 Aug 2017 12:33:15 +1000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> <87shgp2wms.fsf@elektro.pacujo.net> <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Mon, Aug 21, 2017 at 12:19 PM, MRAB wrote: > On 2017-08-21 03:00, Steve D'Aprano wrote: >> >> On Fri, 18 Aug 2017 04:55 pm, Marko Rauhamaa wrote: >> >>> Is a Python implementation >>> allowed to parallelize or otherwise reorder the evaluation loop? >> >> >> No. >> > [snip] > > Well, I suppose an implementation _could_ parallelise, or whatever, > _provided that_ it gave the same result. In other words, it's allowed to parallelise, just as long as everything happens sequentially. With arbitrary expressions, one of them could affect another easily. ChrisA From steve+python at pearwood.info Sun Aug 20 22:43:36 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 21 Aug 2017 12:43:36 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> Message-ID: <599a48d9$0$1586$c3e8da3$5496439d@news.astraweb.com> On Fri, 18 Aug 2017 04:16 pm, Paul Rubin wrote: [...] > Similarly we occasionally have to be aware of the procedural nature > of Python list comprehensions, but most of the time we think of them > in terms of the mathematical abstraction they are designed to resemble. Thanks Paul, you've given me an insight into the disagreement. I strongly disagree with your "most of the time" but I can see some justification for the view. I think you have hit the nail on the head regarding the argument over comprehensions. Can we understand comprehensions as an abstraction? Yes we can: result = [ ... magic happens in here ... ] We can ignore the insides of the comprehension (I don't mean the implementation, I mean literally the stuff between the square brackets) and treat it as a black box that returns a list. Just as we can ignore the insides of a function call: result = make_list(...) Of course we can gloss over the fact that comprehensions are explicitly written as iteration and ignore the details, just as we can ignore the details of any piece of code: result = [] # Oh, it's going to be a list. for x in stuff: ...magic happens here... print(result) # Some sort of list. Probably. and of course we gloss over code all the time, ignoring the details that aren't important at the moment. "Details, details, don't bother me with details!" So from *that* perspective of taking a birds-eye view of the code, I'll grant that if you don't care about the details of what the comprehension returns, we can gloss over it and treat it as a magic black box that returns a list, and we don't care how it was generated: recursively, iteratively, using GOTO or an unrolled loop, or black magic, it doesn't matter and we don't care. But only to a point. If all you care about is "it returns a list", then that's fine. But of course people don't really care about *only* that, they also care about what it contains, and that the comprehension or generator expression iterates over its argument in a specific order. If we write: [process(a) for a in (1, 2, 3)] then we typically expect 1 to be processed before 2, and 3 last of all. If you've ever iterated over a file in a comprehension, you have relied on that fact, whether you realised or not, and even if process() has no side-effects and you don't care about the order of evaluation per se, in general we care about the order that the results are returned. I dare say that there are cases where people would happily replace their list comprehension with a parallel map() that doesn't guarantee either the order of evaluation or the order the results are returned, given some sufficient speed up. But that's a special case, not a universal: most of the time, we expect our data to be processed in the order we give it, not in some arbitrary order, and even if a parallel map was available we'd prefer iteration because it is more easily understood and debugged and matches most people's expectations of sequential processing. For example, given: [format(linenum) + line for (linenum, line) in enumerate(myfile)] I think that most people would be disturbed if the returned list didn't match the order of lines in the file. With the simplest comprehensions, those with a single for loop, its easily to let your eyes slide over the explicit iteration syntax and read it as some sort of funny map syntax: result = [expression ... iterable] # [] means "map" But for more complex comprehensions, that's much harder, if not impossible, and you cannot get away from the execution details, and *that* is explicitly written as iteration using explicit for-loops and conditional if statements. Not as nested maps, or as recursion, or as a parallel set of function calls. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Mon Aug 21 00:03:10 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Mon, 21 Aug 2017 14:03:10 +1000 Subject: A question on modification of a list via a function invocation References: <06682e35-9481-db00-6895-63496a4802f7@nedbatchelder.com> <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> Message-ID: <599a5b80$0$1584$c3e8da3$5496439d@news.astraweb.com> On Sat, 19 Aug 2017 12:04 am, Ben Bacarisse wrote: [...] >> Look at Scott Stanchfield's extremely influential post. It is *not* >> called: >> >> "Java is call by value where the value is an invisible object reference, >> dammit!" >> >> http://javadude.com/articles/passbyvalue.htm >> >> and consequently people who don't read or understand the *entire* post in >> full take away the lesson that >> >> "Java is call by value, dammit!" > > I don't think this is a fair point. You will run out of ideas if they > are to be avoided because some people will get the wrong idea when > reading part of a description of that idea applied to some other language. I don't understand your point here. I'm saying that Scott Stanchfield intentionally created a pithy, short and snappy one-sentence summary of his position which is incorrect and misleading. He actually does know the difference between call by value and "call by value where the value is not the value but a reference or pointer to the value", because he clarifies the second further down in his essay. Python values are objects, not "references or pointers". We bind objects to names: x = [1, 2, 3] and pass objects to functions, and return objects back from functions. There's no way in Python to get a reference to a object instead of the object itself: y = ptr to x If there was, we could write the classic "swap" procedure that Scott talks about: def func(a, b): ref1 = ptr to a ref2 = ptr to b c = a ref1 -> b ref2 -> c return None or something along those lines, I haven't spent the time to debug this pseudo-code so I may have got the details wrong. >> So how do we distinguish between languages like Java and Python and >> those like C and Pascal which *genuinely* are call by value, and do >> exhibit call by value semantics? For example, in Pascal, if you >> declare an array parameter without specifying it as "var", the >> compiler will copy the entire array. Java does not do that. Python >> does not do that. > > Well, I know how I do that but you are not a fan of that view. The problem isn't people like you who understand the point being made. Of course the CPython virtual machine is passing pointers around by value, but that's actually not very interesting unless you care about the detailed implementation of how the virtual machine operates. Which I accept is interesting to some people, but it doesn't help us when we want to reason about Python values (objects). Okay, Python copies a reference to my object. So what? What does that tell me about the behaviour of my Python code? The problem is that your explanation is at the wrong abstraction level for most purposes. Ultimately, all computers do is move electric currents around. But that's not abstract enough to reason about, so we have a hierarchy of abstractions: - flipping bits - copying bytes - reading and writing values at memory locations - copying references/pointers - binding objects to names <--- Python syntax works at this level and so on. (I may have missed a few.) I'll accept that say that are some aspects of Python's behaviour that need to be explained at lower levels of abstraction. Sometimes we care about copying bytes. But as an explanation of the behaviour of Python code, in general we should talk at the same abstraction level as the language itself. And if we drop down to a lower level of abstraction, we should make it clear from the start, not as an after thought halfway down the essay. > I found it a helpful view because it covers a lot more than just > argument passing by saying something about the set of values that Python > expressions manipulate. It may be wrong in some case (hence my > question) but I don't think I've been led astray by it (so far!). I will admit that I haven't spent a lot of time thinking about how the argument passing abstractions apply to general expressions as opposed to function calls. I don't think it matters, but I haven't thought about it in enough detail to be sure. >> C doesn't treat arrays as first class values, so you can't pass an array as >> argument. You can only pass a pointer to the start of the array. But you can >> declare arbitrarily big structs, and they are copied when you pass them to >> functions. Java objects are not. Despite Scott's insistence that Java is >> exactly the same as C, it isn't. > > I'm not here to defend someone else's incorrect statements! Clearly C > is not the same as Java. Equally clearly, C only passes arguments by > value (I have no idea about Java). To be pedantic, Java treats native unboxed machine values (like ints and floats) the same as C, using classical call-by-value "copy the int when you pass it to a function" semantics. But for objects, including "boxed" ints and floats, the semantics are exactly the same as Python. I maintain "call by (object) sharing" is the best term to use, to avoid confusion with classic call-by-value semantics, and to avoid misusing the term "value" to mean part of the implementation rather than the entities we manipulate in our code. Given x = 1, any explanation that relies on denying that x has the value 1 is a non-starter for me. If we have to talk about "the value" being some invisible reference or pointer to 1, you're talking at too deep a level of abstraction. But if somebody asks how call-by-sharing is implemented, I'm very happy to say that Scott's explanation in terms of copying references or pointers to objects is a good one. Now we're talking implementation, rather than the programming interface exposed by the Python programming language (or Java objects), and talking about the lower-level implementation is precisely the right level to use. It may not be the *only* possible implementation that gives the same semantics, but I'll let the compiler people argue that point. >> If we claim that Python is call by value, without specifying the >> proviso "if you consider the value to be the invisible reference to >> the actual value" every time, we risk misleading others into wrongly >> inferring that Python is "call by value" and you shouldn't pass big >> lists to functions because then they will be copied and that's >> inefficient. > > True, though I obviously take issue with using a particularly > long-winded phrase. See later for how Liskov does it with one short > word. You can't use "call by value" to refer to Python semantics without the long-winded phase, not without it sounding like you're referring to what C and Pascal and BASIC and many other languages do, "call by value". > The core of the idea is actually what the value-set of Python programs > is -- the passing by value just drops out of that. Talking about > object identities (or references) is not so very cumbersome. You have > to talk about *something* like that explain the language, don't you? Occasionally. But only, I think, because some people don't like the idea of objects being in multiple places at once -- and they especially don't like the idea of an object containing itself, like the TARDIS in Doctor Who once or twice when things have gone badly wrong. For those who don't like the idea of objects being in two places at once, it is probably necessary to drop down to a lower, implementation level explanation: "of course the object actually only exists in one place in memory, and what the virtual machine actually is passing around is a pointer to the object..." I have no objection to explanations which make it clear when we're talking about the high-level Python objects and when we're talking about the lower-level implementation. I object to people taking the lower-level explanation and treating it as the high-level description. >> Or people will be confused by the behaviour of Python, and decide that maybe >> it is only call by value when you pass an immutable object like a string or >> int, and is call by reference when you pass a mutable object like a list or >> dict. Many people have done that. > > I'm not a fan of this notion that an idea is bad because it goes wrong > when people don't understand it. I don't think any description of > Python's semantics can avoid that trap. Are you familiar with the term "bug magnet"? We can introduce bugs into any sort of code, but some features or libraries *encourage* bugs in ways that others don't. Using familiar terms in unfamiliar ways is a bug magnet. It doesn't just allow or even invite misunderstandings and confusion, it encourages it. Sometimes communities of people deliberate do that as a technique for excluding outsiders. Slang and argots often use the same words as the regular language that they are based on, but twisted, often in obscure ways: - boat (face); - to have a butcher's (look); - weasel (coat). "Have a butcher's at the boat on that geezer in the weasel" would be all but indecipherable to anyone not in the know. Even when not deliberately intended to exclude outsiders, this can lead to difficulty in communication and confusion. Whatever the cultural reason, the majority of programmers have strong intuitions of what "call by value" means, and the implications of it. Slightly less so for "call by reference", but still very common. Taken together with the false dichotomy that they are the only two calling conventions in programming languages (a false dichotomy reinforced by the Java community), this is a bug magnet: it leads some people into mistakenly reasoning that Python must use two different calling conventions: - call by reference for mutable objects; - call by value for immutable objects. [...] > I'm not advocating the former because I want to say more than just what > values get passed, and the latter does not explain some other cases that > confuse people new to the language such as > > x = [[1]] > y = x > x[0][0] = 42 What part of this do you think is confusing? Surely you would expect that: print(x) => prints [[42]] What else would you expect? And given that assignment doesn't copy values (because Python's evaluation strategy is NOT pass by value!) you should expect that print(y) also prints the same thing. If newcomers to the language are confused by that, then they're probably expecting that assignment copies, i.e. pass by value semantics. [...] > Yes I know. I had the pleasure of talking programming languages with > her once -- scary bright person! Liskov on CLU: > > x := e > causes x to refer to the object obtained by evaluating expression e. > > Not the "refer". That's all it takes. The value of x is not the > object, x /refers/ to the object. You can say the same thing even in classic pass by value languages like Pascal or C: x := 1.0; # Pascal syntax the name "x", or just x if you like, refers to the floating point value 1.0. Just as "the POTUS" currently refers to Donald Trump. That's not different from "the value of x is 1.0", it's merely emphasising that the x is a name. > And on calling: > > ... arguments are passed "by object"; the (pointer to the) object > resulting from evaluating the actual argument expression is assigned > to the formal. (Thus passing a parameter is just doing an assignment > to the formal.) > > I think this is true of Python too. If so, I'd be tempted to define > passing "as if by assignment" (as it's done in the C standard) and make > the semantics of assignment the basic feature that needs to be > described. For those not familiar with "as if by assignment" in the C standard, can you explain? > Finally, from the Python tutorial[1] > > "... arguments are passed using call by value (where the value is > always an object reference, not the value of the object)." > > Maybe I got it from there and generalised a little. I would not want to > see that remark removed (because, if that's where I got it from, it > helped me), but maybe it is now doomed. :-) > [1] https://docs.python.org/3/tutorial/controlflow.html#defining-functions -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From jumppanen.jussi at gmail.com Mon Aug 21 01:03:08 2017 From: jumppanen.jussi at gmail.com (jumppanen.jussi at gmail.com) Date: Sun, 20 Aug 2017 22:03:08 -0700 (PDT) Subject: =?UTF-8?Q?=5BANN=5D_Zeus_IDE_=E2=80=93_Version_3=2E98k_Released?= Message-ID: <352229a9-2a8a-4873-acfe-b6600d20871f@googlegroups.com> Zeus is a language neutral programmer's editor/IDE which includes support for the Python language. Python related changes new to this release include: * New feature allowing user input for tools * User input feature adds Python IDLE shell inside editor * Updated Jedi for Python autocomplete and code navigation * More improvements to editor response times * Lots of other minor improvements More?information on Zeus can be found here: ??? http://www.zeusedit.com/ NOTE: Zeus is shareware, runs?on Windows only and was created by me. Jussi Jumppanen Author: Zeus IDE From dieter at handshake.de Mon Aug 21 03:14:26 2017 From: dieter at handshake.de (dieter) Date: Mon, 21 Aug 2017 09:14:26 +0200 Subject: how to create root with treelib? References: <3ea125e1-029d-4a23-8d06-bf082d181d19@googlegroups.com> Message-ID: <878tidmlyl.fsf@handshake.de> Ho Yeung Lee writes: > http://treelib.readthedocs.io/en/latest/examples.html > > tree = Tree() > #create root > tree.create_node((0,0), "root") > result = [aa[0]] > previousnode = (0,0) > >>>> #create root > ... tree.create_node((0,0), "root") > Traceback (most recent call last): > File "", line 2, in > File "C:\Python27\lib\site-packages\treelib\node.py", line 142, in __repr__ > "tag=%r" % self.tag, > TypeError: not all arguments converted during string formatting Check the code of "treelib.node" near line 142 in order to determine where the value for the attribute "tag" comes from. Your error message suggests that "tag" might have gotten its value from the first parameter of "create_node". In this case, "self.tag" would be a tuple of 2 elements and the above error would occur because the pattern has a specification for a single element. In this case, do not pass tuples as first parameter to "create_node" (but strings). From __peter__ at web.de Mon Aug 21 03:45:52 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 21 Aug 2017 09:45:52 +0200 Subject: how to create root with treelib? References: <3ea125e1-029d-4a23-8d06-bf082d181d19@googlegroups.com> <878tidmlyl.fsf@handshake.de> Message-ID: dieter wrote: > Ho Yeung Lee writes: > >> http://treelib.readthedocs.io/en/latest/examples.html >> >> tree = Tree() >> #create root >> tree.create_node((0,0), "root") >> result = [aa[0]] >> previousnode = (0,0) >> >>>>> #create root >> ... tree.create_node((0,0), "root") >> Traceback (most recent call last): >> File "", line 2, in >> File "C:\Python27\lib\site-packages\treelib\node.py", line 142, in >> __repr__ >> "tag=%r" % self.tag, >> TypeError: not all arguments converted during string formatting > > Check the code of "treelib.node" near line 142 in order to determine > where the value for the attribute "tag" comes from. > > Your error message suggests that "tag" might have gotten its value > from the first parameter of "create_node". In this case, "self.tag" > would be a tuple of 2 elements and the above error would occur because > the pattern has a specification for a single element. > In this case, do not pass tuples as first parameter to "create_node" > (but strings). While the author of the library probably didn't expect tag to be anything but a string the problem seems to affect the node's repr() only. Once you replace the naked tag >> "tag=%r" % self.tag, in treelib/node.py with a one-tuple "tag=%r" % (self.tag,), the problem should be fixed. Or you avoid the method invocation in the interactive interpreter by assigning to a dummy variable >>> dummy = tree.create_node((0,0), "root") No, repr(), no exception ;) As MRAB says -- don't forget to report the bug to give the author a chance to fix it, once and for all. From tjreedy at udel.edu Mon Aug 21 07:16:19 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 21 Aug 2017 07:16:19 -0400 Subject: Ask for help about a tkinter problem In-Reply-To: <3d58740b-3251-de99-506d-0fb271712bd4@mrabarnett.plus.com> References: <942ccec3-7998-401d-b750-97a2efe50802@googlegroups.com> <8cfd7c3f-651b-44c0-b07b-17f32769b31e@googlegroups.com> <3d58740b-3251-de99-506d-0fb271712bd4@mrabarnett.plus.com> Message-ID: > On 2017-08-21 01:28, jfong at ms4.hinet.net wrote: >> Peter Otten at 2017/8/20 UTC+8 PM 5:52:24 wrote: > [snip] > >>> That is just a peculiarity of TCL; a "-" is added to the option by the >>> Python wrapper before passing it along >> >> This extra "-" confuses people when showing up in the Traceback info. >> Can't figure out why the author want to do this. >> > To clarify what Peter said, tkinter is a GUI library written in the Tcl > programming language. The Tcl GUI framework is tk, not tkinter. > The 'tkinter' module in Python's standard library is just a wrapper > around that library. tkinter abbreviates tk interface. In particular, it adds a Python class-based interface to tcl and tk functions and structures. > The "-" is added because the Tcl language requires it. From tjreedy at udel.edu Mon Aug 21 08:03:51 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Mon, 21 Aug 2017 08:03:51 -0400 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/20/2017 12:28 AM, Rustom Mody wrote: > Lives today in python in the fact that the russel-set gives a straightforward > syntax error and nothing more grandly profound > > R = {x if x not in x} > R = {x for x not in x} Try the actual Python syntax set builder expression and you get executable code: sos = R = {x for x in sos if x not in x} In Python, the expression creates a new set that is not a member of sos, so the x in 'x not in x' is never S, and there is no problem, as far as S is concerned, in evaluating 'x not in x'. But, is R is equal to some set z in sos? If yes, then we could identify R and z and say that R is in sos. But the answer is No. Russell's 'paradox' comes from separately insisting that the answer is also Yes. From jek7777777 at gmail.com Mon Aug 21 08:44:53 2017 From: jek7777777 at gmail.com (jek) Date: Mon, 21 Aug 2017 05:44:53 -0700 (PDT) Subject: Feature suggestion -- return if true In-Reply-To: <8abff237-5ccd-4eb6-85c8-cdc9e87520b7@bl1g2000vbb.googlegroups.com> References: <8abff237-5ccd-4eb6-85c8-cdc9e87520b7@bl1g2000vbb.googlegroups.com> Message-ID: <43f5ce33-790e-423b-8d2f-355f3e914d0a@googlegroups.com> This is a very old post, but since I just though I would like a conditional return like this, and checked for previous proposals, I thought I'd give my opinion. Unfortunately only about 8 of the 67 replies actually answer the question, and there isn't any overwhelming consensus to if a conditional return would be good or not. Most (if not all) people dislike the syntax though, and I agree. So, my proposal would be the syntax: return if That is more pythonic than return?, does not involve a new keyword, and is "human readable" in a way similar to e.g the ternary statement. //jek tue 12 apr 2011 zildjohn01 wrote: > I propose the following syntax: > > return? expr > > be expanded to > > _temp = expr > if _temp: return _temp As a side note, for the syntax of a cache, that was discussed a bit, I sometimes to use: try: return cache[key] except KeyError: ret = cache[key] = compute(key) return ret In my limited test it is a bit quicker than both "if x in cache" and "v=cache.get(x)" (~ 0.9, 1.1 and 1.3 seconds) Though it might depend on the hash complexity and the number of cache hits vs misses, so I guess either syntax would do fine. From elusivenode at gmail.com Mon Aug 21 10:34:46 2017 From: elusivenode at gmail.com (Hamish MacDonald) Date: Mon, 21 Aug 2017 14:34:46 +0000 Subject: Express thanks In-Reply-To: <43f5ce33-790e-423b-8d2f-355f3e914d0a@googlegroups.com> References: <8abff237-5ccd-4eb6-85c8-cdc9e87520b7@bl1g2000vbb.googlegroups.com> <43f5ce33-790e-423b-8d2f-355f3e914d0a@googlegroups.com> Message-ID: I wanted to give a shout out to the wonderfully passionate contributions to python I've witnessed following this and other mailing lists over the last little bit. The level of knowledge and willingness to help I've seen are truly inspiring. Super motivating. Probably the wrong forum for such a message but what the hey. Hamish -- From alister.ware at ntlworld.com Mon Aug 21 10:39:01 2017 From: alister.ware at ntlworld.com (alister) Date: Mon, 21 Aug 2017 14:39:01 GMT Subject: Feature suggestion -- return if true Message-ID: <9gCmB.132015$yz.34330@fx34.am4> On Mon, 21 Aug 2017 05:44:53 -0700, jek wrote: > This is a very old post, but since I just though I would like a > conditional return like this, and checked for previous proposals, I > thought I'd give my opinion. > > Unfortunately only about 8 of the 67 replies actually answer the > question, and there isn't any overwhelming consensus to if a conditional > return would be good or not. Most (if not all) people dislike the syntax > though, and I agree. > > So, my proposal would be the syntax: > > return if > > That is more pythonic than return?, does not involve a new keyword, and > is "human readable" in a way similar to e.g the ternary statement. > > //jek > > tue 12 apr 2011 zildjohn01 wrote: >> I propose the following syntax: >> >> return? expr >> >> be expanded to >> >> _temp = expr if _temp: return _temp > > As a side note, for the syntax of a cache, that was discussed a bit, I > sometimes to use: > > try: > return cache[key] > except KeyError: > ret = cache[key] = compute(key) > return ret > > In my limited test it is a bit quicker than both "if x in cache" and > "v=cache.get(x)" (~ 0.9, 1.1 and 1.3 seconds) Though it might depend on > the hash complexity and the number of cache hits vs misses, so I guess > either syntax would do fine. how does this syntax enable you to specify the value to be returned? What new benefits would this addition provide beyond what is already available? -- My father was a saint, I'm not. -- Indira Gandhi From ian.g.kelly at gmail.com Mon Aug 21 11:06:20 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Mon, 21 Aug 2017 09:06:20 -0600 Subject: Feature suggestion -- return if true In-Reply-To: <9gCmB.132015$yz.34330@fx34.am4> References: <9gCmB.132015$yz.34330@fx34.am4> Message-ID: On Mon, Aug 21, 2017 at 8:39 AM, alister via Python-list wrote: > On Mon, 21 Aug 2017 05:44:53 -0700, jek wrote: >> This is a very old post, but since I just though I would like a >> conditional return like this, and checked for previous proposals, I >> thought I'd give my opinion. >> >> Unfortunately only about 8 of the 67 replies actually answer the >> question, and there isn't any overwhelming consensus to if a conditional >> return would be good or not. Most (if not all) people dislike the syntax >> though, and I agree. >> >> So, my proposal would be the syntax: >> >> return if >> >> That is more pythonic than return?, does not involve a new keyword, and >> is "human readable" in a way similar to e.g the ternary statement. >> >> //jek >> >> tue 12 apr 2011 zildjohn01 wrote: >>> I propose the following syntax: >>> >>> return? expr >>> >>> be expanded to >>> >>> _temp = expr if _temp: return _temp >> >> As a side note, for the syntax of a cache, that was discussed a bit, I >> sometimes to use: >> >> try: >> return cache[key] >> except KeyError: >> ret = cache[key] = compute(key) >> return ret >> >> In my limited test it is a bit quicker than both "if x in cache" and >> "v=cache.get(x)" (~ 0.9, 1.1 and 1.3 seconds) Though it might depend on >> the hash complexity and the number of cache hits vs misses, so I guess >> either syntax would do fine. > > how does this syntax enable you to specify the value to be returned? > What new benefits would this addition provide beyond what is already > available? The value to be returned is the same as the value of the condition. In my view that is the only benefit of this syntax: it provides a natural way to specify that without evaluating the return value twice. If you want to return a different value, there's already a great way to do that: if : return From clbuell at ncsu.edu Mon Aug 21 11:52:51 2017 From: clbuell at ncsu.edu (Chet Buell) Date: Mon, 21 Aug 2017 11:52:51 -0400 Subject: python to call or start a fortran a.out Message-ID: Need some help with updating python to call or start a fortran a.out executable The problem I am having is I have an old Fortran based model that I need to run, in the past the fortran was triggered through the following python code: #run fortran x = commands.getoutput(path+'/a.out') Since the commands.getoutput has been depreciated it will not run on the newly built server that will now host this model. I have manually confirmed that the compiled a.out does run and produces the files, but the problem I am having is in triggering it to run with python. The answer is probably so easy it is obviously being overlooked, but I can not seem to find it.? Any suggestions or help would be greatly appreciated. From grant.b.edwards at gmail.com Mon Aug 21 12:51:07 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Mon, 21 Aug 2017 16:51:07 +0000 (UTC) Subject: python to call or start a fortran a.out References: Message-ID: On 2017-08-21, Chet Buell wrote: > Need some help with updating python to call or start a fortran a.out > executable > > The problem I am having is I have an old Fortran based model that I need > to run, in the past the fortran was triggered through the following > python code: > > #run fortran > x = commands.getoutput(path+'/a.out') > > Since the commands.getoutput has been depreciated it will not run on the > newly built server that will now host this model. I have manually > confirmed that the compiled a.out does run and produces the files, but > the problem I am having is in triggering it to run with python. > > The answer is probably so easy it is obviously being overlooked, but I > can not seem to find it.? Any suggestions or help would be greatly > appreciated. https://docs.python.org/2/library/commands.html: Deprecated since version 2.6: The commands module has been removed in Python 3. Use the subprocess module instead. The subprocess module provides more powerful facilities for spawning new processes and retrieving their results. Using the subprocess module is preferable to using the commands module. https://docs.python.org/2/library/subprocess.html#popen-constructor: -- Grant Edwards grant.b.edwards Yow! I'm encased in the at lining of a pure pork gmail.com sausage!! From zach.smith at orthofi.com Mon Aug 21 13:08:26 2017 From: zach.smith at orthofi.com (zach.smith at orthofi.com) Date: Mon, 21 Aug 2017 10:08:26 -0700 (PDT) Subject: Dataframe iterating question : 3 ways of calling a row and column Message-ID: <8622234f-0ae5-4521-b330-610e216a20a9@googlegroups.com> I wouldn't say I'm a Python noob, but I wouldn't say I'm a Python expert either. I work in data science and use Pandas Dataframes a lot. My question is regarding the difference in calling out a specific row, column combination in a dataframe. I see 3 ways of doing this: (1) df.loc[row_ind, column_ind] (2) df.column_ind.loc[row_ind] (3) df[column_ind].loc[row_ind] where column_ind is the column name & row_ind is the named row index/row name in the dataframe. Can anyone enlighten me as to the differences between the above 3 methods of getting to the same cell in the dataframe? Are there speed differences? Is it simply a preference thing? Is there a PEP8 preferred way of doing this? Are there specific disadvantages to any of the methods? Thanks in advance. Zach From __peter__ at web.de Mon Aug 21 13:20:53 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 21 Aug 2017 19:20:53 +0200 Subject: python to call or start a fortran a.out References: Message-ID: Chet Buell wrote: > Need some help with updating python to call or start a fortran a.out > executable > > The problem I am having is I have an old Fortran based model that I need > to run, in the past the fortran was triggered through the following > python code: > > #run fortran > x = commands.getoutput(path+'/a.out') > > Since the commands.getoutput has been depreciated it will not run on the > newly built server that will now host this model. I have manually > confirmed that the compiled a.out does run and produces the files, but > the problem I am having is in triggering it to run with python. > > The answer is probably so easy it is obviously being overlooked, but I > can not seem to find it. Any suggestions or help would be greatly > appreciated. I don't see how the documentation could be made more explicit than https://docs.python.org/2/library/commands.html """ Note In Python 3.x [...] getstatusoutput() and getoutput() have been moved to the subprocess module. """ There is also the 2to3 tool that may help you with the mechanical part of the migration from Python 2.7 to 3.x. Example: $ cat runfortran.py #!/usr/bin/env python import commands x = commands.getoutput(path+'/a.out') print x $ 2to3-3.6 -w runfortran.py RefactoringTool: Skipping optional fixer: buffer [...] RefactoringTool: Files that were modified: RefactoringTool: runfortran.py $ cat runfortran.py #!/usr/bin/env python import subprocess x = subprocess.getoutput(path+'/a.out') print(x) $ Personally I would avoid the shell and capture stdout/err in separate strings with p = subprocess.run( [os.path.join(path, "a.out")], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True ) print(p.stdout) or similar. From rantingrickjohnson at gmail.com Mon Aug 21 19:41:09 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Mon, 21 Aug 2017 16:41:09 -0700 (PDT) Subject: Dataframe iterating question : 3 ways of calling a row and column In-Reply-To: <8622234f-0ae5-4521-b330-610e216a20a9@googlegroups.com> References: <8622234f-0ae5-4521-b330-610e216a20a9@googlegroups.com> Message-ID: On Monday, August 21, 2017 at 12:08:54 PM UTC-5, zach.... at orthofi.com wrote: > I wouldn't say I'm a Python noob, but I wouldn't say I'm a Python expert either. I work in data science and use Pandas Dataframes a lot. My question is regarding the difference in calling out a specific row, column combination in a dataframe. > > I see 3 ways of doing this: > (1) df.loc[row_ind, column_ind] > (2) df.column_ind.loc[row_ind] > (3) df[column_ind].loc[row_ind] > > where column_ind is the column name & row_ind is the named row index/row name in the dataframe. > > Can anyone enlighten me as to the differences between the above 3 methods of getting to the same cell in the dataframe? > Are there speed differences? > Is it simply a preference thing? > Is there a PEP8 preferred way of doing this? If you have not read PEP8 in it's entirety, then i encourage you to do so. Of course, i'm not suggesting you must follow PEP8 _religiously_ (we have a formal Inquisition court for that), but you should at least be aware of Python idioms, and try to incorporate as many of them as you can tolerate, so that when you are called to testify, perhaps you can escape the worst of the punishments. Personally, i'm somewhere around 85% in agreement with the suggestions of PEP8, and that's reasonable and tolerable enough... However, the Zen is a whole different beast! You _must_ be 100% in agreement with the Zen, and if not, then your Python interpreter will "know", and will behave mischievously as a punishment. GvR has installed a secret _loki module, you see, specifically for this purpose. There is also a _bigbrother module, but we're not allowed to talk about bigbrother, as directed by the first and second rule of pyclub. -- >>> import this From bill at baddogconsulting.com Mon Aug 21 19:51:52 2017 From: bill at baddogconsulting.com (Bill Deegan) Date: Mon, 21 Aug 2017 16:51:52 -0700 Subject: SCons 3.0.0.alpha.20170821 is available for your testing Message-ID: All, You can install via: (PLEASE ONLY DO IN A VIRTUALENV AS THIS IS PRERELEASE) pip install --index-url https://test.pypi.org/simple/ scons==3.0.0.alpha.20170821 This version supports: Python 2.7.x, 3.5.x, 3.6.x NOTE: 1. You must rm your .sconsign file if you switch python versions between 2 and 3. 2. It is likely you will see a large number of rebuilds due to some changes with signature generation for python action functions. Please report any issues you find to the scons users mailing list. Here's the list of changes: RELEASE 3.0.0.alpha.20170821 - Mon, 21 Aug 2017 16:15:02 -0700 NOTE: This is a major release. You should expect that some targets may rebuild when upgrading. Significant changes in some python action signatures. Also switching between PY 2 and PY 3.5, 3.6 may cause rebuilds. In no case should rebuilds not happen. From William Blevins: - Updated D language scanner support to latest: 2.071.1. (PR #1924) https://dlang.org/spec/module.html accessed 11 August 2016 - Enhancements: - Added support for selective imports: "import A : B, C;" -> A - Added support for renamed imports. "import B = A;" -> A - Supports valid combinations: "import A, B, CCC = C, DDD = D : EEE = FFF;" -> A, B, C, D - Notes: - May find new (previously missed) Dlang dependencies. - May cause rebuild after upgrade due to dependency changes. - Updated Fortran-related tests to pass under GCC 5/6. - Fixed SCons.Tool.Packaging.rpm.package source nondeterminism across builds. From William Deegan: - Removed deprecated tools CVS, Perforce, BitKeeper, RCS, SCCS, Subversion. - Removed deprecated module SCons.Sig - Added prioritized list of xsltproc tools to docbook. The order will now be as follows: xsltproc, saxon, saxon-xslt, xalan (with first being highest priority, first tool found is used) - Fixed MSVSProject example code (http://scons.tigris.org/issues/show_bug.cgi?id=2979) - Defined MS SDK 10.0 and Changed VS 2015 to use SDK 10.0 - Changes to Action Function and Action Class signiture creation. NOTE: This will cause rebuilds for many builds when upgrading to SCons 3.0 - Fixed Bug #3027 - "Cross Compiling issue: cannot override ranlib" - Fixed Bug #3020 - "Download link in user guide wrong. python setup.py install --version-lib broken" - Fixed Bug #2486 - Added SetOption('silent',True) - Previously this value was not allowed to be set. - Fixed Bug #3040 - Non-unicode character in CHANGES.txt - Fixed Bug #2622 - AlwaysBuild + MSVC regression. - Fixed Bug #3025 - (Credit to Florian : User flow86 on tigris) - Fix typo JAVACLASSSUFIX should have been JAVACLASSSUFFIX From Ibrahim Esmat: - Added the capability to build Windows Store Compatible libraries that can be used with Universal Windows Platform (UWP) Apps and published to the store From Daniel Holth: - Add basic support for PyPy (by deleting __slots__ from Node with a metaclass on PyPy); wrap most-used open() calls in 'with' statements to avoid too many open files. - Add __main__.py for `python -m SCons` in case it is on PYTHONPATH. - Always use highest available pickle protocol for efficiency. - Remove unused command line fallback for the zip tool. From Gaurav Juvekar: - Fix issue #2832: Expand construction variables in 'chdir' argument of builders. (PR #463) - Fix issue #2910: Make --tree=all handle Unicode. (PR #427) - Fix issue #2788: Fix typo in documentation example for sconf. (PR #388) From Alexey Klimkin: - Use memoization to optimize PATH evaluation across all dependencies per node. (PR #345) - Use set() where it is applicable (PR #344) From M. Limber: - Fixed msvs.py for Visual Studio Express editions that would report "Error : ValueError: invalid literal for float(): 10.0Exp". From Rick Lupton: - Update LaTeX scanner to understand \import and related commands From Steve Robinson: - Add support for Visual Studio 2017. This support requires vswhere.exe a helper tool installed with newer installs of 2017. SCons expects it to be located at "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" It can be downloaded separately at https://github.com/Microsoft/vswhere From Pawe? Tomulik: - Fixed the issue with LDMODULEVERSIONFLAGS reported by Tim Jennes (https://pairlist4.pair.net/pipermail/scons-users/2016-May/004893.html). An error was causing "-Wl,Bsymbolic" being added to linker's command-line even when there was no specified value in LDMODULEVERSION and thus no need for the flags to be specified. - Added LoadableModule to the list of global functions (DefaultEnvironment builders). From Manish Vachharajani: - Update debian rules, compat, and control to not use features deprecated or obsolete in later versions of debhelpers - Update python version to 2.7 in debian/control From Richard Viney: - Fixed PCHPDBFLAGS causing a deprecation warning on MSVC v8 and later when using PCHs and PDBs together. From Richard West: - Added nested / namespace tool support - Added a small fix to the python3 tool loader when loading a tool as a package - Added additional documentation to the user manual on using toolpaths with the environment This includes the use of sys.path to search for tools installed via pip or package managers - Added support for a PyPackageDir function for use with the toolpath From Russel Winder: - Reordered the default D tools from "dmd, gdc, ldc" to "dmd, ldc, gdc". - Add a ProgramAllAtOnce builder to the dmd, ldc, and gdc tools. (PR #448) - Remove a file name exception for very old Fedora LDC installation. - gdc can now handle building shared objects (tested for version 6.3.0). - Remove establishing the SharedLibrary builder in the dmd, ldc, and gdc tools, must now include the ar tool to get this builder as is required for other compiler tools. - Add clang and clang++ tools based on Pawe? Tomulik's work. From Tom Tanner: - Allow nested $( ... $) sections From rustompmody at gmail.com Mon Aug 21 23:40:15 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Mon, 21 Aug 2017 20:40:15 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: <87h8x2lsbu.fsf@nightsong.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> Message-ID: <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> On Sunday, August 20, 2017 at 11:00:22 AM UTC+5:30, Paul Rubin wrote: > Rustom Mody writes: > > Specifically the term 'comprehension' used today as a programming construct > > traces somewhat tenuously to an axiom that Zermelo/Fraenkel formulated > > in the 1920s > > I thought went back to Frege. Also, it appears in Zermelo set theory Z. > ZF is Z with the Axiom of Replacement added, but Z was somewhat earlier > than ZF. Do you mean Frege or Cantor? No I am not an historian, not even amateur, so my data may be quite screwed up What I know [open to correction!] - Cantor invented naive? Set Theory ? late 19th century - He was the first to discover paradoxes ? Cantor's paradox ? which were not taken too seriously - Russel discovered his paradox ? generally regarded as a bigger problem - Frege ? inventor of predicate calculus ? was, like Russel, interested in a sound and complete foundation of math - Russell's paradox dashed Frege's hope and put him into depression - This is about what (I know of) the relation between Frege and set theory - From beginning 20th century upto 1930 uncovering paradoxes became a cottage industry - While at the same time people like Hilbert were rebelling against the attempts 'to expel us from the paradise created by Cantor' - Zermelo-Fraenkel and G?del-Bernays-Neumann were two of the principa lattempts at formalizing systems (called axiomatization then) so as to avoid the contradictions. At the risk of over-simplification, the G?del-Bernays system is haskell-like (typed) and the Zermelo-Fraenkel system is python-like (untyped) - All this cottage-industry got decimated by G?del's (2nd)? theorem showing that a single unitary axiomatization is impossible Today maybe we should say systematization? Or programming language ? ? Many people seem to think that all this is not related to computer science? Amusing! [For Turing a 'computer' was a (dumb) mathematician doing a computation] ? If such anachronism is permissible. But then much of this thread is anachronistic! ? http://mathworld.wolfram.com/GoedelsSecondIncompletenessTheorem.html From no.email at nospam.invalid Tue Aug 22 02:28:54 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Mon, 21 Aug 2017 23:28:54 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> Message-ID: <87wp5wjeu1.fsf@nightsong.com> Rustom Mody writes: > Do you mean Frege or Cantor? Frege. Cantor was concerned with set theory, while Frege was concerned with logic in general. Frege's notation was different from what we use now but the issue was about the same: unrestricted comprehension led to contradiction. As you mention, Russell was the one who recognized the inconsistency in Frege's system, though I don't know how Frege took it at a personal level. Many of the original writings from that era are reproduced in the book "From Frege to G?del: A Source Book in Mathematical Logic". It has good introductions to the papers and is pretty interesting. From greg.ewing at canterbury.ac.nz Tue Aug 22 02:49:05 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Tue, 22 Aug 2017 18:49:05 +1200 Subject: Proposed new syntax In-Reply-To: <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> <87shgp2wms.fsf@elektro.pacujo.net> <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > from io import StringIO # simulate reading from a file > myfile = StringIO('Is this the room for an argument?') > values = [myfile.read(1) for i in range(33)] > print(''.join(values)) Which is a very contrived and longwinded way to write print(myfile.read(33)) and would be much better written that way. Nobody is denying that it's *possible* to write comprehensions that rely on order of evaluation. That doesn't mean it's a good idea to do so. > they also care > about what it contains, and that the comprehension or generator expression > iterates over its argument in a specific order. I don't think they really care about that. What they actually care about is that the resulting elements are in the same *order* as the corresponding source elements. That's a concept that doesn't inherently have anything to do with time, so you can think about it without having to visualise things happening sequentially. Or at least you can as long as the comprehension doesn't have anything like 'while' in it. If it does, then the abstraction isn't just a bit leaky, it has a massive iceberg-sized hole in the hull. > [format(linenum) + line for (linenum, line) in enumerate(myfile)] > > I think that most people would be disturbed if the returned list didn't match > the order of lines in the file. The order of the elements in the list, yes, but not the order in time in which they were generated. > If we write: > > [process(a) for a in (1, 2, 3)] then we get ridiculed for being a clueless noobie who doesn't know how to use comprehensions properly. :-) (Actually, this being c.l.p, we just get it gently pointed out that we're uselessly building a list of Nones and then throwing it away, so it would be much better to write it as a for-statement instead. But the essence is the same.) -- Greg From chris at simplistix.co.uk Tue Aug 22 02:49:10 2017 From: chris at simplistix.co.uk (Chris Withers) Date: Tue, 22 Aug 2017 07:49:10 +0100 Subject: xlrd 1.1.0 and xlwt 1.3.0 released! Message-ID: Hi All, I'm pleased to announce the release of xlrd 1.1.0 and xlwt 1.3.0. Please consult their change logs on readthedocs.org to see what's new. As before, I will be upfront and say you should no longer be using these unless libraries unless you have a particular need to work with .xls files. If you only work with .xlsx files, and that's the only Excel format you should look to create nowadays, then you should be using openpyxl instead. This is open source, so none of xlrd, xlwt or xlutils are going away, just be aware that if you have problems, you'll likely need to be the one to do the work, read the specs, read the code, and propose fixes. Until someone better comes forward, I'll still be gatekeeper for merging pull requests along with John Machin, and I'll be looking for tests and descriptive code changes before doing so. Stability is of utmost importance in these now mature packages. If you have a passion to maintain any of these libraries, please make yourself known, and prove you're serious about it. cheers, Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk From greg.ewing at canterbury.ac.nz Tue Aug 22 03:15:15 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Tue, 22 Aug 2017 19:15:15 +1200 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> Message-ID: Chris Angelico wrote: > a naive ASCII upper-casing wouldn't produce 0x81 either - if it did, it > would also convert 0x21 ("!") into 0x01 (SOH, a control character). So > this one's still a mystery. It's unlikely that even a naive ascii upper/lower casing algorithm would be *that* naive; it would have to check that the character appeared to be a letter before changing it. You might expect bytes >= 0x80 to be classed as non-letters by that test, but what if it ignores the top bit or assumes it's a parity bit to be left alone? What do you get under those assumptions? -- Greg From greg.ewing at canterbury.ac.nz Tue Aug 22 03:29:52 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Tue, 22 Aug 2017 19:29:52 +1200 Subject: A question on modification of a list via a function invocation In-Reply-To: References: <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <445fb28d-45f9-4d96-8775-95380ae73302@googlegroups.com> <59981a06$0$1606$c3e8da3$5496439d@news.astraweb.com> <79jgpcptvpa7n90jqkai0elu8110p412lj@4ax.com> Message-ID: Dennis Lee Bieber wrote: > On Sat, 19 Aug 2017 20:59:16 +1000, Steve D'Aprano > declaimed the following: > >>I'm not sure that the VIN defines the vehicle exactly... I wouldn't want to try >>driving a VIN without the rest of the vehicle. The mileage is terrible... > > ... or phenomenal > > Depends on how one interprets 0miles / 0gallons Your fuel consumption is NaN at that point, leading to the well-known disclaimer in car advertisements, "Your mileage may not be equal to itself." -- Greg From arj.python at gmail.com Tue Aug 22 04:38:18 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Tue, 22 Aug 2017 12:38:18 +0400 Subject: python list name in subject Message-ID: Hi all, i am subscribed to different python lists and they put their names in the subject [name] subject hence i can at a glance tell which mail belongs to which list. A requests to admins to implement if possible Thank you! Garanti sans virus. www.avast.com <#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> From rosuav at gmail.com Tue Aug 22 04:51:49 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 22 Aug 2017 18:51:49 +1000 Subject: What extended ASCII character set uses 0x9D? In-Reply-To: References: <87wp61pehu.fsf@nightsong.com> <87o9rd2wjh.fsf@elektro.pacujo.net> <87efs92vuz.fsf@elektro.pacujo.net> Message-ID: On Tue, Aug 22, 2017 at 5:15 PM, Gregory Ewing wrote: > Chris Angelico wrote: >> >> a naive ASCII upper-casing wouldn't produce 0x81 either - if it did, it >> would also convert 0x21 ("!") into 0x01 (SOH, a control character). So >> this one's still a mystery. > > > It's unlikely that even a naive ascii upper/lower casing algorithm > would be *that* naive; it would have to check that the character > appeared to be a letter before changing it. > > You might expect bytes >= 0x80 to be classed as non-letters by > that test, but what if it ignores the top bit or assumes it's > a parity bit to be left alone? What do you get under those > assumptions? Exactly, I do assume that it's checking for it to be a letter. But everything previously has been on the assumption that it ignores the top bit. That's how we got this far. ChrisA From marko at pacujo.net Tue Aug 22 05:41:21 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Tue, 22 Aug 2017 12:41:21 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> Message-ID: <874lt0aqim.fsf@elektro.pacujo.net> Paul Rubin : > As you mention, Russell was the one who recognized the inconsistency > in Frege's system, though I don't know how Frege took it at a personal > level. I read (can't remember where) that Frege was just finishing his third and final volume when Russell's paradox was brought to his attention. Frege was devastated, as he had spent a large part of his life on this extensive treatise of mathematics. It turned out, though, Frege's mistakes were fixable. BTW, the main take of the metamathematical "fiasco" was that you can't get rid of the meta-level. There's no consistent logical system that is closed and encompasses everything including itself. You will always have to step outside your formal system and resort to hand-waving in a natural language. Marko From stephanh42 at gmail.com.invalid Tue Aug 22 05:58:17 2017 From: stephanh42 at gmail.com.invalid (Stephan Houben) Date: 22 Aug 2017 09:58:17 GMT Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> Message-ID: Op 2017-08-11, Paul Rubin schreef : > I don't think we need this since we have itertools.takewhile: > > from operator import gt > from functools import partial > from itertools import takewhile > > [x + 1 for x in takewhile(partial(gt,5), (0,1,2,999,3,4))] > No need for partial and gt. [x + 1 for x in takewhile((5).__gt__, (0,1,2,999,3,4))] Basically, Haskell's infix opererator sections can often be translated into Python by attribute access to the bound method. Stephan From zak.fenton at outlook.com Tue Aug 22 06:13:09 2017 From: zak.fenton at outlook.com (Zak Fenton) Date: Tue, 22 Aug 2017 10:13:09 +0000 Subject: Free Beta Invite for new scripting/VM technology (some survey answers required) Message-ID: Hi everyone! I'm in the process of launching a business around a new scripting-related technology. It's not specific to Python users, but may be of interest to many of you, so I'd like to make sure Python users are represented in my initial market research. It's a very short survey and should take less than five minutes to complete. In return, you'll get a chance to play with the first beta release as it becomes available over the coming months (however places in the beta program are limited, so availability cannot be guaranteed). The survey is here (the last page allows you to opt in to the beta program): https://www.surveymonkey.com/r/HTLLWTB Thanks, -Zak. From pavol.lisy at gmail.com Tue Aug 22 07:39:24 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Tue, 22 Aug 2017 13:39:24 +0200 Subject: Dataframe iterating question : 3 ways of calling a row and column In-Reply-To: <8622234f-0ae5-4521-b330-610e216a20a9@googlegroups.com> References: <8622234f-0ae5-4521-b330-610e216a20a9@googlegroups.com> Message-ID: On 8/21/17, zach.smith at orthofi.com wrote: > I wouldn't say I'm a Python noob, but I wouldn't say I'm a Python expert > either. I work in data science and use Pandas Dataframes a lot. My question > is regarding the difference in calling out a specific row, column > combination in a dataframe. > > I see 3 ways of doing this: > (1) df.loc[row_ind, column_ind] > (2) df.column_ind.loc[row_ind] > (3) df[column_ind].loc[row_ind] > > where column_ind is the column name & row_ind is the named row index/row > name in the dataframe. > > Can anyone enlighten me as to the differences between the above 3 methods of > getting to the same cell in the dataframe? > Are there speed differences? > Is it simply a preference thing? > Is there a PEP8 preferred way of doing this? > Are there specific disadvantages to any of the methods? > > Thanks in advance. > Zach First of all I am not expert in pandas or python either. I write just a few thoughts... I don't think PEP-8 is about it. df.column_id is calling __getattr__ where (after some checks) df[column_id] is returned. So it is slower than df[column_id]. But if you are doing things in REPL you could probably be happy to use tab completion to get column name. Or if you are writing paper in (for example) jupyter notebook readability of your formulas could count more than speed! BTW. there are more ways to do it (and I could miss many others) -> (4) df.column_id[row_ind] (5) df.get_value(row_ind, column_ind) (6) df.ix[row_ind, column_ind] interestingly doc - http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.ix.html doesn't say it is deprecated ( http://pandas.pydata.org/pandas-docs/stable/whatsnew.html#deprecate-ix ) Just quick stupid test (python 3.6.2, IPython 6.1.0, pandas 0.20.3) gave me this results (sorted by speed): df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=['Aaaaa', 'Bbbbb', 'Ccccc']) %timeit df.ix[1,0] # this is deprecated! 188 ?s ? 6.55 ?s per loop (mean ? std. dev. of 7 runs, 1000 loops each) %timeit df.Aaaaa.loc[1] 46.2 ?s ? 908 ns per loop (mean ? std. dev. of 7 runs, 10000 loops each) %timeit df['Aaaaa'].loc[1] 42.6 ?s ? 2 ?s per loop (mean ? std. dev. of 7 runs, 10000 loops each) aa = df.Aaaaa %timeit aa[1] 16.6 ?s ? 519 ns per loop (mean ? std. dev. of 7 runs, 10000 loops each) %timeit df.iloc[1,0] 14.5 ?s ? 92.2 ns per loop (mean ? std. dev. of 7 runs, 100000 loops each) %timeit df.loc[1,'Aaaaa'] 13.8 ?s ? 251 ns per loop (mean ? std. dev. of 7 runs, 100000 loops each) %timeit df.ix[1,'Aaaaa'] # this is deprecated! 8.68 ?s ? 107 ns per loop (mean ? std. dev. of 7 runs, 100000 loops each) %timeit df.get_value(1, 'Aaaaa') 3.51 ?s ? 133 ns per loop (mean ? std. dev. of 7 runs, 100000 loops each) But I want to add that thinking about speed of getting one value could be thinking in wrong direction because using built in functions could be better. I just test my stupid benchmark (and gave quite opposite result :P) -> %timeit sum(df.sum()) 150 ?s ? 2.35 ?s per loop (mean ? std. dev. of 7 runs, 1000 loops each) def tst(): summa = 0 for i in range(len(df)): for j in df.columns: summa += df.get_value(i, j) return summa %timeit tst() 37.6 ?s ? 1.1 ?s per loop (mean ? std. dev. of 7 runs, 10000 loops each) But with just a little bigger data frame it is 10x faster using built in function! -> df = pd.DataFrame(data=[[1+3*i, 2+3*i, 3+3*i] for i in range(100)], columns=['Aaaaa', 'Bbbbb', 'Ccccc']) def tst(): summa = 0 for i in range(len(df)): for j in df.columns: summa += df.get_value(i, j) return summa %timeit tst() 1.67 ms ? 68.7 ?s per loop (mean ? std. dev. of 7 runs, 100 loops each) %timeit sum(df.sum()) 151 ?s ? 2.01 ?s per loop (mean ? std. dev. of 7 runs, 10000 loops each) From rantingrickjohnson at gmail.com Tue Aug 22 07:44:07 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Tue, 22 Aug 2017 04:44:07 -0700 (PDT) Subject: python to call or start a fortran a.out In-Reply-To: References: Message-ID: On Monday, August 21, 2017 at 11:31:48 AM UTC-5, Chet Buell wrote: > Need some help with updating python to call or start a > fortran a.out executable The problem I am having is I have > an old Fortran based model that I need to run, in the past > the fortran was triggered through the following python > code: > > #run fortran > x = commands.getoutput(path+'/a.out') > > Since the commands.getoutput has been depreciated it will > not run on the newly built server that will now host this > model. I have manually confirmed that the compiled a.out > does run and produces the files, but the problem I am > having is in triggering it to run with python. The answer > is probably so easy it is obviously being overlooked, but I > can not seem to find it. Any suggestions or help would be > greatly appreciated. > TITLE: python to call or start a fortran a.out Please do consider the title of your posts more carefully. The title you chose here was unfortunate, as it will not provide an intuitive link between the problem and the solution, therefore, it is unlikely that someone with the same _general_ problem, will benefit from this exchange in the future. The _general_ problem here had nothing to with Fortran, much less a specific file or executable named "a.out". So a better title would have been: "How to run an executable from Python", or: "How to spawn a subprocess from Python and capture the result". Or even: "How to poke my OS with a sharp stick, using Python". Perhaps the last example was a bit too generalized, i admit, but you get the point. :-) A good template for composing questions on internet forums is as follows: MESSAGE_TITLE: "A concise, generalization of the problem here..." MESSAGE_BODY: " An elaborate and specific explanation of the problem here..." Mentioning "Fortran" and "a.out" in the body of the message, would be fine. One of the happy-accidents[1] of composing thoughtful queries, is that, many times you will happen upon the answer to your own question during the composition process, and even if you don't, at least you will have a much better chance of receiving prompt and quality responses by following this template. So either way, it's a win-win. [1] Think "Bob Ross" here. As his most important contribution to society was that he taught us all a very important lesson. Namely, that all accidents can be "happy accidents". An eternal optimist, he was... From pavol.lisy at gmail.com Tue Aug 22 09:07:36 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Tue, 22 Aug 2017 15:07:36 +0200 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <599063d3$0$1605$c3e8da3$5496439d@news.astraweb.com> <64414322-bf6e-4fe7-bf7f-5bf240e10acd@googlegroups.com> <599164d9$0$2878$c3e8da3$76491128@news.astraweb.com> <8560dqjwq4.fsf@benfinney.id.au> <5991bde1$0$1586$c3e8da3$5496439d@news.astraweb.com> <85wp65iw3o.fsf@benfinney.id.au> <59944959$0$1614$c3e8da3$5496439d@news.astraweb.com> <59967581$0$1611$c3e8da3$5496439d@news.astraweb.com> <871so9qu3j.fsf@nightsong.com> <87shgp2wms.fsf@elektro.pacujo.net> <599a3ecb$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/21/17, Chris Angelico wrote: > On Mon, Aug 21, 2017 at 12:19 PM, MRAB wrote: >> On 2017-08-21 03:00, Steve D'Aprano wrote: >>> >>> On Fri, 18 Aug 2017 04:55 pm, Marko Rauhamaa wrote: >>> >>>> Is a Python implementation >>>> allowed to parallelize or otherwise reorder the evaluation loop? >>> >>> >>> No. >>> >> [snip] >> >> Well, I suppose an implementation _could_ parallelise, or whatever, >> _provided that_ it gave the same result. > > In other words, it's allowed to parallelise, just as long as > everything happens sequentially. With arbitrary expressions, one of > them could affect another easily. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > import multiprocessing def square(param): ret = param[0] * param[0] param[1].put("%d is done" % param[0]) return ret pool = multiprocessing.Pool(processes=3) m = multiprocessing.Manager() q = m.Queue() squares = pool.map(square, ((i, q) for i in range(10))) print(squares) # ordered print([q.get() for i in range(q.qsize())]) # unordered [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] ['0 is done', '2 is done', '1 is done', '3 is done', '4 is done', '5 is done', '7 is done', '6 is done', '8 is done', '9 is done'] You could collect result sequentially (ordered) but calculate it parallel (unordered). From ian.g.kelly at gmail.com Tue Aug 22 09:42:51 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Tue, 22 Aug 2017 07:42:51 -0600 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> Message-ID: On Tue, Aug 22, 2017 at 3:58 AM, Stephan Houben wrote: > Op 2017-08-11, Paul Rubin schreef : >> I don't think we need this since we have itertools.takewhile: >> >> from operator import gt >> from functools import partial >> from itertools import takewhile >> >> [x + 1 for x in takewhile(partial(gt,5), (0,1,2,999,3,4))] >> > > No need for partial and gt. > > [x + 1 for x in takewhile((5).__gt__, (0,1,2,999,3,4))] > > Basically, Haskell's infix opererator sections can often be > translated into Python by attribute access to the bound method. Careful! Python's dunder methods are reserved for use by Python. They're exposed so that we can override them. Calling them directly is generally considered bad style. And in this case specifically, it's not equivalent. Example: import functools import operator @functools.total_ordering class PseudoInt(object): def __init__(self, value): self.value = value def __eq__(self, other): return self.value == other def __lt__(self, other): return self.value < other >>> PseudoInt(5) > 2 True >>> 5 > PseudoInt(2) True >>> 5 > PseudoInt(7) False >>> operator.gt(5, PseudoInt(7)) False >>> (5).__gt__(PseudoInt(7)) NotImplemented >>> bool((5).__gt__(PseudoInt(7))) True The last line is the reason why the rich comparison methods should have been designed to raise NotImplementedException rather than return NotImplemented, but it's too late to change that. From skip.montanaro at gmail.com Tue Aug 22 10:02:15 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 22 Aug 2017 09:02:15 -0500 Subject: requests.{get,post} timeout Message-ID: I'm using the requests module with timeouts to fetch URLs, for example: response = requests.get("http://www.google.com/", timeout=10) I understand the timeout value in this case applies both to creating the connection and fetching the remote content. Can the server dribble out the content (say, one byte every few seconds) to avoid triggering the timeout, or must the request be completed within ten seconds after the connection is successfully opened? My reading of the documentation here is inconclusive: http://docs.python-requests.org/en/master/user/advanced/#timeouts If you specify a single value for the timeout, like this: r = requests.get('https://github.com', timeout=5) The timeout value will be applied to both the connect and the read timeouts. Does "read timeout" imply the timeout applied to an individual read from the underlying socket? A quick glance at the code suggests that might be the case, but I got a bit lost in the urllib3 code which underpins the requests module. Thx, Skip From grant.b.edwards at gmail.com Tue Aug 22 10:14:33 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 22 Aug 2017 14:14:33 +0000 (UTC) Subject: python list name in subject References: Message-ID: On 2017-08-22, Abdur-Rahmaan Janhangeer wrote: > Hi all, > > i am subscribed to different python lists and they put their names in the > subject > [name] subject > > hence i can at a glance tell which mail belongs to which list. > > A requests to admins to implement if possible Please don't. It wastes space which is better used on the subject. If you want the mailing list prepended, then configure procmail (or whatever) to do it for you. -- Grant Edwards grant.b.edwards Yow! Hey, waiter! I want at a NEW SHIRT and a PONY TAIL gmail.com with lemon sauce! From stephanh42 at gmail.com.invalid Tue Aug 22 11:12:39 2017 From: stephanh42 at gmail.com.invalid (Stephan Houben) Date: 22 Aug 2017 15:12:39 GMT Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> Message-ID: Op 2017-08-22, Ian Kelly schreef : > Careful! Python's dunder methods are reserved for use by Python. > They're exposed so that we can override them. Calling them directly is > generally considered bad style. And in this case specifically, it's > not equivalent. Mmm, you are correct. That's kind of a deception, really. I have often done things like: generate_id = itertools.count().__next__ but I suppose that isn't OK either, then. Stephan From rosuav at gmail.com Tue Aug 22 11:19:01 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 01:19:01 +1000 Subject: Proposed new syntax In-Reply-To: References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> Message-ID: On Wed, Aug 23, 2017 at 1:12 AM, Stephan Houben wrote: > Op 2017-08-22, Ian Kelly schreef : >> Careful! Python's dunder methods are reserved for use by Python. >> They're exposed so that we can override them. Calling them directly is >> generally considered bad style. And in this case specifically, it's >> not equivalent. > > Mmm, you are correct. That's kind of a deception, really. > > I have often done things like: > > generate_id = itertools.count().__next__ > > but I suppose that isn't OK either, then. That one probably won't bite you, but that doesn't mean it's correct. General rule of thumb: Dunders are for defining, not for calling. ChrisA From rantingrickjohnson at gmail.com Tue Aug 22 11:21:25 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Tue, 22 Aug 2017 08:21:25 -0700 (PDT) Subject: python list name in subject In-Reply-To: References: Message-ID: Grant Edwards wrote: > Abdur-Rahmaan Janhangeer wrote: > > > > Hi all, i am subscribed to different python lists and > > they put their names in the subject [name] subject hence > > i can at a glance tell which mail belongs to which list. > > A requests to admins to implement if possible > > Please don't. It wastes space which is better used on the > subject. If you want the mailing list prepended, then > configure procmail (or whatever) to do it for you. Although, considering that the BDFL has now made type-hints an official part of the language, a "forum-of-origin" type- hint, may be more Pythonic than we care to realize. Hmm... From python.list at tim.thechases.com Tue Aug 22 11:43:40 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Tue, 22 Aug 2017 10:43:40 -0500 Subject: python list name in subject In-Reply-To: References: Message-ID: <20170822104340.271c7df8@bigbox.christie.dr> On 2017-08-22 08:21, Rick Johnson wrote: > Grant Edwards wrote: > > Abdur-Rahmaan Janhangeer wrote: > > > > > > Hi all, i am subscribed to different python lists and > > > they put their names in the subject [name] subject hence > > > i can at a glance tell which mail belongs to which list. > > > A requests to admins to implement if possible > > > > Please don't. It wastes space which is better used on the > > subject. If you want the mailing list prepended, then > > configure procmail (or whatever) to do it for you. > > Although, considering that the BDFL has now made type-hints > an official part of the language, a "forum-of-origin" type- > hint, may be more Pythonic than we care to realize. Checking mailing list headers...yep, the "forum-of-origin" type hint is already present in standards-compliant fashion defined by RFC4021[1]: List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Just need a mail client that knows about standards and isn't fettered. ;-) -tkc [1] https://tools.ietf.org/html/rfc4021#section-2.1.31 From rantingrickjohnson at gmail.com Tue Aug 22 11:58:49 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Tue, 22 Aug 2017 08:58:49 -0700 (PDT) Subject: python list name in subject In-Reply-To: References: <20170822104340.271c7df8@bigbox.christie.dr> Message-ID: Tim Chase wrote: > Rick Johnson wrote: [...] > Checking mailing list headers...yep, the "forum-of-origin" > type hint is already present in standards-compliant fashion > defined by RFC4021[1]: > > [...] > > Just need a mail client that knows about standards and > isn't fettered. ;-) Well, that pretty much disqualifies google groups. :-) From rosuav at gmail.com Tue Aug 22 12:52:44 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 02:52:44 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 12:02 AM, Skip Montanaro wrote: > I'm using the requests module with timeouts to fetch URLs, for example: > > response = requests.get("http://www.google.com/", timeout=10) > > I understand the timeout value in this case applies both to creating the > connection and fetching the remote content. Can the server dribble out the > content (say, one byte every few seconds) to avoid triggering the timeout, > or must the request be completed within ten seconds after the connection is > successfully opened? My reading of the documentation here is inconclusive: > > http://docs.python-requests.org/en/master/user/advanced/#timeouts > > If you specify a single value for the timeout, like this: > > r = requests.get('https://github.com', timeout=5) > > The timeout value will be applied to both the connect and the read > timeouts. > > Does "read timeout" imply the timeout applied to an individual read from > the underlying socket? A quick glance at the code suggests that might be > the case, but I got a bit lost in the urllib3 code which underpins the > requests module. """ Once your client has connected to the server and sent the HTTP request, the read timeout is the number of seconds the client will wait for the server to send a response. (Specifically, it's the number of seconds that the client will wait between bytes sent from the server. In 99.9% of cases, this is the time before the server sends the first byte). """ "Between bytes" implies that you could have a long request, as long as there's a keep-alive transmission every few seconds. ChrisA From jon+usenet at unequivocal.eu Tue Aug 22 12:58:10 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 22 Aug 2017 16:58:10 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-22, Skip Montanaro wrote: > I'm using the requests module with timeouts to fetch URLs, for example: > > response = requests.get("http://www.google.com/", timeout=10) > > I understand the timeout value in this case applies both to creating the > connection and fetching the remote content. Can the server dribble out the > content (say, one byte every few seconds) to avoid triggering the timeout, Yes. There is no timeout feature that can be used to limit the total time a 'requests' request takes. Some people might think that this is a serious flaw in the requests library that would need urgent rectification in order to make the library safe and useful to use in almost any situation, but the 'requests' developers are apparently not among those people. From rosuav at gmail.com Tue Aug 22 13:08:33 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 03:08:33 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 2:58 AM, Jon Ribbens wrote: > On 2017-08-22, Skip Montanaro wrote: >> I'm using the requests module with timeouts to fetch URLs, for example: >> >> response = requests.get("http://www.google.com/", timeout=10) >> >> I understand the timeout value in this case applies both to creating the >> connection and fetching the remote content. Can the server dribble out the >> content (say, one byte every few seconds) to avoid triggering the timeout, > > Yes. There is no timeout feature that can be used to limit the total > time a 'requests' request takes. Some people might think that this is > a serious flaw in the requests library that would need urgent > rectification in order to make the library safe and useful to use in > almost any situation, but the 'requests' developers are apparently not > among those people. I'm not either. The idea of a timeout is to detect when something's completely not working, not to limit the overall time to process. If you want that, you can do it locally, maybe with signal.alarm or a thread or something. ChrisA From skip.montanaro at gmail.com Tue Aug 22 13:08:45 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 22 Aug 2017 12:08:45 -0500 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: > """ > Once your client has connected to the server and sent the HTTP > request, the read timeout is the number of seconds the client will > wait for the server to send a response. (Specifically, it's the number > of seconds that the client will wait between bytes sent from the > server. In 99.9% of cases, this is the time before the server sends > the first byte). > """ > > "Between bytes" implies that you could have a long request, as long as > there's a keep-alive transmission every few seconds. Thanks, Chris. That appears to be what's going on. S From ganesh1pal at gmail.com Tue Aug 22 13:14:04 2017 From: ganesh1pal at gmail.com (Ganesh Pal) Date: Tue, 22 Aug 2017 22:44:04 +0530 Subject: Multiple try expect in a for loop Message-ID: Hello python friends, I need a suggestion on the below piece of code . I have for loop and I need to do the below i.e create 100 of queue ,open ,and append some data to a data structure. Is multiple try except the way to go or any other idea's. I feel that there is a better way to write those try except statement or avoid it . I am a Linux user on python 2.7 def create_queue(): q_name = "" q_fd = "" for itr in range(1, 100): q_name = randomword(100) print q_name try: q.create(q_name) except OSError as e: sys.stderr.write('Unable to create Queue %s: %s\n' % (q_name, str(e))) return False try: q_fd = q.open(q_name); // Can I add multiple statement like this ? q.append(q_fd, randomword(100)) except OSError as e: sys.stderr.write('Unable to open or append Queue %s: %s\n' % (q_name, str(e))) return False return True Regards, Ganesh From jon+usenet at unequivocal.eu Tue Aug 22 14:14:58 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 22 Aug 2017 18:14:58 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-22, Chris Angelico wrote: > On Wed, Aug 23, 2017 at 2:58 AM, Jon Ribbens wrote: >> Yes. There is no timeout feature that can be used to limit the total >> time a 'requests' request takes. Some people might think that this is >> a serious flaw in the requests library that would need urgent >> rectification in order to make the library safe and useful to use in >> almost any situation, but the 'requests' developers are apparently not >> among those people. > > I'm not either. The idea of a timeout is to detect when something's > completely not working, not to limit the overall time to process. We appear to have different understandings of the word "timeout". I think it means a time, which if it runs out, will stop the operation. I am somewhat surprised that anyone might have a different definition - not least because, from a human being's point of view, they care about the overall time something takes to happen and telling them that nothing's wrong because technically we are still "successfully" receiving the expected 10 kilobytes of data 3 hours later is unlikely to make them happy. From grant.b.edwards at gmail.com Tue Aug 22 14:31:09 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Tue, 22 Aug 2017 18:31:09 +0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-22, Chris Angelico wrote: > """ > Once your client has connected to the server and sent the HTTP > request, the read timeout is the number of seconds the client will > wait for the server to send a response. (Specifically, it's the number > of seconds that the client will wait between bytes sent from the > server. In 99.9% of cases, this is the time before the server sends > the first byte). > """ > > "Between bytes" implies that you could have a long request, as long as > there's a keep-alive transmission every few seconds. Except a keep-alive transmission doesn't contain any bytes, so it shouldn't reset the timer. -- Grant Edwards grant.b.edwards Yow! It's some people at inside the wall! This is gmail.com better than mopping! From rosuav at gmail.com Tue Aug 22 14:43:09 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 04:43:09 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 4:14 AM, Jon Ribbens wrote: > On 2017-08-22, Chris Angelico wrote: >> On Wed, Aug 23, 2017 at 2:58 AM, Jon Ribbens wrote: >>> Yes. There is no timeout feature that can be used to limit the total >>> time a 'requests' request takes. Some people might think that this is >>> a serious flaw in the requests library that would need urgent >>> rectification in order to make the library safe and useful to use in >>> almost any situation, but the 'requests' developers are apparently not >>> among those people. >> >> I'm not either. The idea of a timeout is to detect when something's >> completely not working, not to limit the overall time to process. > > We appear to have different understandings of the word "timeout". > I think it means a time, which if it runs out, will stop the operation. > > I am somewhat surprised that anyone might have a different definition > - not least because, from a human being's point of view, they care > about the overall time something takes to happen and telling them that > nothing's wrong because technically we are still "successfully" receiving > the expected 10 kilobytes of data 3 hours later is unlikely to make > them happy. You start downloading a file from a web page. It stalls out. Is it merely slow, and continuing to wait will get you a result? Or has it actually stalled out and you should give up? The low-level timeout will distinguish between those. If you want a high-level timeout across the entire job, you can do that too, but then you have to figure out exactly how long is "too long". Let's say you set a thirty-second timeout. Great! Now someone uses your program on a midrange connection to download a 100MB file, or on a poor connection to download a 5MB file, or on dial-up to download a 10KB file. Data is constantly flowing, but at some point, the connection just dies, because it's hit your timeout. This is EXTREMELY frustrating. You can always add in the overall timeout separately. If the low-level timeout were implemented that way, there would be no way to externally add the other form of timeout. Therefore the only sane way to implement the request timeout is a between-byte limit. ChrisA From rosuav at gmail.com Tue Aug 22 14:44:49 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 04:44:49 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 4:31 AM, Grant Edwards wrote: > On 2017-08-22, Chris Angelico wrote: > >> """ >> Once your client has connected to the server and sent the HTTP >> request, the read timeout is the number of seconds the client will >> wait for the server to send a response. (Specifically, it's the number >> of seconds that the client will wait between bytes sent from the >> server. In 99.9% of cases, this is the time before the server sends >> the first byte). >> """ >> >> "Between bytes" implies that you could have a long request, as long as >> there's a keep-alive transmission every few seconds. > > Except a keep-alive transmission doesn't contain any bytes, so it > shouldn't reset the timer. If it's a TCP keep-alive, yes. But if you're looking at a long-poll HTTP server, or a websocket, or you're proxying a different type of connection, you can use a connection-level keep-alive to reset it. I've often worked with TELNET, using an IAC GA or similar as a keep-alive to get past stupid routers that drop connections after five minutes of idleness.. ChrisA From jon+usenet at unequivocal.eu Tue Aug 22 15:06:04 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 22 Aug 2017 19:06:04 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-22, Chris Angelico wrote: > The low-level timeout will distinguish between those. If you want a > high-level timeout across the entire job, you can do that too, but > then you have to figure out exactly how long is "too long". Let's say > you set a thirty-second timeout. Great! Now someone uses your program > on a midrange connection to download a 100MB file, or on a poor > connection to download a 5MB file, or on dial-up to download a 10KB > file. Data is constantly flowing, but at some point, the connection > just dies, because it's hit your timeout. This is EXTREMELY > frustrating. Sure, the right timeout to use depends on what your application is and what it's doing. > You can always add in the overall timeout separately. If the low-level > timeout were implemented that way, there would be no way to externally > add the other form of timeout. Therefore the only sane way to > implement the request timeout is a between-byte limit. I have no idea what you mean here. The only sane way to implement the request timeout is to provide both types of timeout. From python at mrabarnett.plus.com Tue Aug 22 15:10:12 2017 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 22 Aug 2017 20:10:12 +0100 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On 2017-08-22 19:43, Chris Angelico wrote: > On Wed, Aug 23, 2017 at 4:14 AM, Jon Ribbens wrote: >> On 2017-08-22, Chris Angelico wrote: >>> On Wed, Aug 23, 2017 at 2:58 AM, Jon Ribbens wrote: >>>> Yes. There is no timeout feature that can be used to limit the total >>>> time a 'requests' request takes. Some people might think that this is >>>> a serious flaw in the requests library that would need urgent >>>> rectification in order to make the library safe and useful to use in >>>> almost any situation, but the 'requests' developers are apparently not >>>> among those people. >>> >>> I'm not either. The idea of a timeout is to detect when something's >>> completely not working, not to limit the overall time to process. >> >> We appear to have different understandings of the word "timeout". >> I think it means a time, which if it runs out, will stop the operation. >> >> I am somewhat surprised that anyone might have a different definition >> - not least because, from a human being's point of view, they care >> about the overall time something takes to happen and telling them that >> nothing's wrong because technically we are still "successfully" receiving >> the expected 10 kilobytes of data 3 hours later is unlikely to make >> them happy. > > You start downloading a file from a web page. It stalls out. > > Is it merely slow, and continuing to wait will get you a result? > > Or has it actually stalled out and you should give up? > > The low-level timeout will distinguish between those. If you want a > high-level timeout across the entire job, you can do that too, but > then you have to figure out exactly how long is "too long". Let's say > you set a thirty-second timeout. Great! Now someone uses your program > on a midrange connection to download a 100MB file, or on a poor > connection to download a 5MB file, or on dial-up to download a 10KB > file. Data is constantly flowing, but at some point, the connection > just dies, because it's hit your timeout. This is EXTREMELY > frustrating. > > You can always add in the overall timeout separately. If the low-level > timeout were implemented that way, there would be no way to externally > add the other form of timeout. Therefore the only sane way to > implement the request timeout is a between-byte limit. > You might want to have a way of setting the minimum data rate in order to defend against a slowloris attack. From rosuav at gmail.com Tue Aug 22 15:20:55 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 05:20:55 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 5:10 AM, MRAB wrote: > On 2017-08-22 19:43, Chris Angelico wrote: >> >> On Wed, Aug 23, 2017 at 4:14 AM, Jon Ribbens >> wrote: >>> >>> On 2017-08-22, Chris Angelico wrote: >>>> >>>> On Wed, Aug 23, 2017 at 2:58 AM, Jon Ribbens >>>> wrote: >>>>> >>>>> Yes. There is no timeout feature that can be used to limit the total >>>>> time a 'requests' request takes. Some people might think that this is >>>>> a serious flaw in the requests library that would need urgent >>>>> rectification in order to make the library safe and useful to use in >>>>> almost any situation, but the 'requests' developers are apparently not >>>>> among those people. >>>> >>>> >>>> I'm not either. The idea of a timeout is to detect when something's >>>> completely not working, not to limit the overall time to process. >>> >>> >>> We appear to have different understandings of the word "timeout". >>> I think it means a time, which if it runs out, will stop the operation. >>> >>> I am somewhat surprised that anyone might have a different definition >>> - not least because, from a human being's point of view, they care >>> about the overall time something takes to happen and telling them that >>> nothing's wrong because technically we are still "successfully" receiving >>> the expected 10 kilobytes of data 3 hours later is unlikely to make >>> them happy. >> >> >> You start downloading a file from a web page. It stalls out. >> >> Is it merely slow, and continuing to wait will get you a result? >> >> Or has it actually stalled out and you should give up? >> >> The low-level timeout will distinguish between those. If you want a >> high-level timeout across the entire job, you can do that too, but >> then you have to figure out exactly how long is "too long". Let's say >> you set a thirty-second timeout. Great! Now someone uses your program >> on a midrange connection to download a 100MB file, or on a poor >> connection to download a 5MB file, or on dial-up to download a 10KB >> file. Data is constantly flowing, but at some point, the connection >> just dies, because it's hit your timeout. This is EXTREMELY >> frustrating. >> >> You can always add in the overall timeout separately. If the low-level >> timeout were implemented that way, there would be no way to externally >> add the other form of timeout. Therefore the only sane way to >> implement the request timeout is a between-byte limit. >> > You might want to have a way of setting the minimum data rate in order to > defend against a slowloris attack. That assumes that that's an attack - it often isn't. But if that's what you want, then add that as a separate feature - it's distinct from a timeout. ChrisA From rosuav at gmail.com Tue Aug 22 15:21:53 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 05:21:53 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 5:06 AM, Jon Ribbens wrote: >> You can always add in the overall timeout separately. If the low-level >> timeout were implemented that way, there would be no way to externally >> add the other form of timeout. Therefore the only sane way to >> implement the request timeout is a between-byte limit. > > I have no idea what you mean here. The only sane way to implement the > request timeout is to provide both types of timeout. You could provide both, but since one of them can be handled externally (with a thread, with a SIGALRM, or with some other sort of time limiting), the other one MUST be provided by the request. ChrisA From skip.montanaro at gmail.com Tue Aug 22 16:15:07 2017 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Tue, 22 Aug 2017 15:15:07 -0500 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: > You could provide both, but since one of them can be handled > externally (with a thread, with a SIGALRM, or with some other sort of > time limiting), the other one MUST be provided by the request. Given the semantics of timeouts which percolate up from the socket level, I agree with Chris. It has a particular meaning, that implemented by the underlying socket layer. Unfortunately, the word "timeout" can take on related (but different) meanings, depending on context. We can discuss how to implement the timeout which means, "the maximum amount of time it should take to transfer a chunk of content from one end of the connection to the other", it's difficult to say exactly where detecting such timeouts should live in the application's network stack. That it might be tedious to implement correctly (I suspect given their druthers, most people would prefer to leave sleeping threading and signaling dogs lie) is kind of beside the point. Now that I have a firmer grasp of what timeout I do have (the socket level per-read-or-write call timeout), I can decide how important it is for me to implement the other. Skip From gpgrimes at suddenlink.net Tue Aug 22 19:18:49 2017 From: gpgrimes at suddenlink.net (Gregory Grimes) Date: Tue, 22 Aug 2017 18:18:49 -0500 Subject: Outlook csv Files Message-ID: <72A9DEF1-FD18-44C4-9E26-C29032F4A381@suddenlink.net> All, I have exported Remedy emails from Outlook to a csv file. The issue is one cell, Body, has information in multiple lines: Subject,Body,From: (Name),From: (Address),From: (Type),To: (Name),To: (Address),To: (Type),CC: (Name),CC: (Address),CC: (Type),BCC: (Name),BCC: (Address),BCC: (Type),Billing Information,Categories,Importance,Mileage,Sensitivity INC000000977622 Assigned : DBA - PKG1 : mbbanms0006.xxxxxxx.com - Alert, "Remedy Ticket Information ________________________________ Date Open 08/09/17 12:10:57 Ticket Number INC000000977622 Date Modified 08/09/17 12:10:57 Category Status Assigned Priority High Short Description mbbanms0006.xxxxxxx.com - Alert User Information ________________________________ User Name Remedy SPI User Login remedyspi User Phone ### User Email helpdesk at xxxxxxx.com User Department Staff Information ________________________________ Staff Name Staff Login Staff Phone Staff Email Staff Department DBA - PKG1 Detailed Ticket Information ________________________________ Incident Description Target : mb08dorb Type : Database Instance Host : mbbanms0006.xxxxxxx.com Info : A session was terminated at time/line number: Wed Aug 09 12:10:10 2017/84281. Metric=ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum o Click Here to Access Remedy ? My question, what is the best way to parse the long Body string to extract information from this file for analysis? Thanks. From greg.ewing at canterbury.ac.nz Tue Aug 22 19:27:05 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Wed, 23 Aug 2017 11:27:05 +1200 Subject: Proposed new syntax In-Reply-To: <874lt0aqim.fsf@elektro.pacujo.net> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> <874lt0aqim.fsf@elektro.pacujo.net> Message-ID: Marko Rauhamaa wrote: > You will always have > to step outside your formal system and resort to hand-waving in a > natural language. If the hand-waving is rigorous, this amounts to expanding your formal system by adding new axioms and/or rules to it. If the hand-waving is not rigorous, then you haven't really proved anything. -- Greg From darcy at VybeNetworks.com Tue Aug 22 20:20:04 2017 From: darcy at VybeNetworks.com (D'Arcy Cain) Date: Tue, 22 Aug 2017 20:20:04 -0400 Subject: python list name in subject In-Reply-To: References: Message-ID: On 08/22/2017 10:14 AM, Grant Edwards wrote: > Please don't. It wastes space which is better used on the subject. If > you want the mailing list prepended, then configure procmail (or > whatever) to do it for you. Better yet, put it in its own folder. -- D'Arcy J.M. Cain Vybe Networks Inc. http://www.VybeNetworks.com/ IM:darcy at Vex.Net VoIP: sip:darcy at VybeNetworks.com From grant.b.edwards at gmail.com Tue Aug 22 21:13:14 2017 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Wed, 23 Aug 2017 01:13:14 +0000 (UTC) Subject: python list name in subject References: Message-ID: On 2017-08-23, D'Arcy Cain wrote: > On 08/22/2017 10:14 AM, Grant Edwards wrote: >> Please don't. It wastes space which is better used on the subject. If >> you want the mailing list prepended, then configure procmail (or >> whatever) to do it for you. > > Better yet, put it in its own folder. Even better, point a news client[1] at nntp://news.gmane.org/gmane.comp.python.general [1] https://en.wikipedia.org/wiki/List_of_Usenet_newsreaders From ben+python at benfinney.id.au Tue Aug 22 21:46:18 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 23 Aug 2017 11:46:18 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> Message-ID: <85tw0zf445.fsf@benfinney.id.au> Stephan Houben writes: > I have often done things like: > > generate_id = itertools.count().__next__ Could you be convinced to instead do:: import functools import itertools generate_id = functools.partial(next, itertools.count()) -- \ ?The right to search for truth implies also a duty; one must | `\ not conceal any part of what one has recognized to be true.? | _o__) ?Albert Einstein | Ben Finney From ben+python at benfinney.id.au Tue Aug 22 21:51:32 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Wed, 23 Aug 2017 11:51:32 +1000 Subject: python list name in subject References: Message-ID: <85pobnf3vf.fsf@benfinney.id.au> Abdur-Rahmaan Janhangeer writes: > i am subscribed to different python lists and they put their names in the > subject > [name] subject That's non-standard. The standard place for that information is the ?List-Id? field . > hence i can at a glance tell which mail belongs to which list. Set up a filter on the specific value of the ?List-Id? field, which is set by any standards-conformant mailing list software. Presto, you get any organisation you like based on that information; and the rest of us don't get the Subject field cluttered. -- \ ?Most people are other people. Their thoughts are someone | `\ else?s opinions, their lives a mimicry, their passions a | _o__) quotation.? ?Oscar Wilde, _De Profundis_, 1897 | Ben Finney From arj.python at gmail.com Tue Aug 22 22:12:12 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 23 Aug 2017 06:12:12 +0400 Subject: python list name in subject In-Reply-To: References: Message-ID: ah thanks for the tip about me filtering them thought the community liked core python style (mail lists where python dev talk, discuss ideas,i.e. the ones where guido replies etc) anyways thanks all Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com On 22 Aug 2017 12:38, "Abdur-Rahmaan Janhangeer" wrote: > Hi all, > > i am subscribed to different python lists and they put their names in the > subject > [name] subject > > hence i can at a glance tell which mail belongs to which list. > > A requests to admins to implement if possible > > Thank you! > > > Garanti > sans virus. www.avast.com > > <#m_1748413376357339298_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2> > From arj.python at gmail.com Tue Aug 22 22:28:43 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 23 Aug 2017 06:28:43 +0400 Subject: Outlook csv Files In-Reply-To: <72A9DEF1-FD18-44C4-9E26-C29032F4A381@suddenlink.net> References: <72A9DEF1-FD18-44C4-9E26-C29032F4A381@suddenlink.net> Message-ID: as someone who works with languages, this one seems quite manageable i assume you know how to deal with csv. 1 get the cell string 2 split at _____________ that will make you move around mpre easily as this separates in big chunk 3 for the first chunck, you might want to split at , 4 and so on Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com On 23 Aug 2017 03:34, "Gregory Grimes" wrote: > All, > > I have exported Remedy emails from Outlook to a csv file. The issue is > one cell, Body, has information in multiple lines: > > Subject,Body,From: (Name),From: (Address),From: (Type),To: (Name),To: > (Address),To: (Type),CC: (Name),CC: (Address),CC: (Type),BCC: (Name),BCC: > (Address),BCC: (Type),Billing Information,Categories, > Importance,Mileage,Sensitivity > INC000000977622 Assigned : DBA - PKG1 : mbbanms0006.xxxxxxx.com - Alert, > "Remedy Ticket Information > ________________________________ > Date Open > 08/09/17 12:10:57 > Ticket Number > INC000000977622 com/HPD%3AHelp+Desk/Default+User+View/?eid=INC000000938650> > Date Modified > 08/09/17 12:10:57 > Category > Status > Assigned > Priority > High > Short Description > mbbanms0006.xxxxxxx.com - Alert > User Information > ________________________________ > User Name > Remedy SPI > User Login > remedyspi > User Phone > ### > User Email > helpdesk at xxxxxxx.com > User Department > Staff Information > ________________________________ > Staff Name > Staff Login > Staff Phone > Staff Email > > Staff Department > DBA - PKG1 > Detailed Ticket Information > ________________________________ > Incident Description > Target : mb08dorb Type : Database Instance Host : mbbanms0006.xxxxxxx.com > Info : A session was terminated at time/line number: Wed Aug 09 12:10:10 > 2017/84281. Metric=ORA-01000: maximum open cursors exceeded~ORA-01000: > maximum open cursors exceeded~ORA-01000: maximum open cursors > exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open > cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: > maximum open cursors exceeded~ORA-01000: maximum open cursors > exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: maximum open > cursors exceeded~ORA-01000: maximum open cursors exceeded~ORA-01000: > maximum open cursors exceeded~ORA-01000: maximum o > Click Here to Access Remedy ? > > My question, what is the best way to parse the long Body string to extract > information from this file for analysis? > > Thanks. > -- > https://mail.python.org/mailman/listinfo/python-list > From arj.python at gmail.com Tue Aug 22 22:32:48 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 23 Aug 2017 06:32:48 +0400 Subject: opencv tutorial links In-Reply-To: References: Message-ID: dear mail list, the only famous module i need to cover in python is open cv can you drop some links or book recommendations apart from the official website? thanks, Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com From marko at pacujo.net Tue Aug 22 23:37:05 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 23 Aug 2017 06:37:05 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> <874lt0aqim.fsf@elektro.pacujo.net> Message-ID: <87shgjuf8e.fsf@elektro.pacujo.net> Gregory Ewing : > Marko Rauhamaa wrote: >> You will always have to step outside your formal system and resort to >> hand-waving in a natural language. > > If the hand-waving is rigorous, this amounts to expanding your formal > system by adding new axioms and/or rules to it. Ultimately, it's not rigorous. You can add rigor to any number of meta-levels, but on top of it all, you will need an informal "observer" level. It's turtles all the way down. For example, you can't have a set of all sets. The NBG set theory solves the problem by introducing the concept of classes. You can have a class of all sets. But you can't have a class of all classes. > If the hand-waving is not rigorous, then you haven't really proved > anything. The mathematicians have stopped caring. In fact, even if metamathematics were a closed, formal system, the best it could achieve would be circular reasoning. That would still be satisfactory and "convincing." However, no interesting system can prove its own consistency (but it *can* prove it can't prove its own consistency). Recommended reading: Marko From rustompmody at gmail.com Wed Aug 23 01:42:15 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Tue, 22 Aug 2017 22:42:15 -0700 (PDT) Subject: Proposed new syntax In-Reply-To: <87shgjuf8e.fsf@elektro.pacujo.net> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> <874lt0aqim.fsf@elektro.pacujo.net> <87shgjuf8e.fsf@elektro.pacujo.net> Message-ID: <0da9abfa-3bc3-4aee-8b90-a802051abd03@googlegroups.com> Since this erm? discussion has also brought in Haskell and in this case, the name, the history etc are related I thought I'd mention the following Around 2015 there was a major upheaval in the Haskell community around the socalled FTP (foldable-traversable-prelude) controversy. In many respects this controversy is analogous and even identical to this one and the heat there was considerably more than this thread's storm-in-a-teaspoon Mark Lentczner resigned as Haskell's release manager? which in the python world would be analogous to say Raymond Hettinger saying ?Python 3 is too much of a mess; I am going to stick to python 2.2? Along with hims went other stalwarts like Lennart Augustsson and Eric Meijer's widely acclaimed EdX course switched from haskell to hugs? [which is like switching to python 1.6] The controversy somewhat oversimplified is that foldr (reduce-from-right) was foldr : (a ? b ? b) ? b ? [a] ? b It was changed to foldr : Foldable ? ? (a ? b ? b) ? b ? ? a ? b If we think of [a] as list_of_a and ? a as any general list-like interface we would see the close parallel with the divergence of opinion on this thread ? http://haskell.1045720.n5.nabble.com/quot-Excuse-me-I-think-this-i-my-stop-quot-Resigning-from-the-Platform-td5819861.html ? https://www.reddit.com/r/haskell/comments/3ove2e/got_the_welcome_email_from_edx_fp101x_course_hugs/ From dieter at handshake.de Wed Aug 23 03:01:42 2017 From: dieter at handshake.de (dieter) Date: Wed, 23 Aug 2017 09:01:42 +0200 Subject: requests.{get,post} timeout References: Message-ID: <87d17mlqcp.fsf@handshake.de> Skip Montanaro writes: > ... > Given the semantics of timeouts which percolate up from the socket > level, I agree with Chris. It has a particular meaning, that > implemented by the underlying socket layer. Unfortunately, the word > "timeout" can take on related (but different) meanings, depending on > context. That's why the documentation (you have cited in your original post) clearly distinguished between "connect" and "read" timeout - and thereby explains that only those types of timeouts are supported. As you explained, those timeouts directly derive from the socket layer timeouts. From jon+usenet at unequivocal.eu Wed Aug 23 07:10:22 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 23 Aug 2017 11:10:22 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-22, Chris Angelico wrote: > On Wed, Aug 23, 2017 at 5:06 AM, Jon Ribbens wrote: >> I have no idea what you mean here. The only sane way to implement the >> request timeout is to provide both types of timeout. > > You could provide both, but since one of them can be handled > externally (with a thread, with a SIGALRM, or with some other sort of > time limiting), the other one MUST be provided by the request. I am interested to learn what you mean by "with a thread". How would one execute a requests, er, request in a thread with a proper timeout? From steve+python at pearwood.info Wed Aug 23 07:26:41 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 23 Aug 2017 21:26:41 +1000 Subject: SCons 3.0.0.alpha.20170821 is available for your testing References: Message-ID: <599d6672$0$1622$c3e8da3$5496439d@news.astraweb.com> On Tue, 22 Aug 2017 09:51 am, Bill Deegan wrote: > All, > > You can install via: (PLEASE ONLY DO IN A VIRTUALENV AS THIS IS PRERELEASE) > > pip install --index-url https://test.pypi.org/simple/ > scons==3.0.0.alpha.20170821 What is scons and why should we be interested in it? Thanks, -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Wed Aug 23 08:08:03 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Wed, 23 Aug 2017 22:08:03 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> Message-ID: <599d7025$0$1615$c3e8da3$5496439d@news.astraweb.com> On Tue, 22 Aug 2017 11:42 pm, Ian Kelly wrote: > The last line is the reason why the rich comparison methods should > have been designed to raise NotImplementedException rather than return > NotImplemented, but it's too late to change that. Only if you want operators to be slow as molasses. *wink* -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Wed Aug 23 08:34:04 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 23 Aug 2017 22:34:04 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 9:10 PM, Jon Ribbens wrote: > On 2017-08-22, Chris Angelico wrote: >> On Wed, Aug 23, 2017 at 5:06 AM, Jon Ribbens wrote: >>> I have no idea what you mean here. The only sane way to implement the >>> request timeout is to provide both types of timeout. >> >> You could provide both, but since one of them can be handled >> externally (with a thread, with a SIGALRM, or with some other sort of >> time limiting), the other one MUST be provided by the request. > > I am interested to learn what you mean by "with a thread". How would > one execute a requests, er, request in a thread with a proper timeout? Assuming that by "proper timeout" you mean "limit the entire download's wall time": Use one thread to do the request, and another thread to monitor it. Generally, the monitoring thread is your UI thread (most commonly, the main thread of the program), though it doesn't have to be. If the monitoring thread decide that the requesting thread has taken too long, it can cut it off and report failure to the user. ChrisA From jon+usenet at unequivocal.eu Wed Aug 23 08:52:22 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 23 Aug 2017 12:52:22 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-23, Chris Angelico wrote: > On Wed, Aug 23, 2017 at 9:10 PM, Jon Ribbens wrote: >> I am interested to learn what you mean by "with a thread". How would >> one execute a requests, er, request in a thread with a proper timeout? > > Assuming that by "proper timeout" you mean "limit the entire > download's wall time": Use one thread to do the request, and another > thread to monitor it. Generally, the monitoring thread is your UI > thread (most commonly, the main thread of the program), though it > doesn't have to be. If the monitoring thread decide that the > requesting thread has taken too long, it can cut it off and report > failure to the user. Yes, what I was interested to learn was how the monitoring thread can "cut off" the requesting thread. From rosuav at gmail.com Wed Aug 23 10:03:42 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Aug 2017 00:03:42 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Wed, Aug 23, 2017 at 10:52 PM, Jon Ribbens wrote: > On 2017-08-23, Chris Angelico wrote: >> On Wed, Aug 23, 2017 at 9:10 PM, Jon Ribbens wrote: >>> I am interested to learn what you mean by "with a thread". How would >>> one execute a requests, er, request in a thread with a proper timeout? >> >> Assuming that by "proper timeout" you mean "limit the entire >> download's wall time": Use one thread to do the request, and another >> thread to monitor it. Generally, the monitoring thread is your UI >> thread (most commonly, the main thread of the program), though it >> doesn't have to be. If the monitoring thread decide that the >> requesting thread has taken too long, it can cut it off and report >> failure to the user. > > Yes, what I was interested to learn was how the monitoring thread can > "cut off" the requesting thread. Ah, I see. That partly depends on your definition of "cut off", and how it needs to interact with other things. I'm not sure about the requests module specifically, but one very effective method of terminating a network query is to close the socket (since resources are owned by processes, not threads, any thread can close the underlying socket connection); it won't instantly terminate the thread, but it will result in an end-of-connection read shortly afterwards. You'd have to do some sort of high-level "hey, I'm cancelling this request" for the user's benefit, too - or maybe the user initiated it in the first place. For example, in a web browser, you can hit Esc to cancel the current page download; that can immediately close the socket, and it probably has to tell the cache subsystem not to hold that data, and maybe some logging and stuff, but in terms of aborting the download, closing the socket is usually sufficient. How this interacts with the actual specific details of the requests module I'm not sure, especially since a lot of the work usually happens inside requests.get() or one of its friends; but if you explicitly construct a Request object before sending it [1], it would be conceivable to have a "req.close()" or "req.abort()" method that closes the underlying socket. (Or possibly that goes on the PreparedRequest. Or maybe the Session. I don't know; normally, when I use requests, I use the higher level interfaces.) It would need to be a feature provided by requests ("abort this request"), as it would potentially interact with connection pooling and such. But at the simplest level, closing the socket WILL abort the connection. [1] http://docs.python-requests.org/en/master/user/advanced/#prepared-requests ChrisA From marko at pacujo.net Wed Aug 23 10:07:24 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 23 Aug 2017 17:07:24 +0300 Subject: requests.{get,post} timeout References: Message-ID: <87inhev0mb.fsf@elektro.pacujo.net> Jon Ribbens : > Yes, what I was interested to learn was how the monitoring thread can > "cut off" the requesting thread. In general, that cannot be done. Often, you resort to a dirty trick whereby the monitoring thread closes the I/O object requesting thread is waiting on, triggering an immediate I/O exception in the requesting thread. The fact that threads cannot be terminated at will is one of the big drawbacks of the multithreaded programming model. Note that coroutines can always be interrupted at await. Marko From jon+usenet at unequivocal.eu Wed Aug 23 10:52:28 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 23 Aug 2017 14:52:28 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-23, Chris Angelico wrote: > On Wed, Aug 23, 2017 at 10:52 PM, Jon Ribbens wrote: >> Yes, what I was interested to learn was how the monitoring thread can >> "cut off" the requesting thread. > > Ah, I see. That partly depends on your definition of "cut off", and > how it needs to interact with other things. I'm not sure about the > requests module specifically, but one very effective method of > terminating a network query is to close the socket (since resources > are owned by processes, not threads, any thread can close the > underlying socket connection); it won't instantly terminate the > thread, but it will result in an end-of-connection read shortly > afterwards. You'd have to do some sort of high-level "hey, I'm > cancelling this request" for the user's benefit, too - or maybe the > user initiated it in the first place. For example, in a web browser, > you can hit Esc to cancel the current page download; that can > immediately close the socket, and it probably has to tell the cache > subsystem not to hold that data, and maybe some logging and stuff, but > in terms of aborting the download, closing the socket is usually > sufficient. > > How this interacts with the actual specific details of the requests > module I'm not sure, especially since a lot of the work usually > happens inside requests.get() or one of its friends; but if you > explicitly construct a Request object before sending it [1], it would > be conceivable to have a "req.close()" or "req.abort()" method that > closes the underlying socket. (Or possibly that goes on the > PreparedRequest. Or maybe the Session. I don't know; normally, when I > use requests, I use the higher level interfaces.) It would need to be > a feature provided by requests ("abort this request"), as it would > potentially interact with connection pooling and such. But at the > simplest level, closing the socket WILL abort the connection. OK cool, so circling back to where you were - which is the same place that the 'requests' developers are - which is the claim that requests does not need to provide an "overall timeout" feature because you can cancel the request yourself is untrue since, as you explain above, you cannot in fact cancel the request yourself without some sort of support for this in the module itself. Sure, requests *could* provide a "cancel" feature, just the same as it *could* provide an "overall timeout" feature, but it doesn't actually provide either, and this is a problem. From stephanh42 at gmail.com.invalid Wed Aug 23 11:35:52 2017 From: stephanh42 at gmail.com.invalid (Stephan Houben) Date: 23 Aug 2017 15:35:52 GMT Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> Message-ID: Op 2017-08-23, Ben Finney schreef : > Could you be convinced to instead do:: > > import functools > import itertools > > generate_id = functools.partial(next, itertools.count()) I certainly could be, but I was so far unaware of the desirability to do so. Stephan From rosuav at gmail.com Wed Aug 23 12:08:51 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Aug 2017 02:08:51 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Thu, Aug 24, 2017 at 12:52 AM, Jon Ribbens wrote: > OK cool, so circling back to where you were - which is the same place > that the 'requests' developers are - which is the claim that requests > does not need to provide an "overall timeout" feature because you > can cancel the request yourself is untrue since, as you explain above, > you cannot in fact cancel the request yourself without some sort of > support for this in the module itself. Sure, requests *could* provide > a "cancel" feature, just the same as it *could* provide an "overall > timeout" feature, but it doesn't actually provide either, and this > is a problem. Yes and no. If requests provided a 'cancel query' feature, it would play nicely with everything else, but (a) the entire concept here is that the request has stalled, so you COULD just ignore the pending query and pretend it's failed without actually cancelling it; and (b) you could just close the underlying socket without help, but it might mess up future queries that end up getting put onto the same socket. It's not that you CAN'T do this without help (which is the case for a "time between bytes" timeout), but that having help would allow requests *itself* to benefit. But also, this honestly isn't as big an issue as you might think. If the user thinks a program has been running for too long, s/he can hit Ctrl-C. Voila! Signal is sent, which aborts a socket read, and thus the request. And if your top-level code is doing something else (so cancelling one request shouldn't terminate the whole program), Python already lets you catch KeyboardInterrupt. This is ONLY a problem when you need to have a program decide *by itself* that a request has taken too long. ChrisA From bill at baddogconsulting.com Wed Aug 23 12:58:11 2017 From: bill at baddogconsulting.com (Bill Deegan) Date: Wed, 23 Aug 2017 09:58:11 -0700 Subject: SCons 3.0.0.alpha.20170821 is available for your testing In-Reply-To: <599d6672$0$1622$c3e8da3$5496439d@news.astraweb.com> References: <599d6672$0$1622$c3e8da3$5496439d@news.astraweb.com> Message-ID: What is SCons? SCons is an Open Source software construction tool?that is, a next-generation build tool. Think of SCons as an improved, cross-platform substitute for the classic Make utility with integrated functionality similar to autoconf/automake and compiler caches such as ccache. In short, SCons is an easier, more reliable and faster way to build software. see http://scons.org for more info. -Bill SCons Project Co-Manager On Wed, Aug 23, 2017 at 4:26 AM, Steve D'Aprano wrote: > On Tue, 22 Aug 2017 09:51 am, Bill Deegan wrote: > > > All, > > > > You can install via: (PLEASE ONLY DO IN A VIRTUALENV AS THIS IS > PRERELEASE) > > > > pip install --index-url https://test.pypi.org/simple/ > > scons==3.0.0.alpha.20170821 > > > What is scons and why should we be interested in it? > > > Thanks, > > > > -- > 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 > From marko at pacujo.net Wed Aug 23 12:59:43 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 23 Aug 2017 19:59:43 +0300 Subject: requests.{get,post} timeout References: Message-ID: <87bmn6usn4.fsf@elektro.pacujo.net> Chris Angelico : > But also, this honestly isn't as big an issue as you might think. If > the user thinks a program has been running for too long, s/he can hit > Ctrl-C. Voila! Signal is sent, which aborts a socket read, Well, no, it doesn't. First run: ======================================================================== nc -l -p 12345 ======================================================================== in one window. Then, execute this program in another one: ======================================================================== import threading, socket def f(): s = socket.socket() try: s.connect(("localhost4", 12345)) s.recv(1000) finally: s.close() t = threading.Thread(target=f) t.start() t.join() ======================================================================== After you hit Ctrl-C once (under Linux), you get this trace: ======================================================================== Traceback (most recent call last): File "test.py", line 13, in t.join() File "/usr/lib64/python3.5/threading.py", line 1054, in join self._wait_for_tstate_lock() File "/usr/lib64/python3.5/threading.py", line 1070, in _wait_for_tstate_lock elif lock.acquire(block, timeout): KeyboardInterrupt ======================================================================== The program hangs, though, and "nc" doesn't terminate indicating that the socket hasn't closed. Then, press Ctrl-C again to get: ======================================================================== Exception ignored in: Traceback (most recent call last): File "/usr/lib64/python3.5/threading.py", line 1288, in _shutdown t.join() File "/usr/lib64/python3.5/threading.py", line 1054, in join self._wait_for_tstate_lock() File "/usr/lib64/python3.5/threading.py", line 1070, in _wait_for_tstate_lock elif lock.acquire(block, timeout): KeyboardInterrupt ======================================================================== and the program terminates. Marko From marko at pacujo.net Wed Aug 23 13:11:16 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 23 Aug 2017 20:11:16 +0300 Subject: SCons 3.0.0.alpha.20170821 is available for your testing References: <599d6672$0$1622$c3e8da3$5496439d@news.astraweb.com> Message-ID: <877exuus3v.fsf@elektro.pacujo.net> Bill Deegan : > What is SCons? > > SCons is an Open Source software construction tool?that is, a > next-generation build tool. Think of SCons as an improved, > cross-platform substitute for the classic Make utility with integrated > functionality similar to autoconf/automake and compiler caches such as > ccache. In short, SCons is an easier, more reliable and faster way to > build software. > > see http://scons.org for more info. At the office, we are happy users of SCons-1.3.0. Almost all of our Linux software is built with it. SCons can be used in different styles. We choose to use SCons in a very primitive way. No custom builders. Avoid programming. Marko From rosuav at gmail.com Wed Aug 23 13:29:08 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Aug 2017 03:29:08 +1000 Subject: requests.{get,post} timeout In-Reply-To: <87bmn6usn4.fsf@elektro.pacujo.net> References: <87bmn6usn4.fsf@elektro.pacujo.net> Message-ID: On Thu, Aug 24, 2017 at 2:59 AM, Marko Rauhamaa wrote: > Chris Angelico : > >> But also, this honestly isn't as big an issue as you might think. If >> the user thinks a program has been running for too long, s/he can hit >> Ctrl-C. Voila! Signal is sent, which aborts a socket read, > > Well, no, it doesn't. First run: > > ======================================================================== > nc -l -p 12345 > ======================================================================== > > in one window. Then, execute this program in another one: > > ======================================================================== > import threading, socket > > def f(): > s = socket.socket() > try: > s.connect(("localhost4", 12345)) > s.recv(1000) > finally: > s.close() > > t = threading.Thread(target=f) > t.start() > t.join() > ======================================================================== > > After you hit Ctrl-C once (under Linux), you get this trace: [chomp] What I said was that you don't need threading or alarms because most of the time you can let the user use SIGINT. And without the (utterly totally useless) threading that you have here, it works flawlessly: Ctrl-C instantly breaks the recv call. All you've demonstrated is that Ctrl-C halts a long-running request *in the main thread*, which in this case is your join(). And when I tested it interactively, it left the subthread running and halted the join. The reason you see the "hit Ctrl-C again" phenomenon is that the program wants to join all threads on termination. Solution 1: Keep the program running but halt the request. Solution 2: Daemonize the thread. Just run "t.daemon = True" before starting the thread, and the program terminates cleanly after one Ctrl-C. I'd prefer solution 1, myself, but you can take your pick. ChrisA From marko at pacujo.net Wed Aug 23 14:00:25 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Wed, 23 Aug 2017 21:00:25 +0300 Subject: requests.{get,post} timeout References: <87bmn6usn4.fsf@elektro.pacujo.net> Message-ID: <87y3qatb9i.fsf@elektro.pacujo.net> Chris Angelico : > What I said was that you don't need threading or alarms because most > of the time you can let the user use SIGINT. And without the (utterly > totally useless) threading that you have here, it works flawlessly: > Ctrl-C instantly breaks the recv call. Oh, if you give up threading (which I commend you for), problems evaporate. So just use async if that's your cup of tea, or nonblocking I/O and select.epoll(), which is my favorite. Marko From jon+usenet at unequivocal.eu Wed Aug 23 18:54:29 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Wed, 23 Aug 2017 22:54:29 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-23, Chris Angelico wrote: > Yes and no. If requests provided a 'cancel query' feature, it would > play nicely with everything else, but (a) the entire concept here is > that the request has stalled, so you COULD just ignore the pending > query and pretend it's failed without actually cancelling it; and (b) > you could just close the underlying socket without help, but it might > mess up future queries that end up getting put onto the same socket. > It's not that you CAN'T do this without help (which is the case for a > "time between bytes" timeout), but that having help would allow > requests *itself* to benefit. I don't understand - in the above paragraph you first explain how it cannot be done without help from requests, then you state that it can be done without help from requests. Was your first explanation wrong? > But also, this honestly isn't as big an issue as you might think. If > the user thinks a program has been running for too long, s/he can hit > Ctrl-C. Voila! Signal is sent, which aborts a socket read, and thus > the request. And if your top-level code is doing something else (so > cancelling one request shouldn't terminate the whole program), Python > already lets you catch KeyboardInterrupt. This is ONLY a problem when > you need to have a program decide *by itself* that a request has taken > too long. Yes. Which is a very common situation - indeed, I wouldn't be surprised if it is the most common situation in which requests is used. It is certainly the situation I was trying to use requests in when I came up against this problem. From rosuav at gmail.com Wed Aug 23 19:18:49 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Aug 2017 09:18:49 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Thu, Aug 24, 2017 at 8:54 AM, Jon Ribbens wrote: > On 2017-08-23, Chris Angelico wrote: >> Yes and no. If requests provided a 'cancel query' feature, it would >> play nicely with everything else, but (a) the entire concept here is >> that the request has stalled, so you COULD just ignore the pending >> query and pretend it's failed without actually cancelling it; and (b) >> you could just close the underlying socket without help, but it might >> mess up future queries that end up getting put onto the same socket. >> It's not that you CAN'T do this without help (which is the case for a >> "time between bytes" timeout), but that having help would allow >> requests *itself* to benefit. > > I don't understand - in the above paragraph you first explain how > it cannot be done without help from requests, then you state that it > can be done without help from requests. Was your first explanation > wrong? Not quite. I first explain that it can be done WITH help, and then state that it can be done WITHOUT help. That it can be done with help does not imply that it cannot be done without help. Help is nice but it mainly helps for *subsequent* requests; an external abort might leave internal state somewhat messed up, which would result in resources not being released until the next query, or perhaps a query failing and getting retried. But even without help, it would all work. ChrisA From ben+python at benfinney.id.au Wed Aug 23 20:55:37 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 24 Aug 2017 10:55:37 +1000 Subject: SCons 3.0.0.alpha.20170821 is available for your testing References: <599d6672$0$1622$c3e8da3$5496439d@news.astraweb.com> Message-ID: <857extg4xi.fsf@benfinney.id.au> Bill Deegan writes: > What is SCons? Thank you for the explanation. That's information that is normally in every release announcement: what is it, and why is it relevant to the forum. You might like to add it to the template for future release announcements. -- \ ?I distrust those people who know so well what God wants them | `\ to do to their fellows, because it always coincides with their | _o__) own desires.? ?Susan Brownell Anthony, 1896 | Ben Finney From steve+python at pearwood.info Wed Aug 23 22:02:04 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 24 Aug 2017 12:02:04 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> <874lt0aqim.fsf@elektro.pacujo.net> Message-ID: <599e339d$0$1612$c3e8da3$5496439d@news.astraweb.com> On Tue, 22 Aug 2017 07:41 pm, Marko Rauhamaa wrote: > BTW, the main take of the metamathematical "fiasco" was that you can't > get rid of the meta-level. There's no consistent logical system that is > closed and encompasses everything including itself. You will always have > to step outside your formal system and resort to hand-waving in a > natural language. That's not quite correct. G?del's Incompleteness theorems only apply to "sufficiently powerful" systems. They don't apply to systems which are too weak. Not all such simple systems are either consistent or correct, but those that are, may be provable as such. Standard arithmetic is sufficiently powerful that the Incompleteness theorem applies, but not all such systems do. I've read a few people claim that disallowing multiplication from standard arithmetic renders it weak enough that you can prove it complete and correct, but since they give no proof or even evidence I have my doubts. Unfortunately the interwebs are full of people, even mathematicians, that have a lot of misapprehensions and misunderstandings of G?del's Incompleteness Theorems. For example, there's a comment here: "It's easy to prove that ZFC is consistent in the right theory, e.g. ZFC+Con(ZFC)" https://philosophy.stackexchange.com/questions/28303/if-the-zfc-axioms-cannot-be-proven-consistent-how-can-we-say-for-certain-that-a apparently without the slightest awareness that this would be begging the question. If you assume that ZFC is consistent, of course you can prove that ZFC is consistent. This article has a very nice description of G?del's theorems, the reactions of mathematicians to it ("outrage, condescension, bafflement, fascination, and complete disinterest"), a comparison of mathematical induction and ordinary induction, and why, ultimately, we shouldn't be too worried by the possibility that arithmetic is inconsistent: http://www.mathpages.com/home/kmath347/kmath347.htm -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From no.email at nospam.invalid Thu Aug 24 03:47:09 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 24 Aug 2017 00:47:09 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> Message-ID: <87tw0xe7b6.fsf@nightsong.com> Ben Finney writes: > generate_id = functools.partial(next, itertools.count()) Is something wrong with: >>> g = itertools.count().next >>> g() 0 >>> g() 1 >>> g() 2 >>> ... From no.email at nospam.invalid Thu Aug 24 03:50:42 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 24 Aug 2017 00:50:42 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> <874lt0aqim.fsf@elektro.pacujo.net> <599e339d$0$1612$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87poble759.fsf@nightsong.com> Steve D'Aprano writes: > I've read a few people claim that disallowing multiplication from > standard arithmetic renders it weak enough that you can prove it > complete and correct, but since they give no proof or even evidence I > have my doubts. That system is called Presburger arithmetic (see Wikipedia). It can be proved consistent by quantifier elimination but is not powerful enough to prove (or maybe even state) its own consistency. Surprisingly, there are also theories that can state and prove their own consistency: https://en.wikipedia.org/wiki/Self-verifying_theories From rosuav at gmail.com Thu Aug 24 03:54:34 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Aug 2017 17:54:34 +1000 Subject: Proposed new syntax In-Reply-To: <87tw0xe7b6.fsf@nightsong.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> Message-ID: On Thu, Aug 24, 2017 at 5:47 PM, Paul Rubin wrote: > Ben Finney writes: >> generate_id = functools.partial(next, itertools.count()) > > Is something wrong with: > > >>> g = itertools.count().next > >>> g() > 0 > >>> g() > 1 > >>> g() > 2 > >>> ... That's the Python 2 version of the same thing. The next method was renamed to __next__ to synchronize it with other, similar methods. ChrisA From antoon.pardon at vub.be Thu Aug 24 04:04:03 2017 From: antoon.pardon at vub.be (Antoon Pardon) Date: Thu, 24 Aug 2017 10:04:03 +0200 Subject: Proposed new syntax In-Reply-To: <599e339d$0$1612$c3e8da3$5496439d@news.astraweb.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <5997bb5c$0$1604$c3e8da3$5496439d@news.astraweb.com> <87h8x2lsbu.fsf@nightsong.com> <572f5bf4-5234-46e5-b8d7-6dc1dcc1af1b@googlegroups.com> <87wp5wjeu1.fsf@nightsong.com> <874lt0aqim.fsf@elektro.pacujo.net> <599e339d$0$1612$c3e8da3$5496439d@news.astraweb.com> Message-ID: <1a9fffc4-9709-c10f-9382-73ffffd1191f@vub.be> Op 24-08-17 om 04:02 schreef Steve D'Aprano: > > Unfortunately the interwebs are full of people, even mathematicians, that have a > lot of misapprehensions and misunderstandings of G?del's Incompleteness > Theorems. For example, there's a comment here: > > "It's easy to prove that ZFC is consistent in the right theory, e.g. > ZFC+Con(ZFC)" > > https://philosophy.stackexchange.com/questions/28303/if-the-zfc-axioms-cannot-be-proven-consistent-how-can-we-say-for-certain-that-a > > apparently without the slightest awareness that this would be begging the > question. If you assume that ZFC is consistent, of course you can prove that > ZFC is consistent. Which seems to suggest his point went right over your head. His point being that G?del's 2nd Theorem mentions the specific theory in which you can't prove particular axioms consistent. What you can prove and what not is not an absolute but depending on the system you are working with and he was just illustrating that, by providing a system in which such a proof would be trivial, because the theorem to be proven was just one of the axioms. Begging the question is not applicable in this kind of studies. A proposition is provable in a particular system or not, but it is important to specify what system you are talking about. -- Antoon Pardon From __peter__ at web.de Thu Aug 24 04:05:05 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 24 Aug 2017 10:05:05 +0200 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> Message-ID: Paul Rubin wrote: > Ben Finney writes: >> generate_id = functools.partial(next, itertools.count()) > > Is something wrong with: > > >>> g = itertools.count().next That question seems to be the topic of this subthread. Other than the principle "never call a dunder method" (that I do not follow strictly) you accidentally bring up another argument: compatibility between Python 2 and Python 3 where the next() method has been renamed to __next__(). From no.email at nospam.invalid Thu Aug 24 04:21:33 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 24 Aug 2017 01:21:33 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> Message-ID: <87lgm9e5pu.fsf@nightsong.com> Peter Otten <__peter__ at web.de> writes: > Python 3 where the next() method has been renamed to __next__(). Oh cripes, you're right, it never occurred to me that py3 had broken .next(). I thought it was called .next() instead of .__next() so that it wouldn't be a dunder method. From marko at pacujo.net Thu Aug 24 05:58:13 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 24 Aug 2017 12:58:13 +0300 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> Message-ID: <87inhd9tje.fsf@elektro.pacujo.net> Paul Rubin : > Ben Finney writes: >> generate_id = functools.partial(next, itertools.count()) > > Is something wrong with: > > >>> g = itertools.count().next I don't like lambda in Python. However, I like it better than functools.partial. Best of all, define an inner function. Marko From ben+python at benfinney.id.au Thu Aug 24 06:40:51 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 24 Aug 2017 20:40:51 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> Message-ID: <85wp5tdz9o.fsf@benfinney.id.au> Paul Rubin writes: > Ben Finney writes: > > generate_id = functools.partial(next, itertools.count()) > > Is something wrong with: > > >>> g = itertools.count().next I wasn't looking for a ?next? method on the iterator. Is that special to the ?itertools.count? type? If so, I was attempting to give the more general solution to ?how do I get a function that will give me the next thing from this iterator?. -- \ ?If consumers even know there's a DRM, what it is, and how it | `\ works, we've already failed.? ?Peter Lee, Disney corporation, | _o__) 2005 | Ben Finney From rosuav at gmail.com Thu Aug 24 07:33:38 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 24 Aug 2017 21:33:38 +1000 Subject: Proposed new syntax In-Reply-To: <85wp5tdz9o.fsf@benfinney.id.au> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <85wp5tdz9o.fsf@benfinney.id.au> Message-ID: On Thu, Aug 24, 2017 at 8:40 PM, Ben Finney wrote: > Paul Rubin writes: > >> Ben Finney writes: >> > generate_id = functools.partial(next, itertools.count()) >> >> Is something wrong with: >> >> >>> g = itertools.count().next > > I wasn't looking for a ?next? method on the iterator. Is that special to > the ?itertools.count? type? > > If so, I was attempting to give the more general solution to ?how do I > get a function that will give me the next thing from this iterator?. It's on all iterators; it's the Py2 equivalent for __next__. When you call next(x), Py2 calls x.next(), which - being an inconsistent name - got renamed to the more appropriate __next__() in Py3. ChrisA From jon+usenet at unequivocal.eu Thu Aug 24 07:43:45 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 24 Aug 2017 11:43:45 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-23, Chris Angelico wrote: > On Thu, Aug 24, 2017 at 8:54 AM, Jon Ribbens wrote: >> On 2017-08-23, Chris Angelico wrote: >>> Yes and no. If requests provided a 'cancel query' feature, it would >>> play nicely with everything else, but (a) the entire concept here is >>> that the request has stalled, so you COULD just ignore the pending >>> query and pretend it's failed without actually cancelling it; and (b) >>> you could just close the underlying socket without help, but it might >>> mess up future queries that end up getting put onto the same socket. >>> It's not that you CAN'T do this without help (which is the case for a >>> "time between bytes" timeout), but that having help would allow >>> requests *itself* to benefit. >> >> I don't understand - in the above paragraph you first explain how >> it cannot be done without help from requests, then you state that it >> can be done without help from requests. Was your first explanation >> wrong? > > Not quite. I first explain that it can be done WITH help, and then > state that it can be done WITHOUT help. That it can be done with help > does not imply that it cannot be done without help. Where did you explain how it can be done without help? As far as I'm aware, you can't close the socket without help since you can't get access to it, and as you mentioned even if you were to do so the effect it would have on requests is completely undefined. > Help is nice but it mainly helps for *subsequent* requests; an > external abort might leave internal state somewhat messed up, which > would result in resources not being released until the next query, or > perhaps a query failing and getting retried. But even without help, it > would all work. We now appear to have different understandings of the word "work", which you are defining to include things that are clearly not working. Even in a situation where there is a user constantly watching over the operation, there is still no solution as, while the user might well indicate their running out of patience by pressing 'cancel' or something, the process has no way to cancel the request in response to the user's command. Basically the only way to use requests safely is to fork an individual process for every request, which is of course spectacularly inefficient. From ben+python at benfinney.id.au Thu Aug 24 07:47:19 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Thu, 24 Aug 2017 21:47:19 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <85wp5tdz9o.fsf@benfinney.id.au> Message-ID: <85pobldw6w.fsf@benfinney.id.au> Chris Angelico writes: > On Thu, Aug 24, 2017 at 8:40 PM, Ben Finney wrote: > > Paul Rubin writes: > >> Is something wrong with: > >> > >> >>> g = itertools.count().next > > It's on all iterators; it's the Py2 equivalent for __next__. Yeah, when people are talking today about ?Python?, unqualified by version, I think it's a fair assumption that responses can be only regarding Python 3 unless there's good reason otherwise :-) So, yes there's something wrong with ?itertools.count().next?. What's wrong with it is that it works only on a dead-end Python that everyone should be busily migrating away from. (And I see Paul was later made aware of that. So, we all win! :-) -- \ ?I was gratified to be able to answer promptly and I did. I | `\ said I didn't know.? ?Mark Twain, _Life on the Mississippi_ | _o__) | Ben Finney From steve+python at pearwood.info Thu Aug 24 09:45:13 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 24 Aug 2017 23:45:13 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <87lgm9e5pu.fsf@nightsong.com> Message-ID: <599ed86a$0$1619$c3e8da3$5496439d@news.astraweb.com> On Thu, 24 Aug 2017 06:21 pm, Paul Rubin wrote: > Peter Otten <__peter__ at web.de> writes: >> Python 3 where the next() method has been renamed to __next__(). > > Oh cripes, you're right, it never occurred to me that py3 had broken > .next(). I thought it was called .next() instead of .__next() > so that it wouldn't be a dunder method. Not so much *broken* it as *fixed* it :-) Guido decided years ago that directly exposing next as a public method was a mistake. Instead, like len(), str(), repr(), iter() etc. the public API is to call the next() built-in function, and the implementation is the __next__ dunder. I don't remember whether that decision was just for consistency with other special methods, or whether there was some other deeper reason... Possibly so it was easy to add a default value to next() without having to force every iterator class to re-implement the same default behaviour? That seems reasonable... in Python 2.7, the next method takes no default argument: py> iter("").next(99) Traceback (most recent call last): File "", line 1, in ? TypeError: expected 0 arguments, got 1 but the built-in function does: py> next(iter(""), 99) 99 In general, the public API function (whether built-in like next, or not) can do much more than just call the dunder method, e.g. look at the various operators. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Thu Aug 24 09:59:03 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 24 Aug 2017 23:59:03 +1000 Subject: Cross-language comparison: function map and similar References: <59945c77$0$1597$c3e8da3$5496439d@news.astraweb.com> Message-ID: <599edba8$0$1619$c3e8da3$5496439d@news.astraweb.com> On Thu, 17 Aug 2017 12:53 am, Steve D'Aprano wrote: [...] > Are there language implementations which evaluate the result of map() (or its > equivalent) in some order other than the obvious left-to-right first-to-last > sequential order? Is that order guaranteed by the language, or is it an > implementation detail? Thanks to everyone who answered. It also confirmed my suspicion: apart from explicitly parallel languages, and specialised parallel versions of map, mainstream programming languages do not treat the execution order of map() as an implementation detail. At least not the languages which people here (reading this thread, and motivated to reply) are familiar with. I take this as moderate evidence that programming languages do not *actually* treat execution order of map and equivalent as an implementation detail, even if they reserve the right to. Instead, they generally treat it as semantically a sequential loop[1]. Apart from explicitly parallel languages, if you want a parallel or concurrent map, you need to either call a specialised version, or specify an execution policy to set the execution model, or equivalent. What you can't do, in any language mentioned here, is simply call the regular, standard map function. Thanks again to everyone who answered, and if anyone want to point out an exception, its not too late :-) [1] Whether implemented as a loop, or by recursion, or something else. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Thu Aug 24 10:01:05 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 00:01:05 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Thu, Aug 24, 2017 at 9:43 PM, Jon Ribbens wrote: > On 2017-08-23, Chris Angelico wrote: >> On Thu, Aug 24, 2017 at 8:54 AM, Jon Ribbens wrote: >>> On 2017-08-23, Chris Angelico wrote: >>>> Yes and no. If requests provided a 'cancel query' feature, it would >>>> play nicely with everything else, but (a) the entire concept here is >>>> that the request has stalled, so you COULD just ignore the pending >>>> query and pretend it's failed without actually cancelling it; and (b) >>>> you could just close the underlying socket without help, but it might >>>> mess up future queries that end up getting put onto the same socket. >>>> It's not that you CAN'T do this without help (which is the case for a >>>> "time between bytes" timeout), but that having help would allow >>>> requests *itself* to benefit. >>> >>> I don't understand - in the above paragraph you first explain how >>> it cannot be done without help from requests, then you state that it >>> can be done without help from requests. Was your first explanation >>> wrong? >> >> Not quite. I first explain that it can be done WITH help, and then >> state that it can be done WITHOUT help. That it can be done with help >> does not imply that it cannot be done without help. > > Where did you explain how it can be done without help? As far as I'm > aware, you can't close the socket without help since you can't get > access to it, and as you mentioned even if you were to do so the > effect it would have on requests is completely undefined. In a single-threaded program, just hit Ctrl-C. Job done. No need to know ANYTHING about the internals of the requests module, beyond that it has correct handling of signals. Want that on a clock? SIGALRM. You only need the more complicated solutions if you can't do this (eg if you want multithreading for othre reasons, or if SIGALRM doesn't work on Windows - which is probably the case). >> Help is nice but it mainly helps for *subsequent* requests; an >> external abort might leave internal state somewhat messed up, which >> would result in resources not being released until the next query, or >> perhaps a query failing and getting retried. But even without help, it >> would all work. > > We now appear to have different understandings of the word "work", > which you are defining to include things that are clearly not working. > > Even in a situation where there is a user constantly watching over the > operation, there is still no solution as, while the user might well > indicate their running out of patience by pressing 'cancel' or > something, the process has no way to cancel the request in response to > the user's command. > Since any process-level signal will have the effect I describe, the requests module HAS to cope with it. Hence, it WILL all work. It might not be quite as efficient ("resources not released until next query"), but it will be fully functional. I don't know what you mean by "not working". Basically, you have the potential for a dangling socket that isn't being used for anything but is still an open file. Unless you're creating a billion of them in quick succession, that's not going to break your program. > Basically the only way to use requests safely is to fork an individual > process for every request, which is of course spectacularly inefficient. Yes. Spectacularly inefficient and almost certainly unnecessary. ChrisA From jon+usenet at unequivocal.eu Thu Aug 24 10:17:27 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 24 Aug 2017 14:17:27 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-24, Chris Angelico wrote: > On Thu, Aug 24, 2017 at 9:43 PM, Jon Ribbens wrote: >> Where did you explain how it can be done without help? As far as I'm >> aware, you can't close the socket without help since you can't get >> access to it, and as you mentioned even if you were to do so the >> effect it would have on requests is completely undefined. > > In a single-threaded program, just hit Ctrl-C. By that, do you mean "kill the process"? That's obviously not a sensible answer in general, especially given we were including processes which have no terminal or user sitting there watching them. > Job done. No need to know ANYTHING about the internals of the > requests module, beyond that it has correct handling of signals. > Want that on a clock? SIGALRM. Doesn't work with threading. >> Even in a situation where there is a user constantly watching over the >> operation, there is still no solution as, while the user might well >> indicate their running out of patience by pressing 'cancel' or >> something, the process has no way to cancel the request in response to >> the user's command. > > Since any process-level signal will have the effect I describe, the > requests module HAS to cope with it. Receiving a signal is the same as closing the socket? What? (And as I already mentioned, you can't close the socket anyway.) > Hence, it WILL all work. It might not be quite as efficient > ("resources not released until next query"), but it will be fully > functional. I don't know what you mean by "not working". Resources not released, subsequent operations failing, the library possibly left in a state from which it cannot recover. This is pretty obviously stuff that "is not working". Although even then you still haven't explained how we can abort the operation (even with all these side-effects) in the first place. > Basically, you have the potential for a dangling socket that isn't > being used for anything but is still an open file. Unless you're > creating a billion of them in quick succession, that's not going to > break your program. It would take many orders of magnitude fewer than a billion to break the program. This is not a responsible or sensible way to write a computer program - to deliberately let it leak stuff and invoke undefined behaviour all over the place and hope that somehow it'll muddle along regardless. >> Basically the only way to use requests safely is to fork an individual >> process for every request, which is of course spectacularly inefficient. > > Yes. Spectacularly inefficient and almost certainly unnecessary. You haven't suggested any workable alternative so far. From ned at nedbatchelder.com Thu Aug 24 11:21:27 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Thu, 24 Aug 2017 11:21:27 -0400 Subject: id In-Reply-To: References: Message-ID: On 8/24/17 10:42 AM, Stefan Ram wrote: > i = 0 > while True: print( f"{ i }:{ id( i )}" ); i = i + 1 > > This loop prints increasing ids while i is less than > 257, and then it starts to print alternating ids. > > So this seems to indicate that temporary objects are > created for large integers, and that we can observe > that two (different?) objects (which do not exist > simultaneously) can have "the same identity"? > Correct. Small integers are interned, and will always be the same object for the same value. Ids can be re-used by objects which don't exist at the same time. In CPython, id(x) is the memory address of x. When an object is freed, another object will eventually occupy the same memory address, and get the same id. --Ned. From rosuav at gmail.com Thu Aug 24 12:01:40 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 02:01:40 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Fri, Aug 25, 2017 at 12:17 AM, Jon Ribbens wrote: > On 2017-08-24, Chris Angelico wrote: >> On Thu, Aug 24, 2017 at 9:43 PM, Jon Ribbens wrote: >>> Where did you explain how it can be done without help? As far as I'm >>> aware, you can't close the socket without help since you can't get >>> access to it, and as you mentioned even if you were to do so the >>> effect it would have on requests is completely undefined. >> >> In a single-threaded program, just hit Ctrl-C. > > By that, do you mean "kill the process"? That's obviously not > a sensible answer in general, especially given we were including > processes which have no terminal or user sitting there watching > them. Only in the sense that "kill" is the Unix term for "send signal". Python catches the signal, the system call terminates with EINTR, and the exception is raised. Give it a try. (Caveat: I have no idea how this works on Windows. I do expect, though, that it will abort the connection without terminating the process, just like it does on Unix.) >> Job done. No need to know ANYTHING about the internals of the >> requests module, beyond that it has correct handling of signals. >> Want that on a clock? SIGALRM. > > Doesn't work with threading. How many of your programs have threads in them? Did you not read my point where I said that the bulk of programs can use these simple techniques? >>> Even in a situation where there is a user constantly watching over the >>> operation, there is still no solution as, while the user might well >>> indicate their running out of patience by pressing 'cancel' or >>> something, the process has no way to cancel the request in response to >>> the user's command. >> >> Since any process-level signal will have the effect I describe, the >> requests module HAS to cope with it. > > Receiving a signal is the same as closing the socket? What? > (And as I already mentioned, you can't close the socket anyway.) Not as such, but try it and see what actually happens. The signal aborts the syscall; the exception causes the stack to be unwound. TRY IT. It works. >> Hence, it WILL all work. It might not be quite as efficient >> ("resources not released until next query"), but it will be fully >> functional. I don't know what you mean by "not working". > > Resources not released, subsequent operations failing, the library > possibly left in a state from which it cannot recover. This is > pretty obviously stuff that "is not working". Although even then > you still haven't explained how we can abort the operation (even > with all these side-effects) in the first place. Not released UNTIL NEXT QUERY. Everything is recoverable. TRY IT. It works. >> Basically, you have the potential for a dangling socket that isn't >> being used for anything but is still an open file. Unless you're >> creating a billion of them in quick succession, that's not going to >> break your program. > > It would take many orders of magnitude fewer than a billion to break > the program. This is not a responsible or sensible way to write a > computer program - to deliberately let it leak stuff and invoke > undefined behaviour all over the place and hope that somehow it'll > muddle along regardless. Leaking until the next call? A billion. >>> Basically the only way to use requests safely is to fork an individual >>> process for every request, which is of course spectacularly inefficient. >> >> Yes. Spectacularly inefficient and almost certainly unnecessary. > > You haven't suggested any workable alternative so far. Have you tried any of what I said? ChrisA From marko at pacujo.net Thu Aug 24 13:40:03 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 24 Aug 2017 20:40:03 +0300 Subject: requests.{get,post} timeout References: Message-ID: <87bmn4uaoc.fsf@elektro.pacujo.net> Chris Angelico : > On Fri, Aug 25, 2017 at 12:17 AM, Jon Ribbens > wrote: >> By that, do you mean "kill the process"? That's obviously not a >> sensible answer in general, especially given we were including >> processes which have no terminal or user sitting there watching them. > > Only in the sense that "kill" is the Unix term for "send signal". > Python catches the signal, the system call terminates with EINTR, and > the exception is raised. Give it a try. Signals are an arcane Unix communication method. I strongly recommend against using signals for anything but terminating a process, and even then you have to be extra careful. I have seen code that uses signals for runtime communication, but none of it was free from race conditions. >>>> Basically the only way to use requests safely is to fork an >>>> individual process for every request, which is of course >>>> spectacularly inefficient. >>> >>> Yes. Spectacularly inefficient and almost certainly unnecessary. Processes are a nice way to exercise multiple CPUs and also a way to deal with obnoxious synchronous function calls. However, you don't want to fork a process (or a thread, for that matter) for each context. Rather, you should have a pool of processes in the order of, say, 2 * CPU count, and the processes should fetch work from a queue. And if a process should get stuck, killing it is trivial. Marko From rosuav at gmail.com Thu Aug 24 14:02:02 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 04:02:02 +1000 Subject: requests.{get,post} timeout In-Reply-To: <87bmn4uaoc.fsf@elektro.pacujo.net> References: <87bmn4uaoc.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 25, 2017 at 3:40 AM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Fri, Aug 25, 2017 at 12:17 AM, Jon Ribbens >> wrote: >>> By that, do you mean "kill the process"? That's obviously not a >>> sensible answer in general, especially given we were including >>> processes which have no terminal or user sitting there watching them. >> >> Only in the sense that "kill" is the Unix term for "send signal". >> Python catches the signal, the system call terminates with EINTR, and >> the exception is raised. Give it a try. > > Signals are an arcane Unix communication method. I strongly recommend > against using signals for anything but terminating a process, and even > then you have to be extra careful. > > I have seen code that uses signals for runtime communication, but none > of it was free from race conditions. Strongly disagree. Signals exist so that they can be used. Sending SIGHUP to a daemon to tell it to reload its configs is well-supported by the ecosystem; use of SIGCHLD and SIGWINCH for non-termination conditions is also vital. How else should an operating system or desktop environment inform a process of something important? Ctrl-C sends SIGINT meaning "interrupt". There are many, MANY situations in which "interrupting" a process doesn't terminate it. Here's one very simple example: $ python3 Python 3.7.0a0 (heads/master:3913bad495, Jul 21 2017, 20:53:52) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>> ( ... KeyboardInterrupt >>> You hit Ctrl-C in the middle of typing a multi-line command (maybe you didn't expect it to be multi-line?), and the current input is cancelled. Easy. No termination needed. And no race condition. I don't know why you'd get those, but they're not hard to eliminate. >>>>> Basically the only way to use requests safely is to fork an >>>>> individual process for every request, which is of course >>>>> spectacularly inefficient. >>>> >>>> Yes. Spectacularly inefficient and almost certainly unnecessary. > > Processes are a nice way to exercise multiple CPUs and also a way to > deal with obnoxious synchronous function calls. > > However, you don't want to fork a process (or a thread, for that matter) > for each context. Rather, you should have a pool of processes in the > order of, say, 2 * CPU count, and the processes should fetch work from a > queue. > > And if a process should get stuck, killing it is trivial. Yeah, if you DO need to split them out, a pool is good. I didn't bother mentioning it as a single process was enough for the scenario in question (which definitely sounded like an I/O-bound app), but even if you do fork, there's not a lot of point forking exactly one per request. Interestingly, the 2*CPUs figure isn't always optimal. I've messed around with -j options on repeatable tasks, and sometimes the best figure is lower than that, and other times it's insanely higher. On my four-core-hyperthreading CPU, I've had times when 12 is right, I've had times when 4 is right, and I even had one situation when I was debating between -j64 and -j128 on a task that was theoretically CPU-bound (ray-tracing). There are a lot of weird things happening with caching and such, and the only way to truly know what's best is to try it! ChrisA From alister.ware at ntlworld.com Thu Aug 24 14:09:01 2017 From: alister.ware at ntlworld.com (alister) Date: Thu, 24 Aug 2017 18:09:01 GMT Subject: id References: Message-ID: <1DEnB.834458$b8.50864@fx05.am4> On Thu, 24 Aug 2017 11:21:27 -0400, Ned Batchelder wrote: > On 8/24/17 10:42 AM, Stefan Ram wrote: >> i = 0 while True: print( f"{ i }:{ id( i )}" ); i = i + 1 >> >> This loop prints increasing ids while i is less than 257, and then it >> starts to print alternating ids. >> >> So this seems to indicate that temporary objects are created for >> large integers, and that we can observe that two (different?) objects >> (which do not exist simultaneously) can have "the same identity"? >> >> > Correct. Small integers are interned, and will always be the same > object for the same value. Ids can be re-used by objects which don't > exist at the same time. In CPython, id(x) is the memory address of x. > When an object is freed, another object will eventually occupy the same > memory address, and get the same id. > > --Ned. This is all implementation dependent -- If someone says he will do something "without fail", he won't. From breamoreboy at gmail.com Thu Aug 24 14:26:54 2017 From: breamoreboy at gmail.com (breamoreboy at gmail.com) Date: Thu, 24 Aug 2017 11:26:54 -0700 (PDT) Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: <87ac58de-b92e-41dd-b5fe-01df9a944962@googlegroups.com> On Thursday, August 24, 2017 at 5:02:12 PM UTC+1, Chris Angelico wrote: > > (Caveat: I have no idea how this works on Windows. I do expect, > though, that it will abort the connection without terminating the > process, just like it does on Unix.) > > ChrisA There was a big thread "cross platform alternative for signal.SIGALRM?" https://mail.python.org/pipermail/python-list/2015-November/698968.html which you might find interesting. Kindest regards. Mark Lawrence. From marko at pacujo.net Thu Aug 24 15:07:08 2017 From: marko at pacujo.net (Marko Rauhamaa) Date: Thu, 24 Aug 2017 22:07:08 +0300 Subject: requests.{get,post} timeout References: <87bmn4uaoc.fsf@elektro.pacujo.net> Message-ID: <877exsu6n7.fsf@elektro.pacujo.net> Chris Angelico : > On Fri, Aug 25, 2017 at 3:40 AM, Marko Rauhamaa wrote: >> Signals are an arcane Unix communication method. I strongly recommend >> against using signals for anything but terminating a process, and even >> then you have to be extra careful. >> >> I have seen code that uses signals for runtime communication, but none >> of it was free from race conditions. > > Strongly disagree. Signals exist so that they can be used. Sending > SIGHUP to a daemon to tell it to reload its configs is well-supported > by the ecosystem; The ancient SIGHUP reload antipattern is infamous: /bin/kill -HUP $MAINPID Note however that reloading a daemon by sending a signal (as with the example line above) is usually not a good choice, because this is an asynchronous operation and hence not suitable to order reloads of multiple services against each other. It is strongly recommended to set ExecReload= to a command that not only triggers a configuration reload of the daemon, but also synchronously waits for it to complete. The SIGHUP practice makes automation painful. I want to reconfigure but can't be sure when the new configuration has taken effect. > use of SIGCHLD and SIGWINCH for non-termination conditions is also > vital. How else should an operating system or desktop environment > inform a process of something important? I never use SIGCHLD. Instead I leave a pipe open between the child and the parent and notice an EOF on the pipe as the child exits. The pipe (or socketpair) is handy for other IPC as well. The signalfd mechanism in newer Linux kernels might make signals borderline usable. However, code that relies on signals had better meticulously call sigprocmask(2) and understand the precise points where signals should be let through. Another thing: this is a C programming issue, but functions like fprintf() should never be used together with signals: Marko From rosuav at gmail.com Thu Aug 24 15:15:38 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 05:15:38 +1000 Subject: requests.{get,post} timeout In-Reply-To: <877exsu6n7.fsf@elektro.pacujo.net> References: <87bmn4uaoc.fsf@elektro.pacujo.net> <877exsu6n7.fsf@elektro.pacujo.net> Message-ID: On Fri, Aug 25, 2017 at 5:07 AM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Fri, Aug 25, 2017 at 3:40 AM, Marko Rauhamaa wrote: >>> Signals are an arcane Unix communication method. I strongly recommend >>> against using signals for anything but terminating a process, and even >>> then you have to be extra careful. >>> >>> I have seen code that uses signals for runtime communication, but none >>> of it was free from race conditions. >> >> Strongly disagree. Signals exist so that they can be used. Sending >> SIGHUP to a daemon to tell it to reload its configs is well-supported >> by the ecosystem; > > The ancient SIGHUP reload antipattern is infamous: > > /bin/kill -HUP $MAINPID > > Note however that reloading a daemon by sending a signal (as with the > example line above) is usually not a good choice, because this is an > asynchronous operation and hence not suitable to order reloads of > multiple services against each other. It is strongly recommended to > set ExecReload= to a command that not only triggers a configuration > reload of the daemon, but also synchronously waits for it to > complete. > > e.html> > > The SIGHUP practice makes automation painful. I want to reconfigure but > can't be sure when the new configuration has taken effect. And yet, despite you calling it an antipattern, it's still very well supported. There are limitations to it - as you say, it's asynchronous - but it is the default for many services. SystemD is completely supporting it. ChrisA From nathan.ernst at gmail.com Thu Aug 24 15:54:08 2017 From: nathan.ernst at gmail.com (Nathan Ernst) Date: Thu, 24 Aug 2017 14:54:08 -0500 Subject: Reading the documentation In-Reply-To: References: Message-ID: You passed a string to "math.floor", not anything resembling a numeric type. Try using an actual float, int or Decimal: Python 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from math import floor >>> from decimal import Decimal >>> floor("2.3") Traceback (most recent call last): File "", line 1, in TypeError: a float is required >>> floor(2.3) 2 >>> floor(Decimal("2.3")) 2 >>> floor(2) 2 Remember that Python is strongly typed; you do not get automatic type conversions from strings to numeric types such as in Perl. Regards, Nathan On Thu, Aug 24, 2017 at 2:24 PM, Stefan Ram wrote: > This is a transcript: > > >>> from math import floor > >>> floor( "2.3" ) > Traceback (most recent call last): > File "", line 1, in > TypeError: must be real number, not str > >>> help(floor) > Help on built-in function floor in module math: > > floor(...) > floor(x) > > Return the floor of x as an Integral. > This is the largest integer <= x. > > Is the output of ?help(floor)? supposed to be a kind of > normative documentation, i.e., /the/ authoritative > documentation of ?floor?? > > Is there any hint in the documentation about the type > expected of arguments in a call? > > Is a parameter name ?x? (as used above) described > somewhere to express the requirement of a real number? > > It seems, ?real? means ?int or float?. Is this meaning > of ?real? documented somewhere? > > Thanks in advance! > > -- > https://mail.python.org/mailman/listinfo/python-list > From python at mrabarnett.plus.com Thu Aug 24 16:08:16 2017 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 24 Aug 2017 21:08:16 +0100 Subject: Reading the documentation In-Reply-To: References: Message-ID: On 2017-08-24 20:24, Stefan Ram wrote: > This is a transcript: > >>>> from math import floor >>>> floor( "2.3" ) > Traceback (most recent call last): > File "", line 1, in > TypeError: must be real number, not str >>>> help(floor) > Help on built-in function floor in module math: > > floor(...) > floor(x) > > Return the floor of x as an Integral. > This is the largest integer <= x. > > Is the output of ?help(floor)? supposed to be a kind of > normative documentation, i.e., /the/ authoritative > documentation of ?floor?? > > Is there any hint in the documentation about the type > expected of arguments in a call? > > Is a parameter name ?x? (as used above) described > somewhere to express the requirement of a real number? > > It seems, ?real? means ?int or float?. Is this meaning > of ?real? documented somewhere? > > Thanks in advance! > As the module is called "math", it's not surprising that "floor" expects a number and rejects a string. There's also a "cmath" module, which handles complex numbers. "real" can be int, float or Decimal, but not complex. From __peter__ at web.de Thu Aug 24 16:46:04 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 24 Aug 2017 22:46:04 +0200 Subject: Reading the documentation References: Message-ID: Stefan Ram wrote: > This is a transcript: > >>>> from math import floor >>>> floor( "2.3" ) > Traceback (most recent call last): > File "", line 1, in > TypeError: must be real number, not str >>>> help(floor) > Help on built-in function floor in module math: > > floor(...) > floor(x) > > Return the floor of x as an Integral. > This is the largest integer <= x. > > Is the output of ?help(floor)? supposed to be a kind of > normative documentation, i.e., /the/ authoritative > documentation of ?floor?? You should consult the documentation https://docs.python.org/dev/library/math.html#math.floor which has usually more details. The docstring (i. e. what help() shows) is most helpful when you already have an idea about what a function does. > Is there any hint in the documentation about the type > expected of arguments in a call? Yes. Everything that features a __floor__() method: >>> import math >>> class Foo: ... def __floor__(self): return "yadda" ... >>> math.floor(Foo()) 'yadda' So the current implementation doesn't even mandate an int as the result... > Is a parameter name ?x? (as used above) described > somewhere to express the requirement of a real number? > > It seems, ?real? means ?int or float?. Is this meaning > of ?real? documented somewhere? I don't know if there is something more direct than https://docs.python.org/dev/library/numbers.html and the PEP linked from there. > > Thanks in advance! > From ben.usenet at bsb.me.uk Thu Aug 24 19:15:13 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 25 Aug 2017 00:15:13 +0100 Subject: A question on modification of a list via a function invocation References: <89e6cacb-90f1-e6dc-7376-56aadcda607b@nedbatchelder.com> <178b2da3-9240-143b-7c29-1780923d52ad@t-online.de> <36mdnXQc6v8B9A_EnZ2dnUU7-f_NnZ2d@giganews.com> <1f666425-7311-cb6b-44d6-3c5880fa7b26@t-online.de> <5742ab0b-6bc7-cf7a-e003-ca21ca9bb16f@nedbatchelder.com> <305746fb-66cb-7acb-82d4-e0c6987438a6@t-online.de> <5994f412$0$1618$c3e8da3$5496439d@news.astraweb.com> <87fucqjowo.fsf@bsb.me.uk> <59967693$0$1611$c3e8da3$5496439d@news.astraweb.com> <87y3qhgefe.fsf@bsb.me.uk> <599a5b80$0$1584$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87r2w04kxq.fsf@bsb.me.uk> Steve D'Aprano writes: It took a while to reply, and when I got round it I could not find anything new that seemed to be worth saying. I think we've both stated our positions quite well. I don't think we will end up in agreement, and whilst I can grumble and nit-pick as well as anyone, with the big picture left to one side there only seem to be such details left to fuss over. I hope, therefore, that you will forgive me for not replying in full, but I none the less do thank you for taking the time to talk these points over in depth. -- Ben. From bgailer at gmail.com Thu Aug 24 19:21:23 2017 From: bgailer at gmail.com (bob gailer) Date: Thu, 24 Aug 2017 19:21:23 -0400 Subject: Reading the documentation In-Reply-To: References: Message-ID: <48208081-fa9f-4340-8995-7ceeb6cc4b5e@gmail.com> On 8/24/2017 3:54 PM, Nathan Ernst wrote: > You passed a string to "math.floor", not anything resembling a numeric > type. Try using an actual float, int or Decimal: It would seem you did not understand the OP's question. It was not "why did I get this traceback." He showed the traceback as leading him to use the help builtin. He was questioning what help() returned. > > Python 3.5.2 (default, Nov 17 2016, 17:05:23) > [GCC 5.4.0 20160609] on linux > Type "help", "copyright", "credits" or "license" for more information. >>>> from math import floor >>>> from decimal import Decimal >>>> floor("2.3") > Traceback (most recent call last): > File "", line 1, in > TypeError: a float is required > >>>> floor(2.3) > 2 > >>>> floor(Decimal("2.3")) > 2 > >>>> floor(2) > 2 > > Remember that Python is strongly typed; you do not get automatic type > conversions from strings to numeric types such as in Perl. > > Regards, > Nathan > > On Thu, Aug 24, 2017 at 2:24 PM, Stefan Ram wrote: > >> This is a transcript: >> >>>>> from math import floor >>>>> floor( "2.3" ) >> Traceback (most recent call last): >> File "", line 1, in >> TypeError: must be real number, not str >>>>> help(floor) >> Help on built-in function floor in module math: >> >> floor(...) >> floor(x) >> >> Return the floor of x as an Integral. >> This is the largest integer <= x. >> >> Is the output of ?help(floor)? supposed to be a kind of >> normative documentation, i.e., /the/ authoritative >> documentation of ?floor?? >> >> Is there any hint in the documentation about the type >> expected of arguments in a call? >> >> Is a parameter name ?x? (as used above) described >> somewhere to express the requirement of a real number? >> >> It seems, ?real? means ?int or float?. Is this meaning >> of ?real? documented somewhere? >> >> Thanks in advance! >> >> -- >> https://mail.python.org/mailman/listinfo/python-list >> -- Image and video hosting by TinyPic From ofekmeister at gmail.com Thu Aug 24 19:35:08 2017 From: ofekmeister at gmail.com (ofekmeister at gmail.com) Date: Thu, 24 Aug 2017 16:35:08 -0700 (PDT) Subject: pypinfo: CLI to easily view PyPI download statistics via Google's BigQuery. In-Reply-To: References: Message-ID: If you ever want to quickly check your package's downloads counts or wish to know more about your users, I'd really recommend this! From bgailer at gmail.com Thu Aug 24 19:41:46 2017 From: bgailer at gmail.com (bob gailer) Date: Thu, 24 Aug 2017 19:41:46 -0400 Subject: Reading the documentation In-Reply-To: References: Message-ID: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> On 8/24/2017 3:24 PM, Stefan Ram wrote: > This is a transcript: > >>>> from math import floor >>>> floor( "2.3" ) > Traceback (most recent call last): > File "", line 1, in > TypeError: must be real number, not str >>>> help(floor) > Help on built-in function floor in module math: > > floor(...) > floor(x) > > Return the floor of x as an Integral. > This is the largest integer <= x. > > Is the output of ?help(floor)? supposed to be a kind of > normative documentation, i.e., /the/ authoritative > documentation of ?floor?? > > Is there any hint in the documentation about the type > expected of arguments in a call? > > Is a parameter name ?x? (as used above) described > somewhere to express the requirement of a real number? > > It seems, ?real? means ?int or float?. Is this meaning > of ?real? documented somewhere? in the Python Language Reference 3.2. The standard type hierarchy ??? numbers.Real (float) ??????? These represent machine-level double precision floating point numbers. This? is not the meaning of "real" in mathematics! I was surprised by the use of "integral". A dictionary search does not (IMHO) support this usage! > > Thanks in advance! > -- Image and video hosting by TinyPic From steve+python at pearwood.info Thu Aug 24 20:25:55 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 10:25:55 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> Message-ID: <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 09:41 am, bob gailer wrote: >> Help on built-in function floor in module math: >> >> floor(...) >> floor(x) >> >> Return the floor of x as an Integral. >> This is the largest integer <= x. [...] > I was surprised by the use of "integral". A dictionary search does not > (IMHO) support this usage! Integral \In"te*gral\, a. [Cf. F. int['e]gral. See Integer.] [1913 Webster] 1. Lacking nothing of completeness; complete; perfect; uninjured; whole; entire. [1913 Webster] A local motion keepeth bodies integral. --Bacon. [1913 Webster] 2. Essential to completeness; constituent, as a part; pertaining to, or serving to form, an integer; integrant. [1913 Webster] Ceasing to do evil, and doing good, are the two great integral parts that complete this duty. --South. [1913 Webster] 3. (Math.) (a) Of, pertaining to, or being, a whole number or undivided quantity; not fractional. (b) Pertaining to, or proceeding by, integration; as, the integral calculus. [1913 Webster] -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Thu Aug 24 20:38:10 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 10:38:10 +1000 Subject: id References: Message-ID: <599f7175$0$1610$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 12:42 am, Stefan Ram wrote: > i = 0 > while True: print( f"{ i }:{ id( i )}" ); i = i + 1 > > This loop prints increasing ids while i is less than > 257, and then it starts to print alternating ids. Try running it under Jython or IronPython. Try running it starting with i=1000000 instead. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Thu Aug 24 20:38:43 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 10:38:43 +1000 Subject: Reading the documentation References: Message-ID: <599f7195$0$1610$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 05:24 am, Stefan Ram wrote: > Is the output of ?help(floor)? supposed to be a kind of > normative documentation, i.e., /the/ authoritative > documentation of ?floor?? No. The output of help() is intended as a short description of the function, not the authoritative and complete documentation. For that, see the docs in the website. > Is there any hint in the documentation about the type > expected of arguments in a call? > > Is a parameter name ?x? (as used above) described > somewhere to express the requirement of a real number? There are various weak conventions for variable names: x, y - floats or other real values, occasionally anything at all; i, j, k - integers s - string, set a, b, c - three variables of the same kind (e.g. three lists) o, obj - arbitrary object L - list d - dict, occasionally Decimal spam, eggs, cheese - Pythonic versions of foo, bar, baz > It seems, ?real? means ?int or float?. Is this meaning > of ?real? documented somewhere? See the documentation for the numeric tower. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From jon+usenet at unequivocal.eu Thu Aug 24 20:42:45 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 25 Aug 2017 00:42:45 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-24, Chris Angelico wrote: > On Fri, Aug 25, 2017 at 12:17 AM, Jon Ribbens wrote: >> On 2017-08-24, Chris Angelico wrote: >>> On Thu, Aug 24, 2017 at 9:43 PM, Jon Ribbens wrote: >>>> Where did you explain how it can be done without help? As far as I'm >>>> aware, you can't close the socket without help since you can't get >>>> access to it, and as you mentioned even if you were to do so the >>>> effect it would have on requests is completely undefined. >>> >>> In a single-threaded program, just hit Ctrl-C. >> >> By that, do you mean "kill the process"? That's obviously not >> a sensible answer in general, especially given we were including >> processes which have no terminal or user sitting there watching >> them. > > Only in the sense that "kill" is the Unix term for "send signal". > Python catches the signal, the system call terminates with EINTR, and > the exception is raised. Give it a try. Give what a try? Pressing ctrl-c? That'll kill the process. Obviously we all agree that killing the entire process will terminate the request and all resources associated with it. >>> Job done. No need to know ANYTHING about the internals of the >>> requests module, beyond that it has correct handling of signals. >>> Want that on a clock? SIGALRM. >> >> Doesn't work with threading. > > How many of your programs have threads in them? Um, basically all of them? > Did you not read my point where I said that the bulk of programs can > use these simple techniques? I'm not sure I did but even so your point would appear to be wrong. >> Receiving a signal is the same as closing the socket? What? >> (And as I already mentioned, you can't close the socket anyway.) > > Not as such, but try it and see what actually happens. The signal > aborts the syscall; the exception causes the stack to be unwound. TRY > IT. It works. Try *what*? >> Resources not released, subsequent operations failing, the library >> possibly left in a state from which it cannot recover. This is >> pretty obviously stuff that "is not working". Although even then >> you still haven't explained how we can abort the operation (even >> with all these side-effects) in the first place. > > Not released UNTIL NEXT QUERY. Everything is recoverable. TRY IT. It works. Try what? >> It would take many orders of magnitude fewer than a billion to break >> the program. This is not a responsible or sensible way to write a >> computer program - to deliberately let it leak stuff and invoke >> undefined behaviour all over the place and hope that somehow it'll >> muddle along regardless. > > Leaking until the next call? A billion. I don't believe you about it only leaking "until the next call", whatever that means. >>>> Basically the only way to use requests safely is to fork an individual >>>> process for every request, which is of course spectacularly inefficient. >>> >>> Yes. Spectacularly inefficient and almost certainly unnecessary. >> >> You haven't suggested any workable alternative so far. > > Have you tried any of what I said? What have you actually suggested to try? From rosuav at gmail.com Thu Aug 24 20:54:28 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 10:54:28 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Fri, Aug 25, 2017 at 10:42 AM, Jon Ribbens wrote: > On 2017-08-24, Chris Angelico wrote: >> Only in the sense that "kill" is the Unix term for "send signal". >> Python catches the signal, the system call terminates with EINTR, and >> the exception is raised. Give it a try. > > Give what a try? Pressing ctrl-c? That'll kill the process. > Obviously we all agree that killing the entire process will > terminate the request and all resources associated with it. >>> import requests >>> requests.get("http://192.168.0.1/") ^CTraceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.7/site-packages/requests/api.py", line 70, in get return request('get', url, params=params, **kwargs) File "/usr/local/lib/python3.7/site-packages/requests/api.py", line 56, in request return session.request(method=method, url=url, **kwargs) File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 488, in request resp = self.send(prep, **send_kwargs) File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 609, in send r = adapter.send(request, **kwargs) File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 423, in send timeout=timeout File "/usr/local/lib/python3.7/site-packages/requests/packages/urllib3/connectionpool.py", line 600, in urlopen chunked=chunked) File "/usr/local/lib/python3.7/site-packages/requests/packages/urllib3/connectionpool.py", line 356, in _make_request conn.request(method, url, **httplib_request_kw) File "/usr/local/lib/python3.7/http/client.py", line 1230, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/local/lib/python3.7/http/client.py", line 1276, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/local/lib/python3.7/http/client.py", line 1225, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/local/lib/python3.7/http/client.py", line 1017, in _send_output self.send(msg) File "/usr/local/lib/python3.7/http/client.py", line 955, in send self.connect() File "/usr/local/lib/python3.7/site-packages/requests/packages/urllib3/connection.py", line 166, in connect conn = self._new_conn() File "/usr/local/lib/python3.7/site-packages/requests/packages/urllib3/connection.py", line 141, in _new_conn (self.host, self.port), self.timeout, **extra_kw) File "/usr/local/lib/python3.7/site-packages/requests/packages/urllib3/util/connection.py", line 73, in create_connection sock.connect(sa) KeyboardInterrupt >>> That looks like an exception to me. Not a "process is now terminated". That's what happened when I pressed Ctrl-C (the IP address was deliberately picked as one that doesn't currently exist on my network, so it took time). ChrisA From ben.usenet at bsb.me.uk Thu Aug 24 21:25:25 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 25 Aug 2017 02:25:25 +0100 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87lgm84ewq.fsf@bsb.me.uk> Steve D'Aprano writes: > On Fri, 25 Aug 2017 09:41 am, bob gailer wrote: > >>> Help on built-in function floor in module math: >>> >>> floor(...) >>> floor(x) >>> >>> Return the floor of x as an Integral. >>> This is the largest integer <= x. > [...] > >> I was surprised by the use of "integral". A dictionary search does not >> (IMHO) support this usage! > > Integral \In"te*gral\, a. [Cf. F. int['e]gral. See Integer.] For me (and I suspect for BG too) the surprise is in its use as a noun. The capital letter is, presumably, significant because it refers to the Python class Integral -- a subtype of numbers. With that in mind, "an Integral" is a shorthand for "an Integral value", or more fully, maybe, "an instance of numbers.Integral". > [1913 Webster] > 1. Lacking nothing of completeness; complete; perfect; > uninjured; whole; entire. > [1913 Webster] > > A local motion keepeth bodies integral. --Bacon. > [1913 Webster] > > 2. Essential to completeness; constituent, as a part; > pertaining to, or serving to form, an integer; integrant. > [1913 Webster] > > Ceasing to do evil, and doing good, are the two > great integral parts that complete this duty. > --South. > [1913 Webster] > > 3. (Math.) > (a) Of, pertaining to, or being, a whole number or > undivided quantity; not fractional. > (b) Pertaining to, or proceeding by, integration; as, the > integral calculus. > [1913 Webster] The use as a noun is not covered here, though it is only a small step from other places where membership of a mathematical set has turned the adjective into a noun. "Rational" and "real" started out as adjectives, but their use as nouns is now widespread. "The function returns a real". "The result is a rational". It's much less common for complex and integral, to the point that it sounds wrong to me. -- Ben. From rosuav at gmail.com Thu Aug 24 21:40:13 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 11:40:13 +1000 Subject: Reading the documentation In-Reply-To: <87lgm84ewq.fsf@bsb.me.uk> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> Message-ID: On Fri, Aug 25, 2017 at 11:25 AM, Ben Bacarisse wrote: > The use as a noun is not covered here, though it is only a small step > from other places where membership of a mathematical set has turned the > adjective into a noun. "Rational" and "real" started out as adjectives, > but their use as nouns is now widespread. "The function returns a > real". "The result is a rational". It's much less common for complex > and integral, to the point that it sounds wrong to me. This is a common thing in English (and many other languages). When you find yourself frequently using similar phrases, you abbreviate them: * real number -> real * rational number -> rational * complex number -> complex Thus the adjective acquires a new meaning as a noun. As my mother (and grammar teacher) drummed into me: No word is a part of speech unless it appears in context. ChrisA From ben.usenet at bsb.me.uk Thu Aug 24 21:58:07 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 25 Aug 2017 02:58:07 +0100 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> Message-ID: <87fucg4de8.fsf@bsb.me.uk> Chris Angelico writes: > On Fri, Aug 25, 2017 at 11:25 AM, Ben Bacarisse wrote: >> The use as a noun is not covered here, though it is only a small step >> from other places where membership of a mathematical set has turned the >> adjective into a noun. "Rational" and "real" started out as adjectives, >> but their use as nouns is now widespread. "The function returns a >> real". "The result is a rational". It's much less common for complex >> and integral, to the point that it sounds wrong to me. > > This is a common thing in English (and many other languages). When you > find yourself frequently using similar phrases, you abbreviate them: > > * real number -> real > * rational number -> rational > * complex number -> complex > > Thus the adjective acquires a new meaning as a noun. As my mother (and > grammar teacher) drummed into me: No word is a part of speech unless > it appears in context. Yes, we agree on that, but has it become natural(!) yet with complex and integral? Not to my ear. What about yours? To me, the "adjectiveness" is still so strong that my brain asks "an integral what?", "a complex what?". That does not happen in my head with "a real" or "a rational". -- Ben. From rosuav at gmail.com Thu Aug 24 22:04:46 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 12:04:46 +1000 Subject: Reading the documentation In-Reply-To: <87fucg4de8.fsf@bsb.me.uk> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <87fucg4de8.fsf@bsb.me.uk> Message-ID: On Fri, Aug 25, 2017 at 11:58 AM, Ben Bacarisse wrote: > Chris Angelico writes: > >> On Fri, Aug 25, 2017 at 11:25 AM, Ben Bacarisse wrote: >>> The use as a noun is not covered here, though it is only a small step >>> from other places where membership of a mathematical set has turned the >>> adjective into a noun. "Rational" and "real" started out as adjectives, >>> but their use as nouns is now widespread. "The function returns a >>> real". "The result is a rational". It's much less common for complex >>> and integral, to the point that it sounds wrong to me. >> >> This is a common thing in English (and many other languages). When you >> find yourself frequently using similar phrases, you abbreviate them: >> >> * real number -> real >> * rational number -> rational >> * complex number -> complex >> >> Thus the adjective acquires a new meaning as a noun. As my mother (and >> grammar teacher) drummed into me: No word is a part of speech unless >> it appears in context. > > Yes, we agree on that, but has it become natural(!) yet with complex and > integral? Not to my ear. What about yours? > > To me, the "adjectiveness" is still so strong that my brain asks "an > integral what?", "a complex what?". That does not happen in my head > with "a real" or "a rational". Yes, it's comfortable on my ear. But maybe that's because I'm stronger in programming than in mathematical theory. ChrisA From rustompmody at gmail.com Thu Aug 24 22:16:46 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 19:16:46 -0700 (PDT) Subject: Reading the documentation In-Reply-To: <87lgm84ewq.fsf@bsb.me.uk> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> Message-ID: <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> On Friday, August 25, 2017 at 6:55:46 AM UTC+5:30, Ben Bacarisse wrote: > Steve D'Aprano writes: > > > On Fri, 25 Aug 2017 09:41 am, bob gailer wrote: > > > >>> Help on built-in function floor in module math: > >>> > >>> floor(...) > >>> floor(x) > >>> > >>> Return the floor of x as an Integral. > >>> This is the largest integer <= x. > > [...] > > > >> I was surprised by the use of "integral". A dictionary search does not > >> (IMHO) support this usage! > > > > Integral \In"te*gral\, a. [Cf. F. int['e]gral. See Integer.] > > For me (and I suspect for BG too) the surprise is in its use as a noun. > The capital letter is, presumably, significant because it refers to the > Python class Integral -- a subtype of numbers. > > With that in mind, "an Integral" is a shorthand for "an Integral value", > or more fully, maybe, "an instance of numbers.Integral". > > > [1913 Webster] > > 1. Lacking nothing of completeness; complete; perfect; > > uninjured; whole; entire. > > [1913 Webster] > > > > A local motion keepeth bodies integral. --Bacon. > > [1913 Webster] > > > > 2. Essential to completeness; constituent, as a part; > > pertaining to, or serving to form, an integer; integrant. > > [1913 Webster] > > > > Ceasing to do evil, and doing good, are the two > > great integral parts that complete this duty. > > --South. > > [1913 Webster] > > > > 3. (Math.) > > (a) Of, pertaining to, or being, a whole number or > > undivided quantity; not fractional. > > (b) Pertaining to, or proceeding by, integration; as, the > > integral calculus. > > [1913 Webster] > > The use as a noun is not covered here, though it is only a small step > from other places where membership of a mathematical set has turned the > adjective into a noun. "Rational" and "real" started out as adjectives, > but their use as nouns is now widespread. "The function returns a > real". "The result is a rational". It's much less common for complex > and integral, to the point that it sounds wrong to me. Statement 1: Aeroplanes fly Statement 2: Submarines swim Are these two statements equally acceptable? [Inspired by a talk by Noam Chomsky] From larry.martell at gmail.com Thu Aug 24 22:47:19 2017 From: larry.martell at gmail.com (Larry Martell) Date: Thu, 24 Aug 2017 22:47:19 -0400 Subject: Reading the documentation In-Reply-To: <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> Message-ID: On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > Statement 1: Aeroplanes fly > Statement 2: Submarines swim > > > Are these two statements equally acceptable? > > [Inspired by a talk by Noam Chomsky] There should be a corollary of Godwin's law for that idiot. From python at mrabarnett.plus.com Thu Aug 24 22:49:53 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 25 Aug 2017 03:49:53 +0100 Subject: Reading the documentation In-Reply-To: <87fucg4de8.fsf@bsb.me.uk> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <87fucg4de8.fsf@bsb.me.uk> Message-ID: <680c6c56-abea-3f9b-91f4-a9d9a3069895@mrabarnett.plus.com> On 2017-08-25 02:58, Ben Bacarisse wrote: > Chris Angelico writes: > >> On Fri, Aug 25, 2017 at 11:25 AM, Ben Bacarisse wrote: >>> The use as a noun is not covered here, though it is only a small step >>> from other places where membership of a mathematical set has turned the >>> adjective into a noun. "Rational" and "real" started out as adjectives, >>> but their use as nouns is now widespread. "The function returns a >>> real". "The result is a rational". It's much less common for complex >>> and integral, to the point that it sounds wrong to me. >> >> This is a common thing in English (and many other languages). When you >> find yourself frequently using similar phrases, you abbreviate them: >> >> * real number -> real >> * rational number -> rational >> * complex number -> complex >> >> Thus the adjective acquires a new meaning as a noun. As my mother (and >> grammar teacher) drummed into me: No word is a part of speech unless >> it appears in context. > > Yes, we agree on that, but has it become natural(!) yet with complex and > integral? Not to my ear. What about yours? > > To me, the "adjectiveness" is still so strong that my brain asks "an > integral what?", "a complex what?". That does not happen in my head > with "a real" or "a rational". > To me, an "integral" is the result of integration. I'm OK with "real" as a noun, but only because I'm used to its use in programming. "Complex" already has a meaning as a noun, though not mathematical. But what about "imaginary"? From ian.g.kelly at gmail.com Thu Aug 24 22:58:27 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 24 Aug 2017 20:58:27 -0600 Subject: Reading the documentation In-Reply-To: References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> Message-ID: On Aug 24, 2017 8:51 PM, "Larry Martell" wrote: On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > Statement 1: Aeroplanes fly > Statement 2: Submarines swim > > > Are these two statements equally acceptable? > > [Inspired by a talk by Noam Chomsky] There should be a corollary of Godwin's law for that idiot. Chomsky borrowed it from Dijkstra, I think. http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD898.html From rustompmody at gmail.com Thu Aug 24 23:08:57 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 20:08:57 -0700 (PDT) Subject: Reading the documentation In-Reply-To: References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> Message-ID: <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> On Friday, August 25, 2017 at 8:28:55 AM UTC+5:30, Ian wrote: > On Aug 24, 2017 8:51 PM, "Larry Martell" wrote: > > On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > > > Statement 1: Aeroplanes fly > > Statement 2: Submarines swim > > > > > > Are these two statements equally acceptable? > > > > [Inspired by a talk by Noam Chomsky] > > There should be a corollary of Godwin's law for that idiot. > > > Chomsky borrowed it from Dijkstra, I think. > > http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD898.html I was about to start with the Dijkstra connection but then cut it because irrelevant However I find the two very different I think Dijkstra's "Can a submarine swim?" is almost entirely a mockery of the idea However Chomsky's laconic juxtaposition points to the deep non-rational programming in our subconscious mind of what we accept and what we dont [Larry seems to be angry about/at somethin'? No idea who/what?] From no.email at nospam.invalid Thu Aug 24 23:19:30 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 24 Aug 2017 20:19:30 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <87lgm9e5pu.fsf@nightsong.com> <599ed86a$0$1619$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87d17ke3lp.fsf@nightsong.com> Steve D'Aprano writes: > the public API is to call the next() built-in function, and the > implementation is the __next__ dunder. In that case it would have been nice to make next() cache the most recently generated value from the iterator. That would make lots of code simpler. From larry.martell at gmail.com Thu Aug 24 23:21:22 2017 From: larry.martell at gmail.com (Larry Martell) Date: Thu, 24 Aug 2017 23:21:22 -0400 Subject: Reading the documentation In-Reply-To: <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> Message-ID: On Thu, Aug 24, 2017 at 11:08 PM, Rustom Mody wrote: > On Friday, August 25, 2017 at 8:28:55 AM UTC+5:30, Ian wrote: >> On Aug 24, 2017 8:51 PM, "Larry Martell" wrote: >> >> On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: >> >> > Statement 1: Aeroplanes fly >> > Statement 2: Submarines swim >> > >> > >> > Are these two statements equally acceptable? >> > >> > [Inspired by a talk by Noam Chomsky] >> >> There should be a corollary of Godwin's law for that idiot. >> >> >> Chomsky borrowed it from Dijkstra, I think. >> >> http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD898.html > > I was about to start with the Dijkstra connection but then cut it because irrelevant > However I find the two very different > I think Dijkstra's "Can a submarine swim?" is almost entirely a mockery of the idea > However Chomsky's laconic juxtaposition points to the deep non-rational > programming in our subconscious mind of what we accept and what we dont > > [Larry seems to be angry about/at somethin'? No idea who/what?] I think Chomsky is a jerk, and I'm angry at media outlets like CNN giving him a forum to spew his idiocies. From steve+python at pearwood.info Thu Aug 24 23:21:59 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 13:21:59 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> Message-ID: <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 12:47 pm, Larry Martell wrote: > On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > >> Statement 1: Aeroplanes fly >> Statement 2: Submarines swim >> >> >> Are these two statements equally acceptable? >> >> [Inspired by a talk by Noam Chomsky] > > There should be a corollary of Godwin's law for that idiot. Just because you disagree with him doesn't make him an idiot. In fact, many people would insist the opposite. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rustompmody at gmail.com Thu Aug 24 23:23:09 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 20:23:09 -0700 (PDT) Subject: Reading the documentation In-Reply-To: <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> Message-ID: <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> On Friday, August 25, 2017 at 8:39:25 AM UTC+5:30, Rustom Mody wrote: > On Friday, August 25, 2017 at 8:28:55 AM UTC+5:30, Ian wrote: > > On Aug 24, 2017 8:51 PM, "Larry Martell" wrote: > > > > On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > > > > > Statement 1: Aeroplanes fly > > > Statement 2: Submarines swim > > > > > > > > > Are these two statements equally acceptable? > > > > > > [Inspired by a talk by Noam Chomsky] > > > > There should be a corollary of Godwin's law for that idiot. > > > > > > Chomsky borrowed it from Dijkstra, I think. > > > > http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD898.html > > I was about to start with the Dijkstra connection but then cut it because irrelevant > However I find the two very different > I think Dijkstra's "Can a submarine swim?" is almost entirely a mockery of the idea > However Chomsky's laconic juxtaposition points to the deep non-rational > programming in our subconscious mind of what we accept and what we dont > > [Larry seems to be angry about/at somethin'? No idea who/what?] One more juxtaposition(s) to consider: In Fortran, Pascal the numerics were real and int(eger) In PL-1 it was Float and Fixed So a clear choice of underlying model on the one side and machine representation on the other It was only C onwards that we started seeing the strange juxtaposition - for int(eger) emphasize the (math) model - for real emphasize the float(ing) representation I vaguely remember someone (Niklaus Wirth??) criticizing this mis-juxtaposition In retrospect though I find it fine: - fixpoint numbers are ok representations of integers most of the time - floats as representations of reals are so leaky that remembering the difference sounds like a good idea Early in my python classes I show this: $ python Python 2.7.13 (default, Jan 19 2017, 14:48:08) [GCC 6.3.0 20170118] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> .1 + .1 == .2 True >>> .1 + .1 + .1 == .3 False >>> From rustompmody at gmail.com Thu Aug 24 23:27:46 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 20:27:46 -0700 (PDT) Subject: Reading the documentation In-Reply-To: <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> Message-ID: <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> On Friday, August 25, 2017 at 8:52:11 AM UTC+5:30, Steve D'Aprano wrote: > On Fri, 25 Aug 2017 12:47 pm, Larry Martell wrote: > > > On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > > > >> Statement 1: Aeroplanes fly > >> Statement 2: Submarines swim > >> > >> > >> Are these two statements equally acceptable? > >> > >> [Inspired by a talk by Noam Chomsky] > > > > There should be a corollary of Godwin's law for that idiot. > > > Just because you disagree with him doesn't make him an idiot. People should be free to dislike who they like to dislike However? Calling Newton an idiot is ok? if you are not a physicist (flat-earther??) Calling Turing an idiot is ok if you dont like computers (Luddite??) Given that for most people who have gone through a (? decent) CS education Chomsky is in the Turing bracket, I wonder where Larry falls wrt CS From steve+python at pearwood.info Thu Aug 24 23:27:58 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 13:27:58 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> Message-ID: <599f9940$0$1612$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 01:08 pm, Rustom Mody wrote: > On Friday, August 25, 2017 at 8:28:55 AM UTC+5:30, Ian wrote: >> On Aug 24, 2017 8:51 PM, "Larry Martell" wrote: >> >> On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: >> >> > Statement 1: Aeroplanes fly >> > Statement 2: Submarines swim >> > >> > >> > Are these two statements equally acceptable? >> > >> > [Inspired by a talk by Noam Chomsky] >> >> There should be a corollary of Godwin's law for that idiot. [...] > [Larry seems to be angry about/at somethin'? No idea who/what?] Chomsky challenges the prevailing world-view that the USA is a force for good, by documenting the many, many, many ways that the USA's actions are harmful, unjust, illegal (occasionally all three at once) and in contradiction to the nation's stated values. Many people don't like it when you challenge their cherished myths. The story of the Emperor's New Clothes is relevant here. Also known by its subtitle, "The naughty boy who was sent to bed without his supper for telling lies about His Majesty". -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Thu Aug 24 23:30:23 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 13:30:23 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> Message-ID: <599f99d0$0$1612$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 11:25 am, Ben Bacarisse wrote: >> Integral \In"te*gral\, a. [Cf. F. int['e]gral. See Integer.] > > For me (and I suspect for BG too) the surprise is in its use as a noun. > The capital letter is, presumably, significant because it refers to the > Python class Integral -- a subtype of numbers. English doesn't just verb nouns and noun verbs, it also nouns adverbs and adjectives too. Human, as in human being, is a nouned adjective, as are black and white (as in people, not in colours). Going back a while, a wireless is a wireless radio. We eat Chinese or Italian (as in the foods, not the people). You can probably think of many other examples :-) > With that in mind, "an Integral" is a shorthand for "an Integral value", > or more fully, maybe, "an instance of numbers.Integral". Indeed. This process of nouning words is common enough that native speakers shouldn't be surprised by it. Deplore it, perhaps, but not surprised :-) > The use as a noun is not covered here, though it is only a small step > from other places where membership of a mathematical set has turned the > adjective into a noun. "Rational" and "real" started out as adjectives, > but their use as nouns is now widespread. "The function returns a > real". "The result is a rational". It's much less common for complex > and integral, to the point that it sounds wrong to me. I agree with "complex", but "integral" as a synonym for integer seems okay to me. I think it's because "complexes" is awkward. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Thu Aug 24 23:33:16 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 13:33:16 +1000 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <87lgm9e5pu.fsf@nightsong.com> <599ed86a$0$1619$c3e8da3$5496439d@news.astraweb.com> <87d17ke3lp.fsf@nightsong.com> Message-ID: <599f9a7d$0$1610$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 01:19 pm, Paul Rubin wrote: > Steve D'Aprano writes: >> the public API is to call the next() built-in function, and the >> implementation is the __next__ dunder. > > In that case it would have been nice to make next() cache the most > recently generated value from the iterator. That would make lots of > code simpler. Huh? Why? Did __next__ cache the most recently generated value? The whole point of next() (whether a method or function) is that it evaluates the next value on demand, not to return the previous value you already evaluated earlier. I don't understand what sort of code it would make simpler. I'm tempted to say "buggy code", but I'll give you the benefit of the doubt first *wink* -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Thu Aug 24 23:36:40 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 13:36:40 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> Message-ID: <599f9b49$0$1610$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 01:27 pm, Rustom Mody wrote: > People should be free to dislike who they like to dislike > However? > Calling Newton an idiot is ok? if you are not a physicist (flat-earther??) > Calling Turing an idiot is ok if you dont like computers (Luddite??) > Given that for most people who have gone through a (? decent) CS education > Chomsky is in the Turing bracket, I wonder where Larry falls wrt CS Newton and Turing where many things, but "idiot" was not one of them. Calling Newton an idiot is like calling Barrack Obama a Japanese geisha, or Donald Trump a poor black man from the Brazilian favelas. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From larry.martell at gmail.com Thu Aug 24 23:38:15 2017 From: larry.martell at gmail.com (Larry Martell) Date: Thu, 24 Aug 2017 23:38:15 -0400 Subject: Reading the documentation In-Reply-To: <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> Message-ID: On Thu, Aug 24, 2017 at 11:27 PM, Rustom Mody wrote: > Chomsky is in the Turing bracket, I wonder where Larry falls wrt CS I have a degree in Software Engineering from Rochester Institute of Technology. I stared programming when I was 16, and I have worked professionally since I was 19. I am 57 now. From rustompmody at gmail.com Thu Aug 24 23:47:47 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 20:47:47 -0700 (PDT) Subject: Reading the documentation In-Reply-To: <599f9b49$0$1610$c3e8da3$5496439d@news.astraweb.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> <599f9b49$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Friday, August 25, 2017 at 9:06:53 AM UTC+5:30, Steve D'Aprano wrote: > On Fri, 25 Aug 2017 01:27 pm, Rustom Mody wrote: > > > People should be free to dislike who they like to dislike > > However? > > Calling Newton an idiot is ok? if you are not a physicist (flat-earther??) > > Calling Turing an idiot is ok if you dont like computers (Luddite??) > > Given that for most people who have gone through a (? decent) CS education > > Chomsky is in the Turing bracket, I wonder where Larry falls wrt CS > > > Newton and Turing where many things, but "idiot" was not one of them. > > Calling Newton an idiot is like calling Barrack Obama a Japanese geisha, or > Donald Trump a poor black man from the Brazilian favelas. You may find the etymology of idiot interesting https://en.wikipedia.org/wiki/Idiot#Etymology From no.email at nospam.invalid Fri Aug 25 00:10:37 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 24 Aug 2017 21:10:37 -0700 Subject: Proposed new syntax References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <87lgm9e5pu.fsf@nightsong.com> <599ed86a$0$1619$c3e8da3$5496439d@news.astraweb.com> <87d17ke3lp.fsf@nightsong.com> <599f9a7d$0$1610$c3e8da3$5496439d@news.astraweb.com> Message-ID: <8760dce18i.fsf@nightsong.com> Steve D'Aprano writes: > Did __next__ cache the most recently generated value? No but if they're going to change stuff, they might as well actually improve it instead of just renaming it to break code gratutiously. From rosuav at gmail.com Fri Aug 25 00:21:36 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 14:21:36 +1000 Subject: Reading the documentation In-Reply-To: <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> Message-ID: On Fri, Aug 25, 2017 at 1:23 PM, Rustom Mody wrote: > Early in my python classes I show this: > > $ python > Python 2.7.13 (default, Jan 19 2017, 14:48:08) > [GCC 6.3.0 20170118] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> .1 + .1 == .2 > True >>>> .1 + .1 + .1 == .3 > False >>>> > -- > https://mail.python.org/mailman/listinfo/python-list Aside from the fact that I show it with Python 3 (or sometimes Node.js) instead, I've demonstrated something similar - but then go on to make the point that 0.1 is not "one tenth". The problem isn't with addition, which is completely correct here; the problem is with the assumption that writing "0.1" in your source code indicates the number "one tenth". If you want the details, Python is very helpful here: >>> "%d/%d" % (0.1).as_integer_ratio() '3602879701896397/36028797018963968' >>> "%d/%d" % (0.2).as_integer_ratio() '3602879701896397/18014398509481984' >>> "%d/%d" % (0.3).as_integer_ratio() '5404319552844595/18014398509481984' Or in hex: >>> "%x/%x" % (0.1).as_integer_ratio() 'ccccccccccccd/80000000000000' >>> "%x/%x" % (0.2).as_integer_ratio() 'ccccccccccccd/40000000000000' >>> "%x/%x" % (0.3).as_integer_ratio() '13333333333333/40000000000000' Clearly the second one is exactly double the first. And equally clearly, the first two have been rounded up, while the second is rounded down. But you don't need that much detail to understand what's going on; most people can follow this analogy: 0.6667 + 0.6667 + 0.6667 != 2.000 since, in grade school, most of us learned that the decimal expansion for two-thirds gets rounded up. It's the same thing, just in binary. In fact, the ONLY way to create this confusion is to use (some derivative of) one fifth, which is a factor of base 10 but not of base 2. Any other fraction will either terminate in both bases (eg "0.125" in decimal or "0.001" in binary), or repeat in both (any denominator with any other prime number in it). No other rational numbers can produce this apparently-irrational behaviour, pun intended. ChrisA From rosuav at gmail.com Fri Aug 25 00:26:41 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 14:26:41 +1000 Subject: Proposed new syntax In-Reply-To: <8760dce18i.fsf@nightsong.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <87lgm9e5pu.fsf@nightsong.com> <599ed86a$0$1619$c3e8da3$5496439d@news.astraweb.com> <87d17ke3lp.fsf@nightsong.com> <599f9a7d$0$1610$c3e8da3$5496439d@news.astraweb.com> <8760dce18i.fsf@nightsong.com> Message-ID: On Fri, Aug 25, 2017 at 2:10 PM, Paul Rubin wrote: > Steve D'Aprano writes: >> Did __next__ cache the most recently generated value? > > No but if they're going to change stuff, they might as well actually > improve it instead of just renaming it to break code gratutiously. Any code that called iter.next() instead of next(iter) was already broken. Converting it to the proper notation makes it work on all Python versions. Any code that needs to *implement* an iterator can do so fairly simply: class Foo(object): # you already need (object) for Py2 compat def __iter__(self): return self def __next__(self): # whatever return 42 next = __next__ # this is all you need to add Considering that it then brings the protocol nicely in line with every other magic-method protocol in Python, this is a Good Thing. It's one more line of code in any class that is an iterator - not all iterables, only custom iterators. It's no additional code in consumers of iterators. ChrisA From rustompmody at gmail.com Fri Aug 25 00:37:37 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 21:37:37 -0700 (PDT) Subject: Reading the documentation In-Reply-To: References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> Message-ID: <9cc123d1-ddd1-485f-b034-162544936cbe@googlegroups.com> On Friday, August 25, 2017 at 9:58:15 AM UTC+5:30, Chris Angelico wrote: > On Fri, Aug 25, 2017 at 1:23 PM, Rustom Mody wrote: > > Early in my python classes I show this: > > > > $ python > > Python 2.7.13 (default, Jan 19 2017, 14:48:08) > > [GCC 6.3.0 20170118] on linux2 > > Type "help", "copyright", "credits" or "license" for more information. > >>>> .1 + .1 == .2 > > True > >>>> .1 + .1 + .1 == .3 > > False > >>>> > > -- > > https://mail.python.org/mailman/listinfo/python-list > > Aside from the fact that I show it with Python 3 (or sometimes > Node.js) instead, I've demonstrated something similar - but then go on > to make the point that 0.1 is not "one tenth". The problem isn't with > addition, which is completely correct here; the problem is with the > assumption that writing "0.1" in your source code indicates the number > "one tenth". If you want the details, Python is very helpful here: > > >>> "%d/%d" % (0.1).as_integer_ratio() > '3602879701896397/36028797018963968' > >>> "%d/%d" % (0.2).as_integer_ratio() > '3602879701896397/18014398509481984' > >>> "%d/%d" % (0.3).as_integer_ratio() > '5404319552844595/18014398509481984' > > Or in hex: > > >>> "%x/%x" % (0.1).as_integer_ratio() > 'ccccccccccccd/80000000000000' > >>> "%x/%x" % (0.2).as_integer_ratio() > 'ccccccccccccd/40000000000000' > >>> "%x/%x" % (0.3).as_integer_ratio() > '13333333333333/40000000000000' > Thanks for the hex tip? Useful! > > Clearly the second one is exactly double the first. And equally > clearly, the first two have been rounded up, while the second is > rounded down. But you don't need that much detail to understand what's > going on; most people can follow this analogy: > > 0.6667 + 0.6667 + 0.6667 != 2.000 > > since, in grade school, most of us learned that the decimal expansion > for two-thirds gets rounded up. It's the same thing, just in binary. > > In fact, the ONLY way to create this confusion is to use (some > derivative of) one fifth, which is a factor of base 10 but not of base > 2. Any other fraction will either terminate in both bases (eg "0.125" > in decimal or "0.001" in binary), or repeat in both (any denominator > with any other prime number in it). No other rational numbers can > produce this apparently-irrational behaviour, pun intended. You almost make that sound like a rare exception From rustompmody at gmail.com Fri Aug 25 00:47:41 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 21:47:41 -0700 (PDT) Subject: Reading the documentation In-Reply-To: References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> Message-ID: <98c49883-e56f-475a-ba7e-3f9a4c7b7f66@googlegroups.com> On Friday, August 25, 2017 at 9:09:16 AM UTC+5:30, Larry.... at gmail.com wrote: > On Thu, Aug 24, 2017 at 11:27 PM, Rustom Mody wrote: > > Chomsky is in the Turing bracket, I wonder where Larry falls wrt CS > > I have a degree in Software Engineering from Rochester Institute of > Technology. I stared programming when I was 16, and I have worked > professionally since I was 19. I am 57 now. I was pointing to the link between Chomsky and Computer Science (CS) Chomsky is at least 3 things 1. A pioneer of CS? 2. A linguist? 3. A political activist? 4. Much else? 1 and 2 are obviously linked My original reference to Chomsky was wrt 2 Because of 1 he is on-topic on a programming mailing list ? hopefully! You can bring in 3 if you like? I didn't And then someone is going to red-flag the OT-ness of the discussion For now I will only say (in response to Steven's) > Chomsky challenges the prevailing world-view that the USA is a force for good, > by documenting the many, many, many ways that the USA's actions are harmful, > unjust, illegal (occasionally all three at once) and in contradiction to the > nation's stated values. Many people don't like it when you challenge their > cherished myths. As one of the 19/20th of the world that is not a US citizen I would have thought it axiomatic: When the world's most powerful nation remains that for too long, its only a question of time before it becomes the world's most lethal terrorist? organization. This was true of Britain 100 years ago It was true of Rome 1000 years ago And it would be inexorably true for any grouping following from the axiom: ?Power corrupts; Absolute power absolutely corrupts? Which is why I agree and disagree with Steven's above characterization: - It is literally true - Its implication that the current holder of absolute power is somehow special is false ? http://www.soc.napier.ac.uk/~andrew/co42010/kentucky/languages/langnote.pdf ? http://blog.mangolanguages.com/noam-chomsky-his-contribution-to-linguistics/ ? https://youtu.be/5BXtgq0Nhsc ? eg an anti-Israel jew https://youtu.be/zWaLuVQ_LCc ? The word 'terrorist' today (like 'communist' 50 years ago) is sufficiently overused to be rendered almost meaningless. One could do worse than hearing Chomsky on that https://youtu.be/UWuT8d78yts Inter alia it is related to Chomsky being a linguist who's turned political From rustompmody at gmail.com Fri Aug 25 00:56:00 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Thu, 24 Aug 2017 21:56:00 -0700 (PDT) Subject: Reading the documentation In-Reply-To: <98c49883-e56f-475a-ba7e-3f9a4c7b7f66@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> <98c49883-e56f-475a-ba7e-3f9a4c7b7f66@googlegroups.com> Message-ID: <542371a3-b41d-4791-b7c3-f74578d5187c@googlegroups.com> On Friday, August 25, 2017 at 10:18:07 AM UTC+5:30, Rustom Mody wrote: > On Friday, August 25, 2017 at 9:09:16 AM UTC+5:30, Larry.... at gmail.com wrote: > > On Thu, Aug 24, 2017 at 11:27 PM, Rustom Mody wrote: > > > Chomsky is in the Turing bracket, I wonder where Larry falls wrt CS > > > > I have a degree in Software Engineering from Rochester Institute of > > Technology. I stared programming when I was 16, and I have worked > > professionally since I was 19. I am 57 now. > > I was pointing to the link between Chomsky and Computer Science (CS) ? which is to say that if we want to keep discussions here (reasonably!) on-topic we should (try to!) avoid bringing in irrelevant aspects of relevant personalities [Yeah with some super-eminent guys like Chomsky that can be hard!] From rosuav at gmail.com Fri Aug 25 00:57:27 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 14:57:27 +1000 Subject: Reading the documentation In-Reply-To: <9cc123d1-ddd1-485f-b034-162544936cbe@googlegroups.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <9cc123d1-ddd1-485f-b034-162544936cbe@googlegroups.com> Message-ID: On Fri, Aug 25, 2017 at 2:37 PM, Rustom Mody wrote: > On Friday, August 25, 2017 at 9:58:15 AM UTC+5:30, Chris Angelico wrote: >> On Fri, Aug 25, 2017 at 1:23 PM, Rustom Mody wrote: >> > Early in my python classes I show this: >> > >> > $ python >> > Python 2.7.13 (default, Jan 19 2017, 14:48:08) >> > [GCC 6.3.0 20170118] on linux2 >> > Type "help", "copyright", "credits" or "license" for more information. >> >>>> .1 + .1 == .2 >> > True >> >>>> .1 + .1 + .1 == .3 >> > False >> >>>> >> > -- >> > https://mail.python.org/mailman/listinfo/python-list >> >> Aside from the fact that I show it with Python 3 (or sometimes >> Node.js) instead, I've demonstrated something similar - but then go on >> to make the point that 0.1 is not "one tenth". The problem isn't with >> addition, which is completely correct here; the problem is with the >> assumption that writing "0.1" in your source code indicates the number >> "one tenth". If you want the details, Python is very helpful here: >> >> >>> "%d/%d" % (0.1).as_integer_ratio() >> '3602879701896397/36028797018963968' >> >>> "%d/%d" % (0.2).as_integer_ratio() >> '3602879701896397/18014398509481984' >> >>> "%d/%d" % (0.3).as_integer_ratio() >> '5404319552844595/18014398509481984' >> >> Or in hex: >> >> >>> "%x/%x" % (0.1).as_integer_ratio() >> 'ccccccccccccd/80000000000000' >> >>> "%x/%x" % (0.2).as_integer_ratio() >> 'ccccccccccccd/40000000000000' >> >>> "%x/%x" % (0.3).as_integer_ratio() >> '13333333333333/40000000000000' >> > > Thanks for the hex tip? Useful! Yes, that makes it really obvious that (a) the denominator is a power of two, (b) the numerator is repeating, and (c) one of them got rounded down and the other two got rounded up. The decimal values are almost completely useless, except for the fairly significant fact that most people aren't used to writing numbers like "ccccccccccccd/80000000000000" !!! >> Clearly the second one is exactly double the first. And equally >> clearly, the first two have been rounded up, while the second is >> rounded down. But you don't need that much detail to understand what's >> going on; most people can follow this analogy: >> >> 0.6667 + 0.6667 + 0.6667 != 2.000 >> >> since, in grade school, most of us learned that the decimal expansion >> for two-thirds gets rounded up. It's the same thing, just in binary. >> >> In fact, the ONLY way to create this confusion is to use (some >> derivative of) one fifth, which is a factor of base 10 but not of base >> 2. Any other fraction will either terminate in both bases (eg "0.125" >> in decimal or "0.001" in binary), or repeat in both (any denominator >> with any other prime number in it). No other rational numbers can >> produce this apparently-irrational behaviour, pun intended. > > You almost make that sound like a rare exception Heh, worded that way it does sound rare. But people are at least familiar with one third, one seventh, one ninth, and maybe a few others, so it's not surprising to them when numbers get rounded. ChrisA From gheskett at shentel.net Fri Aug 25 01:02:00 2017 From: gheskett at shentel.net (Gene Heskett) Date: Fri, 25 Aug 2017 01:02:00 -0400 Subject: Reading the documentation In-Reply-To: References: <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> Message-ID: <201708250102.00071.gheskett@shentel.net> On Thursday 24 August 2017 23:21:22 Larry Martell wrote: > On Thu, Aug 24, 2017 at 11:08 PM, Rustom Mody wrote: > > On Friday, August 25, 2017 at 8:28:55 AM UTC+5:30, Ian wrote: > >> On Aug 24, 2017 8:51 PM, "Larry Martell" wrote: > >> > >> On Thu, Aug 24, 2017 at 9:21 PM Rustom Mody wrote: > >> > Statement 1: Aeroplanes fly > >> > Statement 2: Submarines swim > >> > > >> > > >> > Are these two statements equally acceptable? > >> > > >> > [Inspired by a talk by Noam Chomsky] > >> > >> There should be a corollary of Godwin's law for that idiot. > >> > >> > >> Chomsky borrowed it from Dijkstra, I think. > >> > >> http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD898.ht > >>ml > > > > I was about to start with the Dijkstra connection but then cut it > > because irrelevant However I find the two very different > > I think Dijkstra's "Can a submarine swim?" is almost entirely a > > mockery of the idea However Chomsky's laconic juxtaposition points > > to the deep non-rational programming in our subconscious mind of > > what we accept and what we dont > > > > [Larry seems to be angry about/at somethin'? No idea who/what?] > > I think Chomsky is a jerk, and I'm angry at media outlets like CNN > giving him a forum to spew his idiocies. I agree Larry, Chomsky can be described in even more flowery terms, but since its CNN, what else should we expect? That site has not been on my nightly news tour for at least 18 months. Cheers, Gene Heskett -- "There are four boxes to be used in defense of liberty: soap, ballot, jury, and ammo. Please use in that order." -Ed Howdershelt (Author) Genes Web page From steve+python at pearwood.info Fri Aug 25 01:08:04 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 15:08:04 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> Message-ID: <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 02:21 pm, Chris Angelico wrote: > In fact, the ONLY way to create this confusion is to use (some > derivative of) one fifth, which is a factor of base 10 but not of base > 2. Any other fraction will either terminate in both bases (eg "0.125" > in decimal or "0.001" in binary), or repeat in both (any denominator > with any other prime number in it). No other rational numbers can > produce this apparently-irrational behaviour, pun intended. I think that's a bit strong. A lot strong. Let's take 1/13 for example: py> from decimal import Decimal py> sum([1/13]*13) 0.9999999999999998 py> sum([Decimal(1)/Decimal(13)]*13) Decimal('0.9999999999999999999999999997') Or 2/7, added 7 times, should be 2: py> sum([2/7]*7) 1.9999999999999996 py> sum([Decimal(2)/Decimal(7)]*7) Decimal('2.000000000000000000000000001') Its not just addition that "fails". We can take the reciprocal of the reciprocal of a number, and expect to get the original number: py> 1/(1/99) 98.99999999999999 py> Decimal(1)/( Decimal(1)/Decimal(99) ) Decimal('99.00000000000000000000000001') or we can multiply a fraction by the denominator and expect to get the numerator: py> (7/207)*207 6.999999999999999 py> (Decimal(7)/Decimal(207))*Decimal(207) Decimal('6.999999999999999999999999999') These are not isolated examples. You'll note that none of the numbers involved are multiples of 5. Besides: the derivative of 1/5 is 0, like that of every other constant. *wink* -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Fri Aug 25 01:22:53 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 15:22:53 +1000 Subject: Reading the documentation In-Reply-To: <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 25, 2017 at 3:08 PM, Steve D'Aprano wrote: > On Fri, 25 Aug 2017 02:21 pm, Chris Angelico wrote: > >> In fact, the ONLY way to create this confusion is to use (some >> derivative of) one fifth, which is a factor of base 10 but not of base >> 2. Any other fraction will either terminate in both bases (eg "0.125" >> in decimal or "0.001" in binary), or repeat in both (any denominator >> with any other prime number in it). No other rational numbers can >> produce this apparently-irrational behaviour, pun intended. > > > I think that's a bit strong. A lot strong. Let's take 1/13 for example: > > > py> from decimal import Decimal > py> sum([1/13]*13) > 0.9999999999999998 > py> sum([Decimal(1)/Decimal(13)]*13) > Decimal('0.9999999999999999999999999997') Now do the same exercise with pencil and paper. What's 1/13? Actually most people don't know the thirteenths. They might know the sevenths, let's use them. > Or 2/7, added 7 times, should be 2: > > py> sum([2/7]*7) > 1.9999999999999996 > py> sum([Decimal(2)/Decimal(7)]*7) > Decimal('2.000000000000000000000000001') Two sevenths is 0.285714285714. Add seven of those together, and you'll get 0.999999999999. If you want to call it "2/7", you can use fractions.Fraction, but if you treat it as a decimal fraction, it's going to be rounded, just as it will be in a binary fraction (or a float). That's what I mean about the confusion - that there are numbers that you can write accurately as decimal fractions, but as binary fractions, they repeat. > Besides: the derivative of 1/5 is 0, like that of every other constant. > > *wink* Now that one, I'll grant you :) I never learned calculus. ChrisA From steve+python at pearwood.info Fri Aug 25 02:03:12 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 16:03:12 +1000 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> Message-ID: <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 03:22 pm, Chris Angelico wrote: >> py> from decimal import Decimal >> py> sum([1/13]*13) >> 0.9999999999999998 >> py> sum([Decimal(1)/Decimal(13)]*13) >> Decimal('0.9999999999999999999999999997') > > Now do the same exercise with pencil and paper. What's 1/13? Easy: 0.(076923) where the brackets surround the digits which repeat. I'm not so good at division in binary, but I *think* it should be: 0b0.(000100111011) where, again, the repeating bits are in brackets. [...] > Two sevenths is 0.285714285714. No it isn't. The decimal is repeating, so its actually 0.(285714). By truncating it to only a finite number of decimal places, you introduce some rounding error. > Add seven of those together, and > you'll get 0.999999999999. If you want to call it "2/7", you can use > fractions.Fraction, but if you treat it as a decimal fraction, it's > going to be rounded, just as it will be in a binary fraction (or a > float). That's what I mean about the confusion - that there are > numbers that you can write accurately as decimal fractions, but as > binary fractions, they repeat. And there are numbers which repeat in decimal but not binary, and numbers which repeat in both, and numbers which don't repeat in either. And even among those that don't repeat, sometimes you need more precision than float (or Decimal) gives, and so there's still rounding error. Fortunately often the rounding errors cancel rather than reinforce, which is why floats are so accurate most of the time for the sorts of numbers we mostly care about. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Fri Aug 25 02:12:09 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 16:12:09 +1000 Subject: Reading the documentation In-Reply-To: <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 25, 2017 at 4:03 PM, Steve D'Aprano wrote: > On Fri, 25 Aug 2017 03:22 pm, Chris Angelico wrote: > >>> py> from decimal import Decimal >>> py> sum([1/13]*13) >>> 0.9999999999999998 >>> py> sum([Decimal(1)/Decimal(13)]*13) >>> Decimal('0.9999999999999999999999999997') >> >> Now do the same exercise with pencil and paper. What's 1/13? > > Easy: 0.(076923) where the brackets surround the digits which repeat. > > I'm not so good at division in binary, but I *think* it should be: > > 0b0.(000100111011) > > where, again, the repeating bits are in brackets. > > > [...] >> Two sevenths is 0.285714285714. > > No it isn't. The decimal is repeating, so its actually 0.(285714). By truncating > it to only a finite number of decimal places, you introduce some rounding > error. Ask someone to write it down on a piece of paper. I can pretty much guarantee that they'll truncate or round. > And there are numbers which repeat in decimal but not binary, and numbers which > repeat in both, and numbers which don't repeat in either. Which ones repeat in decimal but not binary? An example, please. Ones which repeat in neither are easy. Ones which repeat in both are usually not confusing, as it's easy to explain how the truncation works. ChrisA From no.email at nospam.invalid Fri Aug 25 02:26:43 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Thu, 24 Aug 2017 23:26:43 -0700 Subject: Reading the documentation References: <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> Message-ID: <87wp5scgd8.fsf@nightsong.com> Chris Angelico writes: >> And there are numbers which repeat in decimal but not binary, > Which ones repeat in decimal but not binary? An example, please. That should really have said binary but not decimal, since 2 divides 10. From dieter at handshake.de Fri Aug 25 02:52:01 2017 From: dieter at handshake.de (dieter) Date: Fri, 25 Aug 2017 08:52:01 +0200 Subject: requests.{get,post} timeout References: Message-ID: <87a82oywa6.fsf@handshake.de> Jon Ribbens writes: > On 2017-08-24, Chris Angelico wrote: >> On Thu, Aug 24, 2017 at 9:43 PM, Jon Ribbens wrote: >>> Where did you explain how it can be done without help? As far as I'm >>> aware, you can't close the socket without help since you can't get >>> access to it, and as you mentioned even if you were to do so the >>> effect it would have on requests is completely undefined. >> >> In a single-threaded program, just hit Ctrl-C. > > By that, do you mean "kill the process"? That's obviously not > a sensible answer in general, especially given we were including > processes which have no terminal or user sitting there watching > them. In Python 2, there is "PyThreadState_SetAsyncExc" (defined in "pystate.c"), documented as follows: Asynchronously raise an exception in a thread. Requested by Just van Rossum and Alex Martelli. To prevent naive misuse, you must write your own extension to call this, or use ctypes. Must be called with the GIL held. Returns the number of tstates modified (normally 1, but 0 if `id` didn't match any known thread id). Can be called with exc=NULL to clear an existing async exception. This raises no exceptions int PyThreadState_SetAsyncExc(long id, PyObject *exc); Together with a "read timeout", you can implement a total timeout for your requests: you perform your request in a separate thread; you set up a "connect/read timeout" (relatively small compared to the total timeout; these timeouts ensure that the thread does not stall inside the C runtime (where "PyThreadState_SetAsyncExc" has not effect)); you monitor the request runtime (maybe in a different thread) and send it an exception when your global timeout is exceeded. I do not know whether a similar API function is available for Python 3 (but I suppose so). From ian.g.kelly at gmail.com Fri Aug 25 02:57:59 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Fri, 25 Aug 2017 00:57:59 -0600 Subject: Reading the documentation In-Reply-To: <201708250102.00071.gheskett@shentel.net> References: <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <201708250102.00071.gheskett@shentel.net> Message-ID: On Thu, Aug 24, 2017 at 11:02 PM, Gene Heskett wrote: > On Thursday 24 August 2017 23:21:22 Larry Martell wrote: > >> I think Chomsky is a jerk, and I'm angry at media outlets like CNN >> giving him a forum to spew his idiocies. > > I agree Larry, Chomsky can be described in even more flowery terms, but > since its CNN, what else should we expect? That site has not been on my > nightly news tour for at least 18 months. And I'm also angry with CNN because they give *far* more face time to noted plagiarist and failed human being Ann Coulter than they give to one of the most cited scholar in academia. From dieter at handshake.de Fri Aug 25 03:05:55 2017 From: dieter at handshake.de (dieter) Date: Fri, 25 Aug 2017 09:05:55 +0200 Subject: requests.{get,post} timeout References: Message-ID: <8760dcyvn0.fsf@handshake.de> Chris Angelico writes: > ... > That looks like an exception to me. Not a "process is now terminated". > That's what happened when I pressed Ctrl-C (the IP address was > deliberately picked as one that doesn't currently exist on my network, > so it took time). What Jon argues about: signals are delivered to Python's main thread; if a thread is informed (e.g. via a signal induced exception) that a request (running in a different thread) should terminate, he needs a way to make the different thread do that. You may have argued before that in case of a signal, the request fails anyway due to an EINTR exception from the IO library. This may no longer work. Long ago, I have often been plagued by such EINTR exceptions, and I have wished heavily that in those cases the IO operation should be automatically resumed. In recent time, I have no longer seen such exceptions - and I concluded that my wish has been fulfilled (at least for many signal types). From rosuav at gmail.com Fri Aug 25 03:59:06 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 17:59:06 +1000 Subject: Reading the documentation In-Reply-To: <87wp5scgd8.fsf@nightsong.com> References: <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> <87wp5scgd8.fsf@nightsong.com> Message-ID: On Fri, Aug 25, 2017 at 4:26 PM, Paul Rubin wrote: > Chris Angelico writes: >>> And there are numbers which repeat in decimal but not binary, >> Which ones repeat in decimal but not binary? An example, please. > > That should really have said binary but not decimal, since 2 divides 10. Well, those that repeat in binary but not decimal are the ones that have a 5 in the denominator, which loops us right back to what I originally said :) ChrisA From ned at nedbatchelder.com Fri Aug 25 07:07:04 2017 From: ned at nedbatchelder.com (Ned Batchelder) Date: Fri, 25 Aug 2017 07:07:04 -0400 Subject: Proposed new syntax In-Reply-To: <8760dce18i.fsf@nightsong.com> References: <598c6d74$0$1588$c3e8da3$5496439d@news.astraweb.com> <87k22apm6n.fsf@nightsong.com> <85tw0zf445.fsf@benfinney.id.au> <87tw0xe7b6.fsf@nightsong.com> <87lgm9e5pu.fsf@nightsong.com> <599ed86a$0$1619$c3e8da3$5496439d@news.astraweb.com> <87d17ke3lp.fsf@nightsong.com> <599f9a7d$0$1610$c3e8da3$5496439d@news.astraweb.com> <8760dce18i.fsf@nightsong.com> Message-ID: On 8/25/17 12:10 AM, Paul Rubin wrote: > Steve D'Aprano writes: >> Did __next__ cache the most recently generated value? > No but if they're going to change stuff, they might as well actually > improve it instead of just renaming it to break code gratutiously. The vast majority of iteration has no need for the last-returned value again, so why add it to every iteration? You can provide it yourself (or propose it!) with a small wrapper class.? One of the beautiful things about Python's iteration model is that it does just one thing well.? This means it can be applied in more situations to more kinds of data.? Then if you need more, you build on top of it. --Ned. From steve+python at pearwood.info Fri Aug 25 09:01:28 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 25 Aug 2017 23:01:28 +1000 Subject: Reading the documentation References: <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59a01fa9$0$1619$c3e8da3$5496439d@news.astraweb.com> On Fri, 25 Aug 2017 04:12 pm, Chris Angelico wrote: >> And there are numbers which repeat in decimal but not binary, and numbers >> which repeat in both, and numbers which don't repeat in either. > > Which ones repeat in decimal but not binary? An example, please. What? No. I never said that, that would be silly. You must be replying to some other Steven. *wink* Quoting Wikipedia: "A rational number has a terminating sequence after the radix point if all the prime factors of the denominator of the fully reduced fractional form are also factors of the base. [...] A rational number has an infinitely repeating sequence of [digits] if the reduced fraction's denominator contains a prime factor that is not a factor of the base." https://en.wikipedia.org/wiki/Repeating_decimal#Extension_to_other_bases Fractions will terminate in decimal if their denominator is a power of two, a power of five, or a multiple of such, e.g.: 2, 4, 8, 16, 32, 64, ... 5, 25, 125, 625, ... 10, 20, 40, 50, 80, 100, ... and will terminate in binary if their denominator is: 2, 4, 8, 16, 32, ... so obviously any number which terminates in binary will also terminate in decimal, but not necessarily vice versa. Fractions will repeat in decimal if their denominator is a multiple of any of the following primes: 3, 7, 11, 13, 17, ... and fractions will repeat in binary if their denominator is a multiple of: 3, 5, 7, 11, 13, 17, ... so clearly any number which repeats in decimal will also repeat in binary. Like I said.[1] How did we get onto prime factors of denominators? The point I was making is that there are plenty of fractions which are not multiples of 1/5 which nevertheless lead to unintuitive "wrong answers" in both Decimal and binary floating point. It is not necessary for the fraction to have a denominator which is a multiple of 5 to run into issues. [1] Just now. What may have been said in the past is the past, and long forgotten. *wink* -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From torriem at gmail.com Fri Aug 25 09:06:52 2017 From: torriem at gmail.com (Michael Torrie) Date: Fri, 25 Aug 2017 07:06:52 -0600 Subject: Turtle graphics under the console under Windows In-Reply-To: References: Message-ID: <280fce5a-b6c9-8ade-cff7-97cbd9c09b67@gmail.com> On 08/25/2017 06:10 AM, Stefan Ram wrote: > Do I miss any means to make the turtle graphics window > behave more normally and at the same time be able to draw > graphics interactivley from the console, watching the result > of one move command and then interacticely typing in more > move commands that will continue to move the turtle from > where it was left by the preceding move commands? You have not indicated what operating system version you are using. Or Python version. I suspect you are using an unsupported version of Windows. I just tested Python 3.4 on Windows 10 and Linux, and on neither OS do I see the problems you indicate. It is indeed interactive and I can control the turtle from the interactive python console window and there are no problems with the drawing being delayed or the window going into a non-responsive state. From rosuav at gmail.com Fri Aug 25 09:15:34 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 25 Aug 2017 23:15:34 +1000 Subject: Reading the documentation In-Reply-To: <59a01fa9$0$1619$c3e8da3$5496439d@news.astraweb.com> References: <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> <59a01fa9$0$1619$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Aug 25, 2017 at 11:01 PM, Steve D'Aprano wrote: > How did we get onto prime factors of denominators? The point I was making is > that there are plenty of fractions which are not multiples of 1/5 which > nevertheless lead to unintuitive "wrong answers" in both Decimal and binary > floating point. It is not necessary for the fraction to have a denominator > which is a multiple of 5 to run into issues. Yep. We're in agreement on that. My only point about the confusion was the way in which you could get "wrong answers" in binary but "right answers" in decimal, leading to the "0.1 + 0.2 != 0.3" problem. That's a sum that works flawlessly in decimal but not in binary. ChrisA From p.f.moore at gmail.com Fri Aug 25 09:41:48 2017 From: p.f.moore at gmail.com (Paul Moore) Date: Fri, 25 Aug 2017 06:41:48 -0700 (PDT) Subject: Reading the documentation In-Reply-To: References: <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <8c0e1d7b-27ff-409f-bc69-26b8511d8f1a@googlegroups.com> <599fb0b6$0$22142$c3e8da3$5496439d@news.astraweb.com> <599fbda3$0$22142$c3e8da3$5496439d@news.astraweb.com> <59a01fa9$0$1619$c3e8da3$5496439d@news.astraweb.com> Message-ID: <83fa7ff5-4d8c-4d48-bd65-6962906c0fd8@googlegroups.com> On Friday, 25 August 2017 14:16:05 UTC+1, Chris Angelico wrote: > Yep. We're in agreement on that. My only point about the confusion was > the way in which you could get "wrong answers" in binary but "right > answers" in decimal, leading to the "0.1 + 0.2 != 0.3" problem. That's > a sum that works flawlessly in decimal but not in binary. And in practice this *is* the example that causes the most confusion, in terms of people thinking what Python does is "wrong". The usual "explanation" is something along the lines of "floats aren't exact" or "rounding", neither of which is the real explanation (and "floats aren't exact" isn't even true!) The real explanation is that "0.1" is a textual representation in your source, that gets converted into a value in your code that doesn't actually equate to what you *meant* by 0.1 (i.e. 1/10). Explaining the difference between the form of a literal, and the resulting actual value used in your program, is surprisingly hard (I say this after having recently spent rather longer than I thought I'd need to explaining the difference between a "date literal" and a "date object" to a colleague who's far from being a "dumb newbie"). Paul From jon+usenet at unequivocal.eu Fri Aug 25 11:47:14 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 25 Aug 2017 15:47:14 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-25, Chris Angelico wrote: > That looks like an exception to me. Not a "process is now terminated". > That's what happened when I pressed Ctrl-C (the IP address was > deliberately picked as one that doesn't currently exist on my network, > so it took time). Ok yes, so ctrl-C is sending SIGINT which interrupts the system call and is then caught as a Python exception, so this is very similar to the SIGALRM idea you already suggested, in that it doesn't work with threads, except it also relies on there being a person there to press ctrl-C. So we still don't have any workable solution to the problem. From jon+usenet at unequivocal.eu Fri Aug 25 11:49:35 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 25 Aug 2017 15:49:35 -0000 (UTC) Subject: requests.{get,post} timeout References: <8760dcyvn0.fsf@handshake.de> Message-ID: On 2017-08-25, dieter wrote: > This may no longer work. Long ago, I have often been plagued > by such EINTR exceptions, and I have wished heavily that in those > cases the IO operation should be automatically resumed. In recent time, > I have no longer seen such exceptions - and I concluded that my wish > has been fulfilled (at least for many signal types). You are correct, this was addressed in PEP 475 which was implemented in Python 3.5 and it was indeed a good thing. From rosuav at gmail.com Fri Aug 25 13:31:40 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 26 Aug 2017 03:31:40 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Sat, Aug 26, 2017 at 1:47 AM, Jon Ribbens wrote: > On 2017-08-25, Chris Angelico wrote: >> That looks like an exception to me. Not a "process is now terminated". >> That's what happened when I pressed Ctrl-C (the IP address was >> deliberately picked as one that doesn't currently exist on my network, >> so it took time). > > Ok yes, so ctrl-C is sending SIGINT which interrupts the system call > and is then caught as a Python exception, so this is very similar to > the SIGALRM idea you already suggested, in that it doesn't work with > threads, except it also relies on there being a person there to press > ctrl-C. So we still don't have any workable solution to the problem. The two complement each other. Want something on a specified clock? SIGALRM. Want to handle that fuzzy notion of "it's been too long"? Let the user hit Ctrl-C. They work basically the same way, from different causes. ChrisA From python at mrabarnett.plus.com Fri Aug 25 13:52:49 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 25 Aug 2017 18:52:49 +0100 Subject: Reading the documentation In-Reply-To: References: <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> <98c49883-e56f-475a-ba7e-3f9a4c7b7f66@googlegroups.com> Message-ID: <7602e583-f7ed-61d3-0512-a2e29c8e7a58@mrabarnett.plus.com> On 2017-08-25 15:40, Dennis Lee Bieber wrote: > On Thu, 24 Aug 2017 21:47:41 -0700 (PDT), Rustom Mody > declaimed the following: > > >>This was true of Britain 100 years ago >>It was true of Rome 1000 years ago > > Rome was still a problem in 1017? That's only 50 years away from the > Battle of Hastings and the Norman conquest. > Well, the Byzantine Empire still existed. > Rome was basically washed up 1500 years ago. The first crusade fell > about 900 years ago. > From rustompmody at gmail.com Fri Aug 25 14:02:27 2017 From: rustompmody at gmail.com (Rustom Mody) Date: Fri, 25 Aug 2017 11:02:27 -0700 (PDT) Subject: Reading the documentation In-Reply-To: References: <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <599f97d8$0$1591$c3e8da3$5496439d@news.astraweb.com> <2ba76dcb-e3ba-439c-94fd-099751ffb5af@googlegroups.com> <98c49883-e56f-475a-ba7e-3f9a4c7b7f66@googlegroups.com> <7602e583-f7ed-61d3-0512-a2e29c8e7a58@mrabarnett.plus.com> Message-ID: On Friday, August 25, 2017 at 11:23:26 PM UTC+5:30, MRAB wrote: > On 2017-08-25 15:40, Dennis Lee Bieber wrote: > > On Thu, 24 Aug 2017 21:47:41 -0700 (PDT), Rustom Mody declaimed the following: > > > > > >>This was true of Britain 100 years ago > >>It was true of Rome 1000 years ago > > > > Rome was still a problem in 1017? That's only 50 years away from the > > Battle of Hastings and the Norman conquest. > > > Well, the Byzantine Empire still existed. > > > Rome was basically washed up 1500 years ago. The first crusade fell > > about 900 years ago. > > I meant to say: Rome ? 2000 years [And Denis I dont see your mails (thanks to your settings?) unless someone else quotes them] From mail at timgolden.me.uk Fri Aug 25 14:59:56 2017 From: mail at timgolden.me.uk (Tim Golden) Date: Fri, 25 Aug 2017 19:59:56 +0100 Subject: Express thanks In-Reply-To: References: <8abff237-5ccd-4eb6-85c8-cdc9e87520b7@bl1g2000vbb.googlegroups.com> <43f5ce33-790e-423b-8d2f-355f3e914d0a@googlegroups.com> Message-ID: On 21/08/2017 15:34, Hamish MacDonald wrote: > I wanted to give a shout out to the wonderfully passionate contributions to > python I've witnessed following this and other mailing lists over the > last little bit. > > The level of knowledge and willingness to help I've seen are truly > inspiring. Super motivating. > > Probably the wrong forum for such a message but what the hey. Late in replying, but: thank you for taking the trouble. Speaking both as a long-time list user, but also as one of the list owners/moderators. We often enough hear people grumbling about things, but too rarely calling positive things out. TJG From jon+usenet at unequivocal.eu Fri Aug 25 15:40:22 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 25 Aug 2017 19:40:22 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-25, Chris Angelico wrote: > On Sat, Aug 26, 2017 at 1:47 AM, Jon Ribbens wrote: >> On 2017-08-25, Chris Angelico wrote: >>> That looks like an exception to me. Not a "process is now terminated". >>> That's what happened when I pressed Ctrl-C (the IP address was >>> deliberately picked as one that doesn't currently exist on my network, >>> so it took time). >> >> Ok yes, so ctrl-C is sending SIGINT which interrupts the system call >> and is then caught as a Python exception, so this is very similar to >> the SIGALRM idea you already suggested, in that it doesn't work with >> threads, except it also relies on there being a person there to press >> ctrl-C. So we still don't have any workable solution to the problem. > > The two complement each other. Want something on a specified clock? > SIGALRM. Want to handle that fuzzy notion of "it's been too long"? Let > the user hit Ctrl-C. They work basically the same way, from different > causes. Neither works with threads. Threads, neither of them work with. With threads, neither of them works. Works, threads with, neither of them does. Of them, working with threads, does neither. Threads! Them work with! Does not! From rosuav at gmail.com Fri Aug 25 15:53:54 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 26 Aug 2017 05:53:54 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Sat, Aug 26, 2017 at 5:40 AM, Jon Ribbens wrote: > On 2017-08-25, Chris Angelico wrote: >> On Sat, Aug 26, 2017 at 1:47 AM, Jon Ribbens wrote: >>> On 2017-08-25, Chris Angelico wrote: >>>> That looks like an exception to me. Not a "process is now terminated". >>>> That's what happened when I pressed Ctrl-C (the IP address was >>>> deliberately picked as one that doesn't currently exist on my network, >>>> so it took time). >>> >>> Ok yes, so ctrl-C is sending SIGINT which interrupts the system call >>> and is then caught as a Python exception, so this is very similar to >>> the SIGALRM idea you already suggested, in that it doesn't work with >>> threads, except it also relies on there being a person there to press >>> ctrl-C. So we still don't have any workable solution to the problem. >> >> The two complement each other. Want something on a specified clock? >> SIGALRM. Want to handle that fuzzy notion of "it's been too long"? Let >> the user hit Ctrl-C. They work basically the same way, from different >> causes. > > Neither works with threads. Threads, neither of them work with. > With threads, neither of them works. Works, threads with, neither > of them does. Of them, working with threads, does neither. Threads! > Them work with! Does not! So why are you using multiple threads? You never said that part. ChrisA From ben.usenet at bsb.me.uk Fri Aug 25 16:02:18 2017 From: ben.usenet at bsb.me.uk (Ben Bacarisse) Date: Fri, 25 Aug 2017 21:02:18 +0100 Subject: Reading the documentation References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> Message-ID: <87r2vz2z79.fsf@bsb.me.uk> ram at zedat.fu-berlin.de (Stefan Ram) writes: >>On Fri, 25 Aug 2017 11:25 am, Ben Bacarisse wrote: >>With that in mind, "an Integral" is a shorthand for "an Integral value", > > In math, an integral value is called an /integer/. > Therefore, in math, it would seem strange to avoid the noun > /integer/ using /integral/ as a noun. > > In a programming language with formal types, however, > "an integer value" can be something different than > "an Integer value", which in turn can be something > different than "an Integral value". I think you are agreeing with the text you quote, yes? (But including the part you cut that gives meaning to "With that in mind".) I ask because I am often not sure if you are making some subtle point I've missed. -- Ben. From jon+usenet at unequivocal.eu Fri Aug 25 16:16:52 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 25 Aug 2017 20:16:52 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-25, Chris Angelico wrote: > On Sat, Aug 26, 2017 at 5:40 AM, Jon Ribbens wrote: >> On 2017-08-25, Chris Angelico wrote: >>> On Sat, Aug 26, 2017 at 1:47 AM, Jon Ribbens wrote: >>>> On 2017-08-25, Chris Angelico wrote: >>>>> That looks like an exception to me. Not a "process is now terminated". >>>>> That's what happened when I pressed Ctrl-C (the IP address was >>>>> deliberately picked as one that doesn't currently exist on my network, >>>>> so it took time). >>>> >>>> Ok yes, so ctrl-C is sending SIGINT which interrupts the system call >>>> and is then caught as a Python exception, so this is very similar to >>>> the SIGALRM idea you already suggested, in that it doesn't work with >>>> threads, except it also relies on there being a person there to press >>>> ctrl-C. So we still don't have any workable solution to the problem. >>> >>> The two complement each other. Want something on a specified clock? >>> SIGALRM. Want to handle that fuzzy notion of "it's been too long"? Let >>> the user hit Ctrl-C. They work basically the same way, from different >>> causes. >> >> Neither works with threads. Threads, neither of them work with. >> With threads, neither of them works. Works, threads with, neither >> of them does. Of them, working with threads, does neither. Threads! >> Them work with! Does not! > > So why are you using multiple threads? You never said that part. I said it in the majority of the posts I've made in this thread. I said it in the post you were responding to just now. I'm using threads. Now I've said it again. From rosuav at gmail.com Fri Aug 25 16:32:14 2017 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 26 Aug 2017 06:32:14 +1000 Subject: requests.{get,post} timeout In-Reply-To: References: Message-ID: On Sat, Aug 26, 2017 at 6:16 AM, Jon Ribbens wrote: > On 2017-08-25, Chris Angelico wrote: >> On Sat, Aug 26, 2017 at 5:40 AM, Jon Ribbens wrote: >>> On 2017-08-25, Chris Angelico wrote: >>>> On Sat, Aug 26, 2017 at 1:47 AM, Jon Ribbens wrote: >>>>> On 2017-08-25, Chris Angelico wrote: >>>>>> That looks like an exception to me. Not a "process is now terminated". >>>>>> That's what happened when I pressed Ctrl-C (the IP address was >>>>>> deliberately picked as one that doesn't currently exist on my network, >>>>>> so it took time). >>>>> >>>>> Ok yes, so ctrl-C is sending SIGINT which interrupts the system call >>>>> and is then caught as a Python exception, so this is very similar to >>>>> the SIGALRM idea you already suggested, in that it doesn't work with >>>>> threads, except it also relies on there being a person there to press >>>>> ctrl-C. So we still don't have any workable solution to the problem. >>>> >>>> The two complement each other. Want something on a specified clock? >>>> SIGALRM. Want to handle that fuzzy notion of "it's been too long"? Let >>>> the user hit Ctrl-C. They work basically the same way, from different >>>> causes. >>> >>> Neither works with threads. Threads, neither of them work with. >>> With threads, neither of them works. Works, threads with, neither >>> of them does. Of them, working with threads, does neither. Threads! >>> Them work with! Does not! >> >> So why are you using multiple threads? You never said that part. > > I said it in the majority of the posts I've made in this thread. > I said it in the post you were responding to just now. I'm using > threads. Now I've said it again. You said WHY you are using multiple threads? I can't find it. But if you're using threads, then you can use other techniques, like reaching into the request and closing its socket. You get what you pay for. ChrisA From jon+usenet at unequivocal.eu Fri Aug 25 16:36:36 2017 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Fri, 25 Aug 2017 20:36:36 -0000 (UTC) Subject: requests.{get,post} timeout References: Message-ID: On 2017-08-25, Chris Angelico wrote: > On Sat, Aug 26, 2017 at 6:16 AM, Jon Ribbens wrote: >> I said it in the majority of the posts I've made in this thread. >> I said it in the post you were responding to just now. I'm using >> threads. Now I've said it again. > > You said WHY you are using multiple threads? I can't find it. What's that got to do with anything? Because my program is doing multiple things at once. > But if you're using threads, then you can use other techniques, like > reaching into the request and closing its socket. There's no documented way of doing that that I'm aware of. > You get what you pay for. Are you saying people should expect free software to be rubbish because it's free? If not, what are you saying? From candyrainey at gmail.com Fri Aug 25 19:25:24 2017 From: candyrainey at gmail.com (candyrainey at gmail.com) Date: Fri, 25 Aug 2017 16:25:24 -0700 (PDT) Subject: Test Bank for Essentials of Sociology 6th Edition by Basirico In-Reply-To: References: Message-ID: <5b846a22-01ff-4243-9195-1ad36ae054f9@googlegroups.com> On Wednesday, July 12, 2017 at 5:05:41 PM UTC-4, Test Banks wrote: > Greetings, > > You can get Test Bank for " Essentials of Sociology 6th Edition by Richard P. Appelbaum, Deborah Carr, Mitchell Duneier, Anthony Giddens " at very reasonable price. Our team is available 24/7 and 365 days / year to respond your requests. Send us an email at pro.fast(@)hotmail(dot)com > > Place your order at PRO.FAST(@)HOTMAIL(DOT)COM > > ISBN Numbers for this book (ISBN-10: 0393614298 and ISBN-13: 9780393614299) > > ESSENTIALS OF SOCIOLOGY 6TH EDITION BY APPELBAUM TEST BANK > > You can also email for other Sociology books Solutions and Test Bank at low prices and our team will try to get all resources you need. > > Do not post your reply here. Simply send us an email at PRO.FAST (AT) HOTMAIL (DOT) COM > > Cheers, I need TB/SM for Essentials of Sociology Sixth Edition Title Essentials in Sociology, 6th Edition Author Basirico, et al ISBN 978-1-62751-352-4 Publisher BVT Publishing Publication Date 2014 On Wednesday, July 12, 2017 at 5:05:41 PM UTC-4, Test Banks wrote: > Greetings, > > You can get Test Bank for " Essentials of Sociology 6th Edition by Richard P. Appelbaum, Deborah Carr, Mitchell Duneier, Anthony Giddens " at very reasonable price. Our team is available 24/7 and 365 days / year to respond your requests. Send us an email at pro.fast(@)hotmail(dot)com > > Place your order at PRO.FAST(@)HOTMAIL(DOT)COM > > ISBN Numbers for this book (ISBN-10: 0393614298 and ISBN-13: 9780393614299) > > ESSENTIALS OF SOCIOLOGY 6TH EDITION BY APPELBAUM TEST BANK > > You can also email for other Sociology books Solutions and Test Bank at low prices and our team will try to get all resources you need. > > Do not post your reply here. Simply send us an email at PRO.FAST (AT) HOTMAIL (DOT) COM > > Cheers, From rantingrickjohnson at gmail.com Fri Aug 25 22:22:44 2017 From: rantingrickjohnson at gmail.com (Rick Johnson) Date: Fri, 25 Aug 2017 19:22:44 -0700 (PDT) Subject: Reading the documentation In-Reply-To: <599f9940$0$1612$c3e8da3$5496439d@news.astraweb.com> References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <599f9940$0$1612$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > Rustom Mody wrote: > > Ian wrote: > >> "Larry Martell" wrote: > >> 9:21 PM Rustom Mody wrote: > > > > Statement 1: Aeroplanes fly. Statement 2: Submarines swim. > > > > Are these two statements equally acceptable? [Inspired > > > > by a talk by Noam Chomsky] > > > There should be a corollary of Godwin's law for that > > > idiot. > [...] > > [Larry seems to be angry about/at somethin'? No idea who/what?] > > Chomsky challenges the prevailing world-view that the USA > is a force for good, by documenting the many, many, many > ways that the USA's actions are harmful, unjust, illegal > (occasionally all three at once) and in contradiction to > the nation's stated values. Many people don't like it when > you challenge their cherished myths. Nor when you glorify their most hated enemy. Chomsky may be under the impression that heroes are without flaw, however, many of us do not share such naive beliefs, As any random historian of "super-hero comic book lore" can testify, heroes are deeply flawed. So jump on Chomsky's "Let's all bash America" bandwagon if you must, but please do remember: that the short history of America has presented a social transformation the likes of which this world has never seen. So instead of wasting energy complaining about past events that cannot be changed, you and Chomsky, should spend your "energy capital" convincing people that there is a better way. And calling people names or engaging in endless emotional battles is never going to work. Yes, the history of America has been a dark history of many horrors, but it has also been, at moments, a bright light illuminating the world with the ideals of liberty. At some point we must realize that progress cannot _proceed_ until we bury the hatchet. And that's why Daryl Davis is one of my personal heroes! Daryl Davis is the perfect example of a man who is fighting against the ills of our society in the "right way", by winning hearts and minds. You should learn about this great man and watch his documentary titled "Accidental Courtesy: Daryl Davis, Race & America" -- which you can find on the American PBS website, or in the following links. The Man: https://en.wikipedia.org/wiki/Daryl_Davis The Documentary: http://accidentalcourtesy.com/ https://www.netflix.com/title/80105514 http://www.imdb.com/title/tt5390430/ From mail at timgolden.me.uk Sat Aug 26 04:58:59 2017 From: mail at timgolden.me.uk (Tim Golden) Date: Sat, 26 Aug 2017 09:58:59 +0100 Subject: Reading the documentation In-Reply-To: References: <749eb044-4f82-aa08-420b-ab37742af1a8@gmail.com> <599f6e95$0$1583$c3e8da3$5496439d@news.astraweb.com> <87lgm84ewq.fsf@bsb.me.uk> <382bb48c-3c87-4476-8d68-f2f3eecd6cf0@googlegroups.com> <34f72ad3-99c0-426e-9804-509ed5df1a52@googlegroups.com> <599f9940$0$1612$c3e8da3$5496439d@news.astraweb.com> Message-ID: <05353dda-c5bc-e605-4ce4-86bb4cd7f969@timgolden.me.uk> On 26/08/2017 03:22, Rick Johnson wrote: > Steve D'Aprano wrote: >> Rustom Mody wrote: >>> Ian wrote: >>>> "Larry Martell" wrote: >>>> 9:21 PM Rustom Mody wrote: >>>>> Statement 1: Aeroplanes fly. Statement 2: Submarines swim. >>>>> Are these two statements equally acceptable? [Inspired >>>>> by a talk by Noam Chomsky] >>>> There should be a corollary of Godwin's law for that >>>> idiot. >> [...] >>> [Larry seems to be angry about/at somethin'? No idea who/what?] >> >> Chomsky challenges the prevailing world-view that the USA >> is a force for good, by documenting the many, many, many >> ways that the USA's actions are harmful, unjust, illegal >> (occasionally all three at once) and in contradiction to >> the nation's stated values. Many people don't like it when >> you challenge their cherished myths. > > Nor when you glorify their most hated enemy. [... snip ...] Unusually, I'd like to speak as one of the list owners and ask people to continue this thread of conversation elsewhere. We're quite tolerant to fairly off-topic side-threads here, but I think this one is going to generate more heat than light and it's not even tangentially on-topic. So please feel free to have a private correspondence or to set follow-ups to some political debating group. But let it drop on this list. Thanks TJG From ian.g.kelly at gmail.com Sat Aug 26 22:32:21 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Sat, 26 Aug 2017 20:32:21 -0600 Subject: Protocols in Python In-Reply-To: References: Message-ID: On Sat, Aug 26, 2017 at 6:35 PM, Stefan Ram wrote: > The "The Python Library Reference, Release 3.6.0" (LIB) says: > > ?it must support the sequence protocol (the > __getitem__() method with integer arguments > starting at 0).?. > > But in the "The Python Language Reference, Release 3.6.0" > (LANG) this is called ?old sequence iteration? or ?old-style > iteration? with the (new) sequence protocol being augmented > by ?__len__?. I think you're confused. There is no "new" sequence protocol. The sequence protocol is just the set of special methods that one might use to implement a sequence. There have been methods added over time (e.g. __reversed__ was added in 2.6) but there has been no major overhaul as is suggested by the word "new". Where the sequence protocol is sometimes contrasted is with the iterator protocol in the context of iteration. Prior to PEP 234, only sequences could be iterated over because at the time iteration was implemented using the sequence protocol, specifically the __getitem__ method. PEP 234 added a new way to iterate using the iterator protocol but left the sequence protocol itself unchanged. Hence, iteration using the sequence protocol is "old", and iteration using the iterator protocol is "new". > Then, LANG mentions a ?find_spec() protocol? and one can only > /guess/ that this is what is being described in ?5.3.4 The > meta path?, because there it does not say "this is now the > definition of the find_spec() protocol here". That wording could stand to be tightened up. Muddying the waters further, 5.5.2 describes the "path entry finder protocol" which involves implementing a *different* find_spec method. From christopher_reimer at yahoo.com Sun Aug 27 13:23:07 2017 From: christopher_reimer at yahoo.com (Christopher Reimer) Date: Sun, 27 Aug 2017 10:23:07 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? Message-ID: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> Greetings, I have Python 3.6 script on Windows to scrape comment history from a website. It's currently set up this way: Requestor (threads) -> list -> Parser (threads) -> queue -> CVSWriter (single thread) It takes 15 minutes to process ~11,000 comments. When I replaced the list with a queue between the Requestor and Parser to speed up things, BeautifulSoup stopped working. When I changed BeautifulSoup(contents, "lxml") to BeautifulSoup(contents), I get the UserWarning that no parser wasn't explicitly set and a reference to line 80 in threading.py (which puts it in the RLock factory function). When I switched back to using list between the Requestor and Parser, the Parser worked again. BeautifulSoup doesn't work with a threaded input queue? Thank you, Chris Reimer From __peter__ at web.de Sun Aug 27 14:54:58 2017 From: __peter__ at web.de (Peter Otten) Date: Sun, 27 Aug 2017 20:54:58 +0200 Subject: BeautifulSoup doesn't work with a threaded input queue? References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> Message-ID: Christopher Reimer via Python-list wrote: > Greetings, > > I have Python 3.6 script on Windows to scrape comment history from a > website. It's currently set up this way: > > Requestor (threads) -> list -> Parser (threads) -> queue -> CVSWriter > (single thread) > > It takes 15 minutes to process ~11,000 comments. > > When I replaced the list with a queue between the Requestor and Parser > to speed up things, BeautifulSoup stopped working. > > When I changed BeautifulSoup(contents, "lxml") to > BeautifulSoup(contents), I get the UserWarning that no parser wasn't > explicitly set and a reference to line 80 in threading.py (which puts it > in the RLock factory function). > > When I switched back to using list between the Requestor and Parser, the > Parser worked again. > > BeautifulSoup doesn't work with a threaded input queue? The documentation https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup says you can make the BeautifulSoup object from a string or file. Can you give a few more details where the queue comes into play? A small code sample would be ideal... From christopher_reimer at yahoo.com Sun Aug 27 15:35:03 2017 From: christopher_reimer at yahoo.com (Christopher Reimer) Date: Sun, 27 Aug 2017 12:35:03 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> Message-ID: <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> On 8/27/2017 11:54 AM, Peter Otten wrote: > The documentation > > https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup > > says you can make the BeautifulSoup object from a string or file. > Can you give a few more details where the queue comes into play? A small > code sample would be ideal. A worker thread uses a request object to get the page and puts it into queue as page.content (HTML).? Another worker thread gets the page.content from the queue to apply BeautifulSoup and nothing happens. soup = BeautifulSoup(page_content, 'lxml') print(soup) No output whatsoever. If I remove 'lxml', I get the UserWarning that no parser wasn't explicitly set and get the reference to threading.py at line 80. I verified that page.content that goes into and out of the queue is the same page.content that goes into and out of a list. I read somewhere that BeautifulSoup may not be thread-safe. I've never had a problem with threads storing the output into a queue. Using a queue (random order) instead of a list (sequential order) to feed pages for the input is making it wonky. Chris R. From python at mrabarnett.plus.com Sun Aug 27 16:12:10 2017 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 27 Aug 2017 21:12:10 +0100 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> Message-ID: <320b7ec8-4028-eca1-291f-3bbc77c74197@mrabarnett.plus.com> On 2017-08-27 20:35, Christopher Reimer via Python-list wrote: > On 8/27/2017 11:54 AM, Peter Otten wrote: > >> The documentation >> >> https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup >> >> says you can make the BeautifulSoup object from a string or file. >> Can you give a few more details where the queue comes into play? A small >> code sample would be ideal. > > A worker thread uses a request object to get the page and puts it into > queue as page.content (HTML).? Another worker thread gets the > page.content from the queue to apply BeautifulSoup and nothing happens. > > soup = BeautifulSoup(page_content, 'lxml') > print(soup) > > No output whatsoever. If I remove 'lxml', I get the UserWarning that no > parser wasn't explicitly set and get the reference to threading.py at > line 80. > > I verified that page.content that goes into and out of the queue is the > same page.content that goes into and out of a list. > > I read somewhere that BeautifulSoup may not be thread-safe. I've never > had a problem with threads storing the output into a queue. Using a > queue (random order) instead of a list (sequential order) to feed pages > for the input is making it wonky. > What do you mean by "queue (random order)"? A queue is sequential order, first-in-first-out. From anubhav.yadav at gmx.com Sun Aug 27 16:25:25 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 01:55:25 +0530 Subject: Need advice on writing better test cases. Message-ID: Hello, I am a (self-learned) python developer and I write a lot of python code everyday. I try to do as much unit testing as possible. But I want to be better at it, I want to write more test cases, specially that rely on database insertions and reads and file IO. Here are my use-cases for testing. How to test if things are going into the database properly or not? (mysql/mongo). I want to be able to create a test database environment as simple as possible. Create and delete the test environment before each functional test case is run. Sometimes I write code that read some data from some rabbitmq queue and do certain things. How can I write end to end functional test that creates a test rabbitmq environment (exchanges and queues) -> wait for sometime -> see if the intended work has been done -> delete the test environment. I want to be able to make sure that any new commit on my self hosted gitlab server should first run all functional test cases first before accepting the merge. Since we use lot of docker here to deploy modules to productions, I want to write functional test cases that test the whole system as a whole and see if things are happening the way they are supposed to happen or not. This means firing up lot of docker containers, lot of test databases with some data, and run all the test cases from an end user point of view. Can you suggest me the right python testing frameworks that I should be using? Right now I am using unittest to write test cases and manual if/else statements to run the functional test cases. I try to create rabbitmq queues and bind them to rabbitmq exchanges using the pika module. I then run the module using python -m moduleName and then sleep for sometime. Then I kill the processs (subprocess) and then I see if the intended consequences have happened or not. It's a pain in the ass to be doing so many things for test cases. I clearly need to learn how to do things better. Any suggestion/book/article/course/video will help me immensely in writing better test cases. Thanks for reading. From __peter__ at web.de Sun Aug 27 16:31:35 2017 From: __peter__ at web.de (Peter Otten) Date: Sun, 27 Aug 2017 22:31:35 +0200 Subject: BeautifulSoup doesn't work with a threaded input queue? References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> Message-ID: Christopher Reimer via Python-list wrote: > On 8/27/2017 11:54 AM, Peter Otten wrote: > >> The documentation >> >> https://www.crummy.com/software/BeautifulSoup/bs4/doc/#making-the-soup >> >> says you can make the BeautifulSoup object from a string or file. >> Can you give a few more details where the queue comes into play? A small >> code sample would be ideal. > > A worker thread uses a request object to get the page and puts it into > queue as page.content (HTML). Another worker thread gets the > page.content from the queue to apply BeautifulSoup and nothing happens. > > soup = BeautifulSoup(page_content, 'lxml') > print(soup) > > No output whatsoever. If I remove 'lxml', I get the UserWarning that no > parser wasn't explicitly set and get the reference to threading.py at > line 80. > > I verified that page.content that goes into and out of the queue is the > same page.content that goes into and out of a list. > > I read somewhere that BeautifulSoup may not be thread-safe. I've never > had a problem with threads storing the output into a queue. Using a > queue (random order) instead of a list (sequential order) to feed pages > for the input is making it wonky. Here's a simple example that extracts titles from generated html. It seems to work. Does it resemble what you do? import csv import threading import time from queue import Queue import bs4 def process_html(source, dest, index): while True: html = source.get() if html is DONE: dest.put(DONE) break soup = bs4.BeautifulSoup(html, "lxml") dest.put(soup.find("title").text) def write_csv(source, filename, to_go): with open(filename, "w") as f: writer = csv.writer(f) while True: title = source.get() if title is DONE: to_go -= 1 if not to_go: return else: writer.writerow([title]) NUM_SOUP_THREADS = 10 DONE = object() web_to_soup = Queue() soup_to_file = Queue() soup_threads = [ threading.Thread(target=process_html, args=(web_to_soup, soup_to_file, i)) for i in range(NUM_SOUP_THREADS) ] write_thread = threading.Thread( target=write_csv, args=(soup_to_file, "tmp.csv", NUM_SOUP_THREADS), ) write_thread.start() for thread in soup_threads: thread.start() for i in range(100): web_to_soup.put("#{}".format(i)) for i in range(NUM_SOUP_THREADS): web_to_soup.put(DONE) for t in soup_threads: t.join() write_thread.join() From christopher_reimer at yahoo.com Sun Aug 27 16:35:06 2017 From: christopher_reimer at yahoo.com (Christopher Reimer) Date: Sun, 27 Aug 2017 13:35:06 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: <320b7ec8-4028-eca1-291f-3bbc77c74197@mrabarnett.plus.com> References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> <320b7ec8-4028-eca1-291f-3bbc77c74197@mrabarnett.plus.com> Message-ID: <674e01a3-e127-12bd-74ca-cde94eed9d0a@yahoo.com> On 8/27/2017 1:12 PM, MRAB wrote: > What do you mean by "queue (random order)"? A queue is sequential > order, first-in-first-out. With 20 threads requesting 20 different pages, they're not going into the queue in sequential order (i.e., 0, 1, 2, ..., 17, 18, 19) and coming in at different times for the parser worker threads to get for processing. Similar situation with a list but I sort the list before giving it to the parser, so all the items are in sequential order and fed to the parser one at time. Chris R. From arj.python at gmail.com Sun Aug 27 16:37:04 2017 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Mon, 28 Aug 2017 00:37:04 +0400 Subject: Express thanks In-Reply-To: References: <8abff237-5ccd-4eb6-85c8-cdc9e87520b7@bl1g2000vbb.googlegroups.com> <43f5ce33-790e-423b-8d2f-355f3e914d0a@googlegroups.com> Message-ID: hi, liking py, i follow py discuss at pretty some places, i can say that upto now, py mailing lists are awesome just make a drop on irc ... Keep it up guys ! Abdur-Rahmaan Janhangeer, Mauritius abdurrahmaanjanhangeer.wordpress.com On 21 Aug 2017 18:38, "Hamish MacDonald" wrote: I wanted to give a shout out to the wonderfully passionate contributions to python I've witnessed following this and other mailing lists over the last little bit. The level of knowledge and willingness to help I've seen are truly inspiring. Super motivating. Probably the wrong forum for such a message but what the hey. Hamish -- -- https://mail.python.org/mailman/listinfo/python-list From python at mrabarnett.plus.com Sun Aug 27 16:50:20 2017 From: python at mrabarnett.plus.com (MRAB) Date: Sun, 27 Aug 2017 21:50:20 +0100 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: <674e01a3-e127-12bd-74ca-cde94eed9d0a@yahoo.com> References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> <320b7ec8-4028-eca1-291f-3bbc77c74197@mrabarnett.plus.com> <674e01a3-e127-12bd-74ca-cde94eed9d0a@yahoo.com> Message-ID: <827c895b-fbf7-d848-f65b-11c506ba024f@mrabarnett.plus.com> On 2017-08-27 21:35, Christopher Reimer via Python-list wrote: > On 8/27/2017 1:12 PM, MRAB wrote: > >> What do you mean by "queue (random order)"? A queue is sequential >> order, first-in-first-out. > > With 20 threads requesting 20 different pages, they're not going into > the queue in sequential order (i.e., 0, 1, 2, ..., 17, 18, 19) and > coming in at different times for the parser worker threads to get for > processing. > > Similar situation with a list but I sort the list before giving it to > the parser, so all the items are in sequential order and fed to the > parser one at time. > What if you don't sort the list? I ask because it sounds like you're changing 2 variables (i.e. list->queue, sorted->unsorted) at the same time, so you can't be sure that it's the queue that's the problem. From christopher_reimer at yahoo.com Sun Aug 27 17:14:27 2017 From: christopher_reimer at yahoo.com (Christopher Reimer) Date: Sun, 27 Aug 2017 14:14:27 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> Message-ID: On 8/27/2017 1:31 PM, Peter Otten wrote: > Here's a simple example that extracts titles from generated html. It seems > to work. Does it resemble what you do? Your example is similar to my code when I'm using a list for the input to the parser. You have soup_threads and write_threads, but no read_threads. The particular website I'm scraping requires checking each page for the sentinel value (i.e., "Sorry, no more comments") in order to determine when to stop requesting pages. For my comment history that's ~750 pages to parse ~11,000 comments. I have 20 read_threads requesting and putting pages into the output queue that is the input_queue for the parser. My soup_threads can get items from the queue, but BeautifulSoup doesn't do anything after that. Chris R. From christopher_reimer at yahoo.com Sun Aug 27 17:19:24 2017 From: christopher_reimer at yahoo.com (Christopher Reimer) Date: Sun, 27 Aug 2017 14:19:24 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: <827c895b-fbf7-d848-f65b-11c506ba024f@mrabarnett.plus.com> References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> <320b7ec8-4028-eca1-291f-3bbc77c74197@mrabarnett.plus.com> <674e01a3-e127-12bd-74ca-cde94eed9d0a@yahoo.com> <827c895b-fbf7-d848-f65b-11c506ba024f@mrabarnett.plus.com> Message-ID: <8ba5ac08-5909-f673-0e87-abe7da71dcac@yahoo.com> On 8/27/2017 1:50 PM, MRAB wrote: > What if you don't sort the list? I ask because it sounds like you're > changing 2 variables (i.e. list->queue, sorted->unsorted) at the same > time, so you can't be sure that it's the queue that's the problem. If I'm using a list, I'm using a for loop to input items into the parser. If I'm using a queue, I'm using worker threads to put or get items. The item is still the same whether in a list or a queue. Chris R. From no.email at nospam.invalid Sun Aug 27 17:23:58 2017 From: no.email at nospam.invalid (Paul Rubin) Date: Sun, 27 Aug 2017 14:23:58 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> Message-ID: <87wp5opuvl.fsf@nightsong.com> Christopher Reimer writes: > I have 20 read_threads requesting and putting pages into the output > queue that is the input_queue for the parser. Given how slow parsing is, you probably want to scrap the pages into disk files, and then run the parser in parallel processes that read from the disk. You could also use something like Redis (redis.io) as a queue. From __peter__ at web.de Sun Aug 27 17:45:27 2017 From: __peter__ at web.de (Peter Otten) Date: Sun, 27 Aug 2017 23:45:27 +0200 Subject: BeautifulSoup doesn't work with a threaded input queue? References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> Message-ID: Christopher Reimer via Python-list wrote: > On 8/27/2017 1:31 PM, Peter Otten wrote: > >> Here's a simple example that extracts titles from generated html. It >> seems to work. Does it resemble what you do? > Your example is similar to my code when I'm using a list for the input > to the parser. You have soup_threads and write_threads, but no > read_threads. > > The particular website I'm scraping requires checking each page for the > sentinel value (i.e., "Sorry, no more comments") in order to determine > when to stop requesting pages. Where's that check happening? If it's in the soup thread you need some kind of back channel to the read threads to inform them that you're need no more pages. > For my comment history that's ~750 pages > to parse ~11,000 comments. > > I have 20 read_threads requesting and putting pages into the output > queue that is the input_queue for the parser. My soup_threads can get > items from the queue, but BeautifulSoup doesn't do anything after that. > > Chris R. From christopher_reimer at yahoo.com Sun Aug 27 18:48:27 2017 From: christopher_reimer at yahoo.com (Christopher Reimer) Date: Sun, 27 Aug 2017 15:48:27 -0700 Subject: BeautifulSoup doesn't work with a threaded input queue? In-Reply-To: References: <679baafa-685a-018f-074d-37048b58f66a@yahoo.com> <6a9eac6b-445f-c231-18b8-000e47d82fe6@yahoo.com> Message-ID: <9698d8a8-5b6f-0abb-c85c-47d8320bb027@yahoo.com> Ah, shoot me. I had a .join() statement on the output queue but not on in the input queue. So the threads for the input queue got terminated before BeautifulSoup could get started. I went down that same rabbit hole with CSVWriter the other day. *sigh* Thanks for everyone's help. Chris R. From ben+python at benfinney.id.au Sun Aug 27 19:05:07 2017 From: ben+python at benfinney.id.au (Ben Finney) Date: Mon, 28 Aug 2017 09:05:07 +1000 Subject: Need advice on writing better test cases. References: Message-ID: <857exoehng.fsf@benfinney.id.au> Anubhav Yadav writes: > I want to write more test cases, specially that rely on database > insertions and reads and file IO. Thanks for taking seriously the importance of test cases for your code! One important thing to recognise is that a unit test is only one type of test. It tests one unit of code, typically a function, and should assert exactly one clearly true-or-false result of calling that code unit. If you have a function and you want to assert *that function's* behaviour, you can avoid external dependencies during the test run by providing fake resources. These can be mocks (e.g. with ?unittest.mock?) or other fake resources that are going to behave exactly how you want, for the purpose of testing the code unit. Unit test cases: * Exercise a small unit of code in isolation. * Each test exactly one obvious behavour of the code unit. * Aim to have exactly one reason the test case can fail. Because they are isolated and test a small code unit, they are typically *fast* and can be run very often, because the entire unit test suite completes in seconds. > How to test if things are going into the database properly or not? That is *not* a unit test; it is a test that one part of your code has the right effect on some other part of the system. This meets the description not of a unit test but of an integration test. These integration tests, because they will likely be a lot slower than your unit tests, should be in a separate suite of integration tests, to be run when the time is available to run them. Integration tests: * Exercise many code units together. * Typically make an assertion about the *resulting state* of many underlying actions. * Can have many things that can cause the test case to fail. > (mysql/mongo). I want to be able to create a test database environment > as simple as possible. Create and delete the test environment before > each functional test case is run. One good article discussion how to make integration tests, specifically for database integration with your app, is this one . I hope that helps. -- \ ?The enjoyment of one's tools is an essential ingredient of | `\ successful work.? ?Donald Knuth, _The Art of Computer | _o__) Programming_ | Ben Finney From steve+comp.lang.python at pearwood.info Mon Aug 28 03:55:04 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 28 Aug 2017 07:55:04 GMT Subject: Quiz: Difference between implicit and explicit inheritence Message-ID: <59a3cc58$0$2920$c3e8da3$76491128@news.astraweb.com> In Python 3, what's the difference between these two classes? # implicitly inherit from object class Spam: ... # explicitly inherit from object class Spam(object): ... S P O I L E R S P A C E If you sense a trick question, you're right :-) -- ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From anubhav.yadav at gmx.com Mon Aug 28 04:03:01 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 13:33:01 +0530 Subject: Need advice on writing better test cases. In-Reply-To: <857exoehng.fsf@benfinney.id.au> References: <857exoehng.fsf@benfinney.id.au> Message-ID: <07AEBC19-1E89-4A40-8C2E-A08E7F06DA5A@gmx.com> > On 28-Aug-2017, at 04:35, Ben Finney wrote: > > Anubhav Yadav writes: > >> I want to write more test cases, specially that rely on database >> insertions and reads and file IO. > > Thanks for taking seriously the importance of test cases for your code! > > One important thing to recognise is that a unit test is only one type of > test. It tests one unit of code, typically a function, and should assert > exactly one clearly true-or-false result of calling that code unit. > > If you have a function and you want to assert *that function's* > behaviour, you can avoid external dependencies during the test run by > providing fake resources. These can be mocks (e.g. with ?unittest.mock?) > or other fake resources that are going to behave exactly how you want, > for the purpose of testing the code unit. > > Unit test cases: > > * Exercise a small unit of code in isolation. > * Each test exactly one obvious behavour of the code unit. > * Aim to have exactly one reason the test case can fail. > > Because they are isolated and test a small code unit, they are typically > *fast* and can be run very often, because the entire unit test suite > completes in seconds. > >> How to test if things are going into the database properly or not? > > That is *not* a unit test; it is a test that one part of your code > has the right effect on some other part of the system. This meets the > description not of a unit test but of an integration test. > > These integration tests, because they will likely be a lot slower than > your unit tests, should be in a separate suite of integration tests, to > be run when the time is available to run them. > > Integration tests: > > * Exercise many code units together. > * Typically make an assertion about the *resulting state* of many > underlying actions. > * Can have many things that can cause the test case to fail. > >> (mysql/mongo). I want to be able to create a test database environment >> as simple as possible. Create and delete the test environment before >> each functional test case is run. > > One good article discussion how to make integration tests, specifically > for database integration with your app, is this one > . > > I hope that helps. > > -- > \ ?The enjoyment of one's tools is an essential ingredient of | > `\ successful work.? ?Donald Knuth, _The Art of Computer | > _o__) Programming_ | > Ben Finney > > -- > https://mail.python.org/mailman/listinfo/python-list From anubhav.yadav at gmx.com Mon Aug 28 04:28:34 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 13:58:34 +0530 Subject: Need advice on writing better test cases. In-Reply-To: <857exoehng.fsf@benfinney.id.au> References: <857exoehng.fsf@benfinney.id.au> Message-ID: > If you have a function and you want to assert *that function's* > behaviour, you can avoid external dependencies during the test run by > providing fake resources. These can be mocks (e.g. with ?unittest.mock?) > or other fake resources that are going to behave exactly how you want, > for the purpose of testing the code unit. Yes I have been learning how to mock systems using `unittest.mock` package. I learned how to patch the `requests.get` method to just return true with a fixed json so that I could run my tests cases without relying on the actual server to be running. I think it?s important to read more and more examples on how different libraries and systems are mocked and patched. > > These integration tests, because they will likely be a lot slower than > your unit tests, should be in a separate suite of integration tests, to > be run when the time is available to run them. Is there are standard or structure as to how these integration tests are written? Do we just define different classes for unit tests and different classes for integration tests? Is there any library that can help with writing integration tests? Also how are integration tests different than functional tests? I also want to have a good understanding of functional tests so that I can start writing them first before I start writing my code. This way whatever changes I make my tests will always tell me if the required responsibility of the system if fulfilled or not. Later I would like to run these tests cases automatically when I push my code to GitHub/Gitlab? > Integration tests: > > * Exercise many code units together. > * Typically make an assertion about the *resulting state* of many > underlying actions. > * Can have many things that can cause the test case to fail. I tried to insert some data in a sqlite database and then ran some code and then again ran some sql queries to see if the resulting state is what I intend it to be or not. As the code base grew I realised that it?s a pain to write so many sql queries manually. Is there a framework or library that I can use to simplify this? > >> (mysql/mongo). I want to be able to create a test database environment >> as simple as possible. Create and delete the test environment before >> each functional test case is run. > > One good article discussion how to make integration tests, specifically > for database integration with your app, is this one > . Thank you for the link. Much much helpful. My problem is that I have to write lot of test cases to insert dummy data into the database and then test if the data is changed properly or not. I wanted to know the industry standards and the general practise of doing things. Thanks a lot for your reply. Much much appreciated and helpful. If you can mention some books or videos to watch it will help a lot. Cheers. From steve+comp.lang.python at pearwood.info Mon Aug 28 04:33:53 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 28 Aug 2017 08:33:53 GMT Subject: Need advice on writing better test cases. References: Message-ID: <59a3d571$0$2920$c3e8da3$76491128@news.astraweb.com> On Mon, 28 Aug 2017 01:55:25 +0530, Anubhav Yadav wrote: > Can you suggest me the right python testing frameworks that I should be > using? Right now I am using unittest to write test cases and manual > if/else statements to run the functional test cases. A good way to learn unit testing and regression testing is to download the Python source code and read the test suites. Also consider using doc testing, for both documentation and unit tests. See the doctest module. Can you explain what you mean by "functional test cases", and show an example or two of the sorts of tests you would write? -- ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From anubhav.yadav at gmx.com Mon Aug 28 04:53:05 2017 From: anubhav.yadav at gmx.com (Anubhav Yadav) Date: Mon, 28 Aug 2017 14:23:05 +0530 Subject: Need advice on writing better test cases. In-Reply-To: <59a3d571$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a3d571$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <3CEFB67F-4524-4954-B437-C2511BD041A8@gmx.com> > A good way to learn unit testing and regression testing is to download > the Python source code and read the test suites. It?s a fantastic idea. I will also have a good understanding of the internals of the standard library and at I can learn more about testing. Any specific module that you recommend to get started with? `collections` module maybe? > > Also consider using doc testing, for both documentation and unit tests. > See the doctest module. I have seen some modules with these kind of test cases. I thought it?s just a way to test your code like `unittest`. I will have another look at it. > > Can you explain what you mean by "functional test cases", and show an > example or two of the sorts of tests you would write? So let?s say I want to write a server which listens to client sending data at 12 seconds interval. Here are it?s requirements: 1. Listen to data from all clients. 2. Never lose any data packet. 3. If the data is garbage (not following the spec) discard it. 4. If the data is good, append a timestamp and push it to a rabbitmq queue. So what I would like to do is: 1. Send 100 packets from 1 client and see if the rabbitmq queue has 100 packets. 2. Send 90 good packets and 10 garbage packets and see if the rabbitmq queue has 90 good packets. 3. Send 10 packets from 10 different clients at the same time and see if there is correct data in the rabbitmq queues. 4. So on and so forth. This is just one example. Extension would be another module (which has it?s own suite of unittests) will take this data from queues and do some post processing and put it in some database like `mongo` or `mysql`. So the same set of functional tests should start this second module and see if the intended data is getting parsed properly and delivered to the databases. I don?t really know if this is the write way of writing tests. This is just something that I would do if I am told to make sure your Software does what it?s intended to do. - Anubhav. From leamhall at gmail.com Mon Aug 28 05:41:19 2017 From: leamhall at gmail.com (Leam Hall) Date: Mon, 28 Aug 2017 05:41:19 -0400 Subject: doctest random output? Message-ID: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Is this a good way to test if random numeric output? It seems to work under Python 2.6 and 3.6 but that doesn't make it 'good'. ### Code import random def my_thing(): """ Return a random number from 1-6 >>> 0 < my_thing() <=6 True >>> 6 < my_thing() False """ return random.randint(1,6) if __name__ == "__main__": import doctest doctest.testmod() ### Results python3 test_doctest.py -v Trying: 0 < my_thing() <=6 Expecting: True ok Trying: 6 < my_thing() Expecting: False ok 1 items had no tests: __main__ 1 items passed all tests: 2 tests in __main__.my_thing 2 tests in 2 items. 2 passed and 0 failed. Test passed. From gayuanbu96 at gmail.com Mon Aug 28 06:02:45 2017 From: gayuanbu96 at gmail.com (Gayu anbu) Date: Mon, 28 Aug 2017 03:02:45 -0700 (PDT) Subject: resume Message-ID: <982aea50-5059-428c-8a13-d8e67cfe36e8@googlegroups.com> hi, i am gayathri,studying final year It.i want one page resume please any one send me template From __peter__ at web.de Mon Aug 28 06:07:23 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 28 Aug 2017 12:07:23 +0200 Subject: doctest random output? References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Message-ID: Leam Hall wrote: > Is this a good way to test if random numeric output? It seems to work > under Python 2.6 and 3.6 but that doesn't make it 'good'. > > ### Code > import random > > def my_thing(): > """ Return a random number from 1-6 > >>> 0 < my_thing() <=6 > True > >>> 6 < my_thing() > False > """ These are fine as illustrative tests that demonstrate how my_thing() is used. If you want to test the "randomness" -- that's hard. You could run more often all(1 <= mything() <= 6 for _ in range(1000)) but that doesn't guarantee that the 1001st attempt is outside the specified range. You could have a look at the distribution >>> c = Counter(my_thing() for _ in range(1000)) >>> set(c) == set(range(1, 7)) True but that *should* occasionally fail even though in practice >>> dict(c) == {3: 1000} True would be a strong indication that something is broken rather than that you are really lucky... From gabriel.lins97 at gmail.com Mon Aug 28 07:30:02 2017 From: gabriel.lins97 at gmail.com (gabriel.lins97 at gmail.com) Date: Mon, 28 Aug 2017 04:30:02 -0700 (PDT) Subject: Send mouse clicks to minimized window Message-ID: <43332eba-3286-4c76-8b0f-7eb86736d876@googlegroups.com> Hello, guys I'm using python to automate some seriously boring stuff at work, but would like to improve current code. The way it is now, PyAutoGui moves mouse and clicks the Application. I am, therefore, hostage of my python "assistant", as I cannot use my computer while the .py is running. Is there any way to send mouse clicks to minimized windows, in so that it does not interfere with normal using of my computer? I'm on Windows and have tried pywin32, but could not manage to make it to work. Also tried ctypes, with same results. I'm really new to python. Also, I could migrate to Linux if that's necessary. Any hints? Thanks, guys! From pavol.lisy at gmail.com Mon Aug 28 09:27:30 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Mon, 28 Aug 2017 15:27:30 +0200 Subject: Quiz: Difference between implicit and explicit inheritence In-Reply-To: <59a3cc58$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a3cc58$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: On 8/28/17, Steven D'Aprano wrote: > In Python 3, what's the difference between these two classes? > # implicitly inherit from object > class Spam: > ... > > # explicitly inherit from object > class Spam(object): > ... > > If you sense a trick question, you're right :-) > object = int # this could be trick ... class Spam(object): ... dis.dis show difference too, next line is just for "class Spam(object):" version: LOAD_GLOBAL 0 (object) So nor rebinding object nor rebinding __builtin__.object affect "class Spam:" version. From leamhall at gmail.com Mon Aug 28 15:17:17 2017 From: leamhall at gmail.com (Leam Hall) Date: Mon, 28 Aug 2017 15:17:17 -0400 Subject: doctest random output? In-Reply-To: References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Message-ID: On 08/28/2017 11:40 AM, Dennis Lee Bieber wrote: ... a bunch of good stuff ... I'm (re-)learning python and just trying make sure my function works. Not at the statistical or cryptographic level. :) Thanks! Leam From rosuav at gmail.com Mon Aug 28 16:06:50 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Aug 2017 06:06:50 +1000 Subject: Protocols in Python In-Reply-To: References: Message-ID: On Tue, Aug 29, 2017 at 4:53 AM, Stefan Ram wrote: > ram at zedat.fu-berlin.de (Stefan Ram) writes: >>The "The Python Library Reference, Release 3.6.0" (LIB) says: >>?it must support the sequence protocol (the >>__getitem__() method with integer arguments >>starting at 0).?. >>But in the "The Python Language Reference, Release 3.6.0" >>(LANG) this is called ?old sequence iteration? or ?old-style >>iteration? with the (new) sequence protocol being augmented >>by ?__len__?. > > Can one say that the authoritative test for being ?iterable? > and being ?a sequence? is testing whether the object is an > instance of ?collections.abc.Iterable? and > ?collections.abc.Sequence?, respectively? > > Some parts of the references explain that implementing the > sequence protocol means to have a ?__getitem__? method and > possibly also a ?__len__? method. But, by inheritance, > ?collections.abc.Sequence? seems to require /more/. I.e., > >>>> import collections.abc > >>>> d = { 1: 2 } > >>>> d.__len__ > > >>>> d.__getitem__ > > >>>> isinstance( d, collections.abc.Sequence ) > False > > And the reference does /not/ list dictionary under "Sequences". A dictionary isn't a sequence. At very least, you have to be able to start with d[0] and go up from there; and that is indeed a valid *iterable* protocol: >>> class Demo: ... def __getitem__(self, item): ... item = int(item) ... if 0 <= item < 10: return item * item ... raise IndexError ... >>> list(Demo()) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] But that isn't a sequence still. Be careful that you aren't looking at *iterable* protocol instead. ChrisA From rosuav at gmail.com Mon Aug 28 16:08:24 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Aug 2017 06:08:24 +1000 Subject: a heisenbug In-Reply-To: References: Message-ID: On Tue, Aug 29, 2017 at 4:59 AM, Stefan Ram wrote: > This might be what one calls "heisenbug": > > No attribute 'abc' is visible. One tries to > study it with "help". And next time it's there. > "help" /did/ help! > > Python 3.6.0 ... > >>>> import collections > >>>> isinstance( 'abc', collections.abc.Sequence ) > Traceback (most recent call last): > File "", line 1, in > AttributeError: module 'collections' has no attribute 'abc' > >>>> help(collections) > Help on package collections: ... > >>>> isinstance( 'abc', collections.abc.Sequence ) > True When you import "collections", you load up the package. If anything subsequently runs "import collections.abc", the module gets loaded, and is visible from the package. The help function does exactly that import. It's a bit surprising but only an issue with interactive work. (You won't use help() elsewhere.) ChrisA From rosuav at gmail.com Mon Aug 28 16:14:18 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Aug 2017 06:14:18 +1000 Subject: A vocabulary trainer In-Reply-To: References: Message-ID: On Tue, Aug 29, 2017 at 5:42 AM, Stefan Ram wrote: > def main(): > v = random.choice( list( vocs.keys() )) Should be able to just use list(vocs) here. > print( v, end='' ) > input() input(v) should do the same job of issuing a prompt. > print( vocs[ v ]); > main() > Are there improvements possible (like shorter source code > or a better programming style)? (The recursion will be > replaced by ?while? as soon as ?while? is introduced.) Strongly recommend using a 'while' loop rather than recursion, even from the start. Don't teach bad practices and then replace them later. If you have to, do something like: while True: # don't worry about what this line does yet and then explain it later. Better to have a bit of magic that you later explain than bad code that people will copy and paste. > On the console, I used: > > i = input() > > just to hide the result of ?input()?. I only write to ?i?, > I do not read from it. JavaScript has ?void? to convert > something to ?undefined?. Is there a standard means in > Python to convert a value to ?None? (which also would have > the effect of not showing the value)? That's only an issue when you're working interactively, so I wouldn't worry about it. Either assign to a junk variable ("_ = whatever" is common) or just let it get printed. ChrisA From __peter__ at web.de Mon Aug 28 16:59:18 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 28 Aug 2017 22:59:18 +0200 Subject: A vocabulary trainer References: Message-ID: Stefan Ram wrote: > My course participants always are impatient for "useful > applications". So at a point in my course where no control > structures (if, for, while, ...) have been introduced yet, > but function calls, function declarations, assignments, > lists and dictionaries already were introduced, I wanted to > show a vocabulary trainer. > > One starts it by ?main()?. It then asks for a translation > of a word to German: > >>>> main() > table > > . Now, one can think about the answer and eventually press > return to see the answer: > > Tisch > horse > > and at the same time, the next question is shown. > > Here is the source code: > > vocs = { 'table': 'Tisch', 'book': 'Buch', 'rain': 'Regen', 'horse': > 'Pferd' } For this use case I would prefer a list of tuples word_pairs = [ ("table", "Tisch"), ... ] Then def main(): while True: en, de = random.choice(word_pairs) input(en) print(de) > import random > > def main(): > v = random.choice( list( vocs.keys() )) > print( v, end='' ) > input() > print( vocs[ v ]); > main() > > Are there improvements possible (like shorter source code > or a better programming style)? (The recursion will be > replaced by ?while? as soon as ?while? is introduced.) > > On the console, I used: > > i = input() > > just to hide the result of ?input()?. I only write to ?i?, > I do not read from it. JavaScript has ?void? to convert > something to ?undefined?. Is there a standard means in > Python to convert a value to ?None? (which also would have > the effect of not showing the value)? > From __peter__ at web.de Mon Aug 28 17:09:03 2017 From: __peter__ at web.de (Peter Otten) Date: Mon, 28 Aug 2017 23:09:03 +0200 Subject: a heisenbug References: Message-ID: Chris Angelico wrote: > On Tue, Aug 29, 2017 at 4:59 AM, Stefan Ram > wrote: >> This might be what one calls "heisenbug": >> >> No attribute 'abc' is visible. One tries to >> study it with "help". And next time it's there. >> "help" /did/ help! >> >> Python 3.6.0 ... >> >>>>> import collections >> >>>>> isinstance( 'abc', collections.abc.Sequence ) >> Traceback (most recent call last): >> File "", line 1, in >> AttributeError: module 'collections' has no attribute 'abc' >> >>>>> help(collections) >> Help on package collections: ... >> >>>>> isinstance( 'abc', collections.abc.Sequence ) >> True > > When you import "collections", you load up the package. If anything > subsequently runs "import collections.abc", the module gets loaded, > and is visible from the package. The help function does exactly that > import. It's a bit surprising but only an issue with interactive work. > (You won't use help() elsewhere.) The lesson is that if you use a (sub)module you should never rely on an implicit import. From m at funkyhat.org Mon Aug 28 17:24:05 2017 From: m at funkyhat.org (Matt Wheeler) Date: Mon, 28 Aug 2017 21:24:05 +0000 (UTC) Subject: Send mouse clicks to minimized window In-Reply-To: <43332eba-3286-4c76-8b0f-7eb86736d876@googlegroups.com> References: <43332eba-3286-4c76-8b0f-7eb86736d876@googlegroups.com> Message-ID: On Mon, 28 Aug 2017 at 12:30 wrote: > I'm using python to automate some seriously boring stuff at work, but > would like to improve current code. > > The way it is now, PyAutoGui moves mouse and clicks the Application. I am, > therefore, hostage of my python "assistant", as I cannot use my computer > while the .py is running. > Running your automation in a VM, or as a dedicated user if you're able to run it on a terminal server, is probably a more reliable option. > Is there any way to send mouse clicks to minimized windows, in so that it > does not interfere with normal using of my computer? > pywinauto [0] will happily send events to non-focussed & minimised windows as long as you don't need to use the _input() versions of the control methods. However doing that may cause the automated application to "steal" focus, so it might not help much with your desire to keep the computer usable (I'm not sure if this always happens, so it's worth trying). > I'm on Windows and have tried pywin32, but could not manage to make it to > work. Also tried ctypes, with same results. I'm really new to python. Also, > I could migrate to Linux if that's necessary. > What is the application that you're automating? Mentioning migrating to Linux as an option makes me wonder whether you are working with a web application, in which case selenium is probably a better option than a window-manager level automation tool (and will also solve the focus problem for you). [0] https://github.com/pywinauto/pywinauto -- -- Matt Wheeler http://funkyh.at From greg.ewing at canterbury.ac.nz Mon Aug 28 19:03:59 2017 From: greg.ewing at canterbury.ac.nz (Gregory Ewing) Date: Tue, 29 Aug 2017 11:03:59 +1200 Subject: a heisenbug In-Reply-To: References: Message-ID: Chris Angelico wrote: > It's a bit surprising but only an issue with interactive work. > (You won't use help() elsewhere.) Unless you decide to put help(collections) at the top of your program because it makes the bug go away. :-) -- Greg From rosuav at gmail.com Mon Aug 28 19:14:11 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Aug 2017 09:14:11 +1000 Subject: a heisenbug In-Reply-To: References: Message-ID: On Tue, Aug 29, 2017 at 9:03 AM, Gregory Ewing wrote: > Chris Angelico wrote: >> >> It's a bit surprising but only an issue with interactive work. >> (You won't use help() elsewhere.) > > > Unless you decide to put help(collections) at the top > of your program because it makes the bug go away. :-) That's not a heisenbug, then. It's cargo cult programming. :-) ChrisA From irmen.NOSPAM at xs4all.nl Mon Aug 28 19:20:18 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Tue, 29 Aug 2017 01:20:18 +0200 Subject: tkinter keypress events are a mess for numpad keys Message-ID: <59a4a532$0$789$e4fe514c@news.xs4all.nl> Hi, Using tkinter in python3, I was trying to intercept individual keypresses (and releases) of keys on the numeric keypad. I want to use this as a simple joystick simulation. While you can bind the event, actually doing something sensible with it in a cross platform way seems utterly impossible. The distinguishing attribute of the event object is different depending on what OS you're using (keysym, keycode, keysym_num) and on Windows registering some keys doesn't even seem to work (or they're confused with the same keys on the normal keyboard area). The keysym names/values in the documentation are not correct either (I'm mainly looking at http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/key-names.html) My original question with the details on stackoverflow: https://stackoverflow.com/questions/45869902/better-way-to-deal-with-tks-keyboard-events-mess-for-numpad-keys-in-pythontkin Unfortunately there hasn't been a useful response or answer. A gist with a small example program is here: https://gist.github.com/irmen/2c9d6bb0afb16b464805410c108a2885 Does anyone here have a clue perhaps? Or have any idea why this is so messy? Thank you! Irmen From ian.g.kelly at gmail.com Mon Aug 28 19:49:33 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Mon, 28 Aug 2017 17:49:33 -0600 Subject: Protocols in Python In-Reply-To: References: Message-ID: On Mon, Aug 28, 2017 at 12:53 PM, Stefan Ram wrote: > ram at zedat.fu-berlin.de (Stefan Ram) writes: >>The "The Python Library Reference, Release 3.6.0" (LIB) says: >>?it must support the sequence protocol (the >>__getitem__() method with integer arguments >>starting at 0).?. >>But in the "The Python Language Reference, Release 3.6.0" >>(LANG) this is called ?old sequence iteration? or ?old-style >>iteration? with the (new) sequence protocol being augmented >>by ?__len__?. > > Can one say that the authoritative test for being ?iterable? > and being ?a sequence? is testing whether the object is an > instance of ?collections.abc.Iterable? and > ?collections.abc.Sequence?, respectively? For Iterable, maybe. For Sequence, no. Sequence doesn't define a __subclasshook__ method, perhaps for reasons like your dict example. So the only subclasses of Sequence are those that either explicitly have Sequence in their MRO or are registered subclasses of Sequence: specifically, tuple, str, range, memoryview, bytes, bytearray and list (plus their subclasses). There are probably tons of legacy sequence types that aren't subclasses of Sequence. > Some parts of the references explain that implementing the > sequence protocol means to have a ?__getitem__? method and > possibly also a ?__len__? method. But, by inheritance, > ?collections.abc.Sequence? seems to require /more/. I.e., As noted above, there is no minimum set of methods that will cause Sequence to automatically consider something a subclass. From steve+python at pearwood.info Mon Aug 28 21:17:06 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 29 Aug 2017 11:17:06 +1000 Subject: a heisenbug References: Message-ID: <59a4c092$0$1584$c3e8da3$5496439d@news.astraweb.com> On Tue, 29 Aug 2017 07:09 am, Peter Otten wrote: > The lesson is that if you use a (sub)module you should never rely on an > implicit import. ... unless the module is documented as automatically importing the submodule. An example is os.path. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Mon Aug 28 21:24:10 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 29 Aug 2017 11:24:10 +1000 Subject: Quiz: Difference between implicit and explicit inheritence References: <59a3cc58$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <59a4c23b$0$1617$c3e8da3$5496439d@news.astraweb.com> On Mon, 28 Aug 2017 11:27 pm, Pavol Lisy wrote: > object = int # this could be trick > ... > class Spam(object): > ... > > dis.dis show difference too, next line is just for "class > Spam(object):" version: > LOAD_GLOBAL 0 (object) > > So nor rebinding object nor rebinding __builtin__.object affect "class > Spam:" version. Well done! That's exactly right. When you explicitly inherit from object, Python does a normal name lookup to determine what object is, and so if you have shadowed or rebound the name, you will inherit from whatever object happens to resolve to. When you implicitly inherit from object, the Python interpreter automatically uses the true builtin object as base class, even if it has been shadowed or rebound. See http://bugs.python.org/issue31283 -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From steve+python at pearwood.info Mon Aug 28 21:53:10 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Tue, 29 Aug 2017 11:53:10 +1000 Subject: doctest random output? References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Message-ID: <59a4c907$0$1598$c3e8da3$5496439d@news.astraweb.com> On Mon, 28 Aug 2017 07:41 pm, Leam Hall wrote: > Is this a good way to test if random numeric output? It seems to work > under Python 2.6 and 3.6 but that doesn't make it 'good'. That depends on what you are actually testing. If you are intending to test the statistical properties of random, google for the Die Hard tests and start by porting them to Python. But if you're just hoping to test your library's APIs, that's trickier than it seems. Unfortunately, Python doesn't guarantee that the exact output of the random module is stable across bug fix releases, except for random.random itself. So this is safe: def my_thing(): """blah blah blah >>> random.seed(45) >>> my_thing() # calls random.random 0.738270225794931 """ But this is not: def my_thing(): """blah blah blah >>> random.seed(45) >>> my_thing() # calls random.int 4 """ That makes doctesting anything related to random a PITA. Here are some suggestions, none of them are really great: (1) Disable doctesting for that example, and treat it as just documentation: def my_thing(): """blah blah blah >>> my_thing() #doctest:+SKIP 4 """ (2) Monkey-patch the random module for testing. This is probably the worst idea ever, but it's an idea :-) def my_thing(): """blah blah blah >>> import random >>> save = random.randint >>> try: ... random.randint = lambda a, b: 4 ... my_thing() ... finally: ... random.randint = save 4 """ That makes for a fragile test and poor documentation. (3) Write your functions to take an optional source of randomness, and then in your doctests set them: def my_thing(randint=None): """blah blah blah >>> my_thing(randint=lambda a,b: 4) 4 """ if randint is None: from random import randint ... (4) Write your doctests to test the most general properties of the returned results: def my_thing(randint=None): """blah blah blah >>> num = my_thing() >>> isinstance(num, int) and 0 <= my_thing() <= 6 True """ -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rosuav at gmail.com Mon Aug 28 22:25:45 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Aug 2017 12:25:45 +1000 Subject: doctest random output? In-Reply-To: <59a4c907$0$1598$c3e8da3$5496439d@news.astraweb.com> References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> <59a4c907$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Tue, Aug 29, 2017 at 11:53 AM, Steve D'Aprano wrote: > (1) Disable doctesting for that example, and treat it as just documentation: > > def my_thing(): > """blah blah blah > > >>> my_thing() #doctest:+SKIP > 4 > > """ For a lot of functions, this completely destroys the value of doctesting. > (2) Monkey-patch the random module for testing. This is probably the worst idea > ever, but it's an idea :-) > > That makes for a fragile test and poor documentation. This highlights the inherent weakness of doctests. For proper unit testing, I would definitely recommend this. Maybe a hybrid of 1 and 2 could be organized... hmm. > (3) Write your functions to take an optional source of randomness, and then in > your doctests set them: > > def my_thing(randint=None): > """blah blah blah > > >>> my_thing(randint=lambda a,b: 4) > 4 > > """ > if randint is None: > from random import randint > ... Unless that would be useful for other reasons, not something I like doing. Having code in your core that exists solely (or even primarily) to make testing easier seems like doing things backwards. > (4) Write your doctests to test the most general properties of the returned > results: > > > def my_thing(randint=None): > """blah blah blah > > >>> num = my_thing() > >>> isinstance(num, int) and 0 <= my_thing() <= 6 > True > > """ This is what I'd probably do, tbh. None of the options really appeal though. Personally, I'd probably either go with #4, or maybe something like this: def roll(sequence): """Roll a set of dice >>> from test_mymodule import * # ensure stable RNG >>> roll("d12 + 2d6 + 3") You roll d12: 8 You roll 2d6: 1, 6, totalling 7. You add a bonus of 3 For d12 + 2d6 + 3, you total: 18 """ and bury all the monkey-patching into test_mymodule. It can have its own implementations of randint and whatever else you use. That way, at least there's only one line that does the messing around. I still don't like it though - so quite honestly, I'm most likely to go the route of "don't actually use doctests". ChrisA From tjreedy at udel.edu Tue Aug 29 00:32:24 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 29 Aug 2017 00:32:24 -0400 Subject: tkinter keypress events are a mess for numpad keys In-Reply-To: <59a4a532$0$789$e4fe514c@news.xs4all.nl> References: <59a4a532$0$789$e4fe514c@news.xs4all.nl> Message-ID: On 8/28/2017 7:20 PM, Irmen de Jong wrote: > Hi, > > Using tkinter in python3, I was trying to intercept individual keypresses (and releases) > of keys on the numeric keypad. I want to use this as a simple joystick simulation. > While you can bind the event, actually doing something sensible with it in a > cross platform way seems utterly impossible. > > The distinguishing attribute of the event object is different depending on what OS > you're using (keysym, keycode, keysym_num) and on Windows registering some keys doesn't > even seem to work (or they're confused with the same keys on the normal keyboard area). > The keysym names/values in the documentation are not correct either > (I'm mainly looking at http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/key-names.html) *The* documentation (for 8.6) is the tcl.tk/man doc set: https://www.tcl.tk/man/tcl8.6/TkCmd/contents.htm For the level of detail you are looking at, they are essential. The nmt docs for 8.5 are neither complete (intentionally not) nor always correct nor always up to date. The tk docs may also have errors, just as our do, but I presume one can file a report somewhere and possibly get a fix. > My original question with the details on stackoverflow: > https://stackoverflow.com/questions/45869902/better-way-to-deal-with-tks-keyboard-events-mess-for-numpad-keys-in-pythontkin > > Unfortunately there hasn't been a useful response or answer. > > A gist with a small example program is here: > https://gist.github.com/irmen/2c9d6bb0afb16b464805410c108a2885 > > Does anyone here have a clue perhaps? > Or have any idea why this is so messy? -- Terry Jan Reedy From __peter__ at web.de Tue Aug 29 02:49:34 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 29 Aug 2017 08:49:34 +0200 Subject: a heisenbug References: <59a4c092$0$1584$c3e8da3$5496439d@news.astraweb.com> Message-ID: Steve D'Aprano wrote: > On Tue, 29 Aug 2017 07:09 am, Peter Otten wrote: > >> The lesson is that if you use a (sub)module you should never rely on an >> implicit import. > > ... unless the module is documented as automatically importing the > submodule. An example is os.path. os.path is the only exception that I know of, and it's used so often that it may teach you bad habits. From ole-usenet-spam at gmx.net Tue Aug 29 02:56:18 2017 From: ole-usenet-spam at gmx.net (=?utf-8?B?0J5s0LUg0IV0ctC10ZbRgWjQtXI=?=) Date: Tue, 29 Aug 2017 08:56:18 +0200 Subject: Swig and distutils Message-ID: <87mv6i50bx.fsf@gmx.net> Hi, I want to write a setup.py for a module from a swig source. The recommended way [1] does not work because it does not process the generated Python file. Searching on Stackoverflow gives an (ugly) workaround and the hint "this may be considered as a bug" [2]. However, I couldn't find a distutils bug or a discussion why this is not changed (the problems seems to be already >5 years old). Is there a rationale behind the current behauviour? And shouldn't that documented in the Python distutils documentation? [1] is very misleading here then. I have another problem with the current setup: I am using a directory structure where setup.py resides outside of the current sources (since it is generated by a CMakeFile) in the build directory. That means that I have to use the "package_dir" argument of setup.py. This however has two drawbacks: 1. It does not apply to ext_modules: how can I do that? 2. The Python code generated by swig will/should be placed in the build dir (since it is generated), so they are not found when the package_dir is set to the source directory. When I set package_dir to the build directory, then the other Python source files are not found. How can I specify both directories here? One workaround would be to just call the setup function twice: First with the existing Python source and the swig C sources, and then with the Python sources generated from swig: ---------------------8<-------------------------------- from distutils.core import setup, Extension setup(name="my", version="1.0", package_dir={"my": "../../src"} py_modules=["my"], ext_modules=[ Extension("_my_c", ["my_c.i"]) # specify source dir of my_c.i here? ]) setup(name="my", version="1.0", py_modules=["my_c"]) ---------------------8<-------------------------------- Although I didn't find any documentation that forbids calling the setup function twice, I also did not find an example where this is done. Would that work? Best regards Ole [1] https://docs.python.org/3.6/distutils/setupscript.html#extension-source-files [2] https://stackoverflow.com/questions/17666018/using-distutils-where-swig-interface-file-is-in-src-folder?rq=1 From steve+comp.lang.python at pearwood.info Tue Aug 29 03:39:07 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 29 Aug 2017 07:39:07 GMT Subject: doctest random output? References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> <59a4c907$0$1598$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59a51a1b$0$2920$c3e8da3$76491128@news.astraweb.com> On Tue, 29 Aug 2017 12:25:45 +1000, Chris Angelico wrote: > On Tue, Aug 29, 2017 at 11:53 AM, Steve D'Aprano > wrote: >> (1) Disable doctesting for that example, and treat it as just >> documentation: >> >> def my_thing(): >> """blah blah blah >> >> >>> my_thing() #doctest:+SKIP >> 4 >> >> """ > > For a lot of functions, this completely destroys the value of > doctesting. "The" value? Doc tests have two values: documentation (as examples of use) and as tests. Disabling the test aspect leaves the value as documentation untouched, and arguably is the least-worst result. You can always write a unit test suite to perform more detailed, complicated tests. Doc tests are rarely exhaustive, so you need unit tests as well. >> (2) Monkey-patch the random module for testing. This is probably the >> worst idea ever, but it's an idea :-) >> >> That makes for a fragile test and poor documentation. > > This highlights the inherent weakness of doctests. For proper unit > testing, I would definitely recommend this. Maybe a hybrid of 1 and 2 > could be organized... hmm. Doc tests should be seen as *documentation first* and tests second. The main roll of the tests is to prove that the documented examples still do what you say they do. It makes for a horrible and uninformative help() experience to have detailed, complex, exhaustive doc tests exercising every little corner case of your function. That should go in your unit tests. Possibly relevant: the unittest module has functionality to automatically extract and run your library's doctests, treating them as unit tests. So you can already do both. >> (3) Write your functions to take an optional source of randomness, and >> then in your doctests set them: >> >> def my_thing(randint=None): >> """blah blah blah >> >> >>> my_thing(randint=lambda a,b: 4) >> 4 >> >> """ >> if randint is None: >> from random import randint >> ... > > Unless that would be useful for other reasons, not something I like > doing. Having code in your core that exists solely (or even primarily) > to make testing easier seems like doing things backwards. I see your point, and I don't completely disagree. I'm on the fence about this one. But testing is important, and we often write code to make testing easier, e.g. pulling out a complex but short bit of code into its own function so we can test it, using dependency injection, etc. Why shouldn't we add hooks to enable testing? Not every function needs such a hook, but some do. See, for example, "Enemies of Test Driven Development": https://jasonmbaker.wordpress.com/2009/01/08/enemies-of-test-driven- development-part-i-encapsulation/ In Python, we have the best of both worlds: we can flag a method as private, and *still* test it! So in a sense, Python's very design has been created specifically to allow testing. For a dissenting view, "Are Private Methods a Code Smell?": http://carlosschults.net/en/are-private-methods-a-code-smell/ >> (4) Write your doctests to test the most general properties of the >> returned results: >> >> >> def my_thing(randint=None): >> """blah blah blah >> >> >>> num = my_thing() >> >>> isinstance(num, int) and 0 <= my_thing() <= 6 >> True >> >> """ > > This is what I'd probably do, tbh. Sometimes that's sufficient. Sometimes its not. It depends on the function. For example, imagine a function that returns a randomly selected prime number. The larger the prime, the less likely it is to be selected, but there's no upper limit. So you write: >>> num = my_thing() >>> isinstance(num, int) and 2 <= num True Not very informative as documentation, and a lousy test too. > None of the options really appeal though. Personally, I'd probably > either go with #4, or maybe something like this: > > def roll(sequence): > """Roll a set of dice > > >>> from test_mymodule import * # ensure stable RNG > >>> roll("d12 + 2d6 + 3") > You roll d12: 8 You roll 2d6: 1, 6, totalling 7. > You add a bonus of 3 For d12 + 2d6 + 3, you total: 18 > """ > > and bury all the monkey-patching into test_mymodule. Wait... are you saying that importing test_mymodule monkey-patches the current library? And doesn't un-patch it afterwards? That's horrible. Or are you saying that test_module has its own version of roll(), and so you're using *that* version instead of the one in the library? That's horrible too. I think that once you are talking about monkey-patching things in order to test them, you should give up on doc tests and use unittest instead. At least then you get nice setUp and tearDown methods that you can use. > It can have its own > implementations of randint and whatever else you use. That way, at least > there's only one line that does the messing around. I still don't like > it though - so quite honestly, I'm most likely to go the route of "don't > actually use doctests". Are you saying don't use doctests for *this* problem, or don't use them *at all*? -- Steven D'Aprano ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From rosuav at gmail.com Tue Aug 29 04:40:35 2017 From: rosuav at gmail.com (Chris Angelico) Date: Tue, 29 Aug 2017 18:40:35 +1000 Subject: doctest random output? In-Reply-To: <59a51a1b$0$2920$c3e8da3$76491128@news.astraweb.com> References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> <59a4c907$0$1598$c3e8da3$5496439d@news.astraweb.com> <59a51a1b$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: On Tue, Aug 29, 2017 at 5:39 PM, Steven D'Aprano wrote: > On Tue, 29 Aug 2017 12:25:45 +1000, Chris Angelico wrote: > >> For a lot of functions, this completely destroys the value of >> doctesting. > > > "The" value? Doc tests have two values: documentation (as examples of > use) and as tests. Disabling the test aspect leaves the value as > documentation untouched, and arguably is the least-worst result. You can > always write a unit test suite to perform more detailed, complicated > tests. Doc tests are rarely exhaustive, so you need unit tests as well. You can have a docstring that isn't crafted to be runnable tests. The point about doc tests is that they're executable documentation - the point of them is to be tests, not just docs. You can always write your unit tests separately, and let your docstrings merely be documentation, and then none of this matters. > For example, imagine a function that returns a randomly selected prime > number. The larger the prime, the less likely it is to be selected, but > there's no upper limit. So you write: > > >>> num = my_thing() > >>> isinstance(num, int) and 2 <= num > True > > > Not very informative as documentation, and a lousy test too. Yes, but you could have some sort of primality test on it. >>> is_prime(my_thing()) True Even if all you have is a "probably prime" test, that would still make for better documentation AND better testing than no test at all. > Wait... are you saying that importing test_mymodule monkey-patches the > current library? And doesn't un-patch it afterwards? That's horrible. > > Or are you saying that test_module has its own version of roll(), and so > you're using *that* version instead of the one in the library? > > That's horrible too. My original plan was to have *a function in* that module that does the monkey-patching, but I seem to have not actually typed that part in... mea culpa. I agree that merely importing your test helpers shouldn't do the changes! Even with "import test_mymodule; test_mymodule.stable()" it's still just one extra line (better than the full version). Not un-patching it afterwards? Yes. Since part of its purpose is to seed the RNG with a fixed value, it's not really possible or practical to "undo" that, and so I wouldn't worry too much about an "afterwards" - after testing, you exit the interpreter, if you want to get back to normality. >> It can have its own >> implementations of randint and whatever else you use. That way, at least >> there's only one line that does the messing around. I still don't like >> it though - so quite honestly, I'm most likely to go the route of "don't >> actually use doctests". > > Are you saying don't use doctests for *this* problem, or don't use them > *at all*? For this and any other problem where doctesting is impractical. Because let's face it, laziness is a big thing. If it's too much hassle to make a docstring executable, I'm just not going to make it executable. Which has the unfortunate downside of allowing the docstrings to get out of sync with the code, but that's the cost. ChrisA From __peter__ at web.de Tue Aug 29 05:11:59 2017 From: __peter__ at web.de (Peter Otten) Date: Tue, 29 Aug 2017 11:11:59 +0200 Subject: To mock/patch or not to, was Re: doctest random output? References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> <59a4c907$0$1598$c3e8da3$5496439d@news.astraweb.com> <59a51a1b$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: Steven D'Aprano wrote: > Wait... are you saying that importing test_mymodule monkey-patches the > current library? And doesn't un-patch it afterwards? That's horrible. There's something in the library, unittest.mock that makes this relatively safe -- if not painless with mock.patch("random.randint", side_effect=[42]) as randint: self.assertEqual(my_module.my_thing(), 42) randint.assert_called_once_with(1, 6) and sometimes monkey-patching may be a necessary evil to verify that a portion of the code that is buried a bit too deep is called as expected. However, in this case it tests that the code is what it is rather than what it does. Good tests would allow for replacing random.randint() with random.randrange() or random.SystemRandom().randrange() and still succeed. From azadbekm at gmail.com Tue Aug 29 06:59:08 2017 From: azadbekm at gmail.com (Yusuf Mohammad) Date: Tue, 29 Aug 2017 12:59:08 +0200 Subject: IDLE won't install on manual installation In-Reply-To: References: Message-ID: Hi! i want to ask my question again. I have now subscribed to the list. I'll just copy and past it here again: Hi! My name is Yusuf Mohammad. I work for a hospital in Norway and we plan to use python to program a mobile application. I have a admin account on my computer and i am trying to install python with the manual option. The reason so that it can be stored in the C:/Program files (x86) section so that the applicaton does not auto uninstall when the computer is turned off (don't know why it does that, but it's standard on our work computers): After installing Python with the manual option, i can't seem to find IDLE. Any suggestions? Kindly Yusuf Mohammad 2017-08-28 8:57 GMT+02:00 Yusuf Mohammad : > Hi! My name is Yusuf Mohammad. I work for a hospital in Norway and we plan > to use python to program a mobile application. > > I have a admin account on my computer and i am trying to install python > with the manual option. The reason so that it can be stored in the > C:/Program files (x86) section so that the applicaton does not auto > uninstall when the computer is turned off (don't know why it does that, but > it's standard on our work computers): > > After installing Python with the manual option, i can't seem to find IDLE. > Any suggestions? > > Kindly > > Yusuf Mohammad > From pavol.lisy at gmail.com Tue Aug 29 09:15:31 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Tue, 29 Aug 2017 15:15:31 +0200 Subject: doctest random output? In-Reply-To: References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Message-ID: On 8/28/17, Leam Hall wrote: > On 08/28/2017 11:40 AM, Dennis Lee Bieber wrote: > > ... a bunch of good stuff ... > > I'm (re-)learning python and just trying make sure my function works. > Not at the statistical or cryptographic level. :) > > Thanks! > > Leam > -- > https://mail.python.org/mailman/listinfo/python-list > I am not sure what is best practice but I would use sys.exit to propagate failure (for better scripting possibility). For example: if __name__ == "__main__": import doctest import sys sys.exit(doctest.testmod()[0]) But maybe I am wrong and non zero exit status is just for errors in code? --- If you don't need something at scientific level (which is hard, see: https://www.random.org/analysis/ ) you could probably use fact that random sequences are "hard" to compress. For example something like this could help -> >>> import zlib >>> A = [my_thing() for i in range(100)] >>> 50 < len(zlib.compress(bytes(A))) < 70 True But be careful!! Other randint parameters would need other limit values! # for randint(1,6) you have distribution of lengths like this collections.Counter(len(zlib.compress(bytes(random.randint(1,6) for i in range(100)))) for j in range(100000)) Counter({55: 1, 56: 46, 57: 834, 58: 7349, 59: 31035, 60: 42884, 61: 16434, 62: 1397, 63: 20}) # but for randint(1,16) you have distribution like this! collections.Counter(len(zlib.compress(bytes(random.randint(1,16) for i in range(100)))) for j in range(100000)) Counter({71: 4, 72: 412, 73: 11291, 74: 27392, 75: 28293, 76: 29103, 77: 3296, 78: 209}) So maybe it help you, maybe not :) From shazianusra at gmail.com Tue Aug 29 11:22:48 2017 From: shazianusra at gmail.com (shazianusra at gmail.com) Date: Tue, 29 Aug 2017 08:22:48 -0700 (PDT) Subject: Latency for API call to a Python Function Message-ID: Hi, I have an issue with one piece of code in Python that when my API using Nginx/Uwsgi/EC2 AWS calls this function it causes latency. I need help to figure out if there is I am doing something wrong with this particular function. Rest of the code calls for DB are working fine and no issues. But only this piece of code is causing latency. def getvideos(self, listitem): channelId = "" returnVideos,dictData = {},{} mode = 0 channelId = listitem[KEY_CHANNELID] if KEY_CHANNELMODE in listitem : mode = int(listitem[KEY_CHANNELMODE]) filteredVideos = [] if mode == 0: filteredVideos = self.getFilteredVideos(listitem) if mode == 1: filteredVideos = self.getFocus(listitem) if mode == 2: filteredVideos = self.getFavourites(listitem) newFilteredVideos = [] print "Returning videos : ",filteredVideos if filteredVideos == None or len(filteredVideos) == 0: print "\n\n\n\tWe are returning NO filteredVideos !" #filteredVideos = list(set(filteredVideos)) dictData[KEY_SERVICE] = SERVICE_GETVIDEOS dictData[KEY_CHANNELID] = str(channelId) if len(filteredVideos) > 0 : dictData[KEY_VIDEOS] = self.returnVideos(filteredVideos) else : dictData[KEY_VIDEOS] = {} dictData[KEY_VIDEOS][KEY_STATUS] = 'No Videos' returnVideos[TAG_IRON] = dictData return json.dumps(returnVideos) Looking forward, Regards, Shazia From tjreedy at udel.edu Tue Aug 29 11:38:46 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Tue, 29 Aug 2017 11:38:46 -0400 Subject: Latency for API call to a Python Function In-Reply-To: References: Message-ID: On 8/29/2017 11:22 AM, shazianusra at gmail.com wrote: > def getvideos(self, listitem): > channelId = "" > returnVideos,dictData = {},{} > mode = 0 > channelId = listitem[KEY_CHANNELID] > if KEY_CHANNELMODE in listitem : > mode = int(listitem[KEY_CHANNELMODE]) > filteredVideos = [] ... Please make code readable by indenting properly, *with spaces*. Guessing at what you meant: def getvideos(self, listitem): channelId = "" returnVideos,dictData = {},{} mode = 0 channelId = listitem[KEY_CHANNELID] if KEY_CHANNELMODE in listitem : mode = int(listitem[KEY_CHANNELMODE]) filteredVideos = []. ... If you posted with tab indents, they disappeared, as is common with news/mail. -- Terry Jan Reedy From python at mrabarnett.plus.com Tue Aug 29 11:47:32 2017 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 29 Aug 2017 16:47:32 +0100 Subject: Latency for API call to a Python Function In-Reply-To: References: Message-ID: <2f2c9b45-3301-fdfd-7b3e-8d3610bee693@mrabarnett.plus.com> On 2017-08-29 16:22, shazianusra at gmail.com wrote: > Hi, > > I have an issue with one piece of code in Python that when my API using Nginx/Uwsgi/EC2 AWS calls this function it causes latency. I need help to figure out if there is I am doing something wrong with this particular function. Rest of the code calls for DB are working fine and no issues. But only this piece of code is causing latency. > > def getvideos(self, listitem): > channelId = "" > returnVideos,dictData = {},{} > mode = 0 > channelId = listitem[KEY_CHANNELID] > if KEY_CHANNELMODE in listitem : > mode = int(listitem[KEY_CHANNELMODE]) > filteredVideos = [] > > if mode == 0: > filteredVideos = self.getFilteredVideos(listitem) > > if mode == 1: > filteredVideos = self.getFocus(listitem) > > if mode == 2: > filteredVideos = self.getFavourites(listitem) > newFilteredVideos = [] > > print "Returning videos : ",filteredVideos > if filteredVideos == None or len(filteredVideos) == 0: > print "\n\n\n\tWe are returning NO filteredVideos !" > #filteredVideos = list(set(filteredVideos)) > dictData[KEY_SERVICE] = SERVICE_GETVIDEOS > dictData[KEY_CHANNELID] = str(channelId) > if len(filteredVideos) > 0 : > dictData[KEY_VIDEOS] = self.returnVideos(filteredVideos) > else : > dictData[KEY_VIDEOS] = {} > dictData[KEY_VIDEOS][KEY_STATUS] = 'No Videos' > returnVideos[TAG_IRON] = dictData > return json.dumps(returnVideos) > > Looking forward, > > Regards, > Shazia > It's difficult to read the code because it's not indented correctly. At first glance, the latency might not be in this method itself, but in one of the other methods it calls. Another possibility is that somewhere you're using a list where a set or dict might be better, e.g. doing a search (it'll be a linear search on a list). From shazianusra at gmail.com Tue Aug 29 12:08:13 2017 From: shazianusra at gmail.com (shazianusra at gmail.com) Date: Tue, 29 Aug 2017 09:08:13 -0700 (PDT) Subject: Latency for API call to a Python Function In-Reply-To: References: <2f2c9b45-3301-fdfd-7b3e-8d3610bee693@mrabarnett.plus.com> Message-ID: <8860f090-027e-46b1-b87b-662ef97e04e0@googlegroups.com> You mean recursive linear search? Or is there a way I can test all my code with multiple files to see which function is causing issue? From irmen.NOSPAM at xs4all.nl Tue Aug 29 13:16:27 2017 From: irmen.NOSPAM at xs4all.nl (Irmen de Jong) Date: Tue, 29 Aug 2017 19:16:27 +0200 Subject: tkinter keypress events are a mess for numpad keys In-Reply-To: References: <59a4a532$0$789$e4fe514c@news.xs4all.nl> Message-ID: <59a5a16b$0$752$e4fe514c@news.xs4all.nl> On 29/08/2017 06:32, Terry Reedy wrote: > *The* documentation (for 8.6) is the tcl.tk/man doc set: > https://www.tcl.tk/man/tcl8.6/TkCmd/contents.htm > For the level of detail you are looking at, they are essential. > > The nmt docs for 8.5 are neither complete (intentionally not) nor always correct nor > always up to date.? The tk docs may also have errors, just as our do, but I presume one > can file a report somewhere and possibly get a fix. Hi Terry thanks for pointing me to that resource. I'll have a look at https://www.tcl.tk/man/tcl8.6/TkCmd/keysyms.htm but I don't have high hopes because I already tried empirically to figure out the distinguishing attributes of the keypress event object, on various platforms (Mac OS, Linux, Windows)... Irmen. From python at mrabarnett.plus.com Tue Aug 29 13:40:15 2017 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 29 Aug 2017 18:40:15 +0100 Subject: Latency for API call to a Python Function In-Reply-To: <8860f090-027e-46b1-b87b-662ef97e04e0@googlegroups.com> References: <2f2c9b45-3301-fdfd-7b3e-8d3610bee693@mrabarnett.plus.com> <8860f090-027e-46b1-b87b-662ef97e04e0@googlegroups.com> Message-ID: <0983897b-f4f0-75d9-8f26-b6e1d7760fa8@mrabarnett.plus.com> On 2017-08-29 17:08, shazianusra at gmail.com wrote: > > > You mean recursive linear search? Or is there a way I can test all my code with multiple files to see which function is causing issue? > You can just put some timing around the methods that might be a problem, writing to a logfile. Process a few files and then look at the logfile to see whether any of those methods took longer than expected. From rosuav at gmail.com Tue Aug 29 14:04:09 2017 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 30 Aug 2017 04:04:09 +1000 Subject: doctest random output? In-Reply-To: References: <5204f70c-0a61-be42-6f94-01231defc312@gmail.com> Message-ID: On Wed, Aug 30, 2017 at 1:39 AM, Stefan Ram wrote: > Dennis Lee Bieber writes: >>Testing randomness itself requires statistical tests... > > A perfectly random coin /can/ yield "heads" a thousand times > in sequence (which is very unlikely, but possible). > > This behavior should fail nearly all statistical tests for > randomness. Yet the generator was perfectly random. > > So the tests for randomness give correct answers only with > a certain probability ("confidence"). Insofar the concept of > randomness is "fuzzy" when defined as an observable > property of an otherwise "black box". > > The tests in the OP test only what one can test with > certainity, which might be reasonable. > > To gain confidence in a function providing sufficiently > "random" results other measures might be added, such as > a code review (view the generator as a "white box"). The point of unit testing (of which doctests are a form) is generally that you test THIS function, without needing to test everything else. Testing whether random.random() is "sufficiently random" is not the point of the doctest. For a non-trivial example, consider my dice roller; I don't have a Python function for it, but it's a feature of my D&D MUD. You pass it a string that details the dice you want to roll, and it rolls them: >>> roll d20 You roll d20: 3 >>> roll d20 + 5 You roll d20: 14 You add a bonus of 5 For d20 + 5, you total: 19 >>> roll 3d6+ d8 -2 You roll 3d6: 1, 5, 5, totalling 11. You roll d8: 2 You add a bonus of -2 For 3d6+ d8 -2, you total: 11 This is fine as documentation. The trouble is that, for testing, we have to logically accept any integer from 1 to 20 as "correct", and doctest doesn't support that. I don't care, in this test, whether the dice roller is "fair" (that it has equal probability of returning each value) - what I care about is whether, when you enter a particular string of dice descriptions, you get back a proper pattern of rolls. And I don't think doctest is flexible enough to handle this without some sort of monkeypatching - unless you code your function to use NOTHING other than random.random(), and then you can reliably just seed the RNG. ChrisA From knon060718 at gmail.com Tue Aug 29 15:10:30 2017 From: knon060718 at gmail.com (Bear Light) Date: Wed, 30 Aug 2017 03:10:30 +0800 Subject: pip which should be installed with Python3.62 doesn't work in windows Message-ID: I found many rookies like me asking similar question: why "pip" is not recognized by cmd? I install Python 3.62 64bit in Win10 and I'm sure I add PATH, the Python tutorial doesn't even mention about PATH. You can see the following picture showing the tutorial doesn't work. Please give a hand to the helpless rookies and me. [image: ???? 1] tutorials url: https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments From saxri89 at gmail.com Tue Aug 29 15:39:07 2017 From: saxri89 at gmail.com (Xristos Xristoou) Date: Tue, 29 Aug 2017 12:39:07 -0700 (PDT) Subject: automatically set field values in django using function Message-ID: <4d9dab06-e367-48cd-8e66-67b66a71a4f8@googlegroups.com> I need t define some values of fields automatically in my model using function. my function get input image path and calculate and I need that calculation results to define my database fields in Django. but first the upload image need to get the path in server and after i can to define the values.. i will test this but myfunc cant understand the image path from upload image. here the code : def myview(request): uploadimages = UploadImagesForm(request.POST or None, request.FILES or None) if uploadimages.is_valid(): # Get the images that have been browsed if request.FILES.get('multipleimages', None) is not None: images = request.FILES.getlist('multipleimages') for image in images: instance = MyModel.objects.create(field1=request.user, field2=image) instance.field3 = myfunc(image) instance.field4 = myfunc(image) instance.save() From python at mrabarnett.plus.com Tue Aug 29 17:03:49 2017 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 29 Aug 2017 22:03:49 +0100 Subject: pip which should be installed with Python3.62 doesn't work in windows In-Reply-To: References: Message-ID: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> On 2017-08-29 20:10, Bear Light wrote: > I found many rookies like me asking similar question: why "pip" is not > recognized by cmd? > I install Python 3.62 64bit in Win10 and I'm sure I add PATH, the Python > tutorial doesn't even mention about PATH. > You can see the following picture showing the tutorial doesn't work. This newsgroup is text-only. > Please give a hand to the helpless rookies and me. > > [image: ???? 1] > tutorials url: > https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments > The best way is to use the Python "launcher" py.exe, which should be on the search path, so instead of, say: pip install regex you would write: py -3.6 -m pip install regex This ensures that it's installed into the correct version of Python (in this case v3.6). From knon060718 at gmail.com Tue Aug 29 23:47:04 2017 From: knon060718 at gmail.com (Bear Light) Date: Wed, 30 Aug 2017 11:47:04 +0800 Subject: pip which should be installed with Python3.62 doesn't work inwindows In-Reply-To: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> References: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> Message-ID: <59a6353a.caa0620a.bfb35.19a9@mx.google.com> Thanks for help but it doesn?t work. (cmd) C:\Users\user>py -3.6 -m pip install regex C:\Program Files\Python36\python.exe: No module named pip The picture that I attached showed similar result. Though you can see the option of installing pip during python3 installing, the command about pip doesn?t work. I can install pip manually, but according to the tutorials, it shouldn?t be necessary. What?s more, though people say you can find something like pip.py or pip3.py in the Python36/scripts folder, there is nothing in the scripts folder for me. Is it unusual? ???: MRAB ????: 2017?8?30? ?? 05:07 ???: python-list at python.org ??: Re: pip which should be installed with Python3.62 doesn't work inwindows On 2017-08-29 20:10, Bear Light wrote: > I found many rookies like me asking similar question: why "pip" is not > recognized by cmd? > I install Python 3.62 64bit in Win10 and I'm sure I add PATH, the Python > tutorial doesn't even mention about PATH. > You can see the following picture showing the tutorial doesn't work. This newsgroup is text-only. > Please give a hand to the helpless rookies and me. > > [image: ???? 1] > tutorials url: > https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments > The best way is to use the Python "launcher" py.exe, which should be on the search path, so instead of, say: pip install regex you would write: py -3.6 -m pip install regex This ensures that it's installed into the correct version of Python (in this case v3.6). -- https://mail.python.org/mailman/listinfo/python-list From dieter at handshake.de Wed Aug 30 02:58:57 2017 From: dieter at handshake.de (dieter) Date: Wed, 30 Aug 2017 08:58:57 +0200 Subject: Latency for API call to a Python Function References: Message-ID: <87378935ji.fsf@handshake.de> shazianusra at gmail.com writes: > I have an issue with one piece of code in Python that when my API using Nginx/Uwsgi/EC2 AWS calls this function it causes latency. In those cases, I proceed as follows: * structure the code in a way that it can be called in an interactive Python interpreter (if your Web framework does not directly support profiling) * use profiling (see the "profile" module in the Python library; there are also C variants (-> "cProfile", "hotspot"). to find out where latency is introduced From knon060718 at gmail.com Wed Aug 30 03:16:07 2017 From: knon060718 at gmail.com (Bear Light) Date: Wed, 30 Aug 2017 15:16:07 +0800 Subject: pip which should be installed with Python3.62 doesn't workinwindows In-Reply-To: <59a6353a.caa0620a.bfb35.19a9@mx.google.com> References: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> <59a6353a.caa0620a.bfb35.19a9@mx.google.com> Message-ID: <59a66639.4bee240a.c8e9.b72d@mx.google.com> I finally solve the problem with Python?3.5.4? The pip-related files are correctly installed into ?scripts?, and I can use the pip command now. I try to install Python ?3.6.2? which was released on 2017-07-17 again, and then there?s still no files in ?scripts?. I still don?t know why but at least the problem killing me lots of time was solved, thx to everyone who saw this mail. ???: Bear Light ????: 2017?8?30? ?? 11:47 ???: python-list at python.org ??: RE: pip which should be installed with Python3.62 doesn't workinwindows Thanks for help but it doesn?t work. (cmd) C:\Users\user>py -3.6 -m pip install regex C:\Program Files\Python36\python.exe: No module named pip The picture that I attached showed similar result. Though you can see the option of installing pip during python3 installing, the command about pip doesn?t work. I can install pip manually, but according to the tutorials, it shouldn?t be necessary. What?s more, though people say you can find something like pip.py or pip3.py in the Python36/scripts folder, there is nothing in the scripts folder for me. Is it unusual? ???: MRAB ????: 2017?8?30? ?? 05:07 ???: python-list at python.org ??: Re: pip which should be installed with Python3.62 doesn't work inwindows On 2017-08-29 20:10, Bear Light wrote: > I found many rookies like me asking similar question: why "pip" is not > recognized by cmd? > I install Python 3.62 64bit in Win10 and I'm sure I add PATH, the Python > tutorial doesn't even mention about PATH. > You can see the following picture showing the tutorial doesn't work. This newsgroup is text-only. > Please give a hand to the helpless rookies and me. > > [image: ???? 1] > tutorials url: > https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments > The best way is to use the Python "launcher" py.exe, which should be on the search path, so instead of, say: ???? pip install regex you would write: ???? py -3.6 -m pip install regex This ensures that it's installed into the correct version of Python (in this case v3.6). -- https://mail.python.org/mailman/listinfo/python-list From kevinalejandromolina at gmail.com Wed Aug 30 08:39:53 2017 From: kevinalejandromolina at gmail.com (kevinalejandromolina at gmail.com) Date: Wed, 30 Aug 2017 05:39:53 -0700 (PDT) Subject: trouble consuming null data from wsdl with suds.client Message-ID: <5ac6e972-dff1-4c20-8fbe-a9c28915e5b7@googlegroups.com> i was trying to consume the service but i always have the same error, look over the error message, and i am think that the error is, the suds library does not support null values on the attributes. >>> r=client.service.WSOBTENERINTERRUPCIONWEB(1,1) Traceback (most recent call last): File "", line 1, in File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\client.py", line 542, in __call__ return client.invoke(args, kwargs) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\client.py", line 602, in invoke result = self.send(soapenv) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\client.py", line 643, in send result = self.succeeded(binding, reply.message) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\client.py", line 678, in succeeded reply, result = binding.get_reply(self.method, reply) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\bindings\binding.py", line 165, in get_reply result = unmarshaller.process(nodes[0], resolved) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\typed.py", line 66, in process return Core.process(self, content) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\core.py", line 48, in process return self.append(content) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\core.py", line 63, in append self.append_children(content) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\core.py", line 140, in append_children cval = self.append(cont) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\core.py", line 63, in append self.append_children(content) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\core.py", line 140, in append_children cval = self.append(cont) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\core.py", line 64, in append self.append_text(content) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\typed.py", line 133, in append_text content.text = self.translated(content.text, known) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\umx\typed.py", line 139, in translated return resolved.translate(value) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\xsd\sxbuiltin.py", line 141, in translate return Date(value).date File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\sax\date.py", line 53, in __init__ self.date = self.__parse(date) File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\sax\date.py", line 104, in __parse raise ValueError, 'Invalid format "%s"' % s ValueError: Invalid format " " From python at mrabarnett.plus.com Wed Aug 30 09:34:01 2017 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 30 Aug 2017 14:34:01 +0100 Subject: pip which should be installed with Python3.62 doesn't work inwindows In-Reply-To: <59a6353a.caa0620a.bfb35.19a9@mx.google.com> References: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> <59a6353a.caa0620a.bfb35.19a9@mx.google.com> Message-ID: <3cf38be0-8e8f-ca1a-f415-472f804b0aa4@mrabarnett.plus.com> On 2017-08-30 04:47, Bear Light wrote: > Thanks for help but it doesn?t work. > > (cmd) > C:\Users\user>py -3.6 -m pip install regex > C:\Program Files\Python36\python.exe: No module named pip > > The picture that I attached showed similar result. > Though you can see the option of installing pip during python3 installing, the command about pip doesn?t work. > I can install pip manually, but according to the tutorials, it shouldn?t be necessary. > > What?s more, though people say you can find something like pip.py or pip3.py in the Python36/scripts folder, there is nothing in the scripts folder for me. Is it unusual? > I'm currently on Python 3.6.1 and that did install pip. > ???: MRAB > ????: 2017?8?30? ?? 05:07 > ???: python-list at python.org > ??: Re: pip which should be installed with Python3.62 doesn't work inwindows > > On 2017-08-29 20:10, Bear Light wrote: >> I found many rookies like me asking similar question: why "pip" is not >> recognized by cmd? >> I install Python 3.62 64bit in Win10 and I'm sure I add PATH, the Python >> tutorial doesn't even mention about PATH. >> You can see the following picture showing the tutorial doesn't work. > > This newsgroup is text-only. > >> Please give a hand to the helpless rookies and me. >> >> [image: ???? 1] >> tutorials url: >> https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments >> > The best way is to use the Python "launcher" py.exe, which should be on > the search path, so instead of, say: > > pip install regex > > you would write: > > py -3.6 -m pip install regex > > This ensures that it's installed into the correct version of Python (in > this case v3.6). > From python at mrabarnett.plus.com Wed Aug 30 10:01:02 2017 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 30 Aug 2017 15:01:02 +0100 Subject: pip which should be installed with Python3.62 doesn't work inwindows In-Reply-To: <3cf38be0-8e8f-ca1a-f415-472f804b0aa4@mrabarnett.plus.com> References: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> <59a6353a.caa0620a.bfb35.19a9@mx.google.com> <3cf38be0-8e8f-ca1a-f415-472f804b0aa4@mrabarnett.plus.com> Message-ID: On 2017-08-30 14:34, MRAB wrote: > On 2017-08-30 04:47, Bear Light wrote: >> Thanks for help but it doesn?t work. >> >> (cmd) >> C:\Users\user>py -3.6 -m pip install regex >> C:\Program Files\Python36\python.exe: No module named pip >> >> The picture that I attached showed similar result. >> Though you can see the option of installing pip during python3 installing, the command about pip doesn?t work. >> I can install pip manually, but according to the tutorials, it shouldn?t be necessary. >> >> What?s more, though people say you can find something like pip.py or pip3.py in the Python36/scripts folder, there is nothing in the scripts folder for me. Is it unusual? >> > I'm currently on Python 3.6.1 and that did install pip. > [snip] Just installed Python 3.6.2 using the "executable installer". Pip was included. From knon060718 at gmail.com Wed Aug 30 11:13:26 2017 From: knon060718 at gmail.com (Bear Light) Date: Wed, 30 Aug 2017 23:13:26 +0800 Subject: pip which should be installed with Python3.62 doesn't workinwindows In-Reply-To: References: <329c70ac-0ee3-2de7-0811-a713ca4af5cd@mrabarnett.plus.com> <59a6353a.caa0620a.bfb35.19a9@mx.google.com> <3cf38be0-8e8f-ca1a-f415-472f804b0aa4@mrabarnett.plus.com> Message-ID: <59a6d618.9b0a620a.40421.478d@mx.google.com> On 2017-08-30 14:34, MRAB wrote: > Just installed Python 3.6.2 using the "executable installer". Pip was included. Yeah, I did. Actually I tried a few times, every time the install of ver. 3.6.2 seems to succeed but it didn?t. Since Python 3.5.4 is working good now, I?m okay with that. Thanks for your advise. ???: MRAB ????: 2017?8?30? ?? 10:02 ???: python-list at python.org ??: Re: pip which should be installed with Python3.62 doesn't workinwindows On 2017-08-30 14:34, MRAB wrote: > On 2017-08-30 04:47, Bear Light wrote: >> Thanks for help but it doesn?t work. >> >> (cmd) >> C:\Users\user>py -3.6 -m pip install regex >> C:\Program Files\Python36\python.exe: No module named pip >> >> The picture that I attached showed similar result. >> Though you can see the option of installing pip during python3 installing, the command about pip doesn?t work. >> I can install pip manually, but according to the tutorials, it shouldn?t be necessary. >> >> What?s more, though people say you can find something like pip.py or pip3.py in the Python36/scripts folder, there is nothing in the scripts folder for me. Is it unusual? >> > I'm currently on Python 3.6.1 and that did install pip. > [snip] Just installed Python 3.6.2 using the "executable installer". Pip was included. -- https://mail.python.org/mailman/listinfo/python-list From tjreedy at udel.edu Wed Aug 30 13:35:13 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 30 Aug 2017 13:35:13 -0400 Subject: If you are running 32-bit 3.6 on Windows, please test this Message-ID: https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number reports the following: ----- Microsoft Windows [Version 10.0.16251.1002] (c) 2017 Microsoft Corporation. All rights reserved. C:\Users\Adam>python Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import math >>> math.sqrt(1.3) Traceback (most recent call last): File "", line 1, in ValueError: math domain error >>> I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and restarted my computer but it is still occurring. Some numbers are working (1.2, 1.4) and some others are also not working (1.128). ---- Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug build reproduce this. If anyone has the python.org 32bit 3.6.1/2 releases installed on Windows, please test and report. -- Terry Jan Reedy From python at mrabarnett.plus.com Wed Aug 30 13:48:38 2017 From: python at mrabarnett.plus.com (MRAB) Date: Wed, 30 Aug 2017 18:48:38 +0100 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: <00aecb7e-d095-1d8a-35c9-e84419cd6cd2@mrabarnett.plus.com> On 2017-08-30 18:35, Terry Reedy wrote: > https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number > > reports the following: > ----- > Microsoft Windows [Version 10.0.16251.1002] > (c) 2017 Microsoft Corporation. All rights reserved. > > C:\Users\Adam>python > Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit > (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import math > >>> math.sqrt(1.3) > Traceback (most recent call last): > File "", line 1, in > ValueError: math domain error > >>> > > I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and > restarted my computer but it is still occurring. Some numbers are > working (1.2, 1.4) and some others are also not working (1.128). > ---- > > Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug build > reproduce this. If anyone has the python.org 32bit 3.6.1/2 releases > installed on Windows, please test and report. > Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import math >>> math.sqrt(1.3) 1.140175425099138 >>> This is on 64-bit Windows 10. From malaclypse2 at gmail.com Wed Aug 30 14:38:52 2017 From: malaclypse2 at gmail.com (Jerry Hill) Date: Wed, 30 Aug 2017 14:38:52 -0400 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: <00aecb7e-d095-1d8a-35c9-e84419cd6cd2@mrabarnett.plus.com> References: <00aecb7e-d095-1d8a-35c9-e84419cd6cd2@mrabarnett.plus.com> Message-ID: On Wed, Aug 30, 2017 at 1:48 PM, MRAB wrote: > > On 2017-08-30 18:35, Terry Reedy wrote: >> >> https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number >> >> reports the following: >> ----- >> Microsoft Windows [Version 10.0.16251.1002] >> (c) 2017 Microsoft Corporation. All rights reserved. >> >> C:\Users\Adam>python >> Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit >> (Intel)] on win32 >> Type "help", "copyright", "credits" or "license" for more information. >> >>> import math >> >>> math.sqrt(1.3) >> Traceback (most recent call last): >> File "", line 1, in >> ValueError: math domain error >> >>> >> >> I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and >> restarted my computer but it is still occurring. Some numbers are >> working (1.2, 1.4) and some others are also not working (1.128). >> ---- >> >> Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug build >> reproduce this. If anyone has the python.org 32bit 3.6.1/2 releases >> installed on Windows, please test and report. >> > Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import math > >>> math.sqrt(1.3) > 1.140175425099138 > >>> > > This is on 64-bit Windows 10. > -- > https://mail.python.org/mailman/listinfo/python-list This all seems to work fine with python 3.6.1 on Windows 7 (64-bit OS, 32-bit python). Python 3.6.1 (v3.6.1:69c0db5, Mar 21 2017, 17:54:52) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import math >>> math.sqrt(1.3) 1.140175425099138 >>> -- Jerry From lab at 2020fresno.com Wed Aug 30 15:09:18 2017 From: lab at 2020fresno.com (20/20 Lab) Date: Wed, 30 Aug 2017 12:09:18 -0700 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: On 08/30/2017 10:35 AM, Terry Reedy wrote: > https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number > > > reports the following: > ----- > Microsoft Windows [Version 10.0.16251.1002] > (c) 2017 Microsoft Corporation. All rights reserved. > > C:\Users\Adam>python > Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 > bit (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import math > >>> math.sqrt(1.3) > Traceback (most recent call last): > File "", line 1, in > ValueError: math domain error > >>> > > I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and > restarted my computer but it is still occurring. Some numbers are > working (1.2, 1.4) and some others are also not working (1.128). > ---- > > Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug > build reproduce this. If anyone has the python.org 32bit 3.6.1/2 > releases installed on Windows, please test and report. > Works here. Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> import math >>> math.sqrt(1.3) 1.140175425099138 >>> Fresh windows7 x64 install with python 32bit (My apologies to Terry for "Reply" instead of "Reply to List") -Matt From ian.g.kelly at gmail.com Wed Aug 30 16:24:10 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Wed, 30 Aug 2017 14:24:10 -0600 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: In the Stack Overflow thread, rosuav wrote: > Quick smoke-test: can you show the value of math.__file__ please? Editing your question to add that would eliminate a particular class of issue (or reveal the problem, perhaps). (Replying here because SO requires 50 reputation to comment, and the requirement to have sufficient reputation to do anything on that site is the origin of the reason I don't have any reputation) If there were a math.py file in the path, there would have to be a sqrt function inside it, and then wouldn't the call stack reflect that? From rosuav at gmail.com Wed Aug 30 17:09:33 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 31 Aug 2017 07:09:33 +1000 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: On Thu, Aug 31, 2017 at 6:24 AM, Ian Kelly wrote: > In the Stack Overflow thread, rosuav wrote: >> Quick smoke-test: can you show the value of math.__file__ please? Editing your question to add that would eliminate a particular class of issue (or reveal the problem, perhaps). > > (Replying here because SO requires 50 reputation to comment, and the > requirement to have sufficient reputation to do anything on that site > is the origin of the reason I don't have any reputation) > > If there were a math.py file in the path, there would have to be a > sqrt function inside it, and then wouldn't the call stack reflect > that? That's why it's called a smoke test. It's a basic test to ensure that the obvious stuff is working. I fully expect to see that it's getting the correct file - but imagine if, due to a messed-up PYTHONPATH, "import math" is getting a module from a different version of Python. ChrisA From tjreedy at udel.edu Wed Aug 30 20:46:54 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 30 Aug 2017 20:46:54 -0400 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: On 8/30/2017 1:35 PM, Terry Reedy wrote: > https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number > > > reports the following: > ----- > Microsoft Windows [Version 10.0.16251.1002] > (c) 2017 Microsoft Corporation. All rights reserved. > > C:\Users\Adam>python > Python 3.6.2 (v3.6.2:5fd33b5, Jul? 8 2017, 04:14:34) [MSC v.1900 32 bit > (Intel)] on win32 > Type "help", "copyright", "credits" or "license" for more information. > >>> import math > >>> math.sqrt(1.3) > Traceback (most recent call last): > ?File "", line 1, in > ValueError: math domain error > >>> > > I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and > restarted my computer but it is still occurring. Some numbers are > working (1.2, 1.4) and some others are also not working (1.128). > ---- > > Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug build > reproduce this.? If anyone has the python.org 32bit 3.6.1/2 releases > installed on Windows, please test and report. Three people have reported that math.sqrt(1.3) works in 32 bit Python on 64-bit Windows and no one otherwise. I reported back on SO that the problem is likely local. Thanks for the responses. -- Terry Jan Reedy From steve+comp.lang.python at pearwood.info Thu Aug 31 01:13:37 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 31 Aug 2017 05:13:37 GMT Subject: If you are running 32-bit 3.6 on Windows, please test this References: Message-ID: <59a79b01$0$2920$c3e8da3$76491128@news.astraweb.com> On Wed, 30 Aug 2017 20:46:54 -0400, Terry Reedy wrote: > On 8/30/2017 1:35 PM, Terry Reedy wrote: >> https://stackoverflow.com/questions/45965545/math-sqrt-domain-error- when-square-rooting-a-positive-number [...] > Three people have reported that math.sqrt(1.3) works in 32 bit Python on > 64-bit Windows and no one otherwise. I reported back on SO that the > problem is likely local. Thanks for the responses. I wouldn't entirely rule out a bug yet. Do the Python Devs have a windows build-bot? If so, perhaps: - it is currently failing, and nobody noticed; - it's not failing, because the tests don't cover this case. The tests for sqrt are not exactly extensive, and the poster on SO reports sqrt only fails on *some* numbers, not all. https://github.com/python/cpython/blob/master/Lib/test/test_math.py def testSqrt(self): self.assertRaises(TypeError, math.sqrt) self.ftest('sqrt(0)', math.sqrt(0), 0) self.ftest('sqrt(1)', math.sqrt(1), 1) self.ftest('sqrt(4)', math.sqrt(4), 2) self.assertEqual(math.sqrt(INF), INF) self.assertRaises(ValueError, math.sqrt, -1) self.assertRaises(ValueError, math.sqrt, NINF) self.assertTrue(math.isnan(math.sqrt(NAN))) As far as I can see, apart from tests for NAN and ?INF, there are no tests of math.sqrt on floats at all. -- Steven D'Aprano ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From dieter at handshake.de Thu Aug 31 03:03:39 2017 From: dieter at handshake.de (dieter) Date: Thu, 31 Aug 2017 09:03:39 +0200 Subject: trouble consuming null data from wsdl with suds.client References: <5ac6e972-dff1-4c20-8fbe-a9c28915e5b7@googlegroups.com> Message-ID: <877exkgqwk.fsf@handshake.de> kevinalejandromolina at gmail.com writes: > i was trying to consume the service but i always have the same error, look over the error message, and i am think that the error is, the suds library does not support null values on the attributes. > >>>> r=client.service.WSOBTENERINTERRUPCIONWEB(1,1) > Traceback (most recent call last): > ... > self.date = self.__parse(date) > File "C:\Python27\ArcGIS10.2\lib\site-packages\suds\sax\date.py", line 104, in __parse > raise ValueError, 'Invalid format "%s"' % s > ValueError: Invalid format " > " Apparently, the server side delivers an invalid SOAP message (one which does not conform to the WSDL description). >From the WSDL, "suds" is expecting a "date" value. The "XML-Schema" standard clearly defines how date values must look like -- and a string filled with blank characters is not conforming. Contact the server side administrator about the problem. "suds" has some infrastructure to cope with broken WSDL descriptions -- however, you will need some deeper knowledge about "WSDL", "XML-Schema" and "suds" to make use of them. Thus, hopefully, the problem can be solved on the server side (where it also should be solved). From steve+comp.lang.python at pearwood.info Thu Aug 31 03:10:10 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 31 Aug 2017 07:10:10 GMT Subject: Case-insensitive string equality Message-ID: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Three times in the last week the devs where I work accidentally introduced bugs into our code because of a mistake with case-insensitive string comparisons. They managed to demonstrate three different failures: # 1 a = something().upper() # normalise string ... much later on if a == b.lower(): ... # 2 a = something().upper() ... much later on if a == 'maildir': ... # 3 a = something() # unnormalised assert 'foo' in a ... much later on pos = a.find('FOO') Not every two line function needs to be in the standard library, but I've come to the conclusion that case-insensitive testing and searches should be. I've made these mistakes myself at times, as I'm sure most people have, and I'm tired of writing my own case-insensitive function over and over again. So I'd like to propose some additions to 3.7 or 3.8. If the feedback here is positive, I'll take it to Python-Ideas for the negative feedback :-) (1) Add a new string method, which performs a case-insensitive equality test. Here is a potential implementation, written in pure Python: def equal(self, other): if self is other: return True if not isinstance(other, str): raise TypeError if len(self) != len(other): return False casefold = str.casefold for a, b in zip(self, other): if casefold(a) != casefold(b): return False return True Alternatively: how about a === triple-equals operator to do the same thing? (2) Add keyword-only arguments to str.find and str.index: casefold=False which does nothing if false (the default), and switches to a case- insensitive search if true. Alternatives: (i) Do nothing. The status quo wins a stalemate. (ii) Instead of str.find or index, use a regular expression. This is less discoverable (you need to know regular expressions) and harder to get right than to just call a string method. Also, I expect that invoking the re engine just for case insensitivity will be a lot more expensive than a simple search need be. (iii) Not every two line function needs to be in the standard library. Just add this to the top of every module: def equal(s, t): return s.casefold() == t.casefold() That's the status quo wins again. It's an annoyance. A small annoyance, but multiplied by the sheer number of times it happens, it becomes a large annoyance. I believe the annoyance factor of case-insensitive comparisons outweighs the "two line function" objection. And the two-line "equal" function doesn't solve the problem for find and index, or for sets dicts, list.index and the `in` operator either. Unsolved problems: This proposal doesn't help with sets and dicts, list.index and the `in` operator either. Thoughts? -- Steven D'Aprano ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From coreylean1 at gmail.com Thu Aug 31 03:18:39 2017 From: coreylean1 at gmail.com (coreylean1 at gmail.com) Date: Thu, 31 Aug 2017 00:18:39 -0700 (PDT) Subject: copy locked files In-Reply-To: <1182178224.486883.203330@q75g2000hsh.googlegroups.com> References: <1182178224.486883.203330@q75g2000hsh.googlegroups.com> Message-ID: <881aca2d-23b9-4a1f-a084-1d000ed8c834@googlegroups.com> On Monday, June 18, 2007 at 8:20:24 PM UTC+5:30, rubbis... at web.de wrote: > Hello, > > do you know of any way to copy locked / opened files under win xp? > I know there is something like "Volume Shadow Copy" but I don't know > how to use it. > Maybe someone already has a python solution? > > > Many thanks > > > Daniel No please! I have tried using shadow copy but hell no it didn't worked at all, even hangs multiple times. I don't know much about python but I am currently using GS Richcopy 360 to solve this issue. Its a GUI based software, a paid one not to mention. But its worth every single penny. I have been using it for a year now and it never disappoints me. From steve+comp.lang.python at pearwood.info Thu Aug 31 03:29:29 2017 From: steve+comp.lang.python at pearwood.info (Steven D'Aprano) Date: 31 Aug 2017 07:29:29 GMT Subject: copy locked files References: <1182178224.486883.203330@q75g2000hsh.googlegroups.com> <881aca2d-23b9-4a1f-a084-1d000ed8c834@googlegroups.com> Message-ID: <59a7bad9$0$2920$c3e8da3$76491128@news.astraweb.com> On Thu, 31 Aug 2017 00:18:39 -0700, coreylean1 wrote: > On Monday, June 18, 2007 ^^^^^^^^^^^^^^^^^^^^^^^^^^ > No please! I have tried using shadow copy You are replying to a ten year old message. I very much doubt the original poster (or anyone else for that matter) still cares. They're either already solved the problem, or moved on. -- Steven D'Aprano ?You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.? ?Theo de Raadt From antoon.pardon at vub.be Thu Aug 31 03:44:24 2017 From: antoon.pardon at vub.be (Antoon Pardon) Date: Thu, 31 Aug 2017 09:44:24 +0200 Subject: Case-insensitive string equality In-Reply-To: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <10f6b3c8-7d9c-61b1-72f4-cfa7259883c2@vub.be> IMO this should be solved by a company used library and I would go in the direction of a Normalized_String class. This has the advantages (1) that the company can choose whatever normalization suits them, not all cases are suited by comparing case insentitively, (2) individual devs in the company don't have to write there own. (3) and Normalized_Strings can be keys in directories and members in a set. Op 31-08-17 om 09:10 schreef Steven D'Aprano: > Three times in the last week the devs where I work accidentally > introduced bugs into our code because of a mistake with case-insensitive > string comparisons. They managed to demonstrate three different failures: > > # 1 > a = something().upper() # normalise string > ... much later on > if a == b.lower(): ... > > > # 2 > a = something().upper() > ... much later on > if a == 'maildir': ... > > > # 3 > a = something() # unnormalised > assert 'foo' in a > ... much later on > pos = a.find('FOO') > > > > Not every two line function needs to be in the standard library, but I've > come to the conclusion that case-insensitive testing and searches should > be. I've made these mistakes myself at times, as I'm sure most people > have, and I'm tired of writing my own case-insensitive function over and > over again. > > > So I'd like to propose some additions to 3.7 or 3.8. If the feedback here > is positive, I'll take it to Python-Ideas for the negative feedback :-) > > > (1) Add a new string method, which performs a case-insensitive equality > test. Here is a potential implementation, written in pure Python: > > > def equal(self, other): > if self is other: > return True > if not isinstance(other, str): > raise TypeError > if len(self) != len(other): > return False > casefold = str.casefold > for a, b in zip(self, other): > if casefold(a) != casefold(b): > return False > return True > > Alternatively: how about a === triple-equals operator to do the same > thing? > > > > (2) Add keyword-only arguments to str.find and str.index: > > casefold=False > > which does nothing if false (the default), and switches to a case- > insensitive search if true. > > > > > Alternatives: > > (i) Do nothing. The status quo wins a stalemate. > > (ii) Instead of str.find or index, use a regular expression. > > This is less discoverable (you need to know regular expressions) and > harder to get right than to just call a string method. Also, I expect > that invoking the re engine just for case insensitivity will be a lot > more expensive than a simple search need be. > > (iii) Not every two line function needs to be in the standard library. > Just add this to the top of every module: > > def equal(s, t): > return s.casefold() == t.casefold() > > > That's the status quo wins again. It's an annoyance. A small annoyance, > but multiplied by the sheer number of times it happens, it becomes a > large annoyance. I believe the annoyance factor of case-insensitive > comparisons outweighs the "two line function" objection. > > And the two-line "equal" function doesn't solve the problem for find and > index, or for sets dicts, list.index and the `in` operator either. > > > Unsolved problems: > > This proposal doesn't help with sets and dicts, list.index and the `in` > operator either. > > > > Thoughts? > > > From storchaka at gmail.com Thu Aug 31 03:51:19 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 31 Aug 2017 10:51:19 +0300 Subject: Case-insensitive string equality In-Reply-To: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: 31.08.17 10:10, Steven D'Aprano ????: > (iii) Not every two line function needs to be in the standard library. > Just add this to the top of every module: > > def equal(s, t): > return s.casefold() == t.casefold() This is my answer. > Unsolved problems: > > This proposal doesn't help with sets and dicts, list.index and the `in` > operator either. This is the end of the discussion. From storchaka at gmail.com Thu Aug 31 03:55:17 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 31 Aug 2017 10:55:17 +0300 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: <59a79b01$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a79b01$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: 31.08.17 08:13, Steven D'Aprano ????: > As far as I can see, apart from tests for NAN and ?INF, there are no > tests of math.sqrt on floats at all. See test_testfile in test_math.py. From azadbekm at gmail.com Thu Aug 31 04:17:38 2017 From: azadbekm at gmail.com (Yusuf Mohammad) Date: Thu, 31 Aug 2017 10:17:38 +0200 Subject: Cannot find IDLE Message-ID: Hi! I am trying to send this email again. For some reason when Python is installing it stores in Appdata/Local folder. This is quite weird and when i'm trying to install Python with the custom option to change the location (to Program files (x86)), IDLE is not to be found. I work at a hospital where if we don't install application to a specific folder, the application will automatically be uninstalled. How do i install Python in a specific folder with the custom option and be able to use IDLE? NB: I am a newbie when it comes to Python, so be gentle with me :) Greetings From ahmed.gamal.omar.80 at gmail.com Thu Aug 31 04:41:55 2017 From: ahmed.gamal.omar.80 at gmail.com (ahmed.gamal.omar.80 at gmail.com) Date: Thu, 31 Aug 2017 01:41:55 -0700 (PDT) Subject: Case Solution: A Dark Horse in the Global Smartphone Market Huawei's Smartphone Strategy by Yangao Xiao, Tony Tong, Guoli Chen, Kathy Wu In-Reply-To: References: Message-ID: On Saturday, 8 July 2017 05:22:24 UTC+2, Case Solution & Analysis wrote: > Case Solution and Analysis of A Dark Horse in the Global Smartphone Market: Huawei's Smartphone Strategy by Yangao Xiao, Tony Tong, Guoli Chen, Kathy Wu is available at a lowest price, send email to casesolutionscentre(at)gmail(dot)com > > Case Study ID: IN1324 > > Get Case Study Solution and Analysis of A Dark Horse in the Global Smartphone Market: Huawei's Smartphone Strategy in a FAIR PRICE!! > > Our e-mail address is CASESOLUTIONSCENTRE (AT) GMAIL (DOT) COM. Please replace (at) by @ and (dot) by . > > YOU MUST WRITE FOLLOWING WHILE PLACING YOUR ORDER: > Complete Case Study Name > Authors > Case Study ID > Publisher of Case Study > Your Requirements / Case Questions > > Note: Do not REPLY to this post because we do not reply to posts here. If you need any Case Solution please send us an email. We can help you to get it. From pavol.lisy at gmail.com Thu Aug 31 04:53:49 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Thu, 31 Aug 2017 10:53:49 +0200 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: On 8/31/17, Terry Reedy wrote: > On 8/30/2017 1:35 PM, Terry Reedy wrote: >> https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number >> >> >> >> reports the following: >> ----- >> Microsoft Windows [Version 10.0.16251.1002] >> (c) 2017 Microsoft Corporation. All rights reserved. >> >> C:\Users\Adam>python >> Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit >> (Intel)] on win32 >> Type "help", "copyright", "credits" or "license" for more information. >> >>> import math >> >>> math.sqrt(1.3) >> Traceback (most recent call last): >> File "", line 1, in >> ValueError: math domain error >> >>> >> >> I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and >> restarted my computer but it is still occurring. Some numbers are >> working (1.2, 1.4) and some others are also not working (1.128). >> ---- >> >> Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug build >> reproduce this. If anyone has the python.org 32bit 3.6.1/2 releases >> installed on Windows, please test and report. > > Three people have reported that math.sqrt(1.3) works in 32 bit Python on > 64-bit Windows and no one otherwise. I reported back on SO that the > problem is likely local. Thanks for the responses. Problem is reported on win10 and I see just 2 tests on win7 (third is maybe Terry's but on SO I don't see win version). If I am not wrong (with analyze source code) sqrt is calling function from "libm" which is some kind of msvcrt.dll on windows... (see https://github.com/python/cpython/blob/a0ce375e10b50f7606cb86b072fed7d8cd574fe7/Modules/mathmodule.c#L1183 and https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Lib/ctypes/util.py#L34 ) And with "MSC v. 1900 ..." it seems that "alternative approaches" (see here https://bugs.python.org/issue23606 ) are used. So I would be cautious. PS. BTW on my ubuntu I got this: from ctypes import cdll print(cdll.LoadLibrary("libcrypt.so")) print(cdll.LoadLibrary("libm.so")) ... OSError: /usr/lib/x86_64-linux-gnu/libm.so: invalid ELF header (same with distro's python3, python2 and anaconda 3.6.2) So this test -> https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Lib/ctypes/util.py#L328 has to crash on some environments (see for example: https://github.com/scipy/scipy/pull/5416/files ). And it seems like some test failures are just ignored... From rhodri at kynesim.co.uk Thu Aug 31 06:15:16 2017 From: rhodri at kynesim.co.uk (Rhodri James) Date: Thu, 31 Aug 2017 11:15:16 +0100 Subject: Case-insensitive string equality In-Reply-To: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <0f5b6875-03ef-7532-e171-b3fbdbf64d63@kynesim.co.uk> On 31/08/17 08:10, Steven D'Aprano wrote: > So I'd like to propose some additions to 3.7 or 3.8. If the feedback here > is positive, I'll take it to Python-Ideas for the negative feedback :-) > > > (1) Add a new string method, which performs a case-insensitive equality > test. Here is a potential implementation, written in pure Python: > > > def equal(self, other): > if self is other: > return True > if not isinstance(other, str): > raise TypeError > if len(self) != len(other): > return False > casefold = str.casefold > for a, b in zip(self, other): > if casefold(a) != casefold(b): > return False > return True I'd quibble about the name and the implementation (length is not preserved under casefolding), but I'd go for this. The number of times I've written something like this in different languages... > Alternatively: how about a === triple-equals operator to do the same > thing? Much less keen on new syntax, especially when other languages use it for other purposes. > (2) Add keyword-only arguments to str.find and str.index: > > casefold=False > > which does nothing if false (the default), and switches to a case- > insensitive search if true. There's an implementation argument to be had about whether separate casefolded methods would be better, but yes. > Unsolved problems: > > This proposal doesn't help with sets and dicts, list.index and the `in` > operator either. The only way I can think of to get much traction with this is to have a separate case-insensitive string class. That feels a bit heavyweight, though. -- Rhodri James *-* Kynesim Ltd From davidgshi at yahoo.co.uk Thu Aug 31 06:55:04 2017 From: davidgshi at yahoo.co.uk (David Shi) Date: Thu, 31 Aug 2017 10:55:04 +0000 (UTC) Subject: Is there tested Python code for parsing N-Triples? References: <1550532101.443662.1504176904820.ref@mail.yahoo.com> Message-ID: <1550532101.443662.1504176904820@mail.yahoo.com> Is there tested Python code for parsing N-Triples? Looking forward to hearing from you. Regards, David From knon060718 at gmail.com Thu Aug 31 07:29:44 2017 From: knon060718 at gmail.com (Bear Light) Date: Thu, 31 Aug 2017 19:29:44 +0800 Subject: Cannot find IDLE In-Reply-To: References: Message-ID: <59a7f32b.03b9240a.69650.0bbc@mx.google.com> >How do i install Python in a specific folder with the custom option and be able to use IDLE? After you choose customize install, pick the ?Install for all users? option then you can change the install location. ???: Yusuf Mohammad ????: 2017?8?31? ?? 04:52 ???: python-list at python.org ??: Cannot find IDLE Hi! I am trying to send this email again. For some reason when Python is installing it stores in Appdata/Local folder. This is quite weird and when i'm trying to install Python with the custom option to change the location (to Program files (x86)), IDLE is not to be found. I work at a hospital where if we don't install application to a specific folder, the application will automatically be uninstalled. How do i install Python in a specific folder with the custom option and be able to use IDLE? NB: I am a newbie when it comes to Python, so be gentle with me :) Greetings -- https://mail.python.org/mailman/listinfo/python-list From steve+python at pearwood.info Thu Aug 31 08:18:36 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 31 Aug 2017 22:18:36 +1000 Subject: Is there tested Python code for parsing N-Triples? References: <1550532101.443662.1504176904820.ref@mail.yahoo.com> <1550532101.443662.1504176904820@mail.yahoo.com> Message-ID: <59a7fe9e$0$1599$c3e8da3$5496439d@news.astraweb.com> On Thu, 31 Aug 2017 08:55 pm, David Shi wrote: > Is there tested Python code for parsing N-Triples? What do you mean by N-Triples? Can you give an example? -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From rhodri at kynesim.co.uk Thu Aug 31 08:25:15 2017 From: rhodri at kynesim.co.uk (Rhodri James) Date: Thu, 31 Aug 2017 13:25:15 +0100 Subject: Is there tested Python code for parsing N-Triples? In-Reply-To: References: <1550532101.443662.1504176904820.ref@mail.yahoo.com> <1550532101.443662.1504176904820@mail.yahoo.com> Message-ID: On 31/08/17 13:08, Stefan Ram wrote: > David Shi writes: >> Is there tested Python code for parsing N-Triples? > > I know of "n-tuples" and of "triples". I think the OP may mean what he said: https://www.w3.org/TR/n-triples/ According to the wiki (https://wiki.python.org/moin/RdfLibraries) there are several RDF libraries. I don't know how formally tested they are. -- Rhodri James *-* Kynesim Ltd From idokolord at yahoo.com Thu Aug 31 08:35:21 2017 From: idokolord at yahoo.com (Ode Idoko) Date: Thu, 31 Aug 2017 12:35:21 +0000 (UTC) Subject: Exponential Smoothing program References: <1358241856.358131.1504182921026.ref@mail.yahoo.com> Message-ID: <1358241856.358131.1504182921026@mail.yahoo.com> I am running a master degree programme and very new to programming including python. I have been given a project to write a python program on exponential smoothing of some selected stocks. The program should user the user to input alpha, display the graph of the original data and "smoothed data". On the same python program, I am to develop a linear regression model to predict the next period, showing correlation coefficients to indicate the strength of the model. I have been able to?write a program which returns some values but no graph and also having difficulties with the linear regression. This is the program I wrote: def exponential_smoothing (a,y,f): ??? ans = (a*y) + (1-a) * f ??? return ans print ("Exponential_Smoothing Program") a = float(input("please enter a: ")) y = float(input("please enter y: ")) f = float(input("please enter f: ")) ans = exponential_smoothing (a,y,f) print ("the answers are %.2f" %(ans))? Could someone kindly help with tips on how to go about this? Thanks. Ode A. IDOKO ...?writer, author and consultant idokolord at yahoo.com +2347064334855 Author of: "Putting Your Talent to Work" Click link below to view book. http://www.authorhouse.co.uk/Bookstore/BookDetail.aspx?BookId=SKU-000425821 ...let God alone be true and all men liars! From azadbekm at gmail.com Thu Aug 31 08:46:44 2017 From: azadbekm at gmail.com (Yusuf Mohammad) Date: Thu, 31 Aug 2017 14:46:44 +0200 Subject: Cannot find IDLE In-Reply-To: <59a7f32b.03b9240a.69650.0bbc@mx.google.com> References: <59a7f32b.03b9240a.69650.0bbc@mx.google.com> Message-ID: Wont work unfortunately 31. aug. 2017 13:39 skrev "Bear Light" : > > >How do i install Python in a specific folder with the custom option and be > able to use IDLE? > > After you choose customize install, pick the ?Install for all users? > option then you can change the install location. > > ???: Yusuf Mohammad > ????: 2017?8?31? ?? 04:52 > ???: python-list at python.org > ??: Cannot find IDLE > > Hi! I am trying to send this email again. > > For some reason when Python is installing it stores in Appdata/Local > folder. This is quite weird and when i'm trying to install Python with the > custom option to change the location (to Program files (x86)), IDLE is not > to be found. > > I work at a hospital where if we don't install application to a specific > folder, the application will automatically be uninstalled. > > How do i install Python in a specific folder with the custom option and be > able to use IDLE? > > NB: I am a newbie when it comes to Python, so be gentle with me :) > > Greetings > -- > https://mail.python.org/mailman/listinfo/python-list > > -- > https://mail.python.org/mailman/listinfo/python-list > From steve+python at pearwood.info Thu Aug 31 08:49:26 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Thu, 31 Aug 2017 22:49:26 +1000 Subject: Case-insensitive string equality References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> On Thu, 31 Aug 2017 05:51 pm, Serhiy Storchaka wrote: > 31.08.17 10:10, Steven D'Aprano ????: >> (iii) Not every two line function needs to be in the standard library. >> Just add this to the top of every module: >> >> def equal(s, t): >> return s.casefold() == t.casefold() > > This is my answer. > >> Unsolved problems: >> >> This proposal doesn't help with sets and dicts, list.index and the `in` >> operator either. > > This is the end of the discussion. Your answer of an equal() function doesn't help with sets and dicts either. So I guess we're stuck with no good standard answer: - the easy two-line function doesn't even come close to solving the problem of case-insensitive string operations; - but we can't have case-insensitive string operations because too many people say "just use this two-line function". -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From tjreedy at udel.edu Thu Aug 31 09:17:54 2017 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 31 Aug 2017 09:17:54 -0400 Subject: Cannot find IDLE In-Reply-To: References: <59a7f32b.03b9240a.69650.0bbc@mx.google.com> Message-ID: On 8/31/2017 8:46 AM, Yusuf Mohammad wrote: You must provide much more information to get any help. Are you installing on a network or an individual machine? What version of Windows is running, including 32 versus 64 bit? Do you have admin access to the machine? What *exact* python installer are you using, including 32 vs 64 bit? IE, what is the file name of the installer? Where did you get the installation file? Note: Python 3.6+ requires Windows Vista or later. No XP. > Wont work unfortunately Are you guessing or did something 'not work'? If the latter, what exactly did you do and what does 'not work' mean? > 31. aug. 2017 13:39 skrev "Bear Light" : > >> >>> How do i install Python in a specific folder with the custom option and be >> able to use IDLE? >> >> After you choose customize install, pick the ?Install for all users? >> option then you can change the install location. This works for me and for numerous others. >> For some reason when Python is installing it stores in Appdata/Local The reason is that this is the *standard* Windows location for programs installed for a single user. >> folder. This is quite weird and when i'm trying to install Python with the >> custom option to change the location (to Program files (x86)), 32 bit apps go here, 64 bit apps go in /Program files. If you install for all users, the default location is one of these. >> IDLE is not to be found. IDLE is a collection of Python modules. Until you can run Python, you cannot run IDLE. I believe the installer has an option to install tcl/tk, tkinter, and IDLE -- not. I don't know what the standard install does. If you do a custom install, make sure the box is checked. -- Terry Jan Reedy From rosuav at gmail.com Thu Aug 31 09:30:21 2017 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 31 Aug 2017 23:30:21 +1000 Subject: Case-insensitive string equality In-Reply-To: <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 31, 2017 at 10:49 PM, Steve D'Aprano wrote: > On Thu, 31 Aug 2017 05:51 pm, Serhiy Storchaka wrote: > >> 31.08.17 10:10, Steven D'Aprano ????: >>> (iii) Not every two line function needs to be in the standard library. >>> Just add this to the top of every module: >>> >>> def equal(s, t): >>> return s.casefold() == t.casefold() >> >> This is my answer. >> >>> Unsolved problems: >>> >>> This proposal doesn't help with sets and dicts, list.index and the `in` >>> operator either. >> >> This is the end of the discussion. > > Your answer of an equal() function doesn't help with sets and dicts either. > > So I guess we're stuck with no good standard answer: > > - the easy two-line function doesn't even come close to solving the problem > of case-insensitive string operations; > > - but we can't have case-insensitive string operations because too many > people say "just use this two-line function". The method you proposed seems a little odd - it steps through the strings character by character and casefolds them separately. How is it superior to the two-line function? And it still doesn't solve any of your other cases. To make dicts/sets case insensitive, you really need something that people have periodically asked for: a dict with a key function. It would retain the actual key used, but for comparison purposes, would use the modified version. Then you could use str.casefold as your key function, and voila, you have a case insensitive dict. I don't know if that would solve your other problems though. ChrisA From storchaka at gmail.com Thu Aug 31 09:45:08 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 31 Aug 2017 16:45:08 +0300 Subject: Case-insensitive string equality In-Reply-To: <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: 31.08.17 15:49, Steve D'Aprano ????: > On Thu, 31 Aug 2017 05:51 pm, Serhiy Storchaka wrote: >> 31.08.17 10:10, Steven D'Aprano ????: >>> (iii) Not every two line function needs to be in the standard library. >>> Just add this to the top of every module: >>> >>> def equal(s, t): >>> return s.casefold() == t.casefold() >> >> This is my answer. >> >>> Unsolved problems: >>> >>> This proposal doesn't help with sets and dicts, list.index and the `in` >>> operator either. >> >> This is the end of the discussion. > > Your answer of an equal() function doesn't help with sets and dicts either. See rejected issue18986 [1], PEP 455 [2] and corresponding mailing lists discussions. The conclusion was that the need of such collections is low and the problems that they are purposed to solve can be solved with normal dict (as they are solved now). > So I guess we're stuck with no good standard answer: > > - the easy two-line function doesn't even come close to solving the problem > of case-insensitive string operations; It is not clear what is your problem exactly. The easy one-line function solves the problem of testing case-insensitive string equality. Regular expressions solve the problem of case-insensitive searching a position of a substring. If you asked a solution that magically prevent people from making simple programming mistakes, there is no such solution. [1] https://bugs.python.org/issue18986 [2] https://www.python.org/dev/peps/pep-0455/ From rosuav at gmail.com Thu Aug 31 10:03:01 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 1 Sep 2017 00:03:01 +1000 Subject: Case-insensitive string equality In-Reply-To: References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Thu, Aug 31, 2017 at 11:53 PM, Stefan Ram wrote: > Chris Angelico writes: >>On Thu, Aug 31, 2017 at 10:49 PM, Steve D'Aprano >> wrote: >>> On Thu, 31 Aug 2017 05:51 pm, Serhiy Storchaka wrote: >>>> 31.08.17 10:10, Steven D'Aprano ???: >>>>> def equal(s, t): >>>>> return s.casefold() == t.casefold() >>The method you proposed seems a little odd - it steps through the >>strings character by character and casefolds them separately. How is >>it superior to the two-line function? > > When the strings are long, casefolding both strings > just to be able to tell that the first character of > the left string is ?;? while the first character of > the right string is ?'? and so the result is ?False? > might be slower than necessary. > [chomp] > However, premature optimization is the root of all evil! Fair enough. However, I'm more concerned about the possibility of a semantic difference between the two. Is it at all possible for the case folding of an entire string to differ from the concatenation of the case foldings of its individual characters? Additionally: a proper "case insensitive comparison" should almost certainly start with a Unicode normalization. But should it be NFC/NFD or NFKC/NFKD? IMO that's a good reason to leave it in the hands of the application. ChrisA From rhodri at kynesim.co.uk Thu Aug 31 10:23:19 2017 From: rhodri at kynesim.co.uk (Rhodri James) Date: Thu, 31 Aug 2017 15:23:19 +0100 Subject: Case-insensitive string equality In-Reply-To: References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 31/08/17 15:03, Chris Angelico wrote: > On Thu, Aug 31, 2017 at 11:53 PM, Stefan Ram wrote: >> Chris Angelico writes: >>> On Thu, Aug 31, 2017 at 10:49 PM, Steve D'Aprano >>> wrote: >>>> On Thu, 31 Aug 2017 05:51 pm, Serhiy Storchaka wrote: >>>>> 31.08.17 10:10, Steven D'Aprano ???: >>>>>> def equal(s, t): >>>>>> return s.casefold() == t.casefold() >>> The method you proposed seems a little odd - it steps through the >>> strings character by character and casefolds them separately. How is >>> it superior to the two-line function? >> >> When the strings are long, casefolding both strings >> just to be able to tell that the first character of >> the left string is ?;? while the first character of >> the right string is ?'? and so the result is ?False? >> might be slower than necessary. >> [chomp] >> However, premature optimization is the root of all evil! > > Fair enough. > > However, I'm more concerned about the possibility of a semantic > difference between the two. Is it at all possible for the case folding > of an entire string to differ from the concatenation of the case > foldings of its individual characters? > > Additionally: a proper "case insensitive comparison" should almost > certainly start with a Unicode normalization. But should it be NFC/NFD > or NFKC/NFKD? IMO that's a good reason to leave it in the hands of the > application. There's also the example in the documentation of str.casefold to consider. We would rather like str.equal("?", "ss") to be true. -- Rhodri James *-* Kynesim Ltd From steve+python at pearwood.info Thu Aug 31 10:27:58 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 01 Sep 2017 00:27:58 +1000 Subject: Case-insensitive string equality References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59a81cf0$0$22141$c3e8da3$5496439d@news.astraweb.com> On Fri, 1 Sep 2017 12:03 am, Chris Angelico wrote: > On Thu, Aug 31, 2017 at 11:53 PM, Stefan Ram wrote: >> Chris Angelico writes: >>>The method you proposed seems a little odd - it steps through the >>>strings character by character and casefolds them separately. How is >>>it superior to the two-line function? >> >> When the strings are long, casefolding both strings >> just to be able to tell that the first character of >> the left string is ?;? while the first character of >> the right string is ?'? and so the result is ?False? >> might be slower than necessary. Thanks Stefan, that was my reasoning. Also, if the implementation was in C, doing the comparison character by character is unlikely to be slower than doing the comparison all at once, since the "all at once" comparison actually is character by character under the hood. >> [chomp] >> However, premature optimization is the root of all evil! > > Fair enough. Its not premature optimization to plan ahead for obvious scenarios. Sometimes we may want to compare two large strings. Calling casefold on them temporarily uses doubles the memory taken by the two strings, which can be significant. Assuming the method were written in C, you would be very unlikely to build up two large temporary case-folded arrays before doing the comparison. If I were subclassing str in pure Python, I wouldn't bother. The tradeoffs are different. > However, I'm more concerned about the possibility of a semantic > difference between the two. Is it at all possible for the case folding > of an entire string to differ from the concatenation of the case > foldings of its individual characters? I don't believe so, but I welcome correction. > Additionally: a proper "case insensitive comparison" should almost > certainly start with a Unicode normalization. But should it be NFC/NFD > or NFKC/NFKD? IMO that's a good reason to leave it in the hands of the > application. Normalisation is orthogonal to comparisons and searches. Python doesn't automatically normalise strings, as people have pointed out a bazillion times in the past, and it happily compares '?' LATIN SMALL LETTER O WITH DIAERESIS '?' LATIN SMALL LETTER O + COMBINING DIAERESIS as unequal. I don't propose to change that just so that we can get 'a' equals 'A' :-) -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From cbogart at cs.cmu.edu Thu Aug 31 10:33:59 2017 From: cbogart at cs.cmu.edu (Chris Bogart) Date: Thu, 31 Aug 2017 10:33:59 -0400 Subject: Survey results: How software ecosystems deal with breaking changes Message-ID: Last fall we announced on this list a survey about how and why breaking changes are handled differently in 18 different software ecosystems. We've just submitted a paper to a conference about the results, and we've also set up a site (http://breakingapis.org/survey) where you can compare how different ecosystems perceived their values, practices of upstream and downstream developers, and the health of their ecosystem. Results showed some stark differences between software communities, for example: Making updates available to end users quickly was highly valued by Node and Ruby communities, but was considered less important to Eclipse. ( http://breakingapis.org/survey/values.html#rapid?ecos=Haskell_Stack_Stackage_,Node_js_NPM,Ruby_Rubygems) The Perl and Eclipse communities value stability most, while Hackage/Cabal valued it least. ( http://breakingapis.org/survey/values.html#stability?ecos=Eclipse_plugins_,Haskell_Cabal_Hackage_,Perl_CPAN ) Ecosystems have very different ways of dealing with versioning; for example in Go it's common for people to sometimes make small updates without increasing the version number. ( http://breakingapis.org/survey/upstream.html#mon_versionless_updates_eco?ecos=Go,Maven,Node_js_NPM) In Rust, developers more frequently chip in and help with maintenance of upstream packages than in NuGet.( http://breakingapis.org/survey/downstream.html#sync_liaison_code?ecos=NuGet,Rust_Cargo) There are a lot of other results on the linked site, and we?re interested in your impressions of the results. Do the results make sense to you? What answers would you have expected? Do you think the differences are intentional? If you have any thoughts about it I?ll try to keep up with comments here, or you can also send us comments through the website. The anonymized raw data is also available here: https://doi.org/10.1184/R1/5108716 We want to sincerely thank the large number of people in the Python community who responded, and we?re eager to hear what you think! Chris, Anna, Jim, and Christian From rosuav at gmail.com Thu Aug 31 10:36:33 2017 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 1 Sep 2017 00:36:33 +1000 Subject: Case-insensitive string equality In-Reply-To: <59a81cf0$0$22141$c3e8da3$5496439d@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> <59a81cf0$0$22141$c3e8da3$5496439d@news.astraweb.com> Message-ID: On Fri, Sep 1, 2017 at 12:27 AM, Steve D'Aprano wrote: >> Additionally: a proper "case insensitive comparison" should almost >> certainly start with a Unicode normalization. But should it be NFC/NFD >> or NFKC/NFKD? IMO that's a good reason to leave it in the hands of the >> application. > > Normalisation is orthogonal to comparisons and searches. Python doesn't > automatically normalise strings, as people have pointed out a bazillion times > in the past, and it happily compares > > '?' LATIN SMALL LETTER O WITH DIAERESIS > > '?' LATIN SMALL LETTER O + COMBINING DIAERESIS > > > as unequal. I don't propose to change that just so that we can get 'a' > equals 'A' :-) You may not, but others will. Which is just one of the reasons that "case insensitive comparison" is not as simple as it initially seems, and thus (IMO) is best NOT baked into the language. ChrisA From steve+python at pearwood.info Thu Aug 31 10:38:22 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 01 Sep 2017 00:38:22 +1000 Subject: Case-insensitive string equality References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: <59a81f5f$0$1608$c3e8da3$5496439d@news.astraweb.com> On Thu, 31 Aug 2017 11:45 pm, Serhiy Storchaka wrote: > It is not clear what is your problem exactly. That is fair. This is why I am discussing it here first, before taking it to Python-Ideas. At the moment my ideas on the matter are still half-formed. > The easy one-line function > solves the problem of testing case-insensitive string equality. True. Except that when a problem is as common as case-insensitive comparisons, there should be a standard solution, instead of having to re-invent the wheel over and over again. Even when the wheel is only two or three lines. This is why we have dict.clear, for example, instead of: Just add this function to the top of every module and script def clear(d): for key in list(d.keys()): del d[key] We say, *not every* two line function needs to be a builtin, rather than **no** two line function. > Regular > expressions solve the problem of case-insensitive searching a position > of a substring. And now you have two problems... *wink* > If you asked a solution that magically prevent people > from making simple programming mistakes, there is no such solution. Very true. But when there is a common source of mistakes, we can help prevent that mistake. -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From matias.magni at gmail.com Thu Aug 31 10:50:02 2017 From: matias.magni at gmail.com (=?UTF-8?Q?Mat=C3=ADas_Magni?=) Date: Thu, 31 Aug 2017 11:50:02 -0300 Subject: Fwd: Your message to linuxCprogramming awaits moderator approval In-Reply-To: References: Message-ID: Hi everyone, I'm student of Computer Engineering at Universidad de Mendoza. I'm doing my final thesis project to get my degree and I elaborated a survey destined to web developers. If you're so kind, I would like you could fill it and broadcast it among your social environment. I would be very thankful with you. This is the link to the survey: https://en-matiasmagni.blogspot.com.ar/p/spa.html -- Mat?as J. Magni Development Team Leader (Action Associative) Development Team Leader (Digital Creative) Auxiliar Administrativo (Poder Judicial de Mendoza) E-mail alternativo: matiasmagni at gael-asso.com Skype: matias.magni Blogs: - http://matiasmagni.blogspot.com.ar - http://tic-laboral.blogspot.com.ar Curriculum Vitae: http://matiasmagni.blogspot.com.ar/p/curriculum-vitae.html -- Mat?as J. Magni Development Team Leader (Action Associative) Development Team Leader (Digital Creative) Auxiliar Administrativo (Poder Judicial de Mendoza) E-mail alternativo: matiasmagni at gael-asso.com Skype: matias.magni Blogs: - http://matiasmagni.blogspot.com.ar - http://tic-laboral.blogspot.com.ar Curriculum Vitae: http://matiasmagni.blogspot.com.ar/p/curriculum-vitae.html From storchaka at gmail.com Thu Aug 31 11:16:29 2017 From: storchaka at gmail.com (Serhiy Storchaka) Date: Thu, 31 Aug 2017 18:16:29 +0300 Subject: Case-insensitive string equality In-Reply-To: <59a81f5f$0$1608$c3e8da3$5496439d@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> <59a81f5f$0$1608$c3e8da3$5496439d@news.astraweb.com> Message-ID: 31.08.17 17:38, Steve D'Aprano ????: > On Thu, 31 Aug 2017 11:45 pm, Serhiy Storchaka wrote: > >> It is not clear what is your problem exactly. > > That is fair. This is why I am discussing it here first, before taking it to > Python-Ideas. At the moment my ideas on the matter are still half-formed. What are you discussing? Without knowing what problem you are solving and what solution your are proposed it is hard to discuss it. >> The easy one-line function >> solves the problem of testing case-insensitive string equality. > > True. Except that when a problem is as common as case-insensitive comparisons, > there should be a standard solution, instead of having to re-invent the wheel > over and over again. Even when the wheel is only two or three lines. This *is* a standard solution. Don't invent the wheel, just use it properly. > This is why we have dict.clear, for example, instead of: > > Just add this function to the top of every module and script > > def clear(d): > for key in list(d.keys()): del d[key] No, there are other reasons for adding the clear() method in dict. Performance and atomicity (and the latter is more important). > We say, *not every* two line function needs to be a builtin, rather than **no** > two line function. But there should be good reasons for this. >> If you asked a solution that magically prevent people >> from making simple programming mistakes, there is no such solution. > > Very true. But when there is a common source of mistakes, we can help prevent > that mistake. How can you do this? I know only one way -- teaching and practicing. From python.list at tim.thechases.com Thu Aug 31 11:29:29 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Thu, 31 Aug 2017 10:29:29 -0500 Subject: Case-insensitive string equality In-Reply-To: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <20170831102929.556bf28e@bigbox.christie.dr> On 2017-08-31 07:10, Steven D'Aprano wrote: > So I'd like to propose some additions to 3.7 or 3.8. Adding my "yes, a case-insensitive equality-check would be useful" with the following concerns: I'd want to have an optional parameter to take locale into consideration. E.g. "i".case_insensitive_equals("I") # depends on Locale "i".case_insensitive_equals("I", Locale("TR")) == False "i".case_insensitive_equals("I", Locale("US")) == True and other oddities like "?".case_insensitive_equals("SS") == True (though casefold() takes care of that later one). Then you get things like "III".case_insensitive_equals("\N{ROMAN NUMERAL THREE}") "iii".case_insensitive_equals("\N{ROMAN NUMERAL THREE}") "FI".case_insensitive_equals("\N{LATIN SMALL LIGATURE FI}") where the decomposition might need to be considered. There are just a lot of odd edge-cases to consider when discussing fuzzy equality. > (1) Add a new string method, This is my preferred avenue. > Alternatively: how about a === triple-equals operator to do the > same thing? No. A strong -1 for new operators. This peeves me in other languages (looking at you, PHP & JavaScript) > (2) Add keyword-only arguments to str.find and str.index: > > casefold=False > > which does nothing if false (the default), and switches to a > case- insensitive search if true. I'm okay with some means of conveying the insensitivity to str.find/str.index but have no interest in list.find/list.index growing similar functionality. I'm meh on the "casefold=False" syntax, especially in light of my hope it would take a locale for the comparisons. > Unsolved problems: > > This proposal doesn't help with sets and dicts, list.index and the > `in` operator either. I'd be less concerned about these. If you plan to index a set/dict by the key, normalize it before you put it in. Or perhaps create a CaseInsensitiveDict/CaseInsensitiveSet class. For lists and 'in' operator usage, it's not too hard to make up a helper function based on the newly-grown method: def case_insensitive_in(itr, target, locale=None): return any( target.case_insensitive_equals(x, locale) for x in itr ) def case_insensitive_index(itr, target, locale=None): for i, x in enumerate(itr): if target.case_insensitive_equals(x, locale): return i raise ValueError("Could not find %s" % target) -tkc From python.list at tim.thechases.com Thu Aug 31 11:34:37 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Thu, 31 Aug 2017 10:34:37 -0500 Subject: Case-insensitive string equality In-Reply-To: References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> Message-ID: <20170831103437.61212f50@bigbox.christie.dr> On 2017-08-31 23:30, Chris Angelico wrote: > The method you proposed seems a little odd - it steps through the > strings character by character and casefolds them separately. How is > it superior to the two-line function? And it still doesn't solve any > of your other cases. It also breaks when casefold() returns multiple characters: >>> s1 = 'ss' >>> s2 = 'SS' >>> s3 = '?' >>> equal(s1,s2) # using Steve's equal() function True >>> equal(s1,s3) False >>> equal(s2,s3) False >>> s1.casefold() == s2.casefold() True >>> s1.casefold() == s3.casefold() True >>> s2.casefold() == s3.casefold() True -tkc From __peter__ at web.de Thu Aug 31 12:17:19 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 31 Aug 2017 18:17:19 +0200 Subject: Case-insensitive string equality References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: Steven D'Aprano wrote: > Three times in the last week the devs where I work accidentally > introduced bugs into our code because of a mistake with case-insensitive > string comparisons. They managed to demonstrate three different failures: > > # 1 > a = something().upper() # normalise string > ... much later on > if a == b.lower(): ... A quick and dirty fix would be a naming convention: upcase_a = something().upper() > ... much later on > if upcase_a == b.lower(): ... Wait, what... From python.list at tim.thechases.com Thu Aug 31 12:26:06 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Thu, 31 Aug 2017 11:26:06 -0500 Subject: Case-insensitive string equality In-Reply-To: References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> Message-ID: <20170831112606.1efe3f47@bigbox.christie.dr> On 2017-08-31 18:17, Peter Otten wrote: > A quick and dirty fix would be a naming convention: > > upcase_a = something().upper() I tend to use a "_u" suffix as my convention: something_u = something.upper() which keeps the semantics of the original variable-name while hinting at the normalization. -tkc From ian.g.kelly at gmail.com Thu Aug 31 12:40:32 2017 From: ian.g.kelly at gmail.com (Ian Kelly) Date: Thu, 31 Aug 2017 10:40:32 -0600 Subject: Exponential Smoothing program In-Reply-To: <1358241856.358131.1504182921026@mail.yahoo.com> References: <1358241856.358131.1504182921026.ref@mail.yahoo.com> <1358241856.358131.1504182921026@mail.yahoo.com> Message-ID: On Thu, Aug 31, 2017 at 6:35 AM, Ode Idoko via Python-list wrote: > > I am running a master degree programme and very new to programming including python. I have been given a project to write a python program on exponential smoothing of some selected stocks. The program should user the user to input alpha, display the graph of the original data and "smoothed data". > > On the same python program, I am to develop a linear regression model to predict the next period, showing correlation coefficients to indicate the strength of the model. > > I have been able to write a program which returns some values but no graph and also having difficulties with the linear regression. SciPy (https://www.scipy.org/) will provide a linear regression for you. In particular, see https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html Matplotlib (https://matplotlib.org/) is a good tool for plotting graphs. I suggest starting with those. From rgaddi at highlandtechnology.invalid Thu Aug 31 12:40:35 2017 From: rgaddi at highlandtechnology.invalid (Rob Gaddi) Date: Thu, 31 Aug 2017 09:40:35 -0700 Subject: Exponential Smoothing program In-Reply-To: References: <1358241856.358131.1504182921026.ref@mail.yahoo.com> <1358241856.358131.1504182921026@mail.yahoo.com> Message-ID: On 08/31/2017 05:35 AM, Ode Idoko wrote: > > I am running a master degree programme and very new to programming including python. I have been given a project to write a python program on exponential smoothing of some selected stocks. The program should user the user to input alpha, display the graph of the original data and "smoothed data". > > On the same python program, I am to develop a linear regression model to predict the next period, showing correlation coefficients to indicate the strength of the model. > > I have been able to write a program which returns some values but no graph and also having difficulties with the linear regression. > > This is the program I wrote: > > def exponential_smoothing (a,y,f): > ans = (a*y) + (1-a) * f > return ans > > print ("Exponential_Smoothing Program") > a = float(input("please enter a: ")) > y = float(input("please enter y: ")) > f = float(input("please enter f: ")) > ans = exponential_smoothing (a,y,f) > print ("the answers are %.2f" %(ans)) > > Could someone kindly help with tips on how to go about this? > It's time to introduce yourself to Python's data analysis toolkit. Numpy, Scipy, Matplotlib and, if you're going to be doing stocks, Pandas. There's a LOT there between them, it's a bit of a drink from the firehose problem. I like Wes McKinney's "Python for Data Analysis" book and consider it a good investment if you need to get up to speed on this stuff. -- Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix. From gordon at panix.com Thu Aug 31 13:59:35 2017 From: gordon at panix.com (John Gordon) Date: Thu, 31 Aug 2017 17:59:35 +0000 (UTC) Subject: Case-insensitive string equality References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> <59a81f5f$0$1608$c3e8da3$5496439d@news.astraweb.com> Message-ID: In Serhiy Storchaka writes: > > But when there is a common source of mistakes, we can help prevent > > that mistake. > How can you do this? I know only one way -- teaching and practicing. Modify the environment so that the mistake simply can't happen (or at least happens much less frequently.) -- John Gordon A is for Amy, who fell down the stairs gordon at panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" From hslee911 at yahoo.com Thu Aug 31 14:02:54 2017 From: hslee911 at yahoo.com (James) Date: Thu, 31 Aug 2017 11:02:54 -0700 (PDT) Subject: pydoc3 in background Message-ID: How to run "pydoc3 -p port" in background? TIA James From pavol.lisy at gmail.com Thu Aug 31 14:36:46 2017 From: pavol.lisy at gmail.com (Pavol Lisy) Date: Thu, 31 Aug 2017 20:36:46 +0200 Subject: Case-insensitive string equality In-Reply-To: <59a81cf0$0$22141$c3e8da3$5496439d@news.astraweb.com> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <59a805d9$0$1583$c3e8da3$5496439d@news.astraweb.com> <59a81cf0$0$22141$c3e8da3$5496439d@news.astraweb.com> Message-ID: On 8/31/17, Steve D'Aprano wrote: >> Additionally: a proper "case insensitive comparison" should almost >> certainly start with a Unicode normalization. But should it be NFC/NFD >> or NFKC/NFKD? IMO that's a good reason to leave it in the hands of the >> application. > > Normalisation is orthogonal to comparisons and searches. Python doesn't > automatically normalise strings, as people have pointed out a bazillion > times > in the past, and it happily compares > > '?' LATIN SMALL LETTER O WITH DIAERESIS > > '?' LATIN SMALL LETTER O + COMBINING DIAERESIS > > > as unequal. I don't propose to change that just so that we can get 'a' > equals 'A' :-) Locale-dependent Case Mappings. The principal example of a case mapping that depends on the locale is Turkish, where U+0131 ??? latin small letter dotless i maps to U+0049 ?I? latin capital letter i and U+0069 ?i? latin small letter i maps to U+0130 ??? latin capital letter i with dot above. (source: http://www.unicode.org/versions/Unicode10.0.0/ch05.pdf) So 'SIKISIN'.casefold() could be dangerous -> https://translate.google.com/#tr/en/sikisin%0As%C4%B1k%C4%B1s%C4%B1n (although I am not sure if this story is true -> https://www.theinquirer.net/inquirer/news/1017243/cellphone-localisation-glitch ) From lab at 2020fresno.com Thu Aug 31 15:34:32 2017 From: lab at 2020fresno.com (20/20 Lab) Date: Thu, 31 Aug 2017 12:34:32 -0700 Subject: If you are running 32-bit 3.6 on Windows, please test this In-Reply-To: References: Message-ID: <2a450525-992c-a417-772f-2eb8eccfe26d@2020fresno.com> On 08/31/2017 01:53 AM, Pavol Lisy wrote: > On 8/31/17, Terry Reedy wrote: >> On 8/30/2017 1:35 PM, Terry Reedy wrote: >>> https://stackoverflow.com/questions/45965545/math-sqrt-domain-error-when-square-rooting-a-positive-number >>> >>> >>> >>> reports the following: >>> ----- >>> Microsoft Windows [Version 10.0.16251.1002] >>> (c) 2017 Microsoft Corporation. All rights reserved. >>> >>> C:\Users\Adam>python >>> Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit >>> (Intel)] on win32 >>> Type "help", "copyright", "credits" or "license" for more information. >>> >>> import math >>> >>> math.sqrt(1.3) >>> Traceback (most recent call last): >>> File "", line 1, in >>> ValueError: math domain error >>> >>> >>> >>> I upgraded from version 3.6.1 to 3.6.2 to try to resolve the issue and >>> restarted my computer but it is still occurring. Some numbers are >>> working (1.2, 1.4) and some others are also not working (1.128). >>> ---- >>> >>> Neither installed 64 bit 3.6.2 nor my repository 3.6 32-bit debug build >>> reproduce this. If anyone has the python.org 32bit 3.6.1/2 releases >>> installed on Windows, please test and report. >> Three people have reported that math.sqrt(1.3) works in 32 bit Python on >> 64-bit Windows and no one otherwise. I reported back on SO that the >> problem is likely local. Thanks for the responses. > Problem is reported on win10 and I see just 2 tests on win7 (third is > maybe Terry's but on SO I don't see win version). > > If I am not wrong (with analyze source code) sqrt is calling function > from "libm" which is some kind of msvcrt.dll on windows... (see > https://github.com/python/cpython/blob/a0ce375e10b50f7606cb86b072fed7d8cd574fe7/Modules/mathmodule.c#L1183 > and https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Lib/ctypes/util.py#L34 > ) > > And with "MSC v. 1900 ..." it seems that "alternative approaches" > (see here https://bugs.python.org/issue23606 ) are used. > > So I would be cautious. > > PS. > BTW on my ubuntu I got this: > > from ctypes import cdll > print(cdll.LoadLibrary("libcrypt.so")) > > print(cdll.LoadLibrary("libm.so")) > ... > OSError: /usr/lib/x86_64-linux-gnu/libm.so: invalid ELF header > > (same with distro's python3, python2 and anaconda 3.6.2) > > So this test -> > https://github.com/python/cpython/blob/6f0eb93183519024cb360162bdd81b9faec97ba6/Lib/ctypes/util.py#L328 > > has to crash on some environments (see for example: > https://github.com/scipy/scipy/pull/5416/files ). And it seems like > some test failures are just ignored... Valid point, fired up a windows 10 machine and worked as well. Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> import math >>> math.sqrt(1.3) 1.140175425099138 >>> This machine does not have the creators update yet. So there's that. From sean.dizazzo at gmail.com Thu Aug 31 17:04:55 2017 From: sean.dizazzo at gmail.com (Sean DiZazzo) Date: Thu, 31 Aug 2017 14:04:55 -0700 (PDT) Subject: traceback.format_exc() returns 'None\n'?! Message-ID: Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import traceback >>> tb = traceback.format_exc() >>> type(tb) >>> tb 'None\n' >>> Shouldn't it just return None itself? Why a string with a newline? Interested if there is an actual reason for this behavior or if it should be reported as a bug. ~Sean From __peter__ at web.de Thu Aug 31 17:48:48 2017 From: __peter__ at web.de (Peter Otten) Date: Thu, 31 Aug 2017 23:48:48 +0200 Subject: traceback.format_exc() returns 'None\n'?! References: Message-ID: Sean DiZazzo wrote: > Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47) > [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin > Type "help", "copyright", "credits" or "license" for more information. >>>> import traceback >>>> tb = traceback.format_exc() >>>> type(tb) > >>>> tb > 'None\n' >>>> > > > Shouldn't it just return None itself? No. The function expects that there is a current exception. That's not the case here, and thus it should complain in the usual way -- by raising an exception. However, this function has been around for a while which rules out such a disruptive change. > Why a string with a newline? > > Interested if there is an actual reason for this behavior An implementation accident, if I were to guess. > or if it should > be reported as a bug. Certainly not. From steve+python at pearwood.info Thu Aug 31 19:13:39 2017 From: steve+python at pearwood.info (Steve D'Aprano) Date: Fri, 01 Sep 2017 09:13:39 +1000 Subject: pydoc3 in background References: Message-ID: <59a89824$0$1611$c3e8da3$5496439d@news.astraweb.com> On Fri, 1 Sep 2017 04:02 am, James wrote: > How to run "pydoc3 -p port" in background? > > TIA > James pydoc3 -p port & -- Steve ?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure enough, things got worse. From python at mrabarnett.plus.com Thu Aug 31 19:53:38 2017 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 1 Sep 2017 00:53:38 +0100 Subject: Case-insensitive string equality In-Reply-To: <20170831102929.556bf28e@bigbox.christie.dr> References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <20170831102929.556bf28e@bigbox.christie.dr> Message-ID: On 2017-08-31 16:29, Tim Chase wrote: > On 2017-08-31 07:10, Steven D'Aprano wrote: >> So I'd like to propose some additions to 3.7 or 3.8. > > Adding my "yes, a case-insensitive equality-check would be useful" > with the following concerns: > > I'd want to have an optional parameter to take locale into > consideration. E.g. > > "i".case_insensitive_equals("I") # depends on Locale > "i".case_insensitive_equals("I", Locale("TR")) == False > "i".case_insensitive_equals("I", Locale("US")) == True > > and other oddities like > > "?".case_insensitive_equals("SS") == True > > (though casefold() takes care of that later one). Then you get > things like > > "III".case_insensitive_equals("\N{ROMAN NUMERAL THREE}") > "iii".case_insensitive_equals("\N{ROMAN NUMERAL THREE}") > "FI".case_insensitive_equals("\N{LATIN SMALL LIGATURE FI}") > > where the decomposition might need to be considered. There are just > a lot of odd edge-cases to consider when discussing fuzzy equality. > >> (1) Add a new string method, > > This is my preferred avenue. > >> Alternatively: how about a === triple-equals operator to do the >> same thing? > > No. A strong -1 for new operators. This peeves me in other > languages (looking at you, PHP & JavaScript) > >> (2) Add keyword-only arguments to str.find and str.index: >> >> casefold=False >> >> which does nothing if false (the default), and switches to a >> case- insensitive search if true. > > I'm okay with some means of conveying the insensitivity to > str.find/str.index but have no interest in list.find/list.index > growing similar functionality. I'm meh on the "casefold=False" > syntax, especially in light of my hope it would take a locale for the > comparisons. > [snip] What would you expect the result would be for: "\N{LATIN SMALL LIGATURE FI}".case_insensitive_find("F") "\N{LATIN SMALL LIGATURE FI}".case_insensitive_find("I) From python.list at tim.thechases.com Thu Aug 31 20:38:45 2017 From: python.list at tim.thechases.com (Tim Chase) Date: Thu, 31 Aug 2017 19:38:45 -0500 Subject: Case-insensitive string equality In-Reply-To: References: <59a7b652$0$2920$c3e8da3$76491128@news.astraweb.com> <20170831102929.556bf28e@bigbox.christie.dr> Message-ID: <20170831193845.370b82ae@bigbox.christie.dr> On 2017-09-01 00:53, MRAB wrote: > What would you expect the result would be for: > >>> "\N{LATIN SMALL LIGATURE FI}".case_insensitive_find("F") 0 >>> "\N{LATIN SMALL LIGATURE FI}".case_insensitive_find("I) 0.5 >>> "\N{LATIN SMALL LIGATURE FFI}".case_insensitive_find("I) 0.66666666666666666 ;-) (mostly joking, but those are good additional tests to consider) -tkc