From auriocus at gmx.de Fri Apr 1 01:41:09 2022 From: auriocus at gmx.de (Christian Gollwitzer) Date: Fri, 1 Apr 2022 07:41:09 +0200 Subject: Exchange OWA using Python? In-Reply-To: References: <6245bd93.1c69fb81.aa4d6.39b7@mx.google.com> <6246389e.1c69fb81.a040.264a@mx.google.com> Message-ID: Am 01.04.22 um 01:26 schrieb Grant Edwards: > On 2022-03-31, Christian Gollwitzer wrote: >> Davmail is written in Java, not Python, but basically this should >> not matter if you only use it. > > Have you used it with OWA as the protocol? > At least I thought so - this was in 2016 - 2017 and there was external webmail access allowed to our mail server. I've used davmail to connect to it. I vaguely remember that there was one day a sudden change, webmail was disabled and davmail then connected using EWS. Maybe the OWA protocol also evolved, I now see it on the roadmap. Good that you found a solution now with owl! I'm having a similar issue at my current position, we're using Lotus Notes (yes! The package from the 90s, it's outright horrible). There is only one thing available, the iNotes exporter, which allows to read the mail using thunderbird, sending is not implemented. Always keeping fingers crossed that the IT department does not update the server protocol. Sometimes they do minor changes like internal redirection URL changes, which costs me half a day to fix then. Christian From PythonList at DancesWithMice.info Sat Apr 2 13:27:46 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 3 Apr 2022 05:27:46 +1200 Subject: How to detect an undefined method? In-Reply-To: References: Message-ID: <222debfd-88aa-494e-bee2-8ae3dfd31a76@DancesWithMice.info> On 03/04/2022 02.28, anthony.flury wrote: > On 27/03/2022 15:59, dn wrote: > >> What is code coverage? >> In the simplest words, code coverage is a measure of exhaustiveness of a >> test suite. 100% code coverage means that a system is fully tested. > > Sorry, but that is a gross over-simplification. Please be careful how you trim messages/quote previous posts. Above gives an incorrect impression and attribution! The original text: ? The following article includes both pros and cons of using coverage.py: How to use code coverage in Python with pytest? April 11, 2021 Sebastian python, testing software Basics What is code coverage? In the simplest words, code coverage is a measure of exhaustiveness of a test suite. 100% code coverage means that a system is fully tested. ... https://breadcrumbscollector.tech/how-to-use-code-coverage-in-python-with-pytest/ ? Readers will be able to come to their own conclusions - which may very-well mirror your own. Another consideration is the context of the OP and the problem he was trying to solve. -- Regards, =dn From grant.b.edwards at gmail.com Fri Apr 1 11:52:47 2022 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 01 Apr 2022 08:52:47 -0700 (PDT) Subject: Exchange OWA using Python? References: <6245bd93.1c69fb81.aa4d6.39b7@mx.google.com> <6246389e.1c69fb81.a040.264a@mx.google.com> Message-ID: <62471fcf.1c69fb81.bde92.675d@mx.google.com> On 2022-04-01, Christian Gollwitzer wrote: > Am 01.04.22 um 01:26 schrieb Grant Edwards: >> On 2022-03-31, Christian Gollwitzer wrote: >>> Davmail is written in Java, not Python, but basically this should >>> not matter if you only use it. >> >> Have you used it with OWA as the protocol? > > At least I thought so - this was in 2016 - 2017 and there was external > webmail access allowed to our mail server. I've used davmail to connect > to it. I vaguely remember that there was one day a sudden change, > webmail was disabled and davmail then connected using EWS. Maybe the OWA > protocol also evolved, I now see it on the roadmap. It was probably at least 5 years ago when EWS got disabled and I couldn't get davmail to work any longer. It could be that davmail does support the OWA "API" now. I spent some more time browsing the davmail web site, and couldn't really find a clear statement one way or the other. > Good that you found a solution now with owl! It's taken some tweaking to get Thunderbird "adjusted". The Exchange server does some stupid tricks like adding marketing stuff to all messages before they're sent externally. The logic it uses to decide _where_ to insert that stuff isn't very good, and Thunderbird's default reply attribution line causes the marketing "footer" to be inserted at the top of the message. And if you're not careful about reply formatting, Outlook will decide to hide the entire message (a trick it uses to try to compensate for the brain-dead practice of replying on top and including a copy of all previous e-mails in the conversation (that way email disk storage is O(N^2) instead of O(N)) I also didn't like the appearance of quoted text in replies from Thunderbird, so I'm working on an extension to add some CSS to make quoted text look more like it does with other e-mail clients (with a "quote bar" on the left). Surprisingly, Thunderbird also lacks any sort of system-tray support. There's an add-on app that's supposed to do that, but I haven't tried it yet... > I'm having a similar issue at my current position, we're using Lotus > Notes (yes! The package from the 90s, it's outright horrible). Everybody I've ever known who has used Notes hated it. One wonders why it continues to be used... > There is only one thing available, the iNotes exporter, which allows > to read the mail using thunderbird, sending is not > implemented. Always keeping fingers crossed that the IT department > does not update the server protocol. Sometimes they do minor changes > like internal redirection URL changes, which costs me half a day to > fix then. I know how that goes. -- Grant From anthony.flury at btinternet.com Sat Apr 2 09:28:25 2022 From: anthony.flury at btinternet.com (anthony.flury) Date: Sat, 2 Apr 2022 14:28:25 +0100 Subject: How to detect an undefined method? In-Reply-To: References: Message-ID: On 27/03/2022 15:59, dn wrote: > What is code coverage? > In the simplest words, code coverage is a measure of exhaustiveness of a > test suite. 100% code coverage means that a system is fully tested. Sorry, but that is a gross over-simplification. 100% coverage means that you have tested all of the branches in a given module, or a given class; it absolutely does not mean it is fully tested. For example I can write code and unit-test cases for a trivial piece of code, and to achieve 100% coverage, but for the code to still fail on invalid input data, or for the code to fail due to exceptions from library code that my code doesn't handle. To claim to be fully tested a piece of code has to be exercised against *every* possible input and *every* single possible event from *every* single source - that alone makes 100% testing impossible. If you think logically about it, you can only test a very small fraction of all possible test cases; the key is to pick those cases which represent a good range of possible inputs and events (including both valid and invalid data, exceptions, errors etc). At best 100% coverage measure means that every branch through the code has been executed at least once by your test cases. It doesn't prove that your test cases are complete, or that your code takes into account all possible occurrences - 100% coverage doesn't mean it is fully tested. In terms of coverage,? achieving 100% coverage is a laudable target, but it is often either unachievable or not worth the effort; aiming to achieve a high value (say > 80%) is sensible target. If you achieve your high coverage count by doing black-box testing (ie. by testing to the specification of code and thinking what can right and what can go wrong), then the coverage is a more useful measure - if you write your unit-tests by looking at the code, then all that a high measurement means is that you are able (mostly) to read and understand your own code. -- Anthony Flury *Moble*: +44 07743 282707 *Home*: +44 (0)1206 391294 *email*: anthony.flury at btinternet.com From my.alaoui.ia at gmail.com Sat Apr 2 14:50:43 2022 From: my.alaoui.ia at gmail.com (Abdellah ALAOUI ISMAILI) Date: Sat, 2 Apr 2022 11:50:43 -0700 (PDT) Subject: flask app convert sql query to python plotly. Message-ID: i would like to convert in my flask app an SQL query to an plotly pie chart using pandas. this is my code : def query_tickets_status() : query_result = pd.read_sql (""" SELECT COUNT(*)count_status, status FROM tickets GROUP BY status""", con = mydc_db) return query_result labels_statut = query_tickets_status['status'] values_statut = query_tickets_status['count_status'] fig = go.Figure(data=[go.Pie(labels=labels_statut, values=values_statut)]) graphSuppliers = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) return render_template('admin/dashboard.html', graphSuppliers = graphSuppliers) this is my template file.

Your Plotly Chart

but I get this error : TypeError: 'function' object is not subscriptable From python at example.invalid Sat Apr 2 14:56:40 2022 From: python at example.invalid (Python) Date: Sat, 2 Apr 2022 20:56:40 +0200 Subject: flask app convert sql query to python plotly References: <48b7f8b7-9aef-4cbc-8ecb-b2d214aceb86n@googlegroups.com> Message-ID: Abdellah ALAOUI ISMAILI wrote: > def query_tickets_status() : > query_result = pd.read_sql (""" > SELECT COUNT(*)count_status, status > FROM tickets > GROUP BY status""", con = mydc_db) > return query_result > > labels_statut = query_tickets_status['status'] labels_statut = query_tickets_status()['status'] From Marco.Sulla.Python at gmail.com Sat Apr 2 16:44:22 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 2 Apr 2022 22:44:22 +0200 Subject: dict.get_deep() Message-ID: A proposal. Very often dict are used as a deeply nested carrier of data, usually decoded from JSON. Sometimes I needed to get some of this data, something like this: data["users"][0]["address"]["street"] What about something like this instead? data.get_deep("users", 0, "address", "street") and also, instead of this try: result = data["users"][0]["address"]["street"] except KeyError, IndexError: result = "second star" write this: data.get_deep("users", 0, "address", "street", default="second star") ? From kirill.ratkin at devoteam.com Sun Apr 3 10:58:09 2022 From: kirill.ratkin at devoteam.com (Kirill Ratkin) Date: Sun, 3 Apr 2022 17:58:09 +0300 Subject: dict.get_deep() In-Reply-To: References: Message-ID: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> Hi Marco. Recently I met same issue. A service I intergated with was documented badly and sent ... unpredictable jsons. And pattern matching helped me in first solution. (later I switched to Pydantic models) For your example I'd make match rule for key path you need. For example: data = {"users": [{"address": {"street": "Baker"}}]} match data: ??? case {"users": [{"address": {"street": street}}]}: ??????? print(f"street: {street}") ??? case _: ??????? print("unsupported message structure") Structural matching gives you warranty you process exactly message you expect and explicitly discards messages with another structure. But type is still issue. I don't know how to say 'street' must be 'str' not 'int'. That's why I switched to Pydantic. 02.04.2022 23:44, Marco Sulla ?????: > A proposal. Very often dict are used as a deeply nested carrier of > data, usually decoded from JSON. Sometimes I needed to get some of > this data, something like this: > > data["users"][0]["address"]["street"] > > What about something like this instead? > > data.get_deep("users", 0, "address", "street") > > and also, instead of this > > try: > result = data["users"][0]["address"]["street"] > except KeyError, IndexError: > result = "second star" > > write this: > > data.get_deep("users", 0, "address", "street", default="second star") > > ? From kirill.ratkin at devoteam.com Sun Apr 3 11:01:58 2022 From: kirill.ratkin at devoteam.com (Kirill Ratkin) Date: Sun, 3 Apr 2022 18:01:58 +0300 Subject: dict.get_deep() In-Reply-To: References: Message-ID: <8c7d83a2-20fe-3697-08a1-2fe733247976@devoteam.com> To my previous post. It seems 'case if' should help with types: case {"users": [{"address": {"street": street}}]} if isinstance(street, str): :) // BR 02.04.2022 23:44, Marco Sulla ?????: > A proposal. Very often dict are used as a deeply nested carrier of > data, usually decoded from JSON. Sometimes I needed to get some of > this data, something like this: > > data["users"][0]["address"]["street"] > > What about something like this instead? > > data.get_deep("users", 0, "address", "street") > > and also, instead of this > > try: > result = data["users"][0]["address"]["street"] > except KeyError, IndexError: > result = "second star" > > write this: > > data.get_deep("users", 0, "address", "street", default="second star") > > ? From rosuav at gmail.com Sun Apr 3 11:07:18 2022 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 4 Apr 2022 01:07:18 +1000 Subject: dict.get_deep() In-Reply-To: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> Message-ID: On Mon, 4 Apr 2022 at 00:59, Kirill Ratkin via Python-list wrote: > > Hi Marco. > > Recently I met same issue. A service I intergated with was documented > badly and sent ... unpredictable jsons. > > And pattern matching helped me in first solution. (later I switched to > Pydantic models) > > For your example I'd make match rule for key path you need. For example: > > > data = {"users": [{"address": {"street": "Baker"}}]} > > match data: > case {"users": [{"address": {"street": street}}]}: > print(f"street: {street}") > > case _: > print("unsupported message structure") > > > Structural matching gives you warranty you process exactly message you > expect and explicitly discards messages with another structure. > > But type is still issue. I don't know how to say 'street' must be 'str' > not 'int'. That's why I switched to Pydantic. > You can use type names to require that it be that type: case {"users": [{"address": {"street": str(street)}}]}: ChrisA From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Apr 3 11:44:04 2022 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 3 Apr 2022 10:44:04 -0500 Subject: dict.get_deep() In-Reply-To: <8c7d83a2-20fe-3697-08a1-2fe733247976@devoteam.com> References: <8c7d83a2-20fe-3697-08a1-2fe733247976@devoteam.com> Message-ID: On 2022-04-03 at 18:01:58 +0300, Kirill Ratkin via Python-list wrote: > It seems 'case if' should help with types: > > case {"users": [{"address": {"street": street}}]} if isinstance(street, > str): reduce(lambda x, y: x[y], ["users", 0, "address", "street"], data) Unless it's y[x] rather than x[y], and there might be a More Cleverer? way to do it with getattr or one of its relatives instead of lambda. > 02.04.2022 23:44, Marco Sulla ?????: > > A proposal. Very often dict are used as a deeply nested carrier of > > data, usually decoded from JSON. Sometimes I needed to get some of > > this data, something like this: > > > > data["users"][0]["address"]["street"] > > > > What about something like this instead? > > > > data.get_deep("users", 0, "address", "street") > > > > and also, instead of this > > > > try: > > result = data["users"][0]["address"]["street"] > > except KeyError, IndexError: > > result = "second star" > > > > write this: > > > > data.get_deep("users", 0, "address", "street", default="second star") From dieter at handshake.de Sun Apr 3 12:57:50 2022 From: dieter at handshake.de (Dieter Maurer) Date: Sun, 3 Apr 2022 18:57:50 +0200 Subject: dict.get_deep() In-Reply-To: References: Message-ID: <25161.53774.591627.704710@ixdm.fritz.box> Marco Sulla wrote at 2022-4-2 22:44 +0200: >A proposal. Very often dict are used as a deeply nested carrier of >data, usually decoded from JSON. Sometimes I needed to get some of >this data, something like this: > >data["users"][0]["address"]["street"] > >What about something like this instead? > >data.get_deep("users", 0, "address", "street") > >and also, instead of this > >try: > result = data["users"][0]["address"]["street"] >except KeyError, IndexError: > result = "second star" > >write this: > >data.get_deep("users", 0, "address", "street", default="second star") You know you can easily implement this yourself -- in your own `dict` subclass. You can also customize the JSON decoding (--> `object_hook`) to determine how a JSON object is mapped to a Python object; it defaults to `dict` but you could use your own `dict` subclass. From Marco.Sulla.Python at gmail.com Sun Apr 3 15:14:13 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 3 Apr 2022 21:14:13 +0200 Subject: dict.get_deep() In-Reply-To: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> Message-ID: On Sun, 3 Apr 2022 at 16:59, Kirill Ratkin via Python-list wrote: > > Hi Marco. > > Recently I met same issue. A service I intergated with was documented > badly and sent ... unpredictable jsons. > > And pattern matching helped me in first solution. (later I switched to > Pydantic models) > > For your example I'd make match rule for key path you need. For example: > > > data = {"users": [{"address": {"street": "Baker"}}]} > > match data: > case {"users": [{"address": {"street": street}}]}: > print(f"street: {street}") > > case _: > print("unsupported message structure") Hi. I think your solution is very brilliant, but I'm a bit allergic to pattern matching... :D Maybe it's me, but I found it really strange and "magical". From Marco.Sulla.Python at gmail.com Sun Apr 3 15:17:13 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 3 Apr 2022 21:17:13 +0200 Subject: dict.get_deep() In-Reply-To: <25161.53774.591627.704710@ixdm.fritz.box> References: <25161.53774.591627.704710@ixdm.fritz.box> Message-ID: On Sun, 3 Apr 2022 at 18:57, Dieter Maurer wrote: > You know you can easily implement this yourself -- in your own > `dict` subclass. Well, of course, but the question is if such a method is worth to be builtin, in a world imbued with JSON. I suppose your answer is no. From hjp-python at hjp.at Sun Apr 3 15:45:12 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 3 Apr 2022 21:45:12 +0200 Subject: dict.get_deep() In-Reply-To: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> Message-ID: <20220403194512.kcqo6zn5yjryvxz5@hjp.at> On 2022-04-03 17:58:09 +0300, Kirill Ratkin via Python-list wrote: > 02.04.2022 23:44, Marco Sulla ?????: > > A proposal. Very often dict are used as a deeply nested carrier of > > data, usually decoded from JSON. Sometimes I needed to get some of > > this data, something like this: > > > > data["users"][0]["address"]["street"] > > > > What about something like this instead? > > > > data.get_deep("users", 0, "address", "street") Yup. I need something like this quite frequently, so I wrote a little utility function (which I copy and paste into lots of code - I probably should package that up, but a package with a single short function feels weird). [...] > > data.get_deep("users", 0, "address", "street", default="second star") Yep. Did that, too. Plus pass the final result through a function before returning it. I'm not sure whether I considered this when I wrote it, but a function has the advantage of working with every class which can be indexed. A method must be implemented on any class (so at least dict and list to be useful). > Recently I met same issue. A service I intergated with was documented badly > and sent ... unpredictable jsons. > > And pattern matching helped me in first solution. (later I switched to > Pydantic models) > > For your example I'd make match rule for key path you need. For example: > > > data = {"users": [{"address": {"street": "Baker"}}]} > > match data: > ??? case {"users": [{"address": {"street": street}}]}: > ??????? print(f"street: {street}") > > ??? case _: > ??????? print("unsupported message structure") Neat. But that's 5 lines instead of one. I simple loop around try/except also takes 5 lines, and the latter can be easily moved into a function, like this: def get_nested(coll, path, default=None, cast=None): for i in path: try: coll = coll[i] except (KeyError, IndexError, TypeError): return default if cast: coll = cast(coll) return coll which can then be called in a single line. > Structural matching gives you warranty you process exactly message you > expect and explicitly discards messages with another structure. True, and sometimes useful, I'm sure. Not sure whether it would have helped me in the cases where I used the utility function above. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From lizzyhollins99 at gmail.com Sun Apr 3 14:00:33 2022 From: lizzyhollins99 at gmail.com (Betty Hollinshead) Date: Sun, 3 Apr 2022 11:00:33 -0700 (PDT) Subject: Sharing part of a function In-Reply-To: <871qyejwwc.fsf@munus.decebal.nl> References: <871qyejwwc.fsf@munus.decebal.nl> Message-ID: <410b1646-34a2-4974-a344-1e8360a2a8aan@googlegroups.com> "Memoising" is the answer -- see "Python Algorithms" by Magnus Lie Hetland. In the mean time, here a simplified version of "memoising" using a dict. This version handles pretty large fibonacci numbers! # fibonacci sequence # memoised - but using a simple dictionary (see Python Algorithms, p177) memo = {} memo[1] = 1 memo[2] = 2 def fib(n): if n in memo: return memo[n] else: memo[n] = fib(n - 1) + fib(n - 2) return memo[n] print(100, fib(100)) print(memo) From Marco.Sulla.Python at gmail.com Sun Apr 3 17:17:04 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 3 Apr 2022 23:17:04 +0200 Subject: dict.get_deep() In-Reply-To: <20220403194512.kcqo6zn5yjryvxz5@hjp.at> References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> <20220403194512.kcqo6zn5yjryvxz5@hjp.at> Message-ID: On Sun, 3 Apr 2022 at 21:46, Peter J. Holzer wrote: > > > > data.get_deep("users", 0, "address", "street", default="second star") > > Yep. Did that, too. Plus pass the final result through a function before > returning it. I didn't understand. Have you added a func parameter? > I'm not sure whether I considered this when I wrote it, but a function > has the advantage of working with every class which can be indexed. A > method must be implemented on any class (so at least dict and list to be > useful). You're right, but where to put it? I don't know if an iterableutil package exists. If included in the stdlib, I don't know where to put it. In collections maybe? PS: if you're interested, here is my implementation: def get_deep(self, *args, default=_sentinel): r""" Get a nested element of the dictionary. The method accepts multiple arguments or a single one. If a single argument is passed, it must be an iterable. This represents the keys or indexes of the nested element. The method first tries to get the value v1 of the dict using the first key. If it finds v1 and there's no other key, v1 is returned. Otherwise, the method tries to retrieve the value from v1 associated with the second key/index, and so on. If in any point, for any reason, the value can't be retrieved, the `default` parameter is returned if specified. Otherwise, a KeyError or an IndexError is raised. """ if len(args) == 1: single = True it_tpm = args[0] try: len(it_tpm) it = it_tpm except Exception: # maybe it's a generator try: it = tuple(it_tpm) except Exception: err = ( f"`{self.get_deep.__name__}` called with a single " + "argument supports only iterables" ) raise TypeError(err) from None else: it = args single = False if not it: if single: raise ValueError( f"`{self.get_deep.__name__}` argument is empty" ) else: raise TypeError( f"`{self.get_deep.__name__}` expects at least one argument" ) obj = self for k in it: try: obj = obj[k] except (KeyError, IndexError) as e: if default is _sentinel: raise e from None return default return obj From Cecil at decebal.nl Sun Apr 3 17:27:21 2022 From: Cecil at decebal.nl (Cecil Westerhof) Date: Sun, 03 Apr 2022 23:27:21 +0200 Subject: Sharing part of a function References: <871qyejwwc.fsf@munus.decebal.nl> <410b1646-34a2-4974-a344-1e8360a2a8aan@googlegroups.com> Message-ID: <87k0c5j1s6.fsf@munus.decebal.nl> Betty Hollinshead writes: > "Memoising" is the answer -- see "Python Algorithms" by Magnus Lie Hetland. > In the mean time, here a simplified version of "memoising" using a dict. > This version handles pretty large fibonacci numbers! > > # fibonacci sequence > # memoised - but using a simple dictionary (see Python Algorithms, p177) > > memo = {} > memo[1] = 1 > memo[2] = 2 > > def fib(n): > if n in memo: > return memo[n] > else: > memo[n] = fib(n - 1) + fib(n - 2) > return memo[n] > > > print(100, fib(100)) > print(memo) No, it is not. It is the answer on a completely different question. Nice, but not what I was asking about. And there is even an error in the solution. By the way: it is better to do it iterative. Try (when not done a calculation before) fib(3_000). -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From rosuav at gmail.com Sun Apr 3 17:52:14 2022 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 4 Apr 2022 07:52:14 +1000 Subject: dict.get_deep() In-Reply-To: References: <25161.53774.591627.704710@ixdm.fritz.box> Message-ID: On Mon, 4 Apr 2022 at 05:19, Marco Sulla wrote: > > On Sun, 3 Apr 2022 at 18:57, Dieter Maurer wrote: > > You know you can easily implement this yourself -- in your own > > `dict` subclass. > > Well, of course, but the question is if such a method is worth to be > builtin, in a world imbued with JSON. I suppose your answer is no. I think not, for a slightly different reason: There are many small variants of it that might be needed. For instance, I have a system of persistent data that is backed by a JSON file, and I have a path function that does this: def path(self, *parts): ret = self.data # always a dict for part in parts: if part not in ret: ret[part] = {} self.save() # queue a save for the next idle time ret = ret[part] return ret It's used something like this: cfg = persist.path("channels", channame, "alerts", "host") and if there had previously been no configs, you'll get back an empty dict, not None, not an error, etc. This version uses dictionaries only. A version that also supports lists would require one more check before the "part not in ret" check (probably something like "if this is a list, and you're asking for an index higher than the current one, append elements till we get there"), and a version that doesn't autosave wouldn't need the save() call, etc, etc, etc. IMO this is an extremely useful tool to have in your own toolbelt, but I actually don't use *identical* versions of it very often. They're usually subtly different from each other, due to the slight differences in usage. ChrisA From dieter at handshake.de Sun Apr 3 17:53:34 2022 From: dieter at handshake.de (Dieter Maurer) Date: Sun, 3 Apr 2022 23:53:34 +0200 Subject: dict.get_deep() In-Reply-To: References: <25161.53774.591627.704710@ixdm.fritz.box> Message-ID: <25162.5982.559508.621172@ixdm.fritz.box> Marco Sulla wrote at 2022-4-3 21:17 +0200: >On Sun, 3 Apr 2022 at 18:57, Dieter Maurer wrote: >> You know you can easily implement this yourself -- in your own >> `dict` subclass. > >Well, of course, but the question is if such a method is worth to be >builtin, in a world imbued with JSON. I suppose your answer is no. ``` def mget(m, *keys): """return m[k1][k2]...[kn] or `None`""" for k in keys(): if k not in m: return m = m[k] return m ``` Thus, it is so simple to get what you want. No need to make it builtin. -- Dieter From drsalists at gmail.com Sun Apr 3 18:18:24 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 3 Apr 2022 15:18:24 -0700 Subject: Sharing part of a function In-Reply-To: <87k0c5j1s6.fsf@munus.decebal.nl> References: <871qyejwwc.fsf@munus.decebal.nl> <410b1646-34a2-4974-a344-1e8360a2a8aan@googlegroups.com> <87k0c5j1s6.fsf@munus.decebal.nl> Message-ID: On Sun, Apr 3, 2022 at 2:46 PM Cecil Westerhof via Python-list < python-list at python.org> wrote: > Betty Hollinshead writes: > > > "Memoising" is the answer -- see "Python Algorithms" by Magnus Lie > Hetland. > > In the mean time, here a simplified version of "memoising" using a dict. > > This version handles pretty large fibonacci numbers! > > > > # fibonacci sequence > > # memoised - but using a simple dictionary (see Python Algorithms, p177) > > > > memo = {} > > memo[1] = 1 > > memo[2] = 2 > > > > def fib(n): > > if n in memo: > > return memo[n] > > else: > > memo[n] = fib(n - 1) + fib(n - 2) > > return memo[n] > > > > > > print(100, fib(100)) > > print(memo) > > No, it is not. It is the answer on a completely different question. > Nice, but not what I was asking about. And there is even an error in > the solution. > > By the way: it is better to do it iterative. Try (when not done a > calculation before) fib(3_000). > I think I missed part of this conversation, but here is how I've done fibonacci numbers in the past, using functools.lru_cache: #!/usr/local/cpython-3.8/bin/python """Compute the first n numbers in the fibonacci sequence.""" import functools import sys @functools.lru_cache(maxsize=None) # pylint: disable=no-member def find_recursive(number): """Find a Fibonacci number recursively - without the callstack explosion.""" assert number >= 0 if number == 0: return 0 if number == 1: return 1 result = find_recursive(number - 1) + find_recursive(number - 2) return result def main(): """Compute fibonacci numbers.""" top = 5000 if sys.argv[1:]: top = int(sys.argv[1]) if sys.argv[2:]: sys.stderr.write('Usage: {} 5000\n'.format(sys.argv[0])) sys.exit(1) for number in range(1, top + 1): print(number, find_recursive(number)) main() From avigross at verizon.net Sun Apr 3 19:24:35 2022 From: avigross at verizon.net (Avi Gross) Date: Sun, 3 Apr 2022 23:24:35 +0000 (UTC) Subject: dict.get_deep() In-Reply-To: References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> <20220403194512.kcqo6zn5yjryvxz5@hjp.at> Message-ID: <1617313993.737226.1649028275904@mail.yahoo.com> I may have misunderstood something. The original post in this subject sounded to ME likethey had nested dictionaries and wanted to be ableto ask a method in the first dictionary totake an unspecified number of arguments thatwould be successive keys and return the results. I mean if A was a dictionary containing saycities and it had an alphabetical index of lettersA to Z and those contained dictionaries ofsay last names as additional dictionaries andso on, then they wanted to perhaps say; A.getdeep("Boston", "S", "Smith", "Address", default="None") But the replies I am seeing look so different that I mayhave missed something as it seems more about usingpattern matching on the data used to make the dictionariesor something. So I was happy to see Marco suggesting a function alongthe lines of my thought process. But I have another? thought.A stand-alone function along his lines might be fine. Buta method built into a general Dictionary class is anotherthing as it asks a method in one dictionary to march aroundinto other dictionaries. So I wonder if a better methodis sort of recursive.? If you had a class like dictionary that had a getdeep function,and it got called with N arguments, and perhaps a namedargument supplying a default, then would it make sensefor the function checking to see if the FIRST argument canbe found as a key to the current dictionary.? If arguments remain then it should expect to finda result that is a dictionary (or perhaps some otherobject that supports the getdeep() protocol and ask thatobject to operate on the N-1 remaining arguments, passingthe default along too. If the request is valid, after some iterations an object willhave a method invoked with a single argument (plus default)and a value passed back up the chain. For any errors alongthe way, the default would be returned. Is this closer to the spirit of the request? I view this versionof nested dictionaries as a sort of tree structure with variablebranches along the way. So an approach like this could makesense and perhaps Python could be updated eventually to havesome objects support such a protocol. Of course you could sort of do it yourself by subclassing somethingand making changes but that may not work for what is already asort of built-in data structure but could work for one of many variantsalready implemented in modules. -----Original Message----- From: Marco Sulla To: Peter J. Holzer Cc: python-list at python.org Sent: Sun, Apr 3, 2022 5:17 pm Subject: Re: dict.get_deep() On Sun, 3 Apr 2022 at 21:46, Peter J. Holzer wrote: > > > > data.get_deep("users", 0, "address", "street", default="second star") > > Yep. Did that, too. Plus pass the final result through a function before > returning it. I didn't understand. Have you added a func parameter? > I'm not sure whether I considered this when I wrote it, but a function > has the advantage of working with every class which can be indexed. A > method must be implemented on any class (so at least dict and list to be > useful). You're right, but where to put it? I don't know if an iterableutil package exists. If included in the stdlib, I don't know where to put it. In collections maybe? PS: if you're interested, here is my implementation: def get_deep(self, *args, default=_sentinel): ? ? r""" ? ? Get a nested element of the dictionary. ? ? The method accepts multiple arguments or a single one. If a single ? ? argument is passed, it must be an iterable. This represents the ? ? keys or indexes of the nested element. ? ? The method first tries to get the value v1 of the dict using the ? ? first key. If it finds v1 and there's no other key, v1 is ? ? returned. Otherwise, the method tries to retrieve the value from v1 ? ? associated with the second key/index, and so on. ? ? If in any point, for any reason, the value can't be retrieved, the ? ? `default` parameter is returned if specified. Otherwise, a ? ? KeyError or an IndexError is raised. ? ? """ ? ? if len(args) == 1: ? ? ? ? single = True ? ? ? ? it_tpm = args[0] ? ? ? ? try: ? ? ? ? ? ? len(it_tpm) ? ? ? ? ? ? it = it_tpm ? ? ? ? except Exception: ? ? ? ? ? ? # maybe it's a generator ? ? ? ? ? ? try: ? ? ? ? ? ? ? ? it = tuple(it_tpm) ? ? ? ? ? ? except Exception: ? ? ? ? ? ? ? ? err = ( ? ? ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` called with a single " + ? ? ? ? ? ? ? ? ? ? "argument supports only iterables" ? ? ? ? ? ? ? ? ) ? ? ? ? ? ? ? ? raise TypeError(err) from None ? ? else: ? ? ? ? it = args ? ? ? ? single = False ? ? if not it: ? ? ? ? if single: ? ? ? ? ? ? raise ValueError( ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` argument is empty" ? ? ? ? ? ? ) ? ? ? ? else: ? ? ? ? ? ? raise TypeError( ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` expects at least one argument" ? ? ? ? ? ? ) ? ? obj = self ? ? for k in it: ? ? ? ? try: ? ? ? ? ? ? obj = obj[k] ? ? ? ? except (KeyError, IndexError) as e: ? ? ? ? ? ? if default is _sentinel: ? ? ? ? ? ? ? ? raise e from None ? ? ? ? ? ? return default ? ? return obj -- https://mail.python.org/mailman/listinfo/python-list From kirill.ratkin at devoteam.com Mon Apr 4 03:40:47 2022 From: kirill.ratkin at devoteam.com (Kirill Ratkin) Date: Mon, 4 Apr 2022 10:40:47 +0300 Subject: dict.get_deep() In-Reply-To: <1617313993.737226.1649028275904@mail.yahoo.com> References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> <20220403194512.kcqo6zn5yjryvxz5@hjp.at> <1617313993.737226.1649028275904@mail.yahoo.com> Message-ID: <33bfa854-004f-30e2-1ebe-b964797d1e73@devoteam.com> Hello, Yes, I misunderstood as well because started to think about pattern matching which is good but this is not subject the question was about. Sorry for my mistake. Because question was about 'builtin' function which means stdlib function implemented in python itself or even in C. It seems, maybe I miss again, but we are talking about similar ideas behind 'xpath' or 'jsonpath' or even 'LINQ'. We want to find some 'dsl' which give us simple and safe way to get deeply nested values from dict. There are several similar solutions on pypi (https://pypi.org/project/dpath/, https://pypi.org/project/path-dict/). But maybe (and maybe I miss again) we talk about language embedded solution like operator ? or ??. For example deep dict extraction could look like: street = data["users"]?[0]?["address"]?["street"]?. // BR 04.04.2022 2:24, Avi Gross via Python-list ?????: > I may have misunderstood something. > The original post in this subject sounded to ME likethey had nested dictionaries and wanted to be ableto ask a method in the first dictionary totake an unspecified number of arguments thatwould be successive keys and return the results. > I mean if A was a dictionary containing saycities and it had an alphabetical index of lettersA to Z and those contained dictionaries ofsay last names as additional dictionaries andso on, then they wanted to perhaps say; > A.getdeep("Boston", "S", "Smith", "Address", default="None") > But the replies I am seeing look so different that I mayhave missed something as it seems more about usingpattern matching on the data used to make the dictionariesor something. > So I was happy to see Marco suggesting a function alongthe lines of my thought process. But I have another? thought.A stand-alone function along his lines might be fine. Buta method built into a general Dictionary class is anotherthing as it asks a method in one dictionary to march aroundinto other dictionaries. So I wonder if a better methodis sort of recursive. > If you had a class like dictionary that had a getdeep function,and it got called with N arguments, and perhaps a namedargument supplying a default, then would it make sensefor the function checking to see if the FIRST argument canbe found as a key to the current dictionary. > If arguments remain then it should expect to finda result that is a dictionary (or perhaps some otherobject that supports the getdeep() protocol and ask thatobject to operate on the N-1 remaining arguments, passingthe default along too. > If the request is valid, after some iterations an object willhave a method invoked with a single argument (plus default)and a value passed back up the chain. For any errors alongthe way, the default would be returned. > Is this closer to the spirit of the request? I view this versionof nested dictionaries as a sort of tree structure with variablebranches along the way. So an approach like this could makesense and perhaps Python could be updated eventually to havesome objects support such a protocol. > Of course you could sort of do it yourself by subclassing somethingand making changes but that may not work for what is already asort of built-in data structure but could work for one of many variantsalready implemented in modules. > > > > -----Original Message----- > From: Marco Sulla > To: Peter J. Holzer > Cc: python-list at python.org > Sent: Sun, Apr 3, 2022 5:17 pm > Subject: Re: dict.get_deep() > > On Sun, 3 Apr 2022 at 21:46, Peter J. Holzer wrote: >>>> data.get_deep("users", 0, "address", "street", default="second star") >> Yep. Did that, too. Plus pass the final result through a function before >> returning it. > I didn't understand. Have you added a func parameter? > >> I'm not sure whether I considered this when I wrote it, but a function >> has the advantage of working with every class which can be indexed. A >> method must be implemented on any class (so at least dict and list to be >> useful). > You're right, but where to put it? I don't know if an iterableutil package > exists. If included in the stdlib, I don't know where to put it. In > collections maybe? > > PS: if you're interested, here is my implementation: > > def get_deep(self, *args, default=_sentinel): > ? ? r""" > ? ? Get a nested element of the dictionary. > > ? ? The method accepts multiple arguments or a single one. If a single > ? ? argument is passed, it must be an iterable. This represents the > ? ? keys or indexes of the nested element. > > ? ? The method first tries to get the value v1 of the dict using the > ? ? first key. If it finds v1 and there's no other key, v1 is > ? ? returned. Otherwise, the method tries to retrieve the value from v1 > ? ? associated with the second key/index, and so on. > > ? ? If in any point, for any reason, the value can't be retrieved, the > ? ? `default` parameter is returned if specified. Otherwise, a > ? ? KeyError or an IndexError is raised. > ? ? """ > > ? ? if len(args) == 1: > ? ? ? ? single = True > > ? ? ? ? it_tpm = args[0] > > ? ? ? ? try: > ? ? ? ? ? ? len(it_tpm) > ? ? ? ? ? ? it = it_tpm > ? ? ? ? except Exception: > ? ? ? ? ? ? # maybe it's a generator > ? ? ? ? ? ? try: > ? ? ? ? ? ? ? ? it = tuple(it_tpm) > ? ? ? ? ? ? except Exception: > ? ? ? ? ? ? ? ? err = ( > ? ? ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` called with a single " + > ? ? ? ? ? ? ? ? ? ? "argument supports only iterables" > ? ? ? ? ? ? ? ? ) > > ? ? ? ? ? ? ? ? raise TypeError(err) from None > ? ? else: > ? ? ? ? it = args > ? ? ? ? single = False > > ? ? if not it: > ? ? ? ? if single: > ? ? ? ? ? ? raise ValueError( > ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` argument is empty" > ? ? ? ? ? ? ) > ? ? ? ? else: > ? ? ? ? ? ? raise TypeError( > ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` expects at least one argument" > ? ? ? ? ? ? ) > > ? ? obj = self > > ? ? for k in it: > ? ? ? ? try: > ? ? ? ? ? ? obj = obj[k] > ? ? ? ? except (KeyError, IndexError) as e: > ? ? ? ? ? ? if default is _sentinel: > ? ? ? ? ? ? ? ? raise e from None > > ? ? ? ? ? ? return default > > ? ? return obj From tdldev at gmail.com Mon Apr 4 07:36:31 2022 From: tdldev at gmail.com (Jack Dangler) Date: Mon, 4 Apr 2022 07:36:31 -0400 Subject: googletrans in python In-Reply-To: References: Message-ID: <7d17daab-105e-4574-7731-b486a6f25ef2@gmail.com> On 4/12/21 15:24, Karsten Hilbert wrote: > Am Mon, Apr 12, 2021 at 12:48:23PM -0400 schrieb Quentin Bock: > >> Can someone explain the basics of googletrans in python? >> I want to make a program that translates stories into English, but I'm not >> sure how to get a translation printed. Also, is this needed to be done in >> an HTML file inside python? >> If so can someone provide basic code for a translation and how that should >> be written and work? > You might want to post the entire homework assignment verbatim. > > That way people might better understand which part of it to > help you with in what way. > > As to your description of what you want to achieve -- what > did you already try ? > > Karsten > -- > GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B A quick google run turns up a lot of stuff with various interfaces, Pypi being one of the more consistent. However, if the more technical theorist or stoic documentation sites don't help you, this one seems to at least take a more 'tutorial' approach - https://medium.com/mlearning-ai/translate-famous-quotes-one-language-to-another-for-fun-using-googletrans-644956e3313a Do post an update to how you are getting on. Many more people will be responsive to the work once you dig in... Jack From avigross at verizon.net Mon Apr 4 08:50:10 2022 From: avigross at verizon.net (Avi Gross) Date: Mon, 4 Apr 2022 12:50:10 +0000 (UTC) Subject: dict.get_deep() In-Reply-To: <33bfa854-004f-30e2-1ebe-b964797d1e73@devoteam.com> References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> <20220403194512.kcqo6zn5yjryvxz5@hjp.at> <1617313993.737226.1649028275904@mail.yahoo.com> <33bfa854-004f-30e2-1ebe-b964797d1e73@devoteam.com> Message-ID: <1479491782.811817.1649076610483@mail.yahoo.com> Kirill, There are many related needs and issues and solutions such as how to parse XML content?and do all kinds of tree searches for "patterns" that multiple modules have been created to?deal with. My impression here was of a simpler request to allow a list of keys to be applied in?sequence. The example wanted the list to be successive arguments in a call to?a method, but obvious variants would be for a single argument containing atuple or list or any interator that would probe a tree of possibilities while?anchored to the top. This is a much easier task with many solutions offered. -----Original Message----- From: Kirill Ratkin via Python-list To: python-list at python.org Sent: Mon, Apr 4, 2022 3:40 am Subject: Re: dict.get_deep() Hello, Yes, I misunderstood as well because started to think about pattern matching which is good but this is not subject the question was about. Sorry for my mistake. Because question was about 'builtin' function which means stdlib function implemented in python itself or even in C. It seems, maybe I miss again, but we are talking about similar ideas behind 'xpath' or 'jsonpath' or even 'LINQ'. We want to find some 'dsl' which give us simple and safe way to get deeply nested values from dict. There are several similar solutions on pypi (https://pypi.org/project/dpath/, https://pypi.org/project/path-dict/). But maybe (and maybe I miss again) we talk about language embedded solution like operator ? or ??. For example deep dict extraction could look like: street = data["users"]?[0]?["address"]?["street"]?. // BR 04.04.2022 2:24, Avi Gross via Python-list ?????: > I may have misunderstood something. > The original post in this subject sounded to ME likethey had nested dictionaries and wanted to be ableto ask a method in the first dictionary totake an unspecified number of arguments thatwould be successive keys and return the results. > I mean if A was a dictionary containing saycities and it had an alphabetical index of lettersA to Z and those contained dictionaries ofsay last names as additional dictionaries andso on, then they wanted to perhaps say; > A.getdeep("Boston", "S", "Smith", "Address", default="None") > But the replies I am seeing look so different that I mayhave missed something as it seems more about usingpattern matching on the data used to make the dictionariesor something. > So I was happy to see Marco suggesting a function alongthe lines of my thought process. But I have another? thought.A stand-alone function along his lines might be fine. Buta method built into a general Dictionary class is anotherthing as it asks a method in one dictionary to march aroundinto other dictionaries. So I wonder if a better methodis sort of recursive. > If you had a class like dictionary that had a getdeep function,and it got called with N arguments, and perhaps a namedargument supplying a default, then would it make sensefor the function checking to see if the FIRST argument canbe found as a key to the current dictionary. > If arguments remain then it should expect to finda result that is a dictionary (or perhaps some otherobject that supports the getdeep() protocol and ask thatobject to operate on the N-1 remaining arguments, passingthe default along too. > If the request is valid, after some iterations an object willhave a method invoked with a single argument (plus default)and a value passed back up the chain. For any errors alongthe way, the default would be returned. > Is this closer to the spirit of the request? I view this versionof nested dictionaries as a sort of tree structure with variablebranches along the way. So an approach like this could makesense and perhaps Python could be updated eventually to havesome objects support such a protocol. > Of course you could sort of do it yourself by subclassing somethingand making changes but that may not work for what is already asort of built-in data structure but could work for one of many variantsalready implemented in modules. > > > > -----Original Message----- > From: Marco Sulla > To: Peter J. Holzer > Cc: python-list at python.org > Sent: Sun, Apr 3, 2022 5:17 pm > Subject: Re: dict.get_deep() > > On Sun, 3 Apr 2022 at 21:46, Peter J. Holzer wrote: >>>> data.get_deep("users", 0, "address", "street", default="second star") >> Yep. Did that, too. Plus pass the final result through a function before >> returning it. > I didn't understand. Have you added a func parameter? > >> I'm not sure whether I considered this when I wrote it, but a function >> has the advantage of working with every class which can be indexed. A >> method must be implemented on any class (so at least dict and list to be >> useful). > You're right, but where to put it? I don't know if an iterableutil package > exists. If included in the stdlib, I don't know where to put it. In > collections maybe? > > PS: if you're interested, here is my implementation: > > def get_deep(self, *args, default=_sentinel): >? ? ? r""" >? ? ? Get a nested element of the dictionary. > >? ? ? The method accepts multiple arguments or a single one. If a single >? ? ? argument is passed, it must be an iterable. This represents the >? ? ? keys or indexes of the nested element. > >? ? ? The method first tries to get the value v1 of the dict using the >? ? ? first key. If it finds v1 and there's no other key, v1 is >? ? ? returned. Otherwise, the method tries to retrieve the value from v1 >? ? ? associated with the second key/index, and so on. > >? ? ? If in any point, for any reason, the value can't be retrieved, the >? ? ? `default` parameter is returned if specified. Otherwise, a >? ? ? KeyError or an IndexError is raised. >? ? ? """ > >? ? ? if len(args) == 1: >? ? ? ? ? single = True > >? ? ? ? ? it_tpm = args[0] > >? ? ? ? ? try: >? ? ? ? ? ? ? len(it_tpm) >? ? ? ? ? ? ? it = it_tpm >? ? ? ? ? except Exception: >? ? ? ? ? ? ? # maybe it's a generator >? ? ? ? ? ? ? try: >? ? ? ? ? ? ? ? ? it = tuple(it_tpm) >? ? ? ? ? ? ? except Exception: >? ? ? ? ? ? ? ? ? err = ( >? ? ? ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` called with a single " + >? ? ? ? ? ? ? ? ? ? ? "argument supports only iterables" >? ? ? ? ? ? ? ? ? ) > >? ? ? ? ? ? ? ? ? raise TypeError(err) from None >? ? ? else: >? ? ? ? ? it = args >? ? ? ? ? single = False > >? ? ? if not it: >? ? ? ? ? if single: >? ? ? ? ? ? ? raise ValueError( >? ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` argument is empty" >? ? ? ? ? ? ? ) >? ? ? ? ? else: >? ? ? ? ? ? ? raise TypeError( >? ? ? ? ? ? ? ? ? f"`{self.get_deep.__name__}` expects at least one argument" >? ? ? ? ? ? ? ) > >? ? ? obj = self > >? ? ? for k in it: >? ? ? ? ? try: >? ? ? ? ? ? ? obj = obj[k] >? ? ? ? ? except (KeyError, IndexError) as e: >? ? ? ? ? ? ? if default is _sentinel: >? ? ? ? ? ? ? ? ? raise e from None > >? ? ? ? ? ? ? return default > >? ? ? return obj -- https://mail.python.org/mailman/listinfo/python-list From info at egenix.com Mon Apr 4 08:40:57 2022 From: info at egenix.com (eGenix Team) Date: Mon, 4 Apr 2022 14:40:57 +0200 Subject: ANN: eGenix Antispam Bot for Telegram 0.2.0 Message-ID: <86c36da5-e83b-4950-9d6e-bd6f446737a7@egenix.com> ________________________________________________________________________ ANNOUNCING eGenix Antispam Bot for Telegram Version 0.2.0 A simple, yet effective bot implementation to address Telegram signup spam. This announcement is also available on our web-site for online reading: https://www.egenix.com/company/news/eGenix-Antispam-Bot-for-Telegram-0.2.0-GA.html ________________________________________________________________________ INTRODUCTION eGenix has long been running a local user group meeting in D?sseldorf called Python Meeting D?sseldorf and we are using a Telegram group for most of our communication. In the early days, the group worked well and we only had few spammers joining it, which we could well handle manually. More recently, this has changed dramatically. We are seeing between 2-5 spam signups per day, often at night. Furthermore, the signups accounts are not always easy to spot as spammers, since they often come with profile images, descriptions, etc. With the bot, we now have a more flexible way of dealing with the problem. Please see our project page for details and download links: https://www.egenix.com/library/telegram-antispam-bot/ ________________________________________________________________________ FEATURES * Low impact mode of operation: the bot tries to keep noise in the group to a minimum * Several challenge mechanisms to choose from, more can be added as needed * Flexible and easy to use configuration * Only needs a few MB of RAM, so can easily be put into a container or run on a Raspberry Pi * Can handle quite a bit of load due to the async implementation * Works with Python 3.9+ * MIT open source licensed ________________________________________________________________________ NEWS The 0.2.0 release is the first public release of the bot. It has been battle-tested in production for more than a month already and is proving to be a really useful tool to help with Telegram group administration. _______________________________________________________________________ INFORMATION About eGenix (http://www.egenix.com/): eGenix is a database focused software project, consulting and product company delivering expert services and professional quality products for companies, Python users and developers. About Python (http://www.python.org/): Python is an object-oriented Open Source programming language which runs on all modern platforms. By integrating ease-of-use, clarity in coding, enterprise application connectivity and rapid application design, Python establishes an ideal programming platform for today's IT challenges. Enjoy, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Experts (#1, Apr 04 2022) >>> Python Projects, Coaching and Support ... https://www.egenix.com/ >>> Python Product Development ... https://consulting.egenix.com/ ________________________________________________________________________ ::: We implement business ideas - efficiently in both time and costs ::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 https://www.egenix.com/company/contact/ https://www.malemburg.com/ From stefan_ml at behnel.de Mon Apr 4 02:55:53 2022 From: stefan_ml at behnel.de (Stefan Behnel) Date: Mon, 4 Apr 2022 08:55:53 +0200 Subject: The Cython compiler is 20 years old today ! Message-ID: <4491f2c8-22f9-c8eb-3617-910359fd0fab@behnel.de> Dear Python community, it's now 20 years since Greg Ewing posted his first announcement of Pyrex, the tool that is now known and used under the name Cython. https://mail.python.org/pipermail/python-list/2002-April/126661.html It was a long way, and I've written up some of it in a blog post: http://blog.behnel.de/posts/cython-is-20/ Today, if you're working on any kind of larger application in Python, you're likely to have some piece of code downloaded into your venv that was built with Cython. Or many of them. I'm proud of what we have achieved. And I'm happy to see and talk to the many, many users out there whom we could help to help their users get their work done. Happy anniversary, Cython! Stefan PS: The list of Cython implemented packages on PyPI is certainly incomplete, so please add the classifier to yours if it's missing. With almost 3000 dependent packages on Github (and almost 100,000 related repos), I'm sure we can crack the number of 1000 Cython built packages on PyPI as a birthday present. (No Spam, please, just honest classifiers.) https://pypi.org/search/?q=&o=-created&c=Programming+Language+%3A%3A+Cython https://github.com/cython/cython/network/dependents?dependent_type=PACKAGE From alister.ware at ntlworld.com Mon Apr 4 10:43:38 2022 From: alister.ware at ntlworld.com (alister) Date: Mon, 4 Apr 2022 14:43:38 -0000 (UTC) Subject: ANN: eGenix Antispam Bot for Telegram 0.2.0 References: <86c36da5-e83b-4950-9d6e-bd6f446737a7@egenix.com> Message-ID: On Mon, 4 Apr 2022 14:40:57 +0200, eGenix Team wrote: > ________________________________________________________________________ > > ANNOUNCING > > eGenix Antispam Bot for Telegram > > Version 0.2.0 > > A simple, yet effective bot implementation > to address Telegram signup spam. > > This announcement is also available on our web-site for online reading: > https://www.egenix.com/company/news/eGenix-Antispam-Bot-for- Telegram-0.2.0-GA.html > > ________________________________________________________________________ > > INTRODUCTION > > eGenix has long been running a local user group meeting in D?sseldorf > called Python Meeting D?sseldorf and we are using a Telegram group for > most of our communication. > > In the early days, the group worked well and we only had few spammers > joining it, which we could well handle manually. > > More recently, this has changed dramatically. We are seeing between 2-5 > spam signups per day, often at night. Furthermore, the signups accounts > are not always easy to spot as spammers, since they often come with > profile images, descriptions, etc. > > With the bot, we now have a more flexible way of dealing with the > problem. > > Please see our project page for details and download links: > > https://www.egenix.com/library/telegram-antispam-bot/ > > ________________________________________________________________________ > > FEATURES > > * Low impact mode of operation: the bot tries to keep noise in the > group to a minimum > > * Several challenge mechanisms to choose from, more can be added as > needed > > * Flexible and easy to use configuration > > * Only needs a few MB of RAM, so can easily be put into a container or > run on a Raspberry Pi > > * Can handle quite a bit of load due to the async implementation > > * Works with Python 3.9+ > > * MIT open source licensed > > ________________________________________________________________________ > > NEWS > > The 0.2.0 release is the first public release of the bot. > > It has been battle-tested in production for more than a month already > and is proving to be a really useful tool to help with Telegram group > administration. > > _______________________________________________________________________ > > INFORMATION > > About eGenix (http://www.egenix.com/): > > eGenix is a database focused software project, consulting and > product company delivering expert services and professional quality > products for companies, Python users and developers. > > About Python (http://www.python.org/): > > Python is an object-oriented Open Source programming language which > runs on all modern platforms. By integrating ease-of-use, clarity in > coding, enterprise application connectivity and rapid application > design, Python establishes an ideal programming platform for today's > IT challenges. > > Enjoy, > -- > Marc-Andre Lemburg eGenix.com > > Professional Python Services directly from the Experts (#1, Apr 04 2022) >>>> Python Projects, Coaching and Support ... https://www.egenix.com/ >>>> Python Product Development ... https://consulting.egenix.com/ > ________________________________________________________________________ > > ::: We implement business ideas - efficiently in both time and costs ::: > > eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 > D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg > Registered at Amtsgericht Duesseldorf: HRB 46611 > https://www.egenix.com/company/contact/ > https://www.malemburg.com/ Classic, spam a news group with an add for anti spam software can you even spell irony? -- The mosquito exists to keep the mighty humble. From sjeik_appie at hotmail.com Mon Apr 4 13:25:02 2022 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Mon, 04 Apr 2022 19:25:02 +0200 Subject: Marshmallow: json-to-schema helper? Message-ID: Hi, I'm looking for a convenience function to convert a Marshmallow schema into a valid Python class definition. That is, I want to generate python code (class MySchema.. etc) that I could write to a .py file. Does this exist? I tried the code below, but that is not the intended use of marshmallow.Schema.from_dict or inspect.getsource. from inspect import getsource from marshmallow import Schema d = dict(something='potentially', very='complicated') schema = Schema.from_dict(d) python_class_def_as_str = getsource(schema())? # OSError https://marshmallow.readthedocs.io/en/stable/api_reference.html#marshmallow.Schema.from_dict https://docs.python.org/3/library/inspect.html#inspect.getsource Thanks! Albert-Jan From sjeik_appie at hotmail.com Mon Apr 4 13:37:23 2022 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Mon, 04 Apr 2022 19:37:23 +0200 Subject: Fwd: dict.get_deep() In-Reply-To: Message-ID: ---------- Forwarded message ---------- From: Marco Sulla Date: Apr 2, 2022 22:44 Subject: dict.get_deep() To: Python List <> Cc: A proposal. Very often dict are used as a deeply nested carrier of data, usually decoded from JSON.? data["users"][0]["address"]["street"] I have been using jsonpath expressions for that kind of stuff lately. Works really well. https://pypi.org/project/jsonpath-ng/ From sjeik_appie at hotmail.com Mon Apr 4 13:42:44 2022 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Mon, 04 Apr 2022 19:42:44 +0200 Subject: flask app convert sql query to python plotly. In-Reply-To: Message-ID: On Apr 2, 2022 20:50, Abdellah ALAOUI ISMAILI wrote: i would like to convert in my flask app an SQL query to an plotly pie chart using pandas. this is my code : def query_tickets_status() : ??? query_result = pd.read_sql (""" ??????????? SELECT COUNT(*)count_status, status ??????????? FROM tickets ??????????? GROUP BY status""", con = mydc_db) ??? return query_result labels_statut = query_tickets_status['status'] values_statut = query_tickets_status['count_status'] ====== I think you mean: labels_statut = query_tickets_status()['status'] values_statut = query_tickets_status()['count_status'] From drewmossedyou1 at gmail.com Mon Apr 4 15:28:22 2022 From: drewmossedyou1 at gmail.com (Andrew Pierson) Date: Mon, 4 Apr 2022 15:28:22 -0400 Subject: pyinstaller is not a internal or external command Message-ID: I ran pip install pyinstaller fine but after then I type in pyinstaller and it says pyinstaller is not a internal or external command ? Sent from [1]Mail for Windows ? References Visible links 1. https://go.microsoft.com/fwlink/?LinkId=550986 From python at mrabarnett.plus.com Mon Apr 4 17:00:55 2022 From: python at mrabarnett.plus.com (MRAB) Date: Mon, 4 Apr 2022 22:00:55 +0100 Subject: pyinstaller is not a internal or external command In-Reply-To: References: Message-ID: On 2022-04-04 20:28, Andrew Pierson wrote: > I ran pip install pyinstaller fine but after then I type in pyinstaller > and it says pyinstaller is not a internal or external command > Have you tried using the Python launcher? py pyinstaller ... From cs at cskk.id.au Mon Apr 4 17:16:16 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 5 Apr 2022 07:16:16 +1000 Subject: dict.get_deep() In-Reply-To: <20220403194512.kcqo6zn5yjryvxz5@hjp.at> References: <20220403194512.kcqo6zn5yjryvxz5@hjp.at> Message-ID: On 03Apr2022 21:45, Peter J. Holzer wrote: >Yup. I need something like this quite frequently, so I wrote a little >utility function (which I copy and paste into lots of code - I probably >should package that up, but a package with a single short function feels >weird). Start with one with a slightly generic name. It will grow. I've got a cs.seq module with sequence(ish) related utility functions in it. It started with very few functions and now has several. I've also got a cs.mappings module which started with a couple of mapping classes and now has a grab bag of mapping utility stuff. Incremental growth. Cheers, Cameron Simpson From drsalists at gmail.com Mon Apr 4 23:47:34 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Mon, 4 Apr 2022 20:47:34 -0700 Subject: The Cython compiler is 20 years old today ! In-Reply-To: <4491f2c8-22f9-c8eb-3617-910359fd0fab@behnel.de> References: <4491f2c8-22f9-c8eb-3617-910359fd0fab@behnel.de> Message-ID: On Mon, Apr 4, 2022 at 7:42 AM Stefan Behnel wrote: > Dear Python community, > > it's now 20 years since Greg Ewing posted his first announcement of Pyrex, > the tool that is now known and used under the name Cython. > > https://mail.python.org/pipermail/python-list/2002-April/126661.html > That's a cool anniversary. I often shake my head in wonder when I see people still writing extension modules in C instead of Cython. From python at mrabarnett.plus.com Tue Apr 5 08:23:44 2022 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 5 Apr 2022 13:23:44 +0100 Subject: The Cython compiler is 20 years old today ! In-Reply-To: References: <4491f2c8-22f9-c8eb-3617-910359fd0fab@behnel.de> Message-ID: <50f25869-8498-561d-7a2e-15e8d3dc74f5@mrabarnett.plus.com> On 2022-04-05 04:47, Dan Stromberg wrote: > On Mon, Apr 4, 2022 at 7:42 AM Stefan Behnel wrote: > >> Dear Python community, >> >> it's now 20 years since Greg Ewing posted his first announcement of Pyrex, >> the tool that is now known and used under the name Cython. >> >> https://mail.python.org/pipermail/python-list/2002-April/126661.html >> > > That's a cool anniversary. > > I often shake my head in wonder when I see people still writing extension > modules in C instead of Cython. Some of us do it because we enjoy it, much like doing crosswords or sudoku or wordle, but with an end result! :-) From wlfraed at ix.netcom.com Mon Apr 4 16:21:01 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Mon, 04 Apr 2022 16:21:01 -0400 Subject: pyinstaller is not a internal or external command References: Message-ID: <6jkm4hhc8ha906ln5n37jq8iq5dfjgh2b6@4ax.com> On Mon, 4 Apr 2022 15:28:22 -0400, Andrew Pierson declaimed the following: > I ran pip install pyinstaller fine but after then I type in pyinstaller > and it says pyinstaller is not a internal or external command > Per the documentation https://pyinstaller.readthedocs.io/en/stable/installation.html """ If the command is not found, make sure the execution path includes the proper directory: Windows: C:\PythonXY\Scripts where XY stands for the major and minor Python version number, for example C:\Python34\Scripts for Python 3.4) """ A second possibility is that your environment is not configured to recognize .PY files as executables. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From pablogsal at gmail.com Wed Apr 6 06:29:19 2022 From: pablogsal at gmail.com (Pablo Galindo Salgado) Date: Wed, 6 Apr 2022 11:29:19 +0100 Subject: [RELEASE] The last Python 3.11 alpha (3.11.0a7) is available - Prepare for beta freeze Message-ID: Brrrrr..... do you feel that? That's the chill of *beta freeze* coming closer. Meanwhile, your friendly CPython release team doesn?t rest and we have prepared a shiny new release for you: Python 3.11.0a7. ************************************************************************************************************************************************************ Dear fellow core developer: This alpha is the last release before feature freeze (Friday, 2022-05-06), so make sure that all new features and PEPs are landed in the master branch before we release the first beta. Please, be specially mindfully to check the CI and the buildbots, maybe even using the test-with-buildbots label in GitHub before merging so the release team don?t need to fix a bunch of reference leaks or platform-specific problems on the first beta release. ************************************************************************************************************************************************************ *Go get the new alpha here:* https://www.python.org/downloads/release/python-3110a7/ **This is an early developer preview of Python 3.11** # Major new features of the 3.11 series, compared to 3.10 Python 3.11 is still in development. This release, 3.11.0a7 is the last of seven planned alpha releases. Alpha releases are intended to make it easier to test the current state of new features and bug fixes and to test the release process. During the alpha phase, features may be added up until the start of the beta phase (2022-05-06) and, if necessary, may be modified or deleted up until the release candidate phase (2022-08-01). Please keep in mind that this is a preview release and its use is **not** recommended for production environments. Many new features for Python 3.11 are still being planned and written. Among the new major new features and changes so far: * [PEP 657](https://www.python.org/dev/peps/pep-0657/) -- Include Fine-Grained Error Locations in Tracebacks * [PEP 654](https://www.python.org/dev/peps/pep-0654/) -- Exception Groups and except* * [PEP 673](https://www.python.org/dev/peps/pep-0673/) -- Self Type * [PEP 646](https://www.python.org/dev/peps/pep-0646/)-- Variadic Generics * [PEP 680](https://www.python.org/dev/peps/pep-0680/)-- tomllib: Support for Parsing TOML in the Standard Library * [PEP 675](https://www.python.org/dev/peps/pep-0675/)-- Arbitrary Literal String Type * [PEP 655](https://www.python.org/dev/peps/pep-0655/)-- Marking individual TypedDict items as required or potentially-missing * [bpo-46752](https://bugs.python.org/issue46752)-- Introduce task groups to asyncio * The [Faster Cpython Project](https://github.com/faster-cpython) is already yielding some exciting results: this version of CPython 3.11 is ~12% faster on the geometric mean of the [PyPerformance benchmarks]( speed.python.org), compared to 3.10.0. * Hey, **fellow core developer,** if a feature you find important is missing from this list, let me know. The next pre-release of Python 3.11 will be 3.11.0b1, currently scheduled for Friday, 2022-05-06. # More resources * [Online Documentation](https://docs.python.org/3.11/) * [PEP 664](https://www.python.org/dev/peps/pep-0664/), 3.11 Release Schedule * Report bugs at [https://bugs.python.org](https://bugs.python.org). * [Help fund Python and its community](/psf/donations/). # And now for something completely different In mathematics, the Dirac delta distribution (? distribution) is a generalized function or distribution over the real numbers, whose value is zero everywhere except at zero, and whose integral over the entire real line is equal to one. The current understanding of the impulse is as a linear functional that maps every continuous function to its value at zero. The delta function was introduced by physicist Paul Dirac as a tool for the normalization of state vectors. It also has uses in probability theory and signal processing. Its validity was disputed until Laurent Schwartz developed the theory of distributions where it is defined as a linear form acting on functions. Defining this distribution as a "function" as many physicist do is known to be one of the easier ways to annoy mathematicians :) # We hope you enjoy those new releases! Thanks to all of the many volunteers who help make Python Development and these releases possible! Please consider supporting our efforts by volunteering yourself or through organization contributions to the Python Software Foundation. Your friendly release team, Pablo Galindo @pablogsal Ned Deily @nad Steve Dower @steve.dower From antoon.pardon at vub.be Thu Apr 7 07:18:19 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Thu, 7 Apr 2022 13:18:19 +0200 Subject: Comparing sequences with range objects Message-ID: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> I am working with a list of data from which I have to weed out duplicates. At the moment I keep for each entry a container with the other entries that are still possible duplicates. The problem is sometimes that is all the rest. I thought to use a range object for these cases. Unfortunatly I sometimes want to sort things and a range object is not comparable with a list or a tuple. So I have a list of items where each item is itself a list or range object. I of course could sort this by using list as a key function but that would defeat the purpose of using range objects for these cases. So what would be a relatively easy way to get the same result without wasting too much memory on entries that haven't any weeding done on them. -- Antoon Pardon. From joel.goldstick at gmail.com Thu Apr 7 10:08:45 2022 From: joel.goldstick at gmail.com (Joel Goldstick) Date: Thu, 7 Apr 2022 10:08:45 -0400 Subject: Comparing sequences with range objects In-Reply-To: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: On Thu, Apr 7, 2022 at 7:19 AM Antoon Pardon wrote: > > I am working with a list of data from which I have to weed out duplicates. > At the moment I keep for each entry a container with the other entries > that are still possible duplicates. > > The problem is sometimes that is all the rest. I thought to use a range > object for these cases. Unfortunatly I sometimes want to sort things > and a range object is not comparable with a list or a tuple. > > So I have a list of items where each item is itself a list or range object. > I of course could sort this by using list as a key function but that > would defeat the purpose of using range objects for these cases. > > So what would be a relatively easy way to get the same result without wasting > too much memory on entries that haven't any weeding done on them. > > -- > Antoon Pardon. > -- > https://mail.python.org/mailman/listinfo/python-list I'm not sure I understand what you are trying to do, but if your data has no order, you can use set to remove the duplicates -- Joel Goldstick From Cecil at decebal.nl Thu Apr 7 11:09:43 2022 From: Cecil at decebal.nl (Cecil Westerhof) Date: Thu, 07 Apr 2022 17:09:43 +0200 Subject: Sharing part of a function References: <871qyejwwc.fsf@munus.decebal.nl> Message-ID: <87wng1gcaw.fsf@munus.decebal.nl> Cecil Westerhof writes: > To show why it is often easy, but wrong to use recursive functions I > wrote the following two Fibonacci functions: > def fib_ite(n): > if not type(n) is int: > raise TypeError(f'Need an integer ({n})') > if n < 0: > raise ValueError(f'Should not be negative ({n})') > > if n in [0, 1]: > return n > > # a is previous fibonacy (starts with fib(0)) > # b is current fibonaccy (starts with fib(1)) > a, b = 0, 1 > # range goes to n - 1, so after loop b contains fib(n) > for i in range(1, n): > a, b = b, a + b > return b > > > def fib_rec(n): > if not type(n) is int: > raise TypeError(f'Need an integer ({n})') > if n < 0: > raise ValueError(f'Should not be negative ({n})') > > if n in [0, 1]: > return n > > return fib_rec(n - 2) + fib_rec(n - 1) > > The first eight lines are the same. And I did change the description > of the errors, which had to be done in both functions. What would be > the best way to circumvent this? > Two options are: > - Call an init function. > - Call the 'master' function with a lambda. > > What is the preferable way, or is there a better way? I have chosen this implementation with inner functions: def fibonacci(n, implementation = 'iterative'): def ite(n): # a is previous fibonacy (starts with fib(0)) # b is current fibonaccy (starts with fib(1)) a, b = 0, 1 # range goes to n - 1, so after loop b contains fib(n) for i in range(1, n): a, b = b, a + b return b def rec(n): if n in [0, 1]: return n return rec(n - 2) + rec(n - 1) if not type(n) is int: raise TypeError(f'Need an integer ({n})') if n < 0: raise ValueError(f'Should not be negative ({n})') if n in [0, 1]: return n if implementation == 'iterative': return ite(n) elif implementation == 'recursive': return rec(n) raise ValueError(f'Got a wrong function implementation type: {type}') -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From antoon.pardon at vub.be Thu Apr 7 11:16:41 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Thu, 7 Apr 2022 17:16:41 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: Op 7/04/2022 om 16:08 schreef Joel Goldstick: > On Thu, Apr 7, 2022 at 7:19 AM Antoon Pardon wrote: >> I am working with a list of data from which I have to weed out duplicates. >> At the moment I keep for each entry a container with the other entries >> that are still possible duplicates. >> >> The problem is sometimes that is all the rest. I thought to use a range >> object for these cases. Unfortunatly I sometimes want to sort things >> and a range object is not comparable with a list or a tuple. >> >> So I have a list of items where each item is itself a list or range object. >> I of course could sort this by using list as a key function but that >> would defeat the purpose of using range objects for these cases. >> >> So what would be a relatively easy way to get the same result without wasting >> too much memory on entries that haven't any weeding done on them. >> >> -- >> Antoon Pardon. >> -- >> https://mail.python.org/mailman/listinfo/python-list > I'm not sure I understand what you are trying to do, but if your data > has no order, you can use set to remove the duplicates Sorry I wasn't clear. The data contains information about persons. But not all records need to be complete. So a person can occur multiple times in the list, while the records are all different because they are missing different bits. So all records with the same firstname can be duplicates. But if I have a record in which the firstname is missing, it can at that point be a duplicate of all other records. -- Antoon Pardon From dieter at handshake.de Thu Apr 7 12:42:26 2022 From: dieter at handshake.de (Dieter Maurer) Date: Thu, 7 Apr 2022 18:42:26 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: <25167.5234.336295.693150@ixdm.fritz.box> Antoon Pardon wrote at 2022-4-7 17:16 +0200: > ... >Sorry I wasn't clear. The data contains information about persons. But not >all records need to be complete. So a person can occur multiple times in >the list, while the records are all different because they are missing >different bits. > >So all records with the same firstname can be duplicates. But if I have >a record in which the firstname is missing, it can at that point be >a duplicate of all other records. The description is still not clear enough. Especially, it does not show where `range` objects come into play. Answering on a more abstract level: Apparently, you want to sort a list the elements of which can be other lists or range objects. List objects are ordered lexicographically, i.e. for lists l1, l2: l1 <= l2 iff not l1 or (l2 and l1[0] <= l2[0] and l1[1:] <= l2[1:]). If you want to sort a list containing list elements are compared using this order. For your case, you would need to use a `key` parameter for `sort` that implements this order for `range` objects, too. (Note that Python provides a function which transforms an order definition into an appropriate `key` function). A corresponding `sort` call may expand your range objects completely. An alternative might be to not expand `range` objects but to put them all at the start or end of the sorted list. Of course, this would imply that their expansion does not influence their order in the list -- which may or may not be acceptable (depending on your use case). If it is acceptable, it is likely possible to not put range objects into the list to be sorted in the first place. From python at mrabarnett.plus.com Thu Apr 7 13:40:35 2022 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 7 Apr 2022 18:40:35 +0100 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: <9238515d-8dc1-083c-43c0-67989b07b9bf@mrabarnett.plus.com> On 2022-04-07 16:16, Antoon Pardon wrote: > Op 7/04/2022 om 16:08 schreef Joel Goldstick: >> On Thu, Apr 7, 2022 at 7:19 AM Antoon Pardon wrote: >>> I am working with a list of data from which I have to weed out duplicates. >>> At the moment I keep for each entry a container with the other entries >>> that are still possible duplicates. >>> >>> The problem is sometimes that is all the rest. I thought to use a range >>> object for these cases. Unfortunatly I sometimes want to sort things >>> and a range object is not comparable with a list or a tuple. >>> >>> So I have a list of items where each item is itself a list or range object. >>> I of course could sort this by using list as a key function but that >>> would defeat the purpose of using range objects for these cases. >>> >>> So what would be a relatively easy way to get the same result without wasting >>> too much memory on entries that haven't any weeding done on them. >>> >>> -- >>> Antoon Pardon. >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >> I'm not sure I understand what you are trying to do, but if your data >> has no order, you can use set to remove the duplicates > > Sorry I wasn't clear. The data contains information about persons. But not > all records need to be complete. So a person can occur multiple times in > the list, while the records are all different because they are missing > different bits. > > So all records with the same firstname can be duplicates. But if I have > a record in which the firstname is missing, it can at that point be > a duplicate of all other records. > This is how I'd approach it: # Make a list of groups, where each group is a list of potential duplicates. # Initially, all of the records are potential duplicates of each other. records = [list_of_records] # Split the groups into subgroups according to the first name. new_records = [] for group in records: subgroups = defaultdict(list) for record in group: subgroups[record['first_name']].append(record) # Records without a first name could belong to any of the subgroups. missing = subgroups.pop(None, []) for record in missing: for subgroup in subgroups.values(): subgroup.extend(missing) new_records.extend(subgroups.values()) records = new_records # Now repeat for the last name, etc. From as at sci.fi Thu Apr 7 14:47:51 2022 From: as at sci.fi (Anssi Saari) Date: Thu, 07 Apr 2022 21:47:51 +0300 Subject: =?iso-8859-1?Q?'=E4=C4=F6=D6=FC=DC'?= in Unicode (utf-8) In-Reply-To: <78ec4hhoc5m17enimphfl002me8rnghtnh@4ax.com> (Dennis Lee Bieber's message of "Thu, 31 Mar 2022 19:29:23 -0400") References: <30d6b0a8-731b-41a8-aa8e-1e77c21e0e9en@googlegroups.com> <78ec4hhoc5m17enimphfl002me8rnghtnh@4ax.com> Message-ID: Dennis Lee Bieber writes: > On Fri, 1 Apr 2022 03:59:32 +1100, Chris Angelico > declaimed the following: > > >>That's jmf. Ignore him. He knows nothing about Unicode and is >>determined to make everyone aware of that fact. >> >>He got blocked from the mailing list ages ago, and I don't think >>anyone's regretted it. > Ah yes... Unfortunately, when gmane made the mirror read-only, I had to > revert to comp.lang.python... and all the junk that gets in via that and > Google Groups... Hm. I just configured my news reader to send follow-ups to the mailing list when that happened. From hjp-python at hjp.at Fri Apr 8 02:24:48 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Fri, 8 Apr 2022 08:24:48 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: <20220408062448.ny3nufpeyajwkcqp@hjp.at> On 2022-04-07 17:16:41 +0200, Antoon Pardon wrote: > Op 7/04/2022 om 16:08 schreef Joel Goldstick: > > On Thu, Apr 7, 2022 at 7:19 AM Antoon Pardon wrote: > > > I am working with a list of data from which I have to weed out duplicates. > > > At the moment I keep for each entry a container with the other entries > > > that are still possible duplicates. [...] > Sorry I wasn't clear. The data contains information about persons. But not > all records need to be complete. So a person can occur multiple times in > the list, while the records are all different because they are missing > different bits. > > So all records with the same firstname can be duplicates. But if I have > a record in which the firstname is missing, it can at that point be > a duplicate of all other records. There are two problems. The first one is how do you establish identity. The second is how do you ween out identical objects. In your first mail you only asked about the second, but that's easy. The first is really hard. Not only may information be missing, no single single piece of information is unique or immutable. Two people may have the same name (I know about several other "Peter Holzer"s), a single person might change their name (when I was younger I went by my middle name - how would you know that "Peter Holzer" and "Hansi Holzer" are the same person?), they will move (= change their address), change jobs, etc. Unless you have a unique immutable identifier that's enforced by some authority (like a social security number[1]), I don't think there is a chance to do that reliably in a program (although with enough data, a heuristic may be good enough). hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Fri Apr 8 02:27:04 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Fri, 8 Apr 2022 08:27:04 +0200 Subject: dict.get_deep() In-Reply-To: References: <525b0547-0ed2-776d-e862-b1d9193bd70e@devoteam.com> <20220403194512.kcqo6zn5yjryvxz5@hjp.at> Message-ID: <20220408062704.4koaz74sc2qnaigp@hjp.at> On 2022-04-03 23:17:04 +0200, Marco Sulla wrote: > On Sun, 3 Apr 2022 at 21:46, Peter J. Holzer wrote: > > > > data.get_deep("users", 0, "address", "street", default="second star") > > > > Yep. Did that, too. Plus pass the final result through a function before > > returning it. > > I didn't understand. Have you added a func parameter? Yes. Look at the code I posted (it's only 9 lines long). > > I'm not sure whether I considered this when I wrote it, but a function > > has the advantage of working with every class which can be indexed. A > > method must be implemented on any class (so at least dict and list to be > > useful). > > You're right, but where to put it? I don't know if an iterableutil package > exists. If included in the stdlib, I don't know where to put it. In > collections maybe? Yes, that seems like the least bad choice. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From rosuav at gmail.com Fri Apr 8 02:53:34 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 8 Apr 2022 16:53:34 +1000 Subject: Comparing sequences with range objects In-Reply-To: <20220408062448.ny3nufpeyajwkcqp@hjp.at> References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> Message-ID: On Fri, 8 Apr 2022 at 16:26, Peter J. Holzer wrote: > Unless you have a unique immutable identifier that's enforced by > some authority (like a social security number[1]), I don't think there > is a chance to do that reliably in a program (although with enough data, > a heuristic may be good enough). > Not sure what your footnote was supposed to be, but I'll offer two useful footnotes to that: [1] [a] Though they're not actually immutable either, just less frequently changing [1[ [b] Of course, that has privacy implications. ChrisA From antoon.pardon at vub.be Fri Apr 8 03:21:29 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Fri, 8 Apr 2022 09:21:29 +0200 Subject: Comparing sequences with range objects In-Reply-To: <20220408062448.ny3nufpeyajwkcqp@hjp.at> References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> Message-ID: <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> Op 8/04/2022 om 08:24 schreef Peter J. Holzer: > On 2022-04-07 17:16:41 +0200, Antoon Pardon wrote: >> Op 7/04/2022 om 16:08 schreef Joel Goldstick: >>> On Thu, Apr 7, 2022 at 7:19 AM Antoon Pardon wrote: >>>> I am working with a list of data from which I have to weed out duplicates. >>>> At the moment I keep for each entry a container with the other entries >>>> that are still possible duplicates. > [...] >> Sorry I wasn't clear. The data contains information about persons. But not >> all records need to be complete. So a person can occur multiple times in >> the list, while the records are all different because they are missing >> different bits. >> >> So all records with the same firstname can be duplicates. But if I have >> a record in which the firstname is missing, it can at that point be >> a duplicate of all other records. > There are two problems. The first one is how do you establish identity. > The second is how do you ween out identical objects. In your first mail > you only asked about the second, but that's easy. > > The first is really hard. Not only may information be missing, no single > single piece of information is unique or immutable. Two people may have > the same name (I know about several other "Peter Holzer"s), a single > person might change their name (when I was younger I went by my middle > name - how would you know that "Peter Holzer" and "Hansi Holzer" are the > same person?), they will move (= change their address), change jobs, > etc. Unless you have a unique immutable identifier that's enforced by > some authority (like a social security number[1]), I don't think there > is a chance to do that reliably in a program (although with enough data, > a heuristic may be good enough). Yes I know all that. That is why I keep a bucket of possible duplicates per "identifying" field that is examined and use some heuristics at the end of all the comparing instead of starting to weed out the duplicates at the moment something differs. The problem is, that when an identifying field is judged to be unusable, the bucket to be associated with it should conceptually contain all other records (which in this case are the indexes into the population list). But that will eat a lot of memory. So I want some object that behaves as if it is a (immutable) list of all these indexes without actually containing them. A range object almost works, with the only problem it is not comparable with a list. -- Antoon Pardon. From bhavani.putsala2003 at outlook.com Fri Apr 8 12:28:47 2022 From: bhavani.putsala2003 at outlook.com (Putsala Bhavani Maha Laxmi) Date: Fri, 8 Apr 2022 16:28:47 +0000 Subject: the downloaded version is not being detected Message-ID: The purpose of this mail is the problem encountered while using it through an IDE platform. While using an IDE this version of python is not getting detected even though it is already downloaded and a suggestion box to install python appears . I kindly request you to look into this issue. Thanking you Sent from Mail for Windows From ramonhagenaars at gmail.com Fri Apr 8 14:47:31 2022 From: ramonhagenaars at gmail.com (Ramon Hagenaars) Date: Fri, 8 Apr 2022 20:47:31 +0200 Subject: nptyping 2.0.0 has been released Message-ID: Hello all, It fills me with joy to announce that nptyping 2.0.0 is released! nptyping allows type hinting NumPy arrays with support for dynamic type checking. The most notable changes are: * Complete rewrite, extending numpy.typing and to be MyPy-friendly; * "Shape Expressions" that allow for a rich notation of NumPy array shapes; * Dropped support for Python 3.5 and 3.6. For the full history: https://github.com/ramonhagenaars/nptyping/blob/master/HISTORY.md Links -------------------- Source is on Github: https://github.com/ramonhagenaars/nptyping Available on PyPI: https://pypi.org/project/nptyping/ Documentation: https://github.com/ramonhagenaars/nptyping/blob/master/USERDOCS.md License (MIT): https://github.com/ramonhagenaars/nptyping/blob/master/LICENSE -- Ramon Hagenaars From JohnB.Stevenson at memphistn.gov Fri Apr 8 15:35:44 2022 From: JohnB.Stevenson at memphistn.gov (Stevenson, John B) Date: Fri, 8 Apr 2022 19:35:44 +0000 Subject: Issues Message-ID: Hello, As a quick disclaimer, I am sorry if you have received this message multiple times over from me. I've been having technical difficulties trying to reach this email. Thank you. I'm trying to install Python on a computer so that I can use it for various tasks for my job, like mapping and programming. But it's not downloading the necessary files into the right repository for me to run Python commands in a command prompt. I can open the Python app just fine, but I cannot use it in the terminal, and this messes with pip and prevents me from doing my task. What can I do to fix this? Error sent back is "'python' is not recognized as an internal or external command, operable program or batch file." Thank you. John B. (Jack) Stevenson From duncan at invalid.invalid Fri Apr 8 10:28:30 2022 From: duncan at invalid.invalid (duncan smith) Date: Fri, 8 Apr 2022 15:28:30 +0100 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> Message-ID: On 08/04/2022 08:21, Antoon Pardon wrote: > > > Op 8/04/2022 om 08:24 schreef Peter J. Holzer: >> On 2022-04-07 17:16:41 +0200, Antoon Pardon wrote: >>> Op 7/04/2022 om 16:08 schreef Joel Goldstick: >>>> On Thu, Apr 7, 2022 at 7:19 AM Antoon Pardon >>>> wrote: >>>>> I am working with a list of data from which I have to weed out >>>>> duplicates. >>>>> At the moment I keep for each entry a container with the other entries >>>>> that are still possible duplicates. >> [...] >>> Sorry I wasn't clear. The data contains information about persons. >>> But not >>> all records need to be complete. So a person can occur multiple times in >>> the list, while the records are all different because they are missing >>> different bits. >>> >>> So all records with the same firstname can be duplicates. But if I have >>> a record in which the firstname is missing, it can at that point be >>> a duplicate of all other records. >> There are two problems. The first one is how do you establish identity. >> The second is how do you ween out identical objects. In your first mail >> you only asked about the second, but that's easy. >> >> The first is really hard. Not only may information be missing, no single >> single piece of information is unique or immutable. Two people may have >> the same name (I know about several other "Peter Holzer"s), a single >> person might change their name (when I was younger I went by my middle >> name - how would you know that "Peter Holzer" and "Hansi Holzer" are the >> same person?), they will move (= change their address), change jobs, >> etc. Unless you have a unique immutable identifier that's enforced by >> some authority (like a social security number[1]), I don't think there >> is a chance to do that reliably in a program (although with enough data, >> a heuristic may be good enough). > > Yes I know all that. That is why I keep a bucket of possible duplicates > per "identifying" field that is examined and use some heuristics at the > end of all the comparing instead of starting to weed out the duplicates > at the moment something differs. > > The problem is, that when an identifying field is judged to be unusable, > the bucket to be associated with it should conceptually contain all other > records (which in this case are the indexes into the population list). > But that will eat a lot of memory. So I want some object that behaves as > if it is a (immutable) list of all these indexes without actually > containing > them. A range object almost works, with the only problem it is not > comparable with a list. > Is there any reason why you can't use ints? Just set the relevant bits. Duncan From python at mrabarnett.plus.com Fri Apr 8 16:24:20 2022 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 8 Apr 2022 21:24:20 +0100 Subject: Issues In-Reply-To: References: Message-ID: On 2022-04-08 20:35, Stevenson, John B via Python-list wrote: > Hello, > > As a quick disclaimer, I am sorry if you have received this message multiple times over from me. I've been having technical difficulties trying to reach this email. Thank you. > > I'm trying to install Python on a computer so that I can use it for various tasks for my job, like mapping and programming. But it's not downloading the necessary files into the right repository for me to run Python commands in a command prompt. I can open the Python app just fine, but I cannot use it in the terminal, and this messes with pip and prevents me from doing my task. What can I do to fix this? Error sent back is "'python' is not recognized as an internal or external command, operable program or batch file." Thank you. > Try the Python Launcher instead by typing "py" instead of "python". From python at mrabarnett.plus.com Fri Apr 8 16:28:00 2022 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 8 Apr 2022 21:28:00 +0100 Subject: the downloaded version is not being detected In-Reply-To: References: Message-ID: <7b25ccef-7517-6709-1eaa-24c0e09e92b3@mrabarnett.plus.com> On 2022-04-08 17:28, Putsala Bhavani Maha Laxmi wrote: > The purpose of this mail is the problem encountered while using it through an IDE platform. While using an IDE this version of python is not getting detected even though it is already downloaded and a suggestion box to install python appears . > > I kindly request you to look into this issue. > "An IDE platform"? Which IDE platform? Which OS? From antoon.pardon at vub.be Fri Apr 8 17:08:10 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Fri, 8 Apr 2022 23:08:10 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> Message-ID: <92c3d7c7-4876-b4f4-bcd1-f428eb6865c0@vub.be> Op 8/04/2022 om 16:28 schreef duncan smith: > On 08/04/2022 08:21, Antoon Pardon wrote: >> >> Yes I know all that. That is why I keep a bucket of possible duplicates >> per "identifying" field that is examined and use some heuristics at the >> end of all the comparing instead of starting to weed out the duplicates >> at the moment something differs. >> >> The problem is, that when an identifying field is judged to be unusable, >> the bucket to be associated with it should conceptually contain all >> other >> records (which in this case are the indexes into the population list). >> But that will eat a lot of memory. So I want some object that behaves as >> if it is a (immutable) list of all these indexes without actually >> containing >> them. A range object almost works, with the only problem it is not >> comparable with a list. >> > > Is there any reason why you can't use ints? Just set the relevant bits. Well my first thought is that a bitset makes it less obvious to calulate the size of the set or to iterate over its elements. But it is an idea worth exploring. -- Antoon. From mats at wichmann.us Sat Apr 9 12:23:52 2022 From: mats at wichmann.us (Mats Wichmann) Date: Sat, 9 Apr 2022 10:23:52 -0600 Subject: Issues In-Reply-To: References: Message-ID: On 4/8/22 14:24, MRAB wrote: > On 2022-04-08 20:35, Stevenson, John B via Python-list wrote: >> Hello, >> >> As a quick disclaimer, I am sorry if you have received this message >> multiple times over from me. I've been having technical difficulties >> trying to reach this email. Thank you. >> >> I'm trying to install Python on a computer so that I can use it for >> various tasks for my job, like mapping and programming. But it's not >> downloading the necessary files into the right repository for me to >> run Python commands in a command prompt. I can open the Python app >> just fine, but I cannot use it in the terminal, and this messes with >> pip and prevents me from doing my task. What can I do to fix this? >> Error sent back is "'python' is not recognized as an internal or >> external command, operable program or batch file." Thank you. >> > Try the Python Launcher instead by typing "py" instead of "python". And read this: https://docs.python.org/3/using/windows.html#launcher (other parts of the page will probably be useful to you as well) From duncan at invalid.invalid Fri Apr 8 20:01:50 2022 From: duncan at invalid.invalid (duncan smith) Date: Sat, 9 Apr 2022 01:01:50 +0100 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> <92c3d7c7-4876-b4f4-bcd1-f428eb6865c0@vub.be> Message-ID: On 08/04/2022 22:08, Antoon Pardon wrote: > > Op 8/04/2022 om 16:28 schreef duncan smith: >> On 08/04/2022 08:21, Antoon Pardon wrote: >>> >>> Yes I know all that. That is why I keep a bucket of possible duplicates >>> per "identifying" field that is examined and use some heuristics at the >>> end of all the comparing instead of starting to weed out the duplicates >>> at the moment something differs. >>> >>> The problem is, that when an identifying field is judged to be unusable, >>> the bucket to be associated with it should conceptually contain all >>> other >>> records (which in this case are the indexes into the population list). >>> But that will eat a lot of memory. So I want some object that behaves as >>> if it is a (immutable) list of all these indexes without actually >>> containing >>> them. A range object almost works, with the only problem it is not >>> comparable with a list. >>> >> >> Is there any reason why you can't use ints? Just set the relevant bits. > > Well my first thought is that a bitset makes it less obvious to calulate > the size of the set or to iterate over its elements. But it is an idea > worth exploring. > def popcount(n): """ Returns the number of set bits in n """ cnt = 0 while n: n &= n - 1 cnt += 1 return cnt and not tested, def iterinds(n): """ Returns a generator of the indices of the set bits of n """ i = 0 while n: if n & 1: yield i n = n >> 1 i += 1 Duncan From auriocus at gmx.de Sat Apr 9 02:14:57 2022 From: auriocus at gmx.de (Christian Gollwitzer) Date: Sat, 9 Apr 2022 08:14:57 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> Message-ID: Am 08.04.22 um 09:21 schrieb Antoon Pardon: >> The first is really hard. Not only may information be missing, no single >> single piece of information is unique or immutable. Two people may have >> the same name (I know about several other "Peter Holzer"s), a single >> person might change their name (when I was younger I went by my middle >> name - how would you know that "Peter Holzer" and "Hansi Holzer" are the >> same person?), they will move (= change their address), change jobs, >> etc. Unless you have a unique immutable identifier that's enforced by >> some authority (like a social security number[1]), I don't think there >> is a chance to do that reliably in a program (although with enough data, >> a heuristic may be good enough). > > Yes I know all that. That is why I keep a bucket of possible duplicates > per "identifying" field that is examined and use some heuristics at the > end of all the comparing instead of starting to weed out the duplicates > at the moment something differs. > > The problem is, that when an identifying field is judged to be unusable, > the bucket to be associated with it should conceptually contain all other > records (which in this case are the indexes into the population list). > But that will eat a lot of memory. So I want some object that behaves as > if it is a (immutable) list of all these indexes without actually > containing > them. A range object almost works, with the only problem it is not > comparable with a list. Then write your own comparator function? Also, if the only case where this actually works is the index of all other records, then a simple boolean flag "all" vs. "these items in the index list" would suffice - doesn't it? Christian From hobson42 at gmail.com Sun Apr 10 00:37:51 2022 From: hobson42 at gmail.com (Ian Hobson) Date: Sun, 10 Apr 2022 11:37:51 +0700 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> Message-ID: On 09/04/2022 13:14, Christian Gollwitzer wrote: > Am 08.04.22 um 09:21 schrieb Antoon Pardon: >>> The first is really hard. Not only may information be missing, no single >>> single piece of information is unique or immutable. Two people may have >>> the same name (I know about several other "Peter Holzer"s), a single >>> person might change their name (when I was younger I went by my middle >>> name - how would you know that "Peter Holzer" and "Hansi Holzer" are the >>> same person?), they will move (= change their address), change jobs, >>> etc. Unless you have a unique immutable identifier that's enforced by >>> some authority (like a social security number[1]), I don't think there >>> is a chance to do that reliably in a program (although with enough data, >>> a heuristic may be good enough). >> >> Yes I know all that. That is why I keep a bucket of possible duplicates >> per "identifying" field that is examined and use some heuristics at the >> end of all the comparing instead of starting to weed out the duplicates >> at the moment something differs. >> >> The problem is, that when an identifying field is judged to be unusable, >> the bucket to be associated with it should conceptually contain all other >> records (which in this case are the indexes into the population list). >> But that will eat a lot of memory. So I want some object that behaves as >> if it is a (immutable) list of all these indexes without actually >> containing >> them. A range object almost works, with the only problem it is not >> comparable with a list. > > > Then write your own comparator function? > > Also, if the only case where this actually works is the index of all > other records, then a simple boolean flag "all" vs. "these items in the > index list" would suffice - doesn't it? > > ????Christian > Writing a comparator function is only possible for a given key. So my approach would be: 1) Write a comparator function that takes params X and Y, such that: if key data is missing from X, return 1 If key data is missing from Y return -1 if X > Y return 1 if X < Y return -1 return 0 # They are equal and key data for both is present 2) Sort the data using the comparator function. 3) Run through the data with a trailing enumeration loop, merging matching records together. 4) If there are no records copied out with missing key data, then you are done, so exit. 5) Choose a new key and repeat from step 1). Regards Ian -- Ian Hobson Tel (+66) 626 544 695 -- This email has been checked for viruses by AVG. https://www.avg.com From antoon.pardon at vub.be Sun Apr 10 16:20:33 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Sun, 10 Apr 2022 22:20:33 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> <92c3d7c7-4876-b4f4-bcd1-f428eb6865c0@vub.be> Message-ID: <0cdbc5b1-0fd9-7a39-e7a9-c80a4566c087@vub.be> Op 9/04/2022 om 02:01 schreef duncan smith: > On 08/04/2022 22:08, Antoon Pardon wrote: >> >> Well my first thought is that a bitset makes it less obvious to calulate >> the size of the set or to iterate over its elements. But it is an idea >> worth exploring. >> > > > > def popcount(n): > ??? """ > ??? Returns the number of set bits in n > ??? """ > ??? cnt = 0 > ??? while n: > ??????? n &= n - 1 > ??????? cnt += 1 > ??? return cnt > > and not tested, > > def iterinds(n): > ??? """ > ??? Returns a generator of the indices of the set bits of n > ??? """ > ??? i = 0 > ??? while n: > ??????? if n & 1: > ??????????? yield i > ??????? n = n >> 1 > ??????? i += 1 > Sure but these seem rather naive implementation with a time complexity of O(n) where n is the maximum number of possible elements. Using these would turn my O(n) algorithm in a O(n^2) algorithm. -- Antoon Pardon. From pkpearson at nowhere.invalid Sun Apr 10 10:32:10 2022 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 10 Apr 2022 14:32:10 GMT Subject: What to do to correct the error written below: References: <70a8db5b-b034-4006-add9-700283277140n@googlegroups.com> Message-ID: On Sat, 9 Apr 2022 04:59:05 -0700 (PDT), NArshad wrote: > I have accidentally deleted one account in a Django project because of > which one of the pages is no more accessible and is giving the error > written below: > > IndexError at /view_issued_book/ > list index out of range > > and the error is in the line: > > t=(students[i].user,students[i].user_id,books[i].name,books[i].isbn,issuedBooks[0].issued_date,issuedBooks[0].expiry_date,fine) [snip] Without seeing more of the code, one can only guess, but it appears that the data being processed reside in arrays named "students" and "books", which are indexed by an integer i. The "list index out of range" error probably results from i being too large -- running off the end of the array, perhaps because of the deleted account. You could confirm this by printing i, len(students), and len(books) just before the failing line. -- To email me, substitute nowhere->runbox, invalid->com. From duncan at invalid.invalid Sun Apr 10 20:01:58 2022 From: duncan at invalid.invalid (duncan smith) Date: Mon, 11 Apr 2022 01:01:58 +0100 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> <92c3d7c7-4876-b4f4-bcd1-f428eb6865c0@vub.be> <0cdbc5b1-0fd9-7a39-e7a9-c80a4566c087@vub.be> Message-ID: On 10/04/2022 21:20, Antoon Pardon wrote: > > > Op 9/04/2022 om 02:01 schreef duncan smith: >> On 08/04/2022 22:08, Antoon Pardon wrote: >>> >>> Well my first thought is that a bitset makes it less obvious to calulate >>> the size of the set or to iterate over its elements. But it is an idea >>> worth exploring. >>> >> >> >> >> def popcount(n): >> ??? """ >> ??? Returns the number of set bits in n >> ??? """ >> ??? cnt = 0 >> ??? while n: >> ??????? n &= n - 1 >> ??????? cnt += 1 >> ??? return cnt >> >> and not tested, >> >> def iterinds(n): >> ??? """ >> ??? Returns a generator of the indices of the set bits of n >> ??? """ >> ??? i = 0 >> ??? while n: >> ??????? if n & 1: >> ??????????? yield i >> ??????? n = n >> 1 >> ??????? i += 1 >> > Sure but these seem rather naive implementation with a time complexity of > O(n) where n is the maximum number of possible elements. Using these would > turn my O(n) algorithm in a O(n^2) algorithm. > I thought your main concern was memory. Of course, dependent on various factors, you might be able to do much better than the above. But I don't know what your O(n) algorithm is, how using a bitset would make it O(n^2), or if the O(n^2) algorithm would actually be slower for typical n. The overall thing sounds broadly like some of the blocking and clustering methods I've come across in record linkage. Duncan From drsalists at gmail.com Sun Apr 10 20:31:20 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 10 Apr 2022 17:31:20 -0700 Subject: Comparing sequences with range objects In-Reply-To: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: It sounds a little like you're looking for interval arithmetic. Maybe https://pypi.org/project/python-intervals/1.5.3/ ? On Thu, Apr 7, 2022 at 4:19 AM Antoon Pardon wrote: > I am working with a list of data from which I have to weed out duplicates. > At the moment I keep for each entry a container with the other entries > that are still possible duplicates. > > The problem is sometimes that is all the rest. I thought to use a range > object for these cases. Unfortunatly I sometimes want to sort things > and a range object is not comparable with a list or a tuple. > > So I have a list of items where each item is itself a list or range object. > I of course could sort this by using list as a key function but that > would defeat the purpose of using range objects for these cases. > > So what would be a relatively easy way to get the same result without > wasting > too much memory on entries that haven't any weeding done on them. > > -- > Antoon Pardon. > -- > https://mail.python.org/mailman/listinfo/python-list > From 2QdxY4RzWzUUiLuE at potatochowder.com Sun Apr 10 20:44:44 2022 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Sun, 10 Apr 2022 19:44:44 -0500 Subject: Comparing sequences with range objects In-Reply-To: <0cdbc5b1-0fd9-7a39-e7a9-c80a4566c087@vub.be> References: <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> <92c3d7c7-4876-b4f4-bcd1-f428eb6865c0@vub.be> <0cdbc5b1-0fd9-7a39-e7a9-c80a4566c087@vub.be> Message-ID: On 2022-04-10 at 22:20:33 +0200, Antoon Pardon wrote: > > > Op 9/04/2022 om 02:01 schreef duncan smith: > > On 08/04/2022 22:08, Antoon Pardon wrote: > > > > > > Well my first thought is that a bitset makes it less obvious to calulate > > > the size of the set or to iterate over its elements. But it is an idea > > > worth exploring. > > > > > > > > > > > def popcount(n): > > ??? """ > > ??? Returns the number of set bits in n > > ??? """ > > ??? cnt = 0 > > ??? while n: > > ??????? n &= n - 1 > > ??????? cnt += 1 > > ??? return cnt > > > > and not tested, > > > > def iterinds(n): > > ??? """ > > ??? Returns a generator of the indices of the set bits of n > > ??? """ > > ??? i = 0 > > ??? while n: > > ??????? if n & 1: > > ??????????? yield i > > ??????? n = n >> 1 > > ??????? i += 1 > > > Sure but these seem rather naive implementation with a time complexity of > O(n) where n is the maximum number of possible elements. Using these would > turn my O(n) algorithm in a O(n^2) algorithm. O(n) where n is the expected number of elements. The loops iterate once for each bit actually contained in the set, which is usually [much] less than the size of the universe. If you have lots and lots of elements in your sets, or your universe is large and n is a long integer, then these may not be as efficient as other methods. You know your data better than we do. From drsalists at gmail.com Sun Apr 10 23:15:03 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Sun, 10 Apr 2022 20:15:03 -0700 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: Two more things: 1) There are also modules that do interval arithmetic with reals, not just integers. EG: https://pyinterval.readthedocs.io/en/latest/ 2) If you don't mind a small amount of inaccuracy you can often get things down to less than one bit per element for presence/absence, using a bloom filter. EG: https://pypi.org/project/drs-bloom-filter/ On Sun, Apr 10, 2022 at 5:31 PM Dan Stromberg wrote: > > It sounds a little like you're looking for interval arithmetic. > > Maybe https://pypi.org/project/python-intervals/1.5.3/ ? > > On Thu, Apr 7, 2022 at 4:19 AM Antoon Pardon wrote: > >> I am working with a list of data from which I have to weed out duplicates. >> At the moment I keep for each entry a container with the other entries >> that are still possible duplicates. >> >> The problem is sometimes that is all the rest. I thought to use a range >> object for these cases. Unfortunatly I sometimes want to sort things >> and a range object is not comparable with a list or a tuple. >> >> So I have a list of items where each item is itself a list or range >> object. >> I of course could sort this by using list as a key function but that >> would defeat the purpose of using range objects for these cases. >> >> So what would be a relatively easy way to get the same result without >> wasting >> too much memory on entries that haven't any weeding done on them. >> >> -- >> Antoon Pardon. >> -- >> https://mail.python.org/mailman/listinfo/python-list >> > From brianthewag at aol.com Mon Apr 11 12:13:41 2022 From: brianthewag at aol.com (brianthewag at aol.com) Date: Mon, 11 Apr 2022 16:13:41 +0000 (UTC) Subject: Making a Python program into an executable file References: <323387714.394907.1649693621628.ref@mail.yahoo.com> Message-ID: <323387714.394907.1649693621628@mail.yahoo.com> Dear Python team, I am trying to find out how to make my Python programs into executable files (.exe, I presume) using Pyinstaller. I searched on line for how to do this (the document I came across is headed Data to Fish), and it seemed that Step 1 was to download the most recent version of Python and click the Add Python to Path option. I tried to do this, but was given the option to Upgrade Python, and once I did this the Add Python to Path option seemed not to be available. Can you advise me what to do? Best wishes, Brian From pkpearson at nowhere.invalid Mon Apr 11 10:28:51 2022 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 11 Apr 2022 14:28:51 GMT Subject: What to do to correct the error written below: References: <70a8db5b-b034-4006-add9-700283277140n@googlegroups.com> <07624725-d732-453c-9dcb-a491c4177c1en@googlegroups.com> Message-ID: On Mon, 11 Apr 2022 00:14:49 -0700 (PDT), NArshad wrote: [snip] > books = list(models.Book.objects.filter(isbn=i.isbn)) > students = list(models.Student.objects.filter(user=i.student_id)) > i=0 > for l in books: > t=(students[i].user,students[i].user_id,books[i].name,books[i].isbn,issuedBooks[0].issued_date,issuedBooks[0].expiry_date,fine) > i=i+1 > details.append(t) [snip] Is this homework? In this newsgroup, by custom, homework problems should be announced as such, since the best answer to a homework question is different from the best answer to a real-life problem. Back to the problem: By looping over elements in "books" and incrementing counter i, which is used as an index both for "books" and for "students", you will produce an error whenever the number of books exceeds the number of students. Is there some reason to assume that the number of books cannot exceed the number of students? -- To email me, substitute nowhere->runbox, invalid->com. From wlfraed at ix.netcom.com Mon Apr 11 11:52:26 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Mon, 11 Apr 2022 11:52:26 -0400 Subject: What to do to correct the error written below: References: <70a8db5b-b034-4006-add9-700283277140n@googlegroups.com> <07624725-d732-453c-9dcb-a491c4177c1en@googlegroups.com> Message-ID: On Mon, 11 Apr 2022 00:14:49 -0700 (PDT), NArshad declaimed the following: > for i in issuedBooks: Loop control variable is "i"... > i=0 Control variable "i" has been overwritten so any use of "i" following this is suspicious > for l in books: Inner-loop control variable is "l" -- and does not seem to be used for anything following... > t=(students[i].user,students[i].user_id,books[i].name,books[i].isbn,issuedBooks[0].issued_date,issuedBooks[0].expiry_date,fine) > i=i+1 -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From wlfraed at ix.netcom.com Mon Apr 11 11:52:40 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Mon, 11 Apr 2022 11:52:40 -0400 Subject: What to do to correct the error written below: References: <70a8db5b-b034-4006-add9-700283277140n@googlegroups.com> <07624725-d732-453c-9dcb-a491c4177c1en@googlegroups.com> Message-ID: On 11 Apr 2022 14:28:51 GMT, Peter Pearson declaimed the following: >Is this homework? In this newsgroup, by custom, homework problems >should be announced as such, since the best answer to a homework >question is different from the best answer to a real-life problem. > It's a return to a long cryptic thread from January... <199c23c7-de58-44ae-a216-760c8f36c506n at googlegroups.com> "What to write or search on github to get the code for what is written below:" It is nice to see that the insistence on using Excel for the data storage seems to have been dropped (at least, the code shown appears to be something like SQLAlchemy), but the OP really should spend a few weeks studying database normalization and use of foreign keys -- concepts which, properly applied, means there is no need for these confusing hand-tracked indices. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From mats at wichmann.us Mon Apr 11 14:19:24 2022 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 11 Apr 2022 12:19:24 -0600 Subject: Making a Python program into an executable file In-Reply-To: <323387714.394907.1649693621628@mail.yahoo.com> References: <323387714.394907.1649693621628.ref@mail.yahoo.com> <323387714.394907.1649693621628@mail.yahoo.com> Message-ID: On 4/11/22 10:13, Brian Wagstaff via Python-list wrote: > Dear Python team, > I am trying to find out how to make my Python programs into executable files (.exe, I presume) using Pyinstaller. I searched on line for how to do this (the document I came across is headed Data to Fish), and it seemed that Step 1 was to download the most recent version of Python and click the Add Python to Path option. I tried to do this, but was given the option to Upgrade Python, and once I did this the Add Python to Path option seemed not to be available. Can you advise me what to do? > Best wishes, > Brian Presuming this is Windows because it sounds like it (hint: it's useful to say), you can rerun the installer from the Apps & Features applet by clicking on Python and then selecting Modify (the option actually says "Add Python to environment variables"). How to make an "executable" depends on whether you require to include a copy of Python with that, or not. There are a larger number of approaches for the latter than the former. zipapps come close for the latter, if you get your entry point set up right; there's some logic described there for building an exe as well, but it's a little tricky to get right. There's a project called Shiv (search pypi.org to find this one) that attempts to simplify that. An approach that doesn't get mentioned often (and with which I have no experience): https://bazel.build/docs/windows#python You might also want to look into BeeWare if you want to make a self-contained app your of your program. Nice work happening in that project. From antoon.pardon at vub.be Tue Apr 12 02:49:50 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Tue, 12 Apr 2022 08:49:50 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> <20220408062448.ny3nufpeyajwkcqp@hjp.at> <7f32456e-0022-1230-f5b4-b86ad057cb68@vub.be> <92c3d7c7-4876-b4f4-bcd1-f428eb6865c0@vub.be> <0cdbc5b1-0fd9-7a39-e7a9-c80a4566c087@vub.be> Message-ID: Op 11/04/2022 om 02:01 schreef duncan smith: > On 10/04/2022 21:20, Antoon Pardon wrote: >> >> >> Op 9/04/2022 om 02:01 schreef duncan smith: >>> On 08/04/2022 22:08, Antoon Pardon wrote: >>>> >>>> Well my first thought is that a bitset makes it less obvious to >>>> calulate >>>> the size of the set or to iterate over its elements. But it is an idea >>>> worth exploring. >>>> >>> >>> >>> >>> def popcount(n): >>> ??? """ >>> ??? Returns the number of set bits in n >>> ??? """ >>> ??? cnt = 0 >>> ??? while n: >>> ??????? n &= n - 1 >>> ??????? cnt += 1 >>> ??? return cnt >>> >>> and not tested, >>> >>> def iterinds(n): >>> ??? """ >>> ??? Returns a generator of the indices of the set bits of n >>> ??? """ >>> ??? i = 0 >>> ??? while n: >>> ??????? if n & 1: >>> ??????????? yield i >>> ??????? n = n >> 1 >>> ??????? i += 1 >>> >> Sure but these seem rather naive implementation with a time >> complexity of >> O(n) where n is the maximum number of possible elements. Using these >> would >> turn my O(n) algorithm in a O(n^2) algorithm. >> > > I thought your main concern was memory. Of course, dependent on > various factors, you might be able to do much better than the above. > But I don't know what your O(n) algorithm is, how using a bitset would > make it O(n^2), or if the O(n^2) algorithm would actually be slower > for typical n. The overall thing sounds broadly like some of the > blocking and clustering methods I've come across in record linkage. Using bitsets would make change my algorithm from O(n) into O(n^2) because the bitset operations are O(n) instead of O(1). If I have a 20000 people a bitset will take a vector of about 300, 64bit words. With 40000 people the bitset will take a vector of about 600. So doubling the population will also double the time for the bitset operations, meaning doubling the population will increase execution time four times. From antoon.pardon at vub.be Tue Apr 12 02:52:25 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Tue, 12 Apr 2022 08:52:25 +0200 Subject: Comparing sequences with range objects In-Reply-To: References: <98f69f0d-3909-ca13-a440-1d226164b9a5@vub.be> Message-ID: <3fe8d7a1-e0d4-65c3-448a-09d8bbdcb2cb@vub.be> Op 11/04/2022 om 02:31 schreef Dan Stromberg: > > It sounds a little like you're looking for interval arithmetic. > > Maybe https://pypi.org/project/python-intervals/1.5.3/ ? Not completely but it suggested an idea to explore. -- Antoon. From greg.ewing at canterbury.ac.nz Mon Apr 11 18:28:41 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Tue, 12 Apr 2022 10:28:41 +1200 Subject: What to do to correct the error written below: In-Reply-To: References: <70a8db5b-b034-4006-add9-700283277140n@googlegroups.com> <07624725-d732-453c-9dcb-a491c4177c1en@googlegroups.com> Message-ID: On 12/04/22 2:28 am, Peter Pearson wrote: > By looping over elements in "books" and incrementing counter i, > which is used as an index both for "books" and for "students", > you will produce an error whenever the number of books exceeds > the number of students. More fundamentally, it assumes there is a one-to-one correspondence between the list of books and the list of students. It doesn't look like that is true here -- one is a list if students with a given student ID (which doesn't make sense -- surely there should only be one?) and the other is a list of books with a given isbn (presumably all copies of the same book). It would make more sense for there only to be a list of books, and just one reference to the student, at that point in the code. Generally this whole piece of code seems hopelessly confused and needs to be re-thought. -- Greg From pkpearson at nowhere.invalid Tue Apr 12 11:17:34 2022 From: pkpearson at nowhere.invalid (Peter Pearson) Date: 12 Apr 2022 15:17:34 GMT Subject: What to do to correct the error written below: References: <70a8db5b-b034-4006-add9-700283277140n@googlegroups.com> <07624725-d732-453c-9dcb-a491c4177c1en@googlegroups.com> <37d6ec7b-bb49-4572-910c-cdedc0f0c681n@googlegroups.com> Message-ID: On Tue, 12 Apr 2022 04:56:22 -0700 (PDT), NArshad wrote: > >>By looping over elements in "books" and incrementing counter i, >>which is used as an index both for "books" and for "students", >>you will produce an error whenever the number of books exceeds >>the number of students. Is there some reason to assume that the >>number of books cannot exceed the number of students? > > Since this is an online library the number of students can be any when > compared to number of books or the number of students has nothing to > do with the number of books. 1. The code assumes that the number of books does not exceed the number of students. 2. You report that the number of students has nothing to do with the number of books. 3. Therefore we have identified an erroneous assumption in the code. Mystery solved. -- To email me, substitute nowhere->runbox, invalid->com. From stefano.ovus at gmail.com Tue Apr 12 11:28:10 2022 From: stefano.ovus at gmail.com (Stefano Ovus) Date: Tue, 12 Apr 2022 08:28:10 -0700 (PDT) Subject: Circular Import Message-ID: How can I avoid circular imports keeping separated modules ? -- square.py from circle import Cirle class Square: def __init__(self): ... @classmethod def from_circle(cls, circle: Circle) -> Square: ... return cls(...) -- circle.py from square import Square class Circle: def __init__(self): ... @classmethod def from_square(cls, square: Square) -> Circle: ... return cls(...) From stefano.ovus at gmail.com Tue Apr 12 13:22:58 2022 From: stefano.ovus at gmail.com (Stefano Ovus) Date: Tue, 12 Apr 2022 10:22:58 -0700 (PDT) Subject: Circular Import In-Reply-To: References: Message-ID: <0b89e077-d198-4c1d-a1f8-779cc3f898ddn@googlegroups.com> found a solution: importing modules instead of classes, ex. -- square.py import circle ... @classmethod def from_circle(cls, circle: circle.Circle) -> Square: ... return cls(...) From rosuav at gmail.com Tue Apr 12 13:47:41 2022 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 13 Apr 2022 03:47:41 +1000 Subject: Circular Import In-Reply-To: <0b89e077-d198-4c1d-a1f8-779cc3f898ddn@googlegroups.com> References: <0b89e077-d198-4c1d-a1f8-779cc3f898ddn@googlegroups.com> Message-ID: On Wed, 13 Apr 2022 at 03:37, Stefano Ovus wrote: > > found a solution: importing modules instead of classes, ex. > > -- square.py > > import circle > > ... > @classmethod > def from_circle(cls, circle: circle.Circle) -> Square: > ... > return cls(...) Yep! Good solution. Be aware that this will only work if both modules have fully executed before the references are actually needed. Usually not a problem, but if you have code that runs at top-level that needs to refer to the other module (as opposed to simply defining classes and methods, where those methods are going to refer to the other module when they get called), it might not work. But that's no different from any other circular dependency. ChrisA From Marco.Sulla.Python at gmail.com Tue Apr 12 15:03:00 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Tue, 12 Apr 2022 21:03:00 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: <20220328220302.n2pjqqbu7qf3aslf@hjp.at> References: <11041678-4819-a201-a465-b40c8d55441a@gmail.com> <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> Message-ID: On Tue, 29 Mar 2022 at 00:10, Peter J. Holzer wrote: > They are are about a year apart, so they will usually contain different > versions of most packages right from the start. So the Ubuntu and Debian > security teams probably can't benefit much from each other. Well, this is what my updater on Lubuntu says to me today: Changes for tcpdump versions: Installed version: 4.9.3-0ubuntu0.18.04.1 Available version: 4.9.3-0ubuntu0.18.04.2 Version 4.9.3-0ubuntu0.18.04.2: * SECURITY UPDATE: buffer overflow in read_infile - debian/patches/CVE-2018-16301.patch: Add check of file size before allocating and reading content in tcpdump.c and netdissect-stdinc.h. - CVE-2018-16301 * SECURITY UPDATE: resource exhaustion with big packets - debian/patches/CVE-2020-8037.patch: Add a limit to the amount of space that can be allocated when reading the packet. - CVE-2020-8037 I use an LTS version. So it seems that Ubuntu benefits from Debian security patches. Not sure about the contrary. From tim.deke at gmail.com Wed Apr 13 13:38:11 2022 From: tim.deke at gmail.com (Tim Deke) Date: Thu, 14 Apr 2022 03:38:11 +1000 Subject: No shortcut Icon on Desktop Message-ID: Dear Sir, I have successfully downloaded Python into my laptop but the shortcut icon is not appearing on the desktop. I am using Windows 10 with the PC specifications as per snap shot attached below. Can you advise what to do? Thank you Tim Deke [image: image.png] From hjp-python at hjp.at Wed Apr 13 14:03:00 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Wed, 13 Apr 2022 20:03:00 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: References: <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> Message-ID: <20220413180300.qrnneczjdftb2kdq@hjp.at> On 2022-04-12 21:03:00 +0200, Marco Sulla wrote: > On Tue, 29 Mar 2022 at 00:10, Peter J. Holzer wrote: > > They are are about a year apart, so they will usually contain different > > versions of most packages right from the start. So the Ubuntu and Debian > > security teams probably can't benefit much from each other. > > Well, this is what my updater on Lubuntu says to me today: > > Changes for tcpdump versions: > Installed version: 4.9.3-0ubuntu0.18.04.1 > Available version: 4.9.3-0ubuntu0.18.04.2 > > Version 4.9.3-0ubuntu0.18.04.2: > > * SECURITY UPDATE: buffer overflow in read_infile > - debian/patches/CVE-2018-16301.patch: Add check of > file size before allocating and reading content in > tcpdump.c and netdissect-stdinc.h. > - CVE-2018-16301 > * SECURITY UPDATE: resource exhaustion with big packets > - debian/patches/CVE-2020-8037.patch: Add a limit to the > amount of space that can be allocated when reading the > packet. > - CVE-2020-8037 > > I use an LTS version. So it seems that Ubuntu benefits from Debian > security patches. Why do you think so? Because the release notes mention debian/patches/*.patch? This may be an artefact of the build process. The build tools for .deb packages expect all kinds of meta-data to live in a subdirectory called "debian", even on non-debian systems. This includes patches, at least if the maintainer is using quilt (which AFAIK is currently the recommended tool for that purpose). OTOH tcpdump would be one of the those packages where Ubuntu could use a Debian patch directly: 4.9.3 has been the latest version for quite some time (I have it in Debian 9, Ubuntu 18, Debian 10 and Ubuntu 20, but not in Debian 11 (4.99.0)), so if any of those is patched, the others can (almost certainly) use the patch with little or no changes). I think this is rare, though: Packages with frequent security patches tend to have frequent feature updates, too. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From wlfraed at ix.netcom.com Wed Apr 13 14:39:10 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Wed, 13 Apr 2022 14:39:10 -0400 Subject: No shortcut Icon on Desktop References: Message-ID: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> On Thu, 14 Apr 2022 03:38:11 +1000, Tim Deke declaimed the following: >Dear Sir, > >I have successfully downloaded Python into my laptop but the shortcut icon >is not appearing on the desktop. I am using Windows 10 with the PC >specifications as per snap shot attached below. Can you advise what to do? > >Thank you > >Tim Deke > >[image: image.png] Text only group -- if you need to reference a binary file you will have to post it on some hosting service and include a link (URL) to that file. CAVEAT: many of us will not click on random/ad-hoc links -- if the link does not explicitly end in a recognized file name it will be considered dangerous [as it could transfer anything, including mal-ware]; at least with a "safe" file name, it may be considered for examination) As for the main question? WHAT did you download -- where from, what name, etc. ...and where on your computer did you download it? Python normally does not create "shortcut icon"s -- one downloads an installer (which on my system would be saved in %userprofile%\downloads), and executes the installer (once). Python is not an all-in-one GUI development environment (ie; it is not something like Lazarus/FreePascal, Visual Studio, etc.). It is an interpreter for script files and depending upon how the installer sets up the environment, one may never need to directly invoke the Python interpreter -- one just invokes .py script files and the OS activates the correct interpreter. C:\Users\Wulfraed>rem direct invocation; python.exe is found in %PATH% C:\Users\Wulfraed>python Python ActivePython 3.8.2 (ActiveState Software Inc.) based on on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Wulfraed>rem "py launcher" (which I don't trust as it has been known to pick a different Python at times C:\Users\Wulfraed>py Python ActivePython 3.8.2 (ActiveState Software Inc.) based on on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Wulfraed> C:\Users\Wulfraed>type junk.py print("Let me out of here!") C:\Users\Wulfraed>rem invocation of python providing a script file C:\Users\Wulfraed>python junk.py Let me out of here! C:\Users\Wulfraed>rem direct invocation of script file, .py linked to Python by OS C:\Users\Wulfraed>junk.py Let me out of here! C:\Users\Wulfraed>rem direct invocation -- with .py defined as an "executable" extension on my system C:\Users\Wulfraed>junk Let me out of here! C:\Users\Wulfraed> -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From PythonList at DancesWithMice.info Wed Apr 13 16:42:13 2022 From: PythonList at DancesWithMice.info (dn) Date: Thu, 14 Apr 2022 08:42:13 +1200 Subject: No shortcut Icon on Desktop In-Reply-To: References: Message-ID: <2ecddb87-9dc4-68b7-8a97-a8b3274ded82@DancesWithMice.info> On 14/04/2022 05.38, Tim Deke wrote: > Dear Sir, > > I have successfully downloaded Python into my laptop but the shortcut icon > is not appearing on the desktop. I am using Windows 10 with the PC > specifications as per snap shot attached below. Can you advise what to do? https://docs.python.org/3/using/windows.html -- Regards, =dn From barry at barrys-emacs.org Wed Apr 13 17:09:12 2022 From: barry at barrys-emacs.org (Barry) Date: Wed, 13 Apr 2022 22:09:12 +0100 Subject: No shortcut Icon on Desktop In-Reply-To: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> Message-ID: <5C336DDB-C9CB-47BA-8D35-05EDD2DA0756@barrys-emacs.org> > On 13 Apr 2022, at 19:46, Dennis Lee Bieber wrote: > > C:\Users\Wulfraed>rem "py launcher" (which I don't trust as it has been > known to pick a different Python at times > C:\Users\Wulfraed>py > Python ActivePython 3.8.2 (ActiveState Software Inc.) based on > on win32 > Type "help", "copyright", "credits" or "license" for more information. >>>> Py.exe is deterministic. You can edit an .ini file to configure it if the defaults do not work for you. Use py -0 to see what python?s it can find. Barry From kevinmwilson1956 at yahoo.com Wed Apr 13 20:49:55 2022 From: kevinmwilson1956 at yahoo.com (Kevin M. Wilson) Date: Thu, 14 Apr 2022 00:49:55 +0000 (UTC) Subject: Error at https://docs.python.org/3/search.html?q=f+string&check_keywords=yes&area=default References: <1402561910.792463.1649897395867.ref@mail.yahoo.com> Message-ID: <1402561910.792463.1649897395867@mail.yahoo.com> MS Edge settings are displayed in the first picture, the error I encountered is the second picture...not sure how I get around this!I reloaded the browser after checking the settings for JavaScript...confused. Kevin Good sense makes one slow to anger, and it is his glory tooverlook an offense. Proverbs 19:11 From rosuav at gmail.com Wed Apr 13 21:07:27 2022 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 14 Apr 2022 11:07:27 +1000 Subject: Error at https://docs.python.org/3/search.html?q=f+string&check_keywords=yes&area=default In-Reply-To: <1402561910.792463.1649897395867@mail.yahoo.com> References: <1402561910.792463.1649897395867.ref@mail.yahoo.com> <1402561910.792463.1649897395867@mail.yahoo.com> Message-ID: On Thu, 14 Apr 2022 at 11:00, Kevin M. Wilson via Python-list wrote: > > > > > > MS Edge settings are displayed in the first picture, the error I encountered is the second picture...not sure how I get around this!I reloaded the browser after checking the settings for JavaScript...confused. > > Kevin > No attachments here. What's the actual issue? ChrisA From python at mrabarnett.plus.com Wed Apr 13 21:41:48 2022 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 14 Apr 2022 02:41:48 +0100 Subject: Error at https://docs.python.org/3/search.html?q=f+string&check_keywords=yes&area=default In-Reply-To: References: <1402561910.792463.1649897395867.ref@mail.yahoo.com> <1402561910.792463.1649897395867@mail.yahoo.com> Message-ID: <9f32754c-e6d4-2604-3e47-e2dab72c6890@mrabarnett.plus.com> On 2022-04-14 02:07, Chris Angelico wrote: > On Thu, 14 Apr 2022 at 11:00, Kevin M. Wilson via Python-list > wrote: >> >> >> >> >> >> MS Edge settings are displayed in the first picture, the error I encountered is the second picture...not sure how I get around this!I reloaded the browser after checking the settings for JavaScript...confused. >> >> Kevin >> > > No attachments here. What's the actual issue? > I've tried it myself: 1. Go to https://docs.python.org/3/ 2. Type something into the Quick search box 3. Click Go I think the problem is that the panel on the left is empty, and it's not obvious how to navigate out of the search results page. (The answer is to click on the "Documentation" part of "Documentation ? Search".) From loris.bennett at fu-berlin.de Thu Apr 14 09:35:13 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Thu, 14 Apr 2022 15:35:13 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? Message-ID: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> Hi, With Python 3.9.2 I get $ import datetime $ s = "1-00:01:01" $ t = datetime.datetime.strptime(s, "%d-%H:%M:%S") $ d = datetime.timedelta(days=t.day, hours=t.hour, minutes=t.minute, seconds=t.second) $ d.days 1 $ d.seconds 61 $ d.minutes AttributeError: 'datetime.timedelta' object has no attribute 'minutes' Is there a particular reason why there are no attributes 'minutes' and 'hours and the attribute 'seconds' encompasses is the entire fractional day? Cheers, Loris -- This signature is currently under construction. From loris.bennett at fu-berlin.de Thu Apr 14 09:38:14 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Thu, 14 Apr 2022 15:38:14 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> "Loris Bennett" writes: > Hi, > > With Python 3.9.2 I get > > $ import datetime > $ s = "1-00:01:01" > $ t = datetime.datetime.strptime(s, "%d-%H:%M:%S") > $ d = datetime.timedelta(days=t.day, hours=t.hour, minutes=t.minute, seconds=t.second) > $ d.days > 1 > $ d.seconds > 61 > $ d.minutes > AttributeError: 'datetime.timedelta' object has no attribute 'minutes' > > Is there a particular reason why there are no attributes 'minutes' and > 'hours and the attribute 'seconds' encompasses is the entire fractional > day? That should read: Is there a particular reason why there are no attributes 'minutes' and 'hours' and the attribute 'seconds' encompasses the entire fractional day? > Cheers, > > Loris -- Dr. Loris Bennett (Herr/Mr) ZEDAT, Freie Universit?t Berlin Email loris.bennett at fu-berlin.de From pbryan at anode.ca Thu Apr 14 11:01:40 2022 From: pbryan at anode.ca (Paul Bryan) Date: Thu, 14 Apr 2022 08:01:40 -0700 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> I think because minutes and hours can easily be composed by multiplying seconds. days is separate because you cannot compose days from seconds; leap seconds are applied to days at various times, due to irregularities in the Earth's rotation. On Thu, 2022-04-14 at 15:38 +0200, Loris Bennett wrote: > "Loris Bennett" writes: > > > Hi, > > > > With Python 3.9.2 I get > > > > ? $ import datetime > > ? $ s = "1-00:01:01" > > ? $ t = datetime.datetime.strptime(s, "%d-%H:%M:%S") > > ? $ d = datetime.timedelta(days=t.day, hours=t.hour, > > minutes=t.minute, seconds=t.second) > > ? $ d.days > > ? 1 > > ? $ d.seconds > > ? 61 > > ? $ d.minutes > > ? AttributeError: 'datetime.timedelta' object has no attribute > > 'minutes' > > > > Is there a particular reason why there are no attributes 'minutes' > > and > > 'hours and the attribute 'seconds' encompasses is the entire > > fractional > > day? > > That should read: > > ? Is there a particular reason why there are no attributes 'minutes' > and > ? 'hours' and the attribute 'seconds' encompasses the entire > fractional > ? day? > > > Cheers, > > > > Loris > -- > Dr. Loris Bennett (Herr/Mr) > ZEDAT, Freie Universit?t Berlin???????? Email > loris.bennett at fu-berlin.de From lal at solute.de Thu Apr 14 11:17:16 2022 From: lal at solute.de (Lars Liedtke) Date: Thu, 14 Apr 2022 17:17:16 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> Message-ID: <2f4526de-7c71-8c0b-707b-3881e637d82e@solute.de> Additionally, which datatype would you expect them to be returned in? One could argument for int or float (Decimal?),? both could be valid datatypes, depending on how exact you might want them, while the second is the time base of SI units. Cheers Lars -- Lars Liedtke Software Entwickler Phone: Fax: +49 721 98993- E-mail: lal at solute.de solute GmbH Zeppelinstra?e 15 76185 Karlsruhe Germany Marken der solute GmbH | brands of solute GmbH billiger.de | Shopping.de Gesch?ftsf?hrer | Managing Director: Dr. Thilo Gans, Bernd Vermaaten Webseite | www.solute.de Sitz | Registered Office: Karlsruhe Registergericht | Register Court: Amtsgericht Mannheim Registernummer | Register No.: HRB 110579 USt-ID | VAT ID: DE234663798 Informationen zum Datenschutz | Information about privacy policy http://solute.de/ger/datenschutz/grundsaetze-der-datenverarbeitung.php Am 14.04.22 um 17:01 schrieb Paul Bryan: > I think because minutes and hours can easily be composed by multiplying > seconds. days is separate because you cannot compose days from seconds; > leap seconds are applied to days at various times, due to > irregularities in the Earth's rotation. > > On Thu, 2022-04-14 at 15:38 +0200, Loris Bennett wrote: >> "Loris Bennett" writes: >> >>> Hi, >>> >>> With Python 3.9.2 I get >>> >>> ? $ import datetime >>> ? $ s = "1-00:01:01" >>> ? $ t = datetime.datetime.strptime(s, "%d-%H:%M:%S") >>> ? $ d = datetime.timedelta(days=t.day, hours=t.hour, >>> minutes=t.minute, seconds=t.second) >>> ? $ d.days >>> ? 1 >>> ? $ d.seconds >>> ? 61 >>> ? $ d.minutes >>> ? AttributeError: 'datetime.timedelta' object has no attribute >>> 'minutes' >>> >>> Is there a particular reason why there are no attributes 'minutes' >>> and >>> 'hours and the attribute 'seconds' encompasses is the entire >>> fractional >>> day? >> That should read: >> >> ? Is there a particular reason why there are no attributes 'minutes' >> and >> ? 'hours' and the attribute 'seconds' encompasses the entire >> fractional >> ? day? >> >>> Cheers, >>> >>> Loris >> -- >> Dr. Loris Bennett (Herr/Mr) >> ZEDAT, Freie Universit?t Berlin???????? Email >> loris.bennett at fu-berlin.de From Cecil at decebal.nl Thu Apr 14 11:02:02 2022 From: Cecil at decebal.nl (Cecil Westerhof) Date: Thu, 14 Apr 2022 17:02:02 +0200 Subject: Functionality like local static in C Message-ID: <8735ifhfo5.fsf@munus.decebal.nl> In C when you declare a variable static in a function, the variable retains its value between function calls. The first time the function is called it has the default value (0 for an int). But when the function changes the value in a call (for example to 43), the next time the function is called the variable does not have the default value, but the value it had when the function returned. Does python has something like that? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From jon+usenet at unequivocal.eu Thu Apr 14 11:22:29 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 14 Apr 2022 15:22:29 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> Message-ID: On 2022-04-14, Paul Bryan wrote: > I think because minutes and hours can easily be composed by multiplying > seconds. days is separate because you cannot compose days from seconds; > leap seconds are applied to days at various times, due to > irregularities in the Earth's rotation. That's an argument that timedelta should *not* have a 'days' attribute, because a day is not a fixed number of seconds long (to know how long a day is, you have to know which day you're talking about, and where). It's an undocumented feature of timedelta that by 'day' it means '86400 seconds'. From barry at barrys-emacs.org Thu Apr 14 12:11:45 2022 From: barry at barrys-emacs.org (Barry) Date: Thu, 14 Apr 2022 17:11:45 +0100 Subject: Functionality like local static in C In-Reply-To: <8735ifhfo5.fsf@munus.decebal.nl> References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: <1733B797-5775-432D-B26B-155D62946A41@barrys-emacs.org> > On 14 Apr 2022, at 16:28, Cecil Westerhof via Python-list wrote: > > ?In C when you declare a variable static in a function, the variable > retains its value between function calls. > The first time the function is called it has the default value (0 for > an int). > But when the function changes the value in a call (for example to 43), > the next time the function is called the variable does not have the > default value, but the value it had when the function returned. > Does python has something like that? You can define variables at the module level and then use global to use them in your function. a_static_var = 42 def func(value): global a_static_var a_static_var = value Barry > > -- > Cecil Westerhof > Senior Software Engineer > LinkedIn: http://www.linkedin.com/in/cecilwesterhof > -- > https://mail.python.org/mailman/listinfo/python-list > From mirkok.lists at googlemail.com Thu Apr 14 12:52:08 2022 From: mirkok.lists at googlemail.com (Mirko) Date: Thu, 14 Apr 2022 18:52:08 +0200 Subject: Functionality like local static in C In-Reply-To: <8735ifhfo5.fsf@munus.decebal.nl> References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: <62585138.30605@googlemail.com> Am 14.04.2022 um 17:02 schrieb Cecil Westerhof via Python-list: > In C when you declare a variable static in a function, the variable > retains its value between function calls. > The first time the function is called it has the default value (0 for > an int). > But when the function changes the value in a call (for example to 43), > the next time the function is called the variable does not have the > default value, but the value it had when the function returned. > Does python has something like that? > There are several ways to emulate that: ### With a mutable default argument In [1]: def func(var=[-1]): ...: var[0] += 1 ...: return var[0] ...: In [2]: func() Out[2]: 0 In [3]: func() Out[3]: 1 In [4]: func() Out[4]: 2 ### with a callable class In [12]: class Func(): ...: def __init__(self, var=-1): ...: self.var = var ...: ...: def __call__(self): ...: self.var += 1 ...: return self.var ...: In [13]: func = Func() In [14]: func() Out[14]: 0 In [15]: func() Out[15]: 1 In [16]: func() Out[16]: 2 ### with a closure In [29]: def outer(var=-1): ...: def inner(): ...: nonlocal var ...: var += 1 ...: return var ...: return inner ...: In [30]: func = outer() In [31]: func() Out[31]: 0 In [32]: func() Out[32]: 1 In [33]: func() Out[33]: 2 ### with a generator In [2]: def func(init=0, end=3): ...: for var in range(init, end): ...: yield var ...: In [3]: for i in func(): ...: print(i) ...: 0 1 2 HTH From python at mrabarnett.plus.com Thu Apr 14 13:11:44 2022 From: python at mrabarnett.plus.com (MRAB) Date: Thu, 14 Apr 2022 18:11:44 +0100 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> Message-ID: <4346b8a5-30ff-6340-e03d-b32ee9433f31@mrabarnett.plus.com> On 2022-04-14 16:22, Jon Ribbens via Python-list wrote: > On 2022-04-14, Paul Bryan wrote: >> I think because minutes and hours can easily be composed by multiplying >> seconds. days is separate because you cannot compose days from seconds; >> leap seconds are applied to days at various times, due to >> irregularities in the Earth's rotation. > > That's an argument that timedelta should *not* have a 'days' attribute, > because a day is not a fixed number of seconds long (to know how long > a day is, you have to know which day you're talking about, and where). > It's an undocumented feature of timedelta that by 'day' it means '86400 > seconds'. When you're working only with dates, timedelta not having a 'days' attribute would be annoying, especially when you consider that a day is usually 24 hours, but sometimes 23 or 25 hours (DST). From Marco.Sulla.Python at gmail.com Thu Apr 14 13:31:58 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Thu, 14 Apr 2022 19:31:58 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: <20220413180300.qrnneczjdftb2kdq@hjp.at> References: <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> <20220413180300.qrnneczjdftb2kdq@hjp.at> Message-ID: On Wed, 13 Apr 2022 at 20:05, Peter J. Holzer wrote: > > On 2022-04-12 21:03:00 +0200, Marco Sulla wrote: > > On Tue, 29 Mar 2022 at 00:10, Peter J. Holzer wrote: > > > They are are about a year apart, so they will usually contain different > > > versions of most packages right from the start. So the Ubuntu and Debian > > > security teams probably can't benefit much from each other. > > > > Well, this is what my updater on Lubuntu says to me today: > > > > Changes for tcpdump versions: > > Installed version: 4.9.3-0ubuntu0.18.04.1 > > Available version: 4.9.3-0ubuntu0.18.04.2 > > > > Version 4.9.3-0ubuntu0.18.04.2: > > > > * SECURITY UPDATE: buffer overflow in read_infile > > - debian/patches/CVE-2018-16301.patch: Add check of > > file size before allocating and reading content in > > tcpdump.c and netdissect-stdinc.h. > > - CVE-2018-16301 > > * SECURITY UPDATE: resource exhaustion with big packets > > - debian/patches/CVE-2020-8037.patch: Add a limit to the > > amount of space that can be allocated when reading the > > packet. > > - CVE-2020-8037 > > > > I use an LTS version. So it seems that Ubuntu benefits from Debian > > security patches. > > Why do you think so? Because the release notes mention debian/patches/*.patch? Of course. > This may be an artefact of the build process. The build tools for .deb > packages expect all kinds of meta-data to live in a subdirectory called > "debian", even on non-debian systems. This includes patches, at least if > the maintainer is using quilt (which AFAIK is currently the recommended > tool for that purpose). And why does the security update package contain metadata about Debian patches, if the Ubuntu security team did not benefit from Debian security patches but only from internal work? > OTOH tcpdump would be one of the those packages where Ubuntu could use a > Debian patch directly [...] It doesn't seem so. This is a fresh new security update: Changes for git versions: Installed version: 1:2.17.1-1ubuntu0.9 Available version: 1:2.17.1-1ubuntu0.10 Version 1:2.17.1-1ubuntu0.10: * SECURITY UPDATE: Run commands in diff users - debian/patches/CVE-2022-24765-*.patch: fix GIT_CEILING_DIRECTORIES; add an owner check for the top-level-directory; add a function to determine whether a path is owned by the current user in patch.c, t/t0060-path-utils.sh, setup.c, compat/mingw.c, compat/mingw.h, git-compat-util.hi, config.c, config.h. - CVE-2022-24765 I checked packages.debian.org and git 2.17 was never on Debian: Package git stretch (oldoldstable) (vcs): fast, scalable, distributed revision control system 1:2.11.0-3+deb9u7: amd64 arm64 armel armhf i386 mips mips64el mipsel ppc64el s390x stretch-backports (vcs): fast, scalable, distributed revision control system 1:2.20.1-1~bpo9+1: amd64 arm64 armel armhf i386 mips mips64el mipsel ppc64el s390x buster (oldstable) (vcs): fast, scalable, distributed revision control system 1:2.20.1-2+deb10u3: amd64 arm64 armel armhf i386 mips mips64el mipsel ppc64el s390x etc. https://packages.debian.org/search?keywords=git From Marco.Sulla.Python at gmail.com Thu Apr 14 13:43:33 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Thu, 14 Apr 2022 19:43:33 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <4346b8a5-30ff-6340-e03d-b32ee9433f31@mrabarnett.plus.com> References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <4346b8a5-30ff-6340-e03d-b32ee9433f31@mrabarnett.plus.com> Message-ID: On Thu, 14 Apr 2022 at 19:16, MRAB wrote: > > When you're working only with dates, timedelta not having a 'days' > attribute would be annoying, especially when you consider that a day is > usually 24 hours, but sometimes 23 or 25 hours (DST). I agree. Furthermore, timedelta is, well, a time delta, not a date with a timezone. How could a timedelta take into account DST, leap seconds etc? About the initial question, I think it's a good question. From sam.z.ezeh at gmail.com Thu Apr 14 12:09:24 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Thu, 14 Apr 2022 17:09:24 +0100 Subject: Functionality like local static in C In-Reply-To: References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: I've seen people use function attributes for this. ``` Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> def function(): ... print(function.variable) ... function.variable += 1 ... >>> function.variable = 1 >>> function() 1 >>> function() 2 >>> ``` If necessary, the variable can be initialised inside the function too. Kind Regards, Sam Ezeh On Thu, 14 Apr 2022 at 16:36, Sam Ezeh wrote: > > I've seen people use function attributes for this. > ``` > Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> def function(): > ... print(function.variable) > ... function.variable += 1 > ... > >>> function.variable = 1 > >>> function() > 1 > >>> function() > 2 > >>> > ``` > > If necessary, the variable can be initialised inside the function too. > > Kind Regards, > Sam Ezeh > > > On Thu, 14 Apr 2022 at 16:26, Cecil Westerhof via Python-list > wrote: > > > > In C when you declare a variable static in a function, the variable > > retains its value between function calls. > > The first time the function is called it has the default value (0 for > > an int). > > But when the function changes the value in a call (for example to 43), > > the next time the function is called the variable does not have the > > default value, but the value it had when the function returned. > > Does python has something like that? > > > > -- > > Cecil Westerhof > > Senior Software Engineer > > LinkedIn: http://www.linkedin.com/in/cecilwesterhof > > -- > > https://mail.python.org/mailman/listinfo/python-list From pfeiffer at cs.nmsu.edu Thu Apr 14 12:57:01 2022 From: pfeiffer at cs.nmsu.edu (Joe Pfeiffer) Date: Thu, 14 Apr 2022 10:57:01 -0600 Subject: Functionality like local static in C References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: <1b7d7rob6q.fsf@pfeifferfamily.net> Cecil Westerhof writes: > In C when you declare a variable static in a function, the variable > retains its value between function calls. > The first time the function is called it has the default value (0 for > an int). > But when the function changes the value in a call (for example to 43), > the next time the function is called the variable does not have the > default value, but the value it had when the function returned. > Does python has something like that? Others (in particular mirko) have given ways to emulate that functionality. I'll mention that local statics are frequently not found in object oriented languages because member variables can serve much the same function in a more general way. If you think you need a static local variable, ask yourself if what you really need is a class. From rosuav at gmail.com Thu Apr 14 13:58:17 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 15 Apr 2022 03:58:17 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <4346b8a5-30ff-6340-e03d-b32ee9433f31@mrabarnett.plus.com> Message-ID: On Fri, 15 Apr 2022 at 03:45, Marco Sulla wrote: > > On Thu, 14 Apr 2022 at 19:16, MRAB wrote: > > > > When you're working only with dates, timedelta not having a 'days' > > attribute would be annoying, especially when you consider that a day is > > usually 24 hours, but sometimes 23 or 25 hours (DST). > > I agree. Furthermore, timedelta is, well, a time delta, not a date > with a timezone. How could a timedelta take into account DST, leap > seconds etc? It can't. It's a simple representation of a time period. It is useful for situations where you want to express questions like "from this date/time, wait this long, what will the date/time be?". In the absence of a corresponding timezone-aware datetime object, it cannot possibly acknowledge DST. ChrisA From dieter at handshake.de Thu Apr 14 13:43:54 2022 From: dieter at handshake.de (Dieter Maurer) Date: Thu, 14 Apr 2022 19:43:54 +0200 Subject: Functionality like local static in C In-Reply-To: <8735ifhfo5.fsf@munus.decebal.nl> References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: <25176.23898.580820.262878@ixdm.fritz.box> Cecil Westerhof wrote at 2022-4-14 17:02 +0200: >In C when you declare a variable static in a function, the variable >retains its value between function calls. >The first time the function is called it has the default value (0 for >an int). >But when the function changes the value in a call (for example to 43), >the next time the function is called the variable does not have the >default value, but the value it had when the function returned. >Does python has something like that? In "C" a variable designates a storage location; assignment to the variable changes the stored value. In "Python" a variable designates an object. Assignments to the variable do not change the object but the association variable-object. The im|mutability of the object determines whether the object can or cannot have different values. Mutable objects can behave similar to storage locations, e.g. class StaticVariable: def __init__(self, v): self.v = v def set(self, v): self.v = v def get(self): return self.v static_emul = StaticVariable(...) def f(...): ... static_emul.set(...) ... From rosuav at gmail.com Thu Apr 14 14:07:30 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 15 Apr 2022 04:07:30 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On Fri, 15 Apr 2022 at 00:54, Loris Bennett wrote: > > Hi, > > With Python 3.9.2 I get > > $ import datetime > $ s = "1-00:01:01" > $ t = datetime.datetime.strptime(s, "%d-%H:%M:%S") > $ d = datetime.timedelta(days=t.day, hours=t.hour, minutes=t.minute, seconds=t.second) > $ d.days > 1 > $ d.seconds > 61 > $ d.minutes > AttributeError: 'datetime.timedelta' object has no attribute 'minutes' > > Is there a particular reason why there are no attributes 'minutes' and > 'hours and the attribute 'seconds' encompasses is the entire fractional > day? > You can get those by dividing: >>> divmod(d, datetime.timedelta(minutes=1)) (1441, datetime.timedelta(seconds=1)) But the obvious question is: how many minutes ARE there in this time period? I give a response of 1441 (or if you prefer, 1441 + 1/60 or roughly 1441.017), but you might just as reasonably consider that there is one minute. If a good definition could be chosen, it wouldn't be too hard to add a bunch of properties to the timedelta that let you view it in other ways. Otherwise, the easiest way is probably to define yourself a set of units and sequentially divmod: >>> units = {"days": datetime.timedelta(days=1), "hours": datetime.timedelta(hours=1), "minutes": datetime.timedelta(minutes=1), "seconds": datetime.timedelta(seconds=1)} >>> for label, unit in units.items(): ... n, d = divmod(d, unit) ... print(n, label) ... 1 days 0 hours 1 minutes 1 seconds >>> This way, you have full control over which units are "interesting"; for instance, the constructor supports weeks, but a lot of applications won't consider them to be important, and would prefer to see "20 days" than "2 weeks and 6 days". But, as mentioned, adding properties to timedelta would be a relatively benign change, so it could be done if there's enough need and a good definition. ChrisA From rosuav at gmail.com Thu Apr 14 14:19:32 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 15 Apr 2022 04:19:32 +1000 Subject: Functionality like local static in C In-Reply-To: References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: On Fri, 15 Apr 2022 at 03:53, Sam Ezeh wrote: > > I've seen people use function attributes for this. > ``` > Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux > Type "help", "copyright", "credits" or "license" for more information. > >>> def function(): > ... print(function.variable) > ... function.variable += 1 > ... > >>> function.variable = 1 > >>> function() > 1 > >>> function() > 2 > >>> > ``` > > If necessary, the variable can be initialised inside the function too. > Indeed; or you can initialize it with a decorator: def static(**kw): def deco(f): for name, val in kw.items(): setattr(f, name, val) return f return deco @static(variable=1) def function(): print(function.variable) function.variable += 1 There are a good few quirks to the concept of "static variables" though, and how you perceive them may guide your choice of which style to use. For example, what should this do? def outer(): def inner(): static variable = 1 return inner Should it have a single static variable shared among all the closures? If so, you probably want a global. Should each closure have its own static? Then use nonlocal and initialize the variable in outer(). Or what about methods? class Spam: def ham(self): static variable = 1 Shared across them all? Use Spam.variable, which (being attached to the class) is common to all Spam instances. Unique to each instance? Well, that's exactly what object members are, so "self.variable" is perfect. There are other quirks too (like decorated functions that end up wrapped, multiple classes, inheritance, etc etc etc), and honestly, if you don't care about those use cases, go with whichever one seems most convenient at the time :) ChrisA From Joseph.Schachner at Teledyne.com Thu Apr 14 14:29:07 2022 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Thu, 14 Apr 2022 18:29:07 +0000 Subject: Functionality like local static in C In-Reply-To: <8735ifhfo5.fsf@munus.decebal.nl> References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: Yes, python has something like that. In fact, two things. 1) Generator. Use a "yield" statement. Every call "yields" a new value. The state of the function (local variables) is remembered from each previous call to the next. 2) In a file, declare a variable to be global. In the function declare global var, so that it will not only read the global but will also write it. That variable does not go away. On the next time the function is called, It will hold whatever value it had when the function finished previously. ---- Joseph S. Teledyne Confidential; Commercially Sensitive Business Data -----Original Message----- From: Cecil Westerhof Sent: Thursday, April 14, 2022 11:02 AM To: python-list at python.org Subject: Functionality like local static in C In C when you declare a variable static in a function, the variable retains its value between function calls. The first time the function is called it has the default value (0 for an int). But when the function changes the value in a call (for example to 43), the next time the function is called the variable does not have the default value, but the value it had when the function returned. Does python has something like that? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From jon+usenet at unequivocal.eu Thu Apr 14 14:05:31 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 14 Apr 2022 18:05:31 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <4346b8a5-30ff-6340-e03d-b32ee9433f31@mrabarnett.plus.com> Message-ID: On 2022-04-14, MRAB wrote: > On 2022-04-14 16:22, Jon Ribbens via Python-list wrote: >> On 2022-04-14, Paul Bryan wrote: >>> I think because minutes and hours can easily be composed by multiplying >>> seconds. days is separate because you cannot compose days from seconds; >>> leap seconds are applied to days at various times, due to >>> irregularities in the Earth's rotation. >> >> That's an argument that timedelta should *not* have a 'days' attribute, >> because a day is not a fixed number of seconds long (to know how long >> a day is, you have to know which day you're talking about, and where). >> It's an undocumented feature of timedelta that by 'day' it means '86400 >> seconds'. > > When you're working only with dates, timedelta not having a 'days' > attribute would be annoying, especially when you consider that a day is > usually 24 hours, but sometimes 23 or 25 hours (DST). The second half of your sentence is the argument as to why the first half of your sentence is wrong. The difference between noon on the 26th March 2022 in London and noon on the 27th March 2022 is "1 day" from one point of view but is not "1 day" according to timedelta. From mirkok.lists at googlemail.com Thu Apr 14 14:42:34 2022 From: mirkok.lists at googlemail.com (Mirko) Date: Thu, 14 Apr 2022 20:42:34 +0200 Subject: No shortcut Icon on Desktop In-Reply-To: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> Message-ID: <62586B1A.9040702@googlemail.com> Am 13.04.2022 um 20:39 schrieb Dennis Lee Bieber: > On Thu, 14 Apr 2022 03:38:11 +1000, Tim Deke declaimed > the following: > >> Dear Sir, >> >> I have successfully downloaded Python into my laptop but the shortcut icon >> is not appearing on the desktop. I am using Windows 10 with the PC >> specifications as per snap shot attached below. Can you advise what to do? >> >> Thank you >> >> Tim Deke >> > Python normally does not create "shortcut icon"s -- one downloads an The Python Windows installer *absolutely* should. I do not know much about (modern) Windows, but one thing I do know is, that most Windows users are confused when after an installation there is no easy way to call the program. I do not understand, why the Windows installer *still* does not create a "Python 3.10" _*or similar*_ folder on the desktop with links to IDLE (with an icon text describing it properly as a Python Editor/IDE), the CHM and some introduction text in it. > installer (which on my system would be saved in %userprofile%\downloads), > and executes the installer (once). Python is not an all-in-one GUI > development environment (ie; it is not something like Lazarus/FreePascal, > Visual Studio, etc.). It is an interpreter for script files and depending > upon how the installer sets up the environment, one may never need to > directly invoke the Python interpreter -- one just invokes .py script files > and the OS activates the correct interpreter. With all due respect, but do you really think that it is useful for a Python beginner to know how to run the bare interpreter? ;-) Wouldn't it be much better to educate them about IDLE which can be found in the "Startmenu"? From grant.b.edwards at gmail.com Thu Apr 14 15:09:06 2022 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 14 Apr 2022 12:09:06 -0700 (PDT) Subject: No shortcut Icon on Desktop References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> Message-ID: <62587152.1c69fb81.28301.5517@mx.google.com> On 2022-04-14, Mirko via Python-list wrote: >> Python normally does not create "shortcut icon"s -- one downloads an > > The Python Windows installer *absolutely* should. Agreed. I'm not much of a Windows user, but I do maintain a few Windows applications with installers. They all create desktop shortcuts by default. There's a checkbox for it, and the user can uncheck it. In my experience, if an installer doesn't create a desktop shortcut by default, it just generates a lot of support calls about the installer not working or how do you run the program? Expecting people to go read some documentation on how to run a program, or even expecting them to look through the start menu is asking for headaches. That said, I don't really have much skin in this game since I neither use nor help maintain the windows installer. I do sometimes try to respond to the "installer is broken" or "how do I run it" posts, but I've mostly given up on that. -- Grant From andromedeyz at gmail.com Thu Apr 14 16:47:17 2022 From: andromedeyz at gmail.com (Andrew Hernandez) Date: Thu, 14 Apr 2022 13:47:17 -0700 (PDT) Subject: error of opening Python In-Reply-To: References: Message-ID: that is not an error, its simply the python console intrepeter From Richard at Damon-Family.org Thu Apr 14 19:08:25 2022 From: Richard at Damon-Family.org (Richard Damon) Date: Thu, 14 Apr 2022 19:08:25 -0400 Subject: No shortcut Icon on Desktop In-Reply-To: <62586B1A.9040702@googlemail.com> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> Message-ID: On 4/14/22 2:42 PM, Mirko via Python-list wrote: > Am 13.04.2022 um 20:39 schrieb Dennis Lee Bieber: >> On Thu, 14 Apr 2022 03:38:11 +1000, Tim Deke declaimed >> the following: >> >>> Dear Sir, >>> >>> I have successfully downloaded Python into my laptop but the shortcut icon >>> is not appearing on the desktop. I am using Windows 10 with the PC >>> specifications as per snap shot attached below. Can you advise what to do? >>> >>> Thank you >>> >>> Tim Deke >>> >> Python normally does not create "shortcut icon"s -- one downloads an > The Python Windows installer *absolutely* should. I do not know much > about (modern) Windows, but one thing I do know is, that most > Windows users are confused when after an installation there is no > easy way to call the program. I do not understand, why the Windows > installer *still* does not create a "Python 3.10" _*or similar*_ > folder on the desktop with links to IDLE (with an icon text > describing it properly as a Python Editor/IDE), the CHM and some > introduction text in it. > >> installer (which on my system would be saved in %userprofile%\downloads), >> and executes the installer (once). Python is not an all-in-one GUI >> development environment (ie; it is not something like Lazarus/FreePascal, >> Visual Studio, etc.). It is an interpreter for script files and depending >> upon how the installer sets up the environment, one may never need to >> directly invoke the Python interpreter -- one just invokes .py script files >> and the OS activates the correct interpreter. > With all due respect, but do you really think that it is useful for > a Python beginner to know how to run the bare interpreter? ;-) > > Wouldn't it be much better to educate them about IDLE which can be > found in the "Startmenu"? I think the issue is that the 'python' interpreter/compiler isn't the sort of program that makes sense to make a desktop icon for, as it is a command line utility. Perhaps making an icon for IDLE, if it has also been installed, but then the issue becomes would people recognize 'IDLE' as 'Python' to click on. -- Richard Damon From mats at wichmann.us Thu Apr 14 19:47:05 2022 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 14 Apr 2022 17:47:05 -0600 Subject: No shortcut Icon on Desktop In-Reply-To: References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> Message-ID: <9de70319-8248-cc60-d9fc-f3e1ed3fe2a1@wichmann.us> On 4/14/22 17:08, Richard Damon wrote: > I think the issue is that the 'python' interpreter/compiler isn't the > sort of program that makes sense to make a desktop icon for, as it is a > command line utility. > > Perhaps making an icon for IDLE, if it has also been installed, but then > the issue becomes would people recognize 'IDLE' as 'Python' to click on. I think so, the current icon has the Python logo superimposed on what looks like a page of code. From grant.b.edwards at gmail.com Thu Apr 14 20:06:11 2022 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Thu, 14 Apr 2022 17:06:11 -0700 (PDT) Subject: No shortcut Icon on Desktop References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> Message-ID: <6258b6f3.1c69fb81.57df2.744c@mx.google.com> On 2022-04-14, Richard Damon wrote: > I think the issue is that the 'python' interpreter/compiler isn't the > sort of program that makes sense to make a desktop icon for, as it is a > command line utility. Yes, it is a command line utility. Why does that mean you shouldn't have a desktop shortcut for it? I start up a python REPL prompt in a terminal often enough that were I a windows users, I would probably want a desktop shortcut for it. It would at least let people know that something got installed and show them what a Python is. If they don't want/use that shortcut, it's trivial to delete it. -- Grant From mats at wichmann.us Thu Apr 14 20:49:53 2022 From: mats at wichmann.us (Mats Wichmann) Date: Thu, 14 Apr 2022 18:49:53 -0600 Subject: No shortcut Icon on Desktop In-Reply-To: <6258b6f3.1c69fb81.57df2.744c@mx.google.com> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> Message-ID: On 4/14/22 18:06, Grant Edwards wrote: > On 2022-04-14, Richard Damon wrote: > >> I think the issue is that the 'python' interpreter/compiler isn't the >> sort of program that makes sense to make a desktop icon for, as it is a >> command line utility. > > Yes, it is a command line utility. Why does that mean you shouldn't > have a desktop shortcut for it? > > I start up a python REPL prompt in a terminal often enough that were I > a windows users, I would probably want a desktop shortcut for it. > > It would at least let people know that something got installed and > show them what a Python is. If they don't want/use that shortcut, it's > trivial to delete it. > > -- > Grant > > easy to add - it's a windows thing, not a python thing. you can navigate to the install directory and create a shortcut and drag that out of that directiory in explorer and drop it on the desktop. or you can navigate through the start menu, and when you get to the thing you want, pick open folder and then you can create a shortcut and drag off to the desktop. From ojomooluwatolami675 at gmail.com Fri Apr 15 03:41:20 2022 From: ojomooluwatolami675 at gmail.com (Tola Oj) Date: Fri, 15 Apr 2022 08:41:20 +0100 Subject: code confusion Message-ID: i = int(input()) lis = list(map(int,input().strip().split()))[:i] z = max(lis) while max(lis) == z: lis.remove(max(lis)) print (max(lis)) this is an answer to a question from the discussion chat in hackerrank. i didn't know the answer so i found an answer that fitted well to the question, however i struggle to understand the use of some of the methods and functions the person has used. my major questions are: 1. what does "[:i]" mean 2. is there another i could write this code using if statement? thank you From rosuav at gmail.com Fri Apr 15 03:48:26 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 15 Apr 2022 17:48:26 +1000 Subject: code confusion In-Reply-To: References: Message-ID: On Fri, 15 Apr 2022 at 17:42, Tola Oj wrote: > > i = int(input()) > lis = list(map(int,input().strip().split()))[:i] > z = max(lis) > while max(lis) == z: > lis.remove(max(lis)) > > print (max(lis)) > > this is an answer to a question from the discussion chat in hackerrank. i > didn't know the answer so i found an answer that fitted well to the > question, however i struggle to understand the use of some of the methods > and functions the person has used. my major questions are: 1. what does > "[:i]" mean > 2. is there > another i could write this code using if statement? If you don't understand the code, don't submit it :) You should create your own code for hackerrank. I'll just give very very broad hints: 1) It's slicing. Play around with it in the interactive interpreter and see what it does with different inputs. 2) Yes. You can always write code with an if statement. What are you actually trying to accomplish though? ChrisA From PythonList at DancesWithMice.info Fri Apr 15 03:49:35 2022 From: PythonList at DancesWithMice.info (dn) Date: Fri, 15 Apr 2022 19:49:35 +1200 Subject: code confusion In-Reply-To: References: Message-ID: <8fc44be5-12ff-94e6-b155-319f201c00e2@DancesWithMice.info> On 15/04/2022 19.41, Tola Oj wrote: > i = int(input()) > lis = list(map(int,input().strip().split()))[:i] > z = max(lis) > while max(lis) == z: > lis.remove(max(lis)) > > print (max(lis)) > > this is an answer to a question from the discussion chat in hackerrank. i > didn't know the answer so i found an answer that fitted well to the > question, however i struggle to understand the use of some of the methods > and functions the person has used. my major questions are: 1. what does > "[:i]" mean > 2. is there > another i could write this code using if statement? > thank you It is taking a slice from the list: https://docs.python.org/3/glossary.html#term-slice More explanation: https://docs.python.org/3/tutorial/introduction.html?highlight=slice -- Regards, =dn From sam.z.ezeh at gmail.com Fri Apr 15 07:19:21 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Fri, 15 Apr 2022 12:19:21 +0100 Subject: Proposal: Syntax for attribute initialisation in __init__ methods Message-ID: Elsewhere, the idea of supporting new syntax to automatically initialise attributes provided as arguments to __init__ methods was raised. Very often, __init__ functions will take arguments only to assign them as attributes of self. This proposal would remove the need to additionally write `self.argument = argument` when doing this. I'm specifically looking at statements of the form `self.argument = argument`. I ran a query on the source code of the top 20 most downloaded PyPi packages (source: https://github.com/dignissimus/presearch/blob/master/queries/attribute_initialisation.py) and found the following statistics. I found that 19% of classes that define __init__ and have at least one argument that isn't `self` assign all of those non-self arguments as attributes with the same name in the function definition. I also found that 33% of __init__ functions that have more than one non-self argument assign at least one of their arguments as attributes with the same name, that 27% of __init__ functions that have at least two non-self arguments assign at least 2 of them as attributes with the same name and that 28% of __init__ functions that had 3 or more non-self arguments assigned at least 3 of their arguments as attributes with the same name. ``` [sam at samtop]: ~/Documents/git/presearch>$ presearch -f queries/attribute_initialisation.py sources/ Running queries... Out of 1526 classes defining __init__, there were 290 (19.0%) classes whose __init__ functions assigned all non-self arguments as attributes. Out of 1526 __init__ functions with at least one non-self argument, there were 497 (32.57%) __init__ functions that assigned one or more non-self arguments as attributes. Out of 834 __init__ functions with at least two non-self arguments, there were 221 (26.5%) __init__ functions that assigned two or more non-self arguments as attributes. Out of 490 __init__ functions with at least three non-self arguments, there were 139 (28.37%) __init__ functions that assigned three or more non-self arguments as attributes. [sam at samtop]: ~/Documents/git/presearch>$ ``` With the new syntax, the following snippet taking from the pyyaml source code (pyyaml is the 12th most downloaded package this month on PyPi) ``` def __init__(self, default_style=None, default_flow_style=False, sort_keys=True): self.default_style = default_style self.sort_keys = sort_keys self.default_flow_style = default_flow_style self.represented_objects = {} self.object_keeper = [] self.alias_key = None ``` Can be re-written as follows ``` def __init__(self, @default_style=None, @default_flow_style=False, @sort_keys=True): self.represented_objects = {} self.object_keeper = [] self.alias_key = None ``` And from numpy, the following code ``` def __init__(self, mbfunc, fillx=0, filly=0): """ abfunc(fillx, filly) must be defined. abfunc(x, filly) = x for all x to enable reduce. """ super().__init__(mbfunc) self.fillx = fillx self.filly = filly ufunc_domain[mbfunc] = None ufunc_fills[mbfunc] = (fillx, filly) ``` Can be written like this ``` def __init__(self, mbfunc, @fillx=0, @filly=0): """ abfunc(fillx, filly) must be defined. abfunc(x, filly) = x for all x to enable reduce. """ super().__init__(mbfunc) ufunc_domain[mbfunc] = None ufunc_fills[mbfunc] = (fillx, filly) ``` Some related implementations are attrs, dataclasses and the use of a decorator. And there's potentially a point to be raised that the results from the first query indicate that the @dataclasse decorator is not being used enough. One advantage this proposal offers is control over the arguments that the __init__ function takes. A downside to using a decorator is that it might become difficult to accept arguments that don't need to be assigned to anything. I gave the example of the following code (unlike the above, this is not taken from existing python source code). In this example, a decorator can't assign all of the arguments to attributes or else it would produce code that does something different. ``` class ExampleClass: def __init__(self, example, argument, word): self.example = example self.argument = argument do_something(word) ``` In response, the following was given ``` class ExampleClass: @make_attr("example") @make_attr("argument") def __init__(self, example, argument, word): do_something(word) ``` And this could potentially be written like this ``` class ExampleClass: @make_attr("example", "argument") def __init__(self, example, argument, word): do_something(word) ``` However, having to rewrite the argument name might defeat the purpose of having a decorator. As an idea, I thought about the case of when an __init__ method only contains arguments that will become attributes. From the cryptography library, there's the following example. ``` class _DeprecatedValue: def __init__(self, value: object, message: str, warning_class): self.value = value self.message = message self.warning_class = warning_class ``` With the new syntax, this would become the following ``` class _DeprecatedValue: def __init__(self, @value: object, @message: str, @warning_class): pass ``` The empty __init__ method seems unnecessary so perhaps it could be reduced further to the following ``` class _DeprecatedValue: @value: object @message: str @warning_class ``` With regards to implementation details, there are questions about the order of execution, right now it seems to make sense to me that attributes should be assigned to prevent them from being overridden by any calls to super() for code similar to that in the numpy example. Another question could be what happens if the syntax is used outside of an __init__ method. Right now, it seems to me that this could be ok and the code could run the same as it would inside the __init__ method. There is also the question of what happens if the syntax is used inside a function that isn't defined in a class, and perhaps this usage should be rejected. As another edge case, there's the question of what would happen if this syntax is used on functions labelled with the @staticmethod decorator. Type hinting will also have to be dealt with. With all of this in mind, I'd like to hear what other people think about this proposal. To perform the queries I created a tool called presearch which others might find useful. I found it quite fun to make however it's only been in existence for 2 days so there currently isn't any documentation and it's lacking in several areas. The source code can be found here: https://github.com/dignissimus/presearch Kind Regards, Sam Ezeh From grant.b.edwards at gmail.com Fri Apr 15 10:59:06 2022 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 15 Apr 2022 07:59:06 -0700 (PDT) Subject: No shortcut Icon on Desktop References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> Message-ID: <6259883a.1c69fb81.9c6d4.988b@mx.google.com> On 2022-04-15, Mats Wichmann wrote: > On 4/14/22 18:06, Grant Edwards wrote: >> On 2022-04-14, Richard Damon wrote: >> >>> I think the issue is that the 'python' interpreter/compiler isn't the >>> sort of program that makes sense to make a desktop icon for, as it is a >>> command line utility. >> >> Yes, it is a command line utility. Why does that mean you shouldn't >> have a desktop shortcut for it? >> >> I start up a python REPL prompt in a terminal often enough that were I >> a windows users, I would probably want a desktop shortcut for it. >> >> It would at least let people know that something got installed and >> show them what a Python is. If they don't want/use that shortcut, it's >> trivial to delete it. > > easy to add - it's a windows thing, not a python thing. you can > navigate to the install directory and create a shortcut and drag > that out of that directiory in explorer and drop it on the desktop. Of course it's easy to add. But, we're talking about people who have no idea how to do that. They have no clue how to "navigate to the install directory". They don't even realize anything _was_ installed. The problem is that people run the installer, don't see a desktop icon, and think nothing has been installed. Or they think the installer "is python", and run it over and over again trying to "run Python". Then they post the exact same plea for help that has been posted coutless times. If the installer, by default, created an IDLE desktop shortcut and a cmd.exe shortcut that ran Python, I believe it would eliminate most of those problems. -- Grant From mats at wichmann.us Fri Apr 15 12:53:16 2022 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 15 Apr 2022 10:53:16 -0600 Subject: No shortcut Icon on Desktop In-Reply-To: <6259883a.1c69fb81.9c6d4.988b@mx.google.com> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> <6259883a.1c69fb81.9c6d4.988b@mx.google.com> Message-ID: <6c37a4a1-a6c8-27ba-9d9c-85b87aa68871@wichmann.us> On 4/15/22 08:59, Grant Edwards wrote: > Of course it's easy to add. But, we're talking about people who have > no idea how to do that. They have no clue how to "navigate to the > install directory". They don't even realize anything _was_ installed. I dunno, it's a pretty WIndows-y thing, right-click + create shortcut. But anyway... > The problem is that people run the installer, don't see a desktop > icon, and think nothing has been installed. Or they think the > installer "is python", and run it over and over again trying to "run > Python". Then they post the exact same plea for help that has been > posted coutless times. > > If the installer, by default, created an IDLE desktop shortcut and a > cmd.exe shortcut that ran Python, I believe it would eliminate most of > those problems. I'd add - not naming the installer something Windows' memory of recent files retains as being Python itself - could be as simple as including the word "setup" in the name. From auriocus at gmx.de Fri Apr 15 01:43:09 2022 From: auriocus at gmx.de (Christian Gollwitzer) Date: Fri, 15 Apr 2022 07:43:09 +0200 Subject: No shortcut Icon on Desktop In-Reply-To: References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> Message-ID: Am 15.04.22 um 02:49 schrieb Mats Wichmann: > On 4/14/22 18:06, Grant Edwards wrote: >> On 2022-04-14, Richard Damon wrote: >> >>> I think the issue is that the 'python' interpreter/compiler isn't the >>> sort of program that makes sense to make a desktop icon for, as it is a >>> command line utility. >> >> Yes, it is a command line utility. Why does that mean you shouldn't >> have a desktop shortcut for it? >> >> I start up a python REPL prompt in a terminal often enough that were I >> a windows users, I would probably want a desktop shortcut for it. >> >> It would at least let people know that something got installed and >> show them what a Python is. If they don't want/use that shortcut, it's >> trivial to delete it. >> > easy to add - it's a windows thing, not a python thing. you can > navigate to the install directory and create a shortcut and drag that > out of that directiory in explorer and drop it on the desktop. or you > can navigate through the start menu, and when you get to the thing you > want, pick open folder and then you can create a shortcut and drag off > to the desktop. Yes, you *can* do that of course and it is not a Python thing - but the point is, that typical Windows installers create these shortcuts during the installation process for you - typically there is a pre-selected checkbox "Create desktop icons" or similar. I agree with Grant that this is what users expect from the installer. Christian From Cecil at decebal.nl Fri Apr 15 06:18:18 2022 From: Cecil at decebal.nl (Cecil Westerhof) Date: Fri, 15 Apr 2022 12:18:18 +0200 Subject: Functionality like local static in C References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: <87tuaufy51.fsf@munus.decebal.nl> Thanks for the multiple answers. I was pleasantly surprised. I have something to think about. :-D In principle I selected a solution for the problem for which I asked it, but I first have to finish some other stuff. I hope to find time to implement it next week. Everyone a good weekend and Eastern. Cecil Westerhof writes: > In C when you declare a variable static in a function, the variable > retains its value between function calls. > The first time the function is called it has the default value (0 for > an int). > But when the function changes the value in a call (for example to 43), > the next time the function is called the variable does not have the > default value, but the value it had when the function returned. > Does python has something like that? -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof From learn2program at gmail.com Fri Apr 15 06:51:22 2022 From: learn2program at gmail.com (Alan Gauld) Date: Fri, 15 Apr 2022 11:51:22 +0100 Subject: Python app on a Mac In-Reply-To: References: Message-ID: I've just migrated from a Linux PC to a Mac mini running Monterey. I have a Python GUI(Tkinter) app that I wrote on Linux and have managed to get working on MacOS except.... When I start the program I get a Terminal window as well as the GUI. On Windows I'd run it with pythonw and in Linux I just created a desktop launcher to avoid that. But there is no pythonw on MacOS nor a simple way I can find to launch apps from the desktop. Does anyone know how to launch a Python program from the desktop without a Terminal window (or at least with an iconified one!) Does it require Applescript or somesuch? Alan G. From python at example.invalid Fri Apr 15 09:55:38 2022 From: python at example.invalid (Python) Date: Fri, 15 Apr 2022 15:55:38 +0200 Subject: Functionality like local static in C References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: Cecil Westerhof wrote: > In C when you declare a variable static in a function, the variable > retains its value between function calls. > The first time the function is called it has the default value (0 for > an int). > But when the function changes the value in a call (for example to 43), > the next time the function is called the variable does not have the > default value, but the value it had when the function returned. > Does python has something like that? Sort of, one way is to have a argument with a default value which is mutable. Hint: don't do that. From luca72.bertolotti at gmail.com Fri Apr 15 13:18:33 2022 From: luca72.bertolotti at gmail.com (luca72.b...@gmail.com) Date: Fri, 15 Apr 2022 10:18:33 -0700 (PDT) Subject: is there somebody that have experince with python and canopen Message-ID: We are searching for someone that can develop a python program for use servomotor for automotive. From wlfraed at ix.netcom.com Fri Apr 15 14:31:33 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Fri, 15 Apr 2022 14:31:33 -0400 Subject: code confusion References: Message-ID: <9jcj5h1jumpf3sauil11540pqs27c6qnp7@4ax.com> On Fri, 15 Apr 2022 08:41:20 +0100, Tola Oj declaimed the following: >i = int(input()) Obtain a single /integer/ from stdin -- note: any extraneous characters on the input line will result in a failure to convert from textual representation to internal/binary integer >lis = list(map(int,input().strip().split()))[:i] Obtain a line from stdin containing space separated /integer/ representations. Split the line at the spaces. Convert each "word" to internal/binary integer. Keep up to at most "i" integers. Note that the position of the [:i] could be at ... .split()[:i] The difference being that the provided code is converting all "words" on the input into integers and then keeping the first "i"; putting the [:i] after .split() means only the first "i" words are kept, and hence only that many need to be converted to integer. >z = max(lis) Determine largest value in the list of integers >while max(lis) == z: >lis.remove(max(lis)) WHILE the largest value in the (current) list matches the initially determined maximum value... remove that value from the list. Rather than repeat "max(lis)" in the .remove() invocation, just pass it "z" (the WHILE has already confirmed that the maximum "z" is found in the list, so why recompute the maximum). Note: Python indentation is significant -- the above .remove() line needs to be indented. Presuming your code was properly indented please find a posting client that doesn't reformat leading indentation. > >print (max(lis)) > Display the new list maximum value after removing all instances of the initial maximum value. >this is an answer to a question from the discussion chat in hackerrank. i >didn't know the answer so i found an answer that fitted well to the >question, however i struggle to understand the use of some of the methods >and functions the person has used. my major questions are: 1. what does >"[:i]" mean Learn the contents of the Library Reference Manual -- you don't need to memorize it all, but should at least know the major groupings... https://docs.python.org/3/library/stdtypes.html#common-sequence-operations > 2. is there >another i could write this code using if statement? There are many ways to rewrite that... UNTESTED i = int(input("How many integers are to be considered?")) ls = [int(wd) for wd in input( "enter space separated integers" ).split()[:i]] maximum = max(ls) while maximum in ls: ls.remove(maximum) print(ls) Remove the first line, and the [:i], and the code will happily process for however many integers are provided on the input line. The while/remove loop can be replaced with ls = [itm for itm in ls if itm != maximum] which only requires one pass through the list; while/remove has to scan the list to see if maximum is in it, then has to scan it a second time to for the .remove() to find where in the list it is found. Or... for _ in range(ls.count(maximum)): ls.remove(maximum) where _ is a "junk/temp" value that we don't care about -- we only want to loop once for EACH maximum value Or... while maximum in ls: del ls[ls.index(maximum)] -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From python at mrabarnett.plus.com Fri Apr 15 14:53:44 2022 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 15 Apr 2022 19:53:44 +0100 Subject: Python app on a Mac In-Reply-To: References: Message-ID: <2846d03a-48cb-8bdd-fb3a-aad93d20f8ff@mrabarnett.plus.com> On 2022-04-15 11:51, Alan Gauld wrote: > I've just migrated from a Linux PC to a Mac mini running Monterey. > > I have a Python GUI(Tkinter) app that I wrote on Linux > and have managed to get working on MacOS except.... > > When I start the program I get a Terminal window as well > as the GUI. On Windows I'd run it with pythonw and in Linux > I just created a desktop launcher to avoid that. But there > is no pythonw on MacOS nor a simple way I can find to > launch apps from the desktop. > > Does anyone know how to launch a Python program from the > desktop without a Terminal window (or at least with an > iconified one!) Does it require Applescript or somesuch? > There's an answer here: https://stackoverflow.com/questions/50792048/running-a-python-script-without-opening-terminal From rosuav at gmail.com Fri Apr 15 15:13:54 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 16 Apr 2022 05:13:54 +1000 Subject: Functionality like local static in C In-Reply-To: References: <8735ifhfo5.fsf@munus.decebal.nl> Message-ID: On Sat, 16 Apr 2022 at 04:51, Python wrote: > > Cecil Westerhof wrote: > > In C when you declare a variable static in a function, the variable > > retains its value between function calls. > > The first time the function is called it has the default value (0 for > > an int). > > But when the function changes the value in a call (for example to 43), > > the next time the function is called the variable does not have the > > default value, but the value it had when the function returned. > > Does python has something like that? > > Sort of, one way is to have a argument with a default value > which is mutable. Hint: don't do that. > Why do you anonymously suggest a thing and also suggest not doing it? The default argument technique has been mentioned already as a perfectly valid way to do this. ChrisA From alister.ware at ntlworld.com Fri Apr 15 16:12:43 2022 From: alister.ware at ntlworld.com (alister) Date: Fri, 15 Apr 2022 20:12:43 -0000 (UTC) Subject: is there somebody that have experince with python and canopen References: Message-ID: On Fri, 15 Apr 2022 10:18:33 -0700 (PDT), luca72.b... at gmail.com wrote: > We are searching for someone that can develop a python program for use > servomotor for automotive. What location & what is the salary? (although based on the method of recruitment I doubt that you will get many takers) -- MS and Y2K: Windows 95, 98, ... and back again to 01 -- Laurent Szyster From avigross at verizon.net Fri Apr 15 16:58:15 2022 From: avigross at verizon.net (Avi Gross) Date: Fri, 15 Apr 2022 20:58:15 +0000 (UTC) Subject: code confusion In-Reply-To: <9jcj5h1jumpf3sauil11540pqs27c6qnp7@4ax.com> References: <9jcj5h1jumpf3sauil11540pqs27c6qnp7@4ax.com> Message-ID: <1355735908.167920.1650056295834@mail.yahoo.com> As usual, without very clear and precise instructions and parameters,?the answers may not quite fit. It looks like you are asked two and only two questions. The first is asking how many numbers you want.? Before continuing, you need to make sure that is a valid number?as many answer will throw an exception. The next line, complex as it is, asks for one long answer and does?not check anything and breaks rapidly unless you use just normal?integer representation. Yes, it ignores any entry after the "i"th but?if you want valid entries, you might want to evaluate them in a loop?perhaps one at a time and keep going till you have 'i" valid ones. I do suggest you not use the variable name of "i" for many reasons?as modern languages allow more meaningful names like, well, "n"! I understand using i, j, k in some nested loops but here I would haveused something like howMany and verified the number was an integer?larger than 0. As for getting the second largest number, there is nothing wrong?with determining it the hard way. Of course for some people, it?is more intuitive to sort the uniqued data and simply choose the?2nd entry from the end. Some python modules allow you tosee the ranks of various entries and you can simply choose?the one of second rank.? But if this is HW, you are being asked to do things the old-fashioned?way! LOL! -----Original Message----- From: Dennis Lee Bieber To: python-list at python.org Sent: Fri, Apr 15, 2022 2:31 pm Subject: Re: code confusion On Fri, 15 Apr 2022 08:41:20 +0100, Tola Oj declaimed the following: >i = int(input()) ??? Obtain a single /integer/ from stdin -- note: any extraneous characters on the input line will result in a failure to convert from textual representation to internal/binary integer >lis = list(map(int,input().strip().split()))[:i] ??? Obtain a line from stdin containing space separated /integer/ representations. Split the line at the spaces. Convert each "word" to internal/binary integer. Keep up to at most "i" integers. Note that the position of the [:i] could be at ??? ??? ??? ... .split()[:i] The difference being that the provided code is converting all "words" on the input into integers and then keeping the first "i"; putting the [:i] after .split() means only the first "i" words are kept, and hence only that many need to be converted to integer. >z = max(lis) ??? Determine largest value in the list of integers >while max(lis) == z: >lis.remove(max(lis)) ??? WHILE the largest value in the (current) list matches the initially determined maximum value... remove that value from the list. ??? Rather than repeat "max(lis)" in the .remove() invocation, just pass it "z" (the WHILE has already confirmed that the maximum "z" is found in the list, so why recompute the maximum). ??? Note: Python indentation is significant -- the above .remove() line needs to be indented. Presuming your code was properly indented please find a posting client that doesn't reformat leading indentation. > >print (max(lis)) > ??? Display the new list maximum value after removing all instances of the initial maximum value. >this is an answer to a question from the discussion chat in hackerrank. i >didn't know the answer so i found an answer that fitted well to the >question, however i struggle to understand the use of some of the methods >and functions the person has used. my major questions are: 1. what does >"[:i]" mean ??? Learn the contents of the Library Reference Manual -- you don't need to memorize it all, but should at least know the major groupings... https://docs.python.org/3/library/stdtypes.html#common-sequence-operations >? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2. is there >another i could write this code using if statement? ??? There are many ways to rewrite that... UNTESTED i = int(input("How many integers are to be considered?")) ls = [int(wd) for wd in input( ??? ??? ??? ??? "enter space separated integers" ??? ??? ??? ??? ).split()[:i]] maximum = max(ls) while maximum in ls: ??? ls.remove(maximum) print(ls) ??? Remove the first line, and the [:i], and the code will happily process for however many integers are provided on the input line. ??? The while/remove loop can be replaced with ls = [itm for itm in ls if itm != maximum] which only requires one pass through the list; while/remove has to scan the list to see if maximum is in it, then has to scan it a second time to for the .remove() to find where in the list it is found. ??? Or... for _ in range(ls.count(maximum)): ??? ls.remove(maximum) where _ is a "junk/temp" value that we don't care about -- we only want to loop once for EACH maximum value ??? Or... while maximum in ls: ??? del ls[ls.index(maximum)] -- ??? Wulfraed? ? ? ? ? ? ? ? Dennis Lee Bieber? ? ? ? AF6VN ??? wlfraed at ix.netcom.com? ? http://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list From PythonList at DancesWithMice.info Fri Apr 15 17:26:43 2022 From: PythonList at DancesWithMice.info (dn) Date: Sat, 16 Apr 2022 09:26:43 +1200 Subject: Proposal: Syntax for attribute initialisation in __init__ methods In-Reply-To: References: Message-ID: On 15/04/2022 23.19, Sam Ezeh wrote: ... Kudos for doing the research! > Some related implementations are attrs, dataclasses and the use of a > decorator. And there's potentially a point to be raised that the results > from the first query indicate that the @dataclasse decorator is not being > used enough. One advantage this proposal offers is control over the > arguments that the __init__ function takes. > > A downside to using a decorator is that it might become difficult to accept > arguments that don't need to be assigned to anything. > > I gave the example of the following code (unlike the above, this is not > taken from existing python source code). In this example, a decorator can't > assign all of the arguments to attributes or else it would produce code > that does something different. ... I will support anything which reduces 'boiler-plate' or 'make busy' work! Perhaps I'm missing the point, but what functionality or advantage(s) does this give, over data-classes? Maybe Dataclasses are not being used as much as one might hope, but they are relatively new, and many Python-Masters simply carry-on constructing classes the way they have for years... If data-classes give the impression of being 'syntactic sugar', there's no particular need to use them - and certainly no rule or demand. There are constructs where one might find it easier not to use them. @dataclass does allow init=False. There is an argument which says that all data-attributes should be 'created' inside an __init__() or __post_init__(), rather than 'somewhere', 'later'. -- Regards, =dn From ethan at stoneleaf.us Fri Apr 15 17:56:00 2022 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 15 Apr 2022 14:56:00 -0700 Subject: Proposal: Syntax for attribute initialisation in __init__ methods In-Reply-To: References: Message-ID: <866bacfe-2b18-213f-c903-b4322209dc2f@stoneleaf.us> On 4/15/22 04:19, Sam Ezeh wrote: > Elsewhere, the idea of supporting new syntax to automatically initialise > attributes provided as arguments to __init__ methods was raised. [...] Good post! You'll want to send this to python-ideas at some point (that's where most new python features are discussed). This particular desire has come up in the past, so you'll need to do some more research (i.e. find the previous threads on python-ideas) so you can answer objections already raised, or find new data supporting/refuting previous arguments. -- ~Ethan~ From grant.b.edwards at gmail.com Fri Apr 15 20:27:30 2022 From: grant.b.edwards at gmail.com (Grant Edwards) Date: Fri, 15 Apr 2022 17:27:30 -0700 (PDT) Subject: No shortcut Icon on Desktop References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> <6259883a.1c69fb81.9c6d4.988b@mx.google.com> <6c37a4a1-a6c8-27ba-9d9c-85b87aa68871@wichmann.us> Message-ID: <625a0d72.1c69fb81.689e7.d204@mx.google.com> On 2022-04-15, Mats Wichmann wrote: > I'd add - not naming the installer something Windows' memory of recent > files retains as being Python itself - could be as simple as including > the word "setup" in the name. Oh yes, that's been suggested many, many times also. :) I always name all my installers something that ends in -setup.exe or -setup.ini. I always used to build .exe installers, but have more recently been trending towards .ini's. But the end of the basename alway ends in -setup. -- Grant From mirkok.lists at googlemail.com Fri Apr 15 21:07:34 2022 From: mirkok.lists at googlemail.com (Mirko) Date: Sat, 16 Apr 2022 03:07:34 +0200 Subject: No shortcut Icon on Desktop In-Reply-To: <6c37a4a1-a6c8-27ba-9d9c-85b87aa68871@wichmann.us> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> <6259883a.1c69fb81.9c6d4.988b@mx.google.com> <6c37a4a1-a6c8-27ba-9d9c-85b87aa68871@wichmann.us> Message-ID: <625A16D6.5060007@googlemail.com> Am 15.04.2022 um 18:53 schrieb Mats Wichmann: > On 4/15/22 08:59, Grant Edwards wrote: > >> Of course it's easy to add. But, we're talking about people who have >> no idea how to do that. They have no clue how to "navigate to the >> install directory". They don't even realize anything _was_ installed. > > > I dunno, it's a pretty WIndows-y thing, > But anyway... Yes, it is a pretty "Windows-y thing". How do Windows software installers work? What do they do? They add shortcuts to the desktop. I do not use Windows for myself since many years, but it is hard for me to remember any software that did not add those shortcuts. > right-click + create shortcut. Right-click on what and where? On something called "IDLE" (has what to do with python?). Right click on "python.exe" which gives some wired texty DOS-window (or how that thing is called) where one can do what? Don't get me wrong. I do not ask those questions. Myself, I'm perfectly able to compile Python from source on pretty much any system you throw me at. But we are talking about people who are new to programming. AFAIK, almost every Windows tool/application/utility does add those desktop shortcuts/icons/links. Newcomers expect, want and need some editor or IDE or "app". Just put a "Python" folder on the desktop with an "IDLE Python Editor" on the desktop and done. How hard is it do add that functionality to the Windows installer? Because I just can't see any reason not to do it. What is there to lose in trying/doing that? What dire consequences does that might have? From greg.ewing at canterbury.ac.nz Fri Apr 15 20:18:31 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sat, 16 Apr 2022 12:18:31 +1200 Subject: Python app on a Mac In-Reply-To: References: Message-ID: On 15/04/22 10:51 pm, Alan Gauld wrote: > Does anyone know how to launch a Python program from the > desktop without a Terminal window (or at least with an > iconified one!) Does it require Applescript or somesuch? The easiest and most reliable way is probably to use Automator with a Run Shell Script action, and save it as type Application. The command should be something like /path/to/desired/python /path/to/my/python_file.py Note that the current directory will probably be the user's home directory, so it's best to use full pathnames for everything. -- Greg From learn2program at gmail.com Fri Apr 15 20:21:03 2022 From: learn2program at gmail.com (Alan Gauld) Date: Sat, 16 Apr 2022 01:21:03 +0100 Subject: Python app on a Mac Message-ID: <02152ade-cc64-bb7d-08cc-7e4f9f46ab1e@yahoo.co.uk> On 15/04/2022 19:53, MRAB wrote: >> When I start the program I get a Terminal window as well >> as the GUI. On Windows I'd run it with pythonw and in Linux >> ... >> Does anyone know how to launch a Python program from the >> desktop without a Terminal window (or at least with an >> iconified one!) Does it require Applescript or somesuch? >> > There's an answer here: > > https://stackoverflow.com/questions/50792048/running-a-python-script-without-opening-terminal Yes, I've already done all that. The script runs and the GUI displays but so does a Terminal in the background. The SO answer does mention you can get the Terminal to close when the script terminates whhich would be better than now. However, another answer mentions something called Automator, which I'll need to Google... Thanks for the pointer though. -- Alan G Author of the Learn to Program web site http://www.alan-g.me.uk/ http://www.amazon.com/author/alan_gauld Follow my photo-blog on Flickr at: http://www.flickr.com/photos/alangauldphotos From drsalists at gmail.com Fri Apr 15 21:54:03 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Fri, 15 Apr 2022 18:54:03 -0700 Subject: Python app on a Mac In-Reply-To: References: Message-ID: On Fri, Apr 15, 2022 at 11:43 AM Alan Gauld wrote: > I've just migrated from a Linux PC to a Mac mini running Monterey. > I'm using a Mac for work lately. I miss Linux. I feel like MacOS isn't nearly as good at multimonitor setups as Cinnamon. Does anyone know how to launch a Python program from the > desktop without a Terminal window (or at least with an > iconified one!) Does it require Applescript or somesuch? > You could try appify: https://stromberg.dnsalias.org/~strombrg/mactools/ From hjp-python at hjp.at Sat Apr 16 04:14:05 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 10:14:05 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: References: <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> <20220413180300.qrnneczjdftb2kdq@hjp.at> Message-ID: <20220416081405.ux34uzdhxdgsoggk@hjp.at> On 2022-04-14 19:31:58 +0200, Marco Sulla wrote: > On Wed, 13 Apr 2022 at 20:05, Peter J. Holzer wrote: > > > > On 2022-04-12 21:03:00 +0200, Marco Sulla wrote: > > > On Tue, 29 Mar 2022 at 00:10, Peter J. Holzer wrote: > > > > They are are about a year apart, so they will usually contain > > > > different versions of most packages right from the start. So the > > > > Ubuntu and Debian security teams probably can't benefit much > > > > from each other. > > > > > > Well, this is what my updater on Lubuntu says to me today: [...] > > > - debian/patches/CVE-2018-16301.patch: Add check of [...] > > > - debian/patches/CVE-2020-8037.patch: Add a limit to the [...] > > > I use an LTS version. So it seems that Ubuntu benefits from Debian > > > security patches. > > > > Why do you think so? Because the release notes mention > > debian/patches/*.patch? > > Of course. > > > This may be an artefact of the build process. The build tools for .deb > > packages expect all kinds of meta-data to live in a subdirectory called > > "debian", even on non-debian systems. This includes patches, at least if > > the maintainer is using quilt (which AFAIK is currently the recommended > > tool for that purpose). > > And why does the security update package contain metadata about Debian > patches, It doesn't (or at least you can't conclude that from the evidence you posted). There is a subdirectory called "debian" in the build directory of every .deb package. This is true on Debian, Ubuntu and every other distribution which uses the .deb package format. This directory is required by the build tools and it contains all the data (e.g. build instructions, dependencies, patches, description, extra documentation) which was added by the packager. The name of the directory does not imply that any of the files there was created by Debian. I have built quite a few packages myself and I'm not a member of the Debian team. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Sat Apr 16 04:44:11 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 10:44:11 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> Message-ID: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> On 2022-04-14 15:22:29 -0000, Jon Ribbens via Python-list wrote: > On 2022-04-14, Paul Bryan wrote: > > I think because minutes and hours can easily be composed by multiplying > > seconds. days is separate because you cannot compose days from seconds; > > leap seconds are applied to days at various times, due to > > irregularities in the Earth's rotation. > > That's an argument that timedelta should *not* have a 'days' attribute, > because a day is not a fixed number of seconds long (to know how long > a day is, you have to know which day you're talking about, and where). Which is exactly why timedelta *must* have separate fields for seconds, days and months. You can't simply express the larger units as multiples of the smaller units, so they have to be stored separately for date arithmetic to work. > It's an undocumented feature of timedelta that by 'day' it means '86400 > seconds'. I'd call that a bug, not a feature: >>> from datetime import datetime, timedelta >>> t0 = datetime.fromisoformat("2022-03-26T12:00").astimezone() >>> t0 datetime.datetime(2022, 3, 26, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')) >>> d = timedelta(days=1) >>> t1 = t0 + d >>> t1 datetime.datetime(2022, 3, 27, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')) >>> t1.isoformat() '2022-03-27T12:00:00+01:00' Python missed the switch to DST here, the timezone is wrong. If I do the same thing in PostgreSQL: hjp=> select '2022-03-26T12:00'::timestamptz; ?????????????????????????? ? timestamptz ? ?????????????????????????? ? 2022-03-26 12:00:00+01 ? ?????????????????????????? (1 row) Time: 5.542 ms hjp=> select '2022-03-26T12:00'::timestamptz + '1 day'::interval; ?????????????????????????? ? ?column? ? ?????????????????????????? ? 2022-03-27 12:00:00+02 ? ?????????????????????????? (1 row) It correctly determines that DST is already in effect at noon of March 27th. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From Marco.Sulla.Python at gmail.com Sat Apr 16 10:49:17 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 16 Apr 2022 16:49:17 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: <20220416081405.ux34uzdhxdgsoggk@hjp.at> References: <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> <20220413180300.qrnneczjdftb2kdq@hjp.at> <20220416081405.ux34uzdhxdgsoggk@hjp.at> Message-ID: On Sat, 16 Apr 2022 at 10:15, Peter J. Holzer wrote: > It doesn't (or at least you can't conclude that from the evidence you > posted). > > There is a subdirectory called "debian" in the build directory of every > .deb package. This is true on Debian, Ubuntu and every other > distribution which uses the .deb package format. This directory is > required by the build tools and it contains all the data (e.g. build > instructions, dependencies, patches, description, extra documentation) > which was added by the packager. The name of the directory does not > imply that any of the files there was created by Debian. I have built > quite a few packages myself and I'm not a member of the Debian team. Actually I don't care if the package was made by Debian. I'm sure that it does not, since the Ubuntu packages have other terminology in versions. For example, the git package is version 2.17.1-1ubuntu0.10 The important fact is that I suppose it's quite evident that the Ubuntu team uses Debian patches to release their security updates, since the release notes are public and worldwide, made by a professional company, they are not made by an amateur. Furthermore I checked all the security updates my system released when we started this discussion, and all of them have release notes that contain information about security patches made by Debian. Only the security updates have these infos. Is it an amazing coincidence? I suppose no. Furthermore, you didn't answer my simple question: why does the security update package contain metadata about Debian patches, if the Ubuntu security team did not benefit from Debian security patches but only from internal work? I suppose I have to answer myself: because the patch applied by Ubuntu _is_ actually a Debian patch. The more interesting fact is that I checked all the security updates and it seems they are only applications of Debian patches. So it seems that the work of the Ubuntu security team is only to apply Debian security patches. If so, probably Debian is really more secure than Ubuntu, since I don't know if all the security patches made by Debian are applied. From jon+usenet at unequivocal.eu Sat Apr 16 09:47:32 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sat, 16 Apr 2022 13:47:32 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> Message-ID: On 2022-04-16, Peter J. Holzer wrote: > On 2022-04-14 15:22:29 -0000, Jon Ribbens via Python-list wrote: >> On 2022-04-14, Paul Bryan wrote: >> > I think because minutes and hours can easily be composed by multiplying >> > seconds. days is separate because you cannot compose days from seconds; >> > leap seconds are applied to days at various times, due to >> > irregularities in the Earth's rotation. >> >> That's an argument that timedelta should *not* have a 'days' attribute, >> because a day is not a fixed number of seconds long (to know how long >> a day is, you have to know which day you're talking about, and where). > > Which is exactly why timedelta *must* have separate fields for seconds, > days and months. You can't simply express the larger units as > multiples of the smaller units, so they have to be stored separately for > date arithmetic to work. That's impossible unless you redefine 'timedelta' from being, as it is now, a fixed-length period of time, to instead being the difference between two specific dates and times in specific timezones. Days and months have different lengths depending on when and where you are. >> It's an undocumented feature of timedelta that by 'day' it means '86400 >> seconds'. > > I'd call that a bug, not a feature: It's the only possible way of implementing it, so it can't be a bug. The documentation could be better though. >>>> from datetime import datetime, timedelta >>>> t0 = datetime.fromisoformat("2022-03-26T12:00").astimezone() >>>> t0 > datetime.datetime(2022, 3, 26, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')) >>>> d = timedelta(days=1) >>>> t1 = t0 + d >>>> t1 > datetime.datetime(2022, 3, 27, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')) >>>> t1.isoformat() > '2022-03-27T12:00:00+01:00' > > Python missed the switch to DST here, the timezone is wrong. Because you didn't let it use any timezone information. You need to either use the third-party 'pytz' module, or in Python 3.9 or above, the built-in 'zoneinfo' module. From jon+usenet at unequivocal.eu Sat Apr 16 10:22:04 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sat, 16 Apr 2022 14:22:04 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> Message-ID: On 2022-04-16, Jon Ribbens wrote: > On 2022-04-16, Peter J. Holzer wrote: >> Python missed the switch to DST here, the timezone is wrong. > > Because you didn't let it use any timezone information. You need to > either use the third-party 'pytz' module, or in Python 3.9 or above, > the built-in 'zoneinfo' module. ... although now having looked into the new 'zoneinfo' module slightly, it really should have a giant red flashing notice at the top of it saying "BEWARE, TIMEZONES IN PYTHON ARE UTTERLY BROKEN, NEVER USE THEM". Suppose we do this: >>> import datetime, zoneinfo >>> LOS_ANGELES = zoneinfo.ZoneInfo('America/Los_Angeles') >>> UTC = zoneinfo.ZoneInfo('UTC') >>> d = datetime.datetime(2020, 10, 31, 12, tzinfo=LOS_ANGELES) >>> print(d) 2020-10-31 12:00:00-07:00 >>> d1 = d + datetime.timedelta(days=1) >>> print(d1) 2020-11-01 12:00:00-08:00 d1 is *wrong*. timedelta(days=1) is 24 hours (as you can check by calling timedelta(days=1).total_seconds() ), but d1 is 25 hours later than 'd'. If we do the calculations in UTC instead, it works correctly: >>> print((d.astimezone(UTC) + datetime.timedelta(days=1)).astimezone(LOS_ANGELES)) 2020-11-01 11:00:00-08:00 It seems that Python is assuming that if the tzinfo attributes of two datetimes are the same, then it can pretend timezones don't exist and do 'naive' arithmetic. This is of course a totally false assumption. Apparently when making the native version of 'zoneinfo', the lessons learned from 'pytz' have been discarded. There is a general guideline that you should always keep and use your datetimes as UTC, only ever using timezones for the purposes of display. Usually this is because it keeps things simpler for the programmer, and hence they are less likely to introduce bugs into their programs. It appears that with Python it's not so much a guideline as an absolute concrete rule, and not because programmers will introduce bugs, but because you need to avoid bugs in the standard library! From hjp-python at hjp.at Sat Apr 16 11:12:51 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 17:12:51 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: References: <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> <20220413180300.qrnneczjdftb2kdq@hjp.at> <20220416081405.ux34uzdhxdgsoggk@hjp.at> Message-ID: <20220416151251.uljjmka7nroxj3ow@hjp.at> On 2022-04-16 16:49:17 +0200, Marco Sulla wrote: > Furthermore, you didn't answer my simple question: why does the > security update package contain metadata about Debian patches, if the > Ubuntu security team did not benefit from Debian security patches but > only from internal work? It DOES NOT contain metadata about Debian patches. You are misinterpreting the name "debian". The directory has this name because the tools (dpkg, quilt, etc.) were originally written by the Debian team for the Debian distribution. Ubuntu uses the same tools. They didn't bother to rename the directory (why should they?), so the directory is still called "debian" on Ubuntu (and yes I know this because I've built numerous .deb packages on Ubuntu systems). For example, here is the patches directory of one of my own packages: % ls -l debian/patches total 24 -rw-r--r-- 1 hjp hjp 982 Sep 12 2017 makefile -rw-r--r-- 1 hjp hjp 966 Sep 12 2017 makefile-all -rw-r--r-- 1 hjp hjp 367 Jan 15 2021 makefile-checkmk.diff -rw-r--r-- 1 hjp hjp 849 Dec 14 2017 makefile-check_cronwrapper -rw-r--r-- 1 hjp hjp 1126 Sep 12 2017 makefile-mkdir -rw-r--r-- 1 hjp hjp 86 Jan 15 2021 series 5 patches in the subdirectory debian/patches (the file "series" just contains the list of patches in proper order). None of these patches was written by Debian. They were all written by me. Yet they are all in a subdirectory "debian/patches", because that's where they have to be for the tools to find them (yes, this is on Ubuntu). hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Sat Apr 16 11:27:26 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 17:27:26 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> Message-ID: <20220416152726.nayck4tihbzsnrk7@hjp.at> On 2022-04-16 13:47:32 -0000, Jon Ribbens via Python-list wrote: > On 2022-04-16, Peter J. Holzer wrote: > > On 2022-04-14 15:22:29 -0000, Jon Ribbens via Python-list wrote: > >> On 2022-04-14, Paul Bryan wrote: > >> > I think because minutes and hours can easily be composed by multiplying > >> > seconds. days is separate because you cannot compose days from seconds; > >> > leap seconds are applied to days at various times, due to > >> > irregularities in the Earth's rotation. > >> > >> That's an argument that timedelta should *not* have a 'days' attribute, > >> because a day is not a fixed number of seconds long (to know how long > >> a day is, you have to know which day you're talking about, and where). > > > > Which is exactly why timedelta *must* have separate fields for seconds, > > days and months. You can't simply express the larger units as > > multiples of the smaller units, so they have to be stored separately for > > date arithmetic to work. > > That's impossible unless you redefine 'timedelta' from being, as it is > now, a fixed-length period of time, to instead being the difference > between two specific dates and times in specific timezones. Days and > months have different lengths depending on when and where you are. That's what I would have expected it to be. Otherwise, why bother with a class when a simple float suffices? Date arithmetic isn't simple. You need complex data types to implement it correctly. > >> It's an undocumented feature of timedelta that by 'day' it means '86400 > >> seconds'. > > > > I'd call that a bug, not a feature: > > It's the only possible way of implementing it, It's definitely not the only possible way of implementing it. PostgreSQL for examply has implemented it correctly. I'm quite sure some other programming languages have, too. > >>>> from datetime import datetime, timedelta > >>>> t0 = datetime.fromisoformat("2022-03-26T12:00").astimezone() > >>>> t0 > > datetime.datetime(2022, 3, 26, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')) > >>>> d = timedelta(days=1) > >>>> t1 = t0 + d > >>>> t1 > > datetime.datetime(2022, 3, 27, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')) > >>>> t1.isoformat() > > '2022-03-27T12:00:00+01:00' > > > > Python missed the switch to DST here, the timezone is wrong. > > Because you didn't let it use any timezone information. I used astimezone() and it returned something something that Python calls "timezone aware" containing time zone information which is correct for that time and my location (tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')). Why should I expect a "timezone aware" datetime to not be actually timezone aware? hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Sat Apr 16 12:00:28 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 18:00:28 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> Message-ID: <20220416160028.tmedahn64gdpzsov@hjp.at> On 2022-04-16 14:22:04 -0000, Jon Ribbens via Python-list wrote: > On 2022-04-16, Jon Ribbens wrote: > > On 2022-04-16, Peter J. Holzer wrote: > >> Python missed the switch to DST here, the timezone is wrong. > > > > Because you didn't let it use any timezone information. You need to > > either use the third-party 'pytz' module, or in Python 3.9 or above, > > the built-in 'zoneinfo' module. > > ... although now having looked into the new 'zoneinfo' module slightly, > it really should have a giant red flashing notice at the top of it > saying "BEWARE, TIMEZONES IN PYTHON ARE UTTERLY BROKEN, NEVER USE THEM". > > Suppose we do this: > > >>> import datetime, zoneinfo > >>> LOS_ANGELES = zoneinfo.ZoneInfo('America/Los_Angeles') > >>> UTC = zoneinfo.ZoneInfo('UTC') > >>> d = datetime.datetime(2020, 10, 31, 12, tzinfo=LOS_ANGELES) > >>> print(d) > 2020-10-31 12:00:00-07:00 > >>> d1 = d + datetime.timedelta(days=1) > >>> print(d1) > 2020-11-01 12:00:00-08:00 > > d1 is *wrong*. No, this is correct. That's the result you want. So why didn't this work for me (I also used Python 3.9)? My guess is that astimezone() doesn't pick the correct time zone. > timedelta(days=1) is 24 hours (as you can check by > calling timedelta(days=1).total_seconds() ), It shouldn't be. 1 Day is not 24 hours in the real world. > but d1 is 25 hours later > than 'd'. If we do the calculations in UTC instead, it works correctly: > > >>> print((d.astimezone(UTC) + datetime.timedelta(days=1)).astimezone(LOS_ANGELES)) > 2020-11-01 11:00:00-08:00 > > It seems that Python is assuming that if the tzinfo attributes of two > datetimes are the same, There is only one datetime in your examples. > then it can pretend timezones don't exist and do 'naive' arithmetic. On the contrary. When a datetime is timezone aware, it must use that timezone's rules. Adding one day to a datetime just before a DST switch must add 23 or 25 hours, not 24. This is NOT naive. (There is an ambiguity, though: Should 2021-03-27T12:00 CEST - 2021-03-26T12:00 CET return 1 day or 25 hours? Both results are correct, and depending on context you might prefer one or the other). > There is a general guideline that you should always keep and use your > datetimes as UTC, only ever using timezones for the purposes of display. > Usually this is because it keeps things simpler for the programmer, and > hence they are less likely to introduce bugs into their programs. While I generally do this (and often preach it to my collegues) it must be stated that this is only a GENERAL guide line. There are many exceptions, especially when scheduling events in the future. For example, if want to meet somebody on July 18th, 2023 at 19:00 in Vienna, Austria, it would be wrong to store that date as 2023-07-18T17:00Z. The EU has decided to abolish DST, and while I don't expect them to get around to it within the next year (or maybe ever), it might still happen. So we simply don't know yet whether 19:00 local time will be 17:00 or 18:00 UTC. There have been cases where countries have changed their DST rules only days in advance. > It appears that with Python it's not so much a guideline as an > absolute concrete rule, and not because programmers will introduce > bugs, but because you need to avoid bugs in the standard library! As a programmer you must always adapt to the problem. Saying "I must do it the wrong way because my library is buggy" is just lazy. Use a different library or write one yourself. (Unless of course the customer doesn't want to pay for the extra work, then they get what they pay for.) hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From rosuav at gmail.com Sat Apr 16 12:14:44 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 02:14:44 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <20220416160028.tmedahn64gdpzsov@hjp.at> References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 02:03, Peter J. Holzer wrote: > > On 2022-04-16 14:22:04 -0000, Jon Ribbens via Python-list wrote: > > timedelta(days=1) is 24 hours (as you can check by > > calling timedelta(days=1).total_seconds() ), > > It shouldn't be. 1 Day is not 24 hours in the real world. > > > but d1 is 25 hours later > > than 'd'. If we do the calculations in UTC instead, it works correctly: > > > > >>> print((d.astimezone(UTC) + datetime.timedelta(days=1)).astimezone(LOS_ANGELES)) > > 2020-11-01 11:00:00-08:00 > > > > It seems that Python is assuming that if the tzinfo attributes of two > > datetimes are the same, > > There is only one datetime in your examples. > > > then it can pretend timezones don't exist and do 'naive' arithmetic. > > On the contrary. When a datetime is timezone aware, it must use that > timezone's rules. Adding one day to a datetime just before a DST switch > must add 23 or 25 hours, not 24. This is NOT naive. > > (There is an ambiguity, though: Should 2021-03-27T12:00 CEST - > 2021-03-26T12:00 CET return 1 day or 25 hours? Both results are correct, > and depending on context you might prefer one or the other). > That's exactly the problem. A day IS 24 hours *and* it is the time period required for you to get to the same clock on the following date. It's fundamentally ambiguous. Let's take this out of Python altogether for a moment. Imagine that it's 9AM Thursday. You say to your friend, hey, let's meet up again, same time next week. Are you planning to meet 168 hours later, or at 9AM the following Thursday? OF COURSE you mean 168 hours later. That's what "next week" means. OF COURSE you're meeting at 9AM the following Thursday. That's what "next week" means. And they can't both be true if DST is changing. So which one is it? Which one do you get when you add days=7 to a datetime? ChrisA From hjp-python at hjp.at Sat Apr 16 12:44:08 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 18:44:08 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: <20220416164408.zxnulyergevqprn7@hjp.at> On 2022-04-17 02:14:44 +1000, Chris Angelico wrote: > On Sun, 17 Apr 2022 at 02:03, Peter J. Holzer wrote: > > On the contrary. When a datetime is timezone aware, it must use that > > timezone's rules. Adding one day to a datetime just before a DST switch > > must add 23 or 25 hours, not 24. This is NOT naive. > > > > (There is an ambiguity, though: Should 2021-03-27T12:00 CEST - > > 2021-03-26T12:00 CET return 1 day or 25 hours? Both results are correct, > > and depending on context you might prefer one or the other). > > > > That's exactly the problem. A day IS 24 hours *and* it is the time > period required for you to get to the same clock on the following > date. It's fundamentally ambiguous. > > Let's take this out of Python altogether for a moment. Imagine that > it's 9AM Thursday. You say to your friend, hey, let's meet up again, > same time next week. Are you planning to meet 168 hours later, or at > 9AM the following Thursday? > > OF COURSE you mean 168 hours later. That's what "next week" means. Of course NOT. It means that only in 50 out of 52 weeks. A 4% error rate is more than enough to make me acutely aware that it isn't true in general. Also, won't count off 168 hours but look at my calendar/clock. > OF COURSE you're meeting at 9AM the following Thursday. That's what > "next week" means. This. Certainly when meeting a friend. Almost certainly when dealing with humans (if they are in a different time zone we may have to agree on a time zone for "same time"). For a technical process I *might* simplify "1 week" to "168 hours", but only if the spec gives me sufficient leeway. > And they can't both be true if DST is changing. > > So which one is it? Which one do you get when you add days=7 to a datetime? For adding a datetime and timedelta I think the answer is clear. But subtracting two datetimes is ambiguous. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From rosuav at gmail.com Sat Apr 16 12:46:38 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 02:46:38 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <20220416164408.zxnulyergevqprn7@hjp.at> References: <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220416164408.zxnulyergevqprn7@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 02:45, Peter J. Holzer wrote: > > On 2022-04-17 02:14:44 +1000, Chris Angelico wrote: > > On Sun, 17 Apr 2022 at 02:03, Peter J. Holzer wrote: > > > On the contrary. When a datetime is timezone aware, it must use that > > > timezone's rules. Adding one day to a datetime just before a DST switch > > > must add 23 or 25 hours, not 24. This is NOT naive. > > > > > > (There is an ambiguity, though: Should 2021-03-27T12:00 CEST - > > > 2021-03-26T12:00 CET return 1 day or 25 hours? Both results are correct, > > > and depending on context you might prefer one or the other). > > > > > > > That's exactly the problem. A day IS 24 hours *and* it is the time > > period required for you to get to the same clock on the following > > date. It's fundamentally ambiguous. > > > > Let's take this out of Python altogether for a moment. Imagine that > > it's 9AM Thursday. You say to your friend, hey, let's meet up again, > > same time next week. Are you planning to meet 168 hours later, or at > > 9AM the following Thursday? > > > > OF COURSE you mean 168 hours later. That's what "next week" means. > > Of course NOT. It means that only in 50 out of 52 weeks. A 4% error rate > is more than enough to make me acutely aware that it isn't true in > general. Also, won't count off 168 hours but look at my calendar/clock. > > > > OF COURSE you're meeting at 9AM the following Thursday. That's what > > "next week" means. > > This. Certainly when meeting a friend. Almost certainly when dealing > with humans (if they are in a different time zone we may have to agree > on a time zone for "same time"). For a technical process I *might* > simplify "1 week" to "168 hours", but only if the spec gives me > sufficient leeway. > > > > And they can't both be true if DST is changing. > > > > So which one is it? Which one do you get when you add days=7 to a datetime? > > For adding a datetime and timedelta I think the answer is clear. > But subtracting two datetimes is ambiguous. > But if the difference between two datetimes is a timedelta, then surely adding a timedelta to a datetime should give the other datetime? It's just as ambiguous. ChrisA From hjp-python at hjp.at Sat Apr 16 13:35:51 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 19:35:51 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class Message-ID: <20220416173551.fk6voaa3o25iuewm@hjp.at> I intend to take this to python-ideas, but I'm not currently subscribed there and I think I should probably do a bit of research before proposing something over there. So I'll start by gathering some feedback here with a rough sketch. Datetime arithmetic in the real world is typically not done in seconds, but in calendaric units: Hours, days, weeks, months, years, ... The problem is that several of these have varying lengths: * 1 minute may be 60 or 61 seconds (theoretically also 59, but that hasn't happened yet). * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica, where it's even weirder). * 1 month may be 28, 29, 30 or 31 days (let's stick to the Gregorian calendar) The standard library has a datetime.timedelta class which does store days and seconds separately, so somebody seems to have had the right idea, but the normalization rules make it impossible to distinguish between "1 day plus 1 hour" and "25 hours", and it doesn't deal with months at all. Technically it shouldn't be too hard to "fix" timedelta, but that wouldn't be backward compatible and would very likely break existing code. Therefore a new class (provisionally called timedeltacal, because it is calendaric, not absolute) should be added to datetime: Internally it stores months, days, seconds and microseconds as ints. The seconds and microseconds split is mostly for compatibility with datetime and timedelta. We could store seconds as a float instead. We don't store minutes since leap seconds aren't usually represented in "computer time", so they are unlikely to be useful in a timedeltacal object. Days are stored since they aren't a fixed multiple of any smaller unit. Months are stored since they aren't a fixed multiple of any smaller unit. Hours, weeks and years aren't stored since they are always 60 minutes, 7 days and 12 months respectively. When adding a timedeltacal object to a datetime, the fields are added from most to least significant: First a new date is computed by advancing the number of months specified [TODO: Research how other systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't exist)], then advance the number of days. Finally add the number of seconds and microseconds, taking into accout daylight savings time switches if the datetime is time zone aware. Subtracting a timedeltacal object from a datetime is the same, just in the opposite direction. Note that t + d - d is in general not equal to t. We can't cnange the semantics of datetime - datetime, so there must be a function to compute the difference between to datetimes as a timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u like in Go) or a constructor which takes two datetime objects. In any case I think that u + (t - u) == t should hold. [TODO: Check that this is possible] hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Sat Apr 16 13:50:52 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 19:50:52 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220416164408.zxnulyergevqprn7@hjp.at> Message-ID: <20220416175052.fbqkgjstjsxxhk72@hjp.at> On 2022-04-17 02:46:38 +1000, Chris Angelico wrote: > On Sun, 17 Apr 2022 at 02:45, Peter J. Holzer wrote: > > On 2022-04-17 02:14:44 +1000, Chris Angelico wrote: > > > So which one is it? Which one do you get when you add days=7 to a datetime? > > > > For adding a datetime and timedelta I think the answer is clear. > > But subtracting two datetimes is ambiguous. > > > > But if the difference between two datetimes is a timedelta, then > surely adding a timedelta to a datetime should give the other > datetime? Not necessarily. You might compute the difference for another purpose. If you compute a change rate from two gauge readings you would compute something like (r1 - r0) / (t1 - t0). You don't intend to add (t1 - t0) to any timestamp, so that property would be irrelevant. However, you do want something which can be used in a division and which has a consistent unit (so one could argue that you don't want a timedelta object at all, but a floating point number). hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Sat Apr 16 14:18:16 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 20:18:16 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220416173551.fk6voaa3o25iuewm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: <20220416181816.zgroksvrtz6ob6py@hjp.at> On 2022-04-16 19:35:51 +0200, Peter J. Holzer wrote: > Note that t + d - d is in general not equal to t. > > We can't cnange the semantics of datetime - datetime, so there must be a > function to compute the difference between to datetimes as a > timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u > like in Go) or a constructor which takes two datetime objects. Just noticed this. Using a method or constructor instead of an operator adjusting behaviour via additional parameters. So for example a parameter "maxunit" could be used to restrict the units used in the result: Given: >>> CET = zoneinfo.ZoneInfo('Europe/Vienna') >>> t0 = datetime.datetime(2022, 3, 1, tzinfo=CET) >>> t1 = datetime.datetime(2022, 4, 16, 20, tzinfo=CET) we could get these results: >>> timedeltacal(t0, t1, maxunit="month") timedeltacal(months=1, days=15, seconds=72000) >>> timedeltacal(t0, t1, maxunit="days") timedeltacal(days=46, seconds=72000) >>> timedeltacal(t0, t1, maxunit="seconds") timedeltacal(seconds=4042800) (note that 4042800 == 46 * 86400 + 19 * 3600) hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From barry at barrys-emacs.org Sat Apr 16 15:25:45 2022 From: barry at barrys-emacs.org (Barry) Date: Sat, 16 Apr 2022 20:25:45 +0100 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220416173551.fk6voaa3o25iuewm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: > On 16 Apr 2022, at 18:38, Peter J. Holzer wrote: > > ?I intend to take this to python-ideas, but I'm not currently subscribed > there and I think I should probably do a bit of research before > proposing something over there. So I'll start by gathering some feedback > here with a rough sketch. > > Datetime arithmetic in the real world is typically not done in seconds, > but in calendaric units: Hours, days, weeks, months, years, ... > The problem is that several of these have varying lengths: > > * 1 minute may be 60 or 61 seconds (theoretically also 59, but that > hasn't happened yet). > * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica, > where it's even weirder). > * 1 month may be 28, 29, 30 or 31 days (let's stick to the Gregorian > calendar) > > The standard library has a datetime.timedelta class which does store > days and seconds separately, so somebody seems to have had the right > idea, but the normalization rules make it impossible to distinguish > between "1 day plus 1 hour" and "25 hours", and it doesn't deal with > months at all. > > Technically it shouldn't be too hard to "fix" timedelta, but that > wouldn't be backward compatible and would very likely break existing > code. > > Therefore a new class (provisionally called timedeltacal, because it is > calendaric, not absolute) should be added to datetime: > > Internally it stores months, days, seconds and microseconds as ints. > > The seconds and microseconds split is mostly for compatibility with > datetime and timedelta. We could store seconds as a float instead. > > We don't store minutes since leap seconds aren't usually represented in > "computer time", so they are unlikely to be useful in a timedeltacal > object. > > Days are stored since they aren't a fixed multiple of any smaller unit. > Months are stored since they aren't a fixed multiple of any smaller unit. > > Hours, weeks and years aren't stored since they are always 60 minutes, 7 > days and 12 months respectively. > > When adding a timedeltacal object to a datetime, the fields are added > from most to least significant: First a new date is computed by > advancing the number of months specified [TODO: Research how other > systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't > exist)], then advance the number of days. Finally add the number of > seconds and microseconds, taking into accout daylight savings time > switches if the datetime is time zone aware. > > Subtracting a timedeltacal object from a datetime is the same, just in > the opposite direction. > > Note that t + d - d is in general not equal to t. > > We can't cnange the semantics of datetime - datetime, so there must be a > function to compute the difference between to datetimes as a > timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u > like in Go) or a constructor which takes two datetime objects. > > In any case I think that u + (t - u) == t should hold. [TODO: Check that > this is possible] Suggest that you start with the use cases that you want supported. Then you can turn them into a set of tests to check that the solution works. Barry > > hp > > -- > _ | Peter J. Holzer | Story must make more sense than reality. > |_|_) | | > | | | hjp at hjp.at | -- Charles Stross, "Creative writing > __/ | http://www.hjp.at/ | challenge!" > -- > https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Sat Apr 16 15:30:19 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 05:30:19 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <20220416175052.fbqkgjstjsxxhk72@hjp.at> References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220416164408.zxnulyergevqprn7@hjp.at> <20220416175052.fbqkgjstjsxxhk72@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 03:52, Peter J. Holzer wrote: > > On 2022-04-17 02:46:38 +1000, Chris Angelico wrote: > > On Sun, 17 Apr 2022 at 02:45, Peter J. Holzer wrote: > > > On 2022-04-17 02:14:44 +1000, Chris Angelico wrote: > > > > So which one is it? Which one do you get when you add days=7 to a datetime? > > > > > > For adding a datetime and timedelta I think the answer is clear. > > > But subtracting two datetimes is ambiguous. > > > > > > > But if the difference between two datetimes is a timedelta, then > > surely adding a timedelta to a datetime should give the other > > datetime? > > Not necessarily. You might compute the difference for another purpose. > If you compute a change rate from two gauge readings you would compute > something like (r1 - r0) / (t1 - t0). You don't intend to add (t1 - t0) > to any timestamp, so that property would be irrelevant. However, you do > want something which can be used in a division and which has a > consistent unit (so one could argue that you don't want a timedelta > object at all, but a floating point number). > True, but logically, it's hard to explain arithmetic when (x - y) + x != y. ( And yes, I'm aware that floats can violate that, but the discrepancy isn't a good thing.) Your example definitely wants to be measured in UTC, though. It wants to ignore silly changes of clocks, and just show the amount of time that passed. ChrisA From jon+usenet at unequivocal.eu Sat Apr 16 14:53:49 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sat, 16 Apr 2022 18:53:49 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416152726.nayck4tihbzsnrk7@hjp.at> Message-ID: On 2022-04-16, Peter J. Holzer wrote: > On 2022-04-16 13:47:32 -0000, Jon Ribbens via Python-list wrote: >> That's impossible unless you redefine 'timedelta' from being, as it is >> now, a fixed-length period of time, to instead being the difference >> between two specific dates and times in specific timezones. Days and >> months have different lengths depending on when and where you are. > > That's what I would have expected it to be. Otherwise, why bother with a > class when a simple float suffices? > > Date arithmetic isn't simple. You need complex data types to implement > it correctly. > >> >> It's an undocumented feature of timedelta that by 'day' it means '86400 >> >> seconds'. >> > >> > I'd call that a bug, not a feature: >> >> It's the only possible way of implementing it, > > It's definitely not the only possible way of implementing it. It's the only possible way of implementing a fixed time period, which is what timedelta is (modulo the bugs in 'datetime' I mentioned in my other post). >> > Python missed the switch to DST here, the timezone is wrong. >> >> Because you didn't let it use any timezone information. > > I used astimezone() and it returned something something that Python > calls "timezone aware" containing time zone information which is > correct for that time and my location > (tzinfo=datetime.timezone(datetime.timedelta(seconds=3600), 'CET')). Why > should I expect a "timezone aware" datetime to not be actually timezone > aware? I think by "timezone aware" it doesn't mean "timezone aware", it means "has a specified fixed offset from UTC". Yes this is distinctly sub-optimal. From hjp-python at hjp.at Sat Apr 16 15:32:24 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sat, 16 Apr 2022 21:32:24 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220416164408.zxnulyergevqprn7@hjp.at> Message-ID: <20220416193224.3btgzdmqs2gw7ocj@hjp.at> On 2022-04-17 02:46:38 +1000, Chris Angelico wrote: > On Sun, 17 Apr 2022 at 02:45, Peter J. Holzer wrote: > > For adding a datetime and timedelta I think the answer is clear. > > But subtracting two datetimes is ambiguous. > > > > But if the difference between two datetimes is a timedelta, then > surely adding a timedelta to a datetime should give the other > datetime? It's just as ambiguous. To answer the same question in a different way: No, because the timedelta object is overspecified when applied to a specific datetime (when you start at 2022-04-16T21:29, it doesn't matter whether you add 7 days or 168 hours) but that extra information matters with different starting points. When you subtract two specific datetimes, there is no way to extract that extra information. So addition and subtraction are not symmetrical. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From rosuav at gmail.com Sat Apr 16 16:08:54 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 06:08:54 +1000 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220416173551.fk6voaa3o25iuewm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 03:37, Peter J. Holzer wrote: > Datetime arithmetic in the real world is typically not done in seconds, > but in calendaric units: Hours, days, weeks, months, years, ... > The problem is that several of these have varying lengths: > > * 1 minute may be 60 or 61 seconds (theoretically also 59, but that > hasn't happened yet). > * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica, > where it's even weirder). I think Troll still only has days that consist of 23-25 hours; the weird part is that they move their clocks forward for Oslo's summer, which is their winter. > * 1 month may be 28, 29, 30 or 31 days (let's stick to the Gregorian > calendar) > > The standard library has a datetime.timedelta class which does store > days and seconds separately, so somebody seems to have had the right > idea, but the normalization rules make it impossible to distinguish > between "1 day plus 1 hour" and "25 hours", and it doesn't deal with > months at all. > > Technically it shouldn't be too hard to "fix" timedelta, but that > wouldn't be backward compatible and would very likely break existing > code. Almost certainly, yes; but I would say that that's because you're not "fixing" timedelta, you're making a completely different concept. The existing timedelta measures a difference in time; your proposal represents a difference between two civil calendar points. So I agree with your suggestion to make it a new and independent class. > Therefore a new class (provisionally called timedeltacal, because it is > calendaric, not absolute) should be added to datetime: > > Internally it stores months, days, seconds and microseconds as ints. > > The seconds and microseconds split is mostly for compatibility with > datetime and timedelta. We could store seconds as a float instead. > > We don't store minutes since leap seconds aren't usually represented in > "computer time", so they are unlikely to be useful in a timedeltacal > object. > > Days are stored since they aren't a fixed multiple of any smaller unit. > Months are stored since they aren't a fixed multiple of any smaller unit. > > Hours, weeks and years aren't stored since they are always 60 minutes, 7 > days and 12 months respectively. It sounds like you're planning for annual DST changes, but what about other shifts? What about when a location adopts standard time, which could change their UTC offset (yes, I'm aware that most places adopted standard time before UTC was a thing, but we still usually call it a UTC offset rather than messing with GMT-UTC changeover) by an arbitrary amount, even minutes? It might be cleaner to simply have all of the arguments that datetime has: year, month, day, hour, minute, second, microsecond (with the possibility of merging second/usec into a single float). > When adding a timedeltacal object to a datetime, the fields are added > from most to least significant: First a new date is computed by > advancing the number of months specified [TODO: Research how other > systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't > exist)] Quick test in Pike: Pike v8.1 release 15 running Hilfe v3.5 (Incremental Pike Frontend) > import Calendar.ISO; > object base = now(); > base; (1) Result: Fraction(Sun 17 Apr 2022 5:42:15.703571 AEST) > (base - Day() * 17) + Month(); (2) Result: Fraction(Sat 30 Apr 2022 5:42:15.703571 AEST) > (base - Day() * 18) + Month(); (3) Result: Fraction(Sat 30 Apr 2022 5:42:15.703571 AEST) > (base - Day() * 19) + Month(); (4) Result: Fraction(Fri 29 Apr 2022 5:42:15.703571 AEST) > (base - Day() * 16) + Month(); (5) Result: Fraction(Sun 1 May 2022 5:42:15.703571 AEST) > (base - Day() * 15) + Month(); (6) Result: Fraction(Mon 2 May 2022 5:42:15.703571 AEST) Subtracting seventeen days from today gets us to the 31st of March, and adding one month to that gives us the 30th of April. Subtracting eighteen days gets us to the 30th of March, and adding a month to that _also_ gives us the 30th of April. Other nearby dates given for reference. > then advance the number of days. Finally add the number of > seconds and microseconds, taking into accout daylight savings time > switches if the datetime is time zone aware. Here's the local DST switchover: > base - Day() * 15; (7) Result: Fraction(Sat 2 Apr 2022 5:42:15.703571 AEDT) > base - Day() * 14; (8) Result: Fraction(Sun 3 Apr 2022 5:42:15.703571 AEST) > base - Day() * 14 - Hour() * 4; (9) Result: Fraction(Sun 3 Apr 2022 2:42:15.703571 AEDT) > base - Day() * 14 - Hour() * 3; (10) Result: Fraction(Sun 3 Apr 2022 2:42:15.703571 AEST) > base - Day() * 14 - Hour() * 2; (11) Result: Fraction(Sun 3 Apr 2022 3:42:15.703571 AEST) > base - Day() * 14 - Hour() * 1; (12) Result: Fraction(Sun 3 Apr 2022 4:42:15.703571 AEST) BTW, even though the "object display" notation (the repr, if you like) shows some of these in AEST and some in AEDT, internally, they all have the same timezone: Australia/Melbourne. (Side point: I've used consistent syntax here, but there are shorthands for common cases - I could write "base + Day" to add one day.) > Subtracting a timedeltacal object from a datetime is the same, just in > the opposite direction. > > Note that t + d - d is in general not equal to t. By "in general", do you mean "there will be some odd exceptions", or "this is usually going to be unequal"? For instance, going back to the month boundary case, since it's not possible for "add one month" from two different dates to give the same result, obviously subtracting a month from that result can't give both the originals. But for the most part, I would expect t + d - d to be equal to t, modulo rounding error and possible DST corrections. Crossing a DST boundary shouldn't break this pattern; only landing in the actual gap/fold should cause issues. Is that the intention? > We can't cnange the semantics of datetime - datetime, so there must be a > function to compute the difference between to datetimes as a > timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u > like in Go) or a constructor which takes two datetime objects. > > In any case I think that u + (t - u) == t should hold. [TODO: Check that > this is possible] > Isn't that the exact same thing as saying that t + d - d == t? Or are you saying that, when you subtract two timestamps, you can never get one of the odd exceptions that would cause problems? Because I'd believe that; the net result would be that u+(t-u) == t, but u+((t+d)-(u+d)) might not equal t. Putting it another way: Shift invariance should *normally* hold, but there may be some exceptions at month ends (basically rounding error when you add/subtract a month) and DST switches. When the time comes, if you need a hand putting together a PEP, feel free to reach out to me. ChrisA From rosuav at gmail.com Sat Apr 16 16:10:47 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 06:10:47 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <20220416193224.3btgzdmqs2gw7ocj@hjp.at> References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220416164408.zxnulyergevqprn7@hjp.at> <20220416193224.3btgzdmqs2gw7ocj@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 05:38, Peter J. Holzer wrote: > > On 2022-04-17 02:46:38 +1000, Chris Angelico wrote: > > On Sun, 17 Apr 2022 at 02:45, Peter J. Holzer wrote: > > > For adding a datetime and timedelta I think the answer is clear. > > > But subtracting two datetimes is ambiguous. > > > > > > > But if the difference between two datetimes is a timedelta, then > > surely adding a timedelta to a datetime should give the other > > datetime? It's just as ambiguous. > > To answer the same question in a different way: > > No, because the timedelta object is overspecified when applied to a > specific datetime (when you start at 2022-04-16T21:29, it doesn't matter > whether you add 7 days or 168 hours) but that extra information matters > with different starting points. When you subtract two specific > datetimes, there is no way to extract that extra information. So > addition and subtraction are not symmetrical. > Ah, that's fair. So what you're really saying is that the difference between two datetimes *isn't* a timedelta, but when we subtract them and get back a timedelta, we're throwing away information for simplicity. ChrisA From Karsten.Hilbert at gmx.net Sat Apr 16 17:17:10 2022 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sat, 16 Apr 2022 23:17:10 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220416173551.fk6voaa3o25iuewm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: Am Sat, Apr 16, 2022 at 07:35:51PM +0200 schrieb Peter J. Holzer: > So I'll start by gathering some feedback > here with a rough sketch. > [TODO: Research how other systems handle overflow > (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't exist)], That is context dependant: Take this medication for 1 month ! is quite likely to mean "take it for 28 days". This standing order (Dauerauftrag) is to be run every months from now on. will mean "every 1st of the month, regardless of how many days passed". Karsten GNUmed -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From sam.z.ezeh at gmail.com Sat Apr 16 17:36:04 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Sat, 16 Apr 2022 22:36:04 +0100 Subject: Tuple unpacking inside lambda expressions Message-ID: Two questions here. Firstly, does anybody know of existing discussions (e.g. on here or on python-ideas) relating to unpacking inside lambda expressions? I found myself wanting to write the following. ``` map( lambda (module, data): result.process(module, data), jobs ) ``` However, it's of course not legal Python syntax. The following were potential options but I felt they removed some of the meaning from the code, making it less understandable for other people. ``` map( lambda job: result.process(job[0], job[1]), jobs ) ``` ``` map( lambda job: result.process(*job), jobs ) ``` Secondly, for situations like these, do you have any go-to methods of rewriting these while maintaining clarity? Kind Regards, Sam Ezeh From rosuav at gmail.com Sat Apr 16 17:40:33 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 07:40:33 +1000 Subject: Tuple unpacking inside lambda expressions In-Reply-To: References: Message-ID: On Sun, 17 Apr 2022 at 07:37, Sam Ezeh wrote: > > Two questions here. > > Firstly, does anybody know of existing discussions (e.g. on here or on > python-ideas) relating to unpacking inside lambda expressions? > > I found myself wanting to write the following. > > ``` > map( > lambda (module, data): result.process(module, data), > jobs > ) > ``` > However, it's of course not legal Python syntax. What about: [result.process(module, data) for module, data in jobs] (or with () instead of [] around the outside if you want a generator)? In general, if you're using map() with a lambda function, it's often simpler to switch to a comprehension. ChrisA From sam.z.ezeh at gmail.com Sat Apr 16 18:05:03 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Sat, 16 Apr 2022 23:05:03 +0100 Subject: Fwd: Proposal: Syntax for attribute initialisation in __init__ methods In-Reply-To: References: Message-ID: > Perhaps I'm missing the point, but what functionality or advantage(s) > does this give, over data-classes? One advantage is maintaining control over the __init__ function without having to write extra code to do so. In the linked discussion from python-ideas, it was mentioned that keyword-only and positional-only arguments can't be used with dataclasses [1]. > Maybe Dataclasses are not being used as much as one might hope, but they > are relatively new, and many Python-Masters simply carry-on constructing > classes the way they have for years... I think one concern I have is that even if this is useful, it might still fall to the same fate. [1]: https://mail.python.org/archives/list/python-ideas at python.org/message/SCTXSEKOWDRDGVXXOEB7JUC6WE7XKGMO/ On Fri, 15 Apr 2022 at 22:30, dn wrote: > > On 15/04/2022 23.19, Sam Ezeh wrote: > ... > > Kudos for doing the research! > > > > Some related implementations are attrs, dataclasses and the use of a > > decorator. And there's potentially a point to be raised that the results > > from the first query indicate that the @dataclasse decorator is not being > > used enough. One advantage this proposal offers is control over the > > arguments that the __init__ function takes. > > > > A downside to using a decorator is that it might become difficult to accept > > arguments that don't need to be assigned to anything. > > > > I gave the example of the following code (unlike the above, this is not > > taken from existing python source code). In this example, a decorator can't > > assign all of the arguments to attributes or else it would produce code > > that does something different. > ... > > > I will support anything which reduces 'boiler-plate' or 'make busy' work! > > Perhaps I'm missing the point, but what functionality or advantage(s) > does this give, over data-classes? > > Maybe Dataclasses are not being used as much as one might hope, but they > are relatively new, and many Python-Masters simply carry-on constructing > classes the way they have for years... > > If data-classes give the impression of being 'syntactic sugar', there's > no particular need to use them - and certainly no rule or demand. > > There are constructs where one might find it easier not to use them. > > @dataclass does allow init=False. > > There is an argument which says that all data-attributes should be > 'created' inside an __init__() or __post_init__(), rather than > 'somewhere', 'later'. > -- > Regards, > =dn > -- > https://mail.python.org/mailman/listinfo/python-list From jon+usenet at unequivocal.eu Sat Apr 16 16:35:22 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sat, 16 Apr 2022 20:35:22 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <87ilrbdbzi.fsf@hornfels.zedat.fu-berlin.de> <87ee1zdbuh.fsf@hornfels.zedat.fu-berlin.de> <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: On 2022-04-16, Peter J. Holzer wrote: > On 2022-04-16 14:22:04 -0000, Jon Ribbens via Python-list wrote: >> On 2022-04-16, Jon Ribbens wrote: >> > On 2022-04-16, Peter J. Holzer wrote: >> >> Python missed the switch to DST here, the timezone is wrong. >> > >> > Because you didn't let it use any timezone information. You need to >> > either use the third-party 'pytz' module, or in Python 3.9 or above, >> > the built-in 'zoneinfo' module. >> >> ... although now having looked into the new 'zoneinfo' module slightly, >> it really should have a giant red flashing notice at the top of it >> saying "BEWARE, TIMEZONES IN PYTHON ARE UTTERLY BROKEN, NEVER USE THEM". >> >> Suppose we do this: >> >> >>> import datetime, zoneinfo >> >>> LOS_ANGELES = zoneinfo.ZoneInfo('America/Los_Angeles') >> >>> UTC = zoneinfo.ZoneInfo('UTC') >> >>> d = datetime.datetime(2020, 10, 31, 12, tzinfo=LOS_ANGELES) >> >>> print(d) >> 2020-10-31 12:00:00-07:00 >> >>> d1 = d + datetime.timedelta(days=1) >> >>> print(d1) >> 2020-11-01 12:00:00-08:00 >> >> d1 is *wrong*. > > No, this is correct. That's the result you want. I can categorically guarantee you it is not. But let's put it a different way, if you like, if I want to add 24 hours, i.e. 86,400 seconds (or indeed any other fixed time period), to a timezone-aware datetime in Python, how do I do it? It would appear that, without converting to UTC before doing the calculation, you can't. > So why didn't this work for me (I also used Python 3.9)? My guess is > that astimezone() doesn't pick the correct time zone. astimezone() doesn't pick a time zone at all. It works out the current local offset from UTC. It doesn't know anything about when or if that offset ever changes. >> timedelta(days=1) is 24 hours (as you can check by >> calling timedelta(days=1).total_seconds() ), > > It shouldn't be. 1 Day is not 24 hours in the real world. Nevertheless, timedelta is a fixed time period so that is the only definition possible. >> then it can pretend timezones don't exist and do 'naive' arithmetic. > > On the contrary. When a datetime is timezone aware, it must use that > timezone's rules. Adding one day to a datetime just before a DST switch > must add 23 or 25 hours, not 24. This is NOT naive. But it is. It's adding 24 hours and while it's doing so it's naively assuming that the UTC offset doesn't change during that period. Then once it's got that naive result it's labelling it with what it thinks is the timezone data at that time. Here's another example to prove the point: >>> LONDON = zoneinfo.ZoneInfo('Europe/London') >>> d0 = datetime.datetime(2022, 3, 27, 0, tzinfo=LONDON) >>> print(d0) 2022-03-27 00:00:00+00:00 >>> print(d0 + datetime.timedelta(seconds=3600+1800)) 2022-03-27 01:30:00+00:00 That is impossible - 2022-03-27 01:30 is a time that *doesn't exist* in the Europe/London timezone. At 01:00 the clocks moved instantly to 02:00 as daylight savings kicked in. So the following is wrong too: >>> print(d0 + datetime.timedelta(seconds=3600*2)) 2022-03-27 02:00:00+01:00 That's not 2 hours after midnight, that's 1 hour after midnight. Doing the calculations in UTC works of course: >>> print((d0.astimezone(UTC) + datetime.timedelta(seconds=3600+1800)).astimezone(LONDON)) 2022-03-27 02:30:00+01:00 >>> print((d0.astimezone(UTC) + datetime.timedelta(seconds=3600*2)).astimezone(LONDON)) 2022-03-27 03:00:00+01:00 > (There is an ambiguity, though: Should 2021-03-27T12:00 CEST - > 2021-03-26T12:00 CET return 1 day or 25 hours? Both results are correct, > and depending on context you might prefer one or the other). But if you're returning that result as a timedelta then only "25 hours" is correct (or indeed "1 day 3,600 seconds"), because for a timedelta a day is 24 hours *by definition*. >> There is a general guideline that you should always keep and use your >> datetimes as UTC, only ever using timezones for the purposes of display. >> Usually this is because it keeps things simpler for the programmer, and >> hence they are less likely to introduce bugs into their programs. > > While I generally do this (and often preach it to my collegues) it must > be stated that this is only a GENERAL guide line. Yes, that's what I just said. >> It appears that with Python it's not so much a guideline as an >> absolute concrete rule, and not because programmers will introduce >> bugs, but because you need to avoid bugs in the standard library! > > As a programmer you must always adapt to the problem. Saying "I must do > it the wrong way because my library is buggy" is just lazy. I didn't say any of that. I said you must do it the conservative way, and it's not "my library" that's buggy, it's the language's built-in *standard library* that's buggy. From sam.z.ezeh at gmail.com Sat Apr 16 18:06:03 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Sat, 16 Apr 2022 23:06:03 +0100 Subject: Fwd: Proposal: Syntax for attribute initialisation in __init__ methods In-Reply-To: References: <866bacfe-2b18-213f-c903-b4322209dc2f@stoneleaf.us> Message-ID: I've just seen Pablo's very recent post on python-ideas so I thought I'd link it here. [1] [1]: https://mail.python.org/archives/list/python-ideas at python.org/message/SCXHEWCHBJN3A7DPGGPPFLSTMBLLAOTX/ Kind Regards, Sam Ezeh On Fri, 15 Apr 2022 at 22:57, Ethan Furman wrote: > > On 4/15/22 04:19, Sam Ezeh wrote: > > Elsewhere, the idea of supporting new syntax to automatically initialise > > attributes provided as arguments to __init__ methods was raised. > > [...] > > Good post! You'll want to send this to python-ideas at some point (that's where most new python features are > discussed). This particular desire has come up in the past, so you'll need to do some more research (i.e. find the > previous threads on python-ideas) so you can answer objections already raised, or find new data supporting/refuting > previous arguments. > > -- > ~Ethan~ > -- > https://mail.python.org/mailman/listinfo/python-list From sam.z.ezeh at gmail.com Sat Apr 16 18:07:23 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Sat, 16 Apr 2022 23:07:23 +0100 Subject: Tuple unpacking inside lambda expressions In-Reply-To: References: Message-ID: > In general, if you're using map() with a lambda function, it's often simpler to switch to a comprehension. Oh, of course, completely went past my head. > [result.process(module, data) for module, data in jobs] And this works great, thanks! On Sat, 16 Apr 2022 at 22:42, Chris Angelico wrote: > > On Sun, 17 Apr 2022 at 07:37, Sam Ezeh wrote: > > > > Two questions here. > > > > Firstly, does anybody know of existing discussions (e.g. on here or on > > python-ideas) relating to unpacking inside lambda expressions? > > > > I found myself wanting to write the following. > > > > ``` > > map( > > lambda (module, data): result.process(module, data), > > jobs > > ) > > ``` > > However, it's of course not legal Python syntax. > > What about: > > [result.process(module, data) for module, data in jobs] > > (or with () instead of [] around the outside if you want a generator)? > > In general, if you're using map() with a lambda function, it's often > simpler to switch to a comprehension. > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list From wlfraed at ix.netcom.com Sat Apr 16 18:22:31 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Sat, 16 Apr 2022 18:22:31 -0400 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: On Sat, 16 Apr 2022 20:35:22 -0000 (UTC), Jon Ribbens declaimed the following: >I can categorically guarantee you it is not. But let's put it a >different way, if you like, if I want to add 24 hours, i.e. 86,400 >seconds (or indeed any other fixed time period), to a timezone-aware >datetime in Python, how do I do it? It would appear that, without >converting to UTC before doing the calculation, you can't. > Which is probably the recommended means to do just that. UTC is an international standard (call it a zero-reference). All other time-zones (and daylight savings time) tend to be local/civil time entities (even if widely accepted), subject to change by whim of the government (consider, just in the US alone, there are some states, or even parts of states, that do not honor the DST change over [I really don't know how my watch would handle some of those, since it time-syncs with WWV-B, including shifting to DST when WWV-B includes the flag in its broadcast]). And proposals to make DST permanent year round -- so "noon" (1200hrs) is not "noon" (sun at zenith) pretty much anywhere. The only thing that is most noticeable about UTC is the incorporation of leap-seconds. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From rosuav at gmail.com Sat Apr 16 18:53:36 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 08:53:36 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 08:37, Dennis Lee Bieber wrote: > And proposals to make > DST permanent year round -- so "noon" (1200hrs) is not "noon" (sun at > zenith) pretty much anywhere. > Noon isn't precisely zenith anyway, for several reasons: 1) Time zones synchronize their clocks on the mean noon at some location. Usually that's approximately close to the most populous part of the region, but not always - for instance, all of China is on one timezone, despite spanning 4-5 hours' worth of solar noon. 2) Solar noon migrates around a bit during the year. I don't remember the exact figures, but if you want to read a sundial with any precision, you need to take a date-based adjustment. 3) Solar days aren't all 24 hours long anyway. The clock and calendar should *roughly* correspond to the sun, in that broadly speaking, 2AM will be in darkness and 2PM will be in sunlight, and the solstices will land in June and December. But down to the minute, it's much more useful to synchronize on atomic time than astronomical. ChrisA From greg.ewing at canterbury.ac.nz Sat Apr 16 19:10:01 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Sun, 17 Apr 2022 11:10:01 +1200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: On 17/04/22 9:17 am, Karsten Hilbert wrote: > Take this medication for 1 month ! > > is quite likely to mean "take it for 28 days". Except when your doctor prescribes 90 days worth of tablets, they come boxes of 84 (6 cards * 14 tablets), and the pharmacist dutifully opens a box, cuts off an extra 6 and adds them in. -- Greg From jon+usenet at unequivocal.eu Sat Apr 16 18:49:29 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Sat, 16 Apr 2022 22:49:29 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: On 2022-04-16, Dennis Lee Bieber wrote: > On Sat, 16 Apr 2022 20:35:22 -0000 (UTC), Jon Ribbens > declaimed the following: >>I can categorically guarantee you it is not. But let's put it a >>different way, if you like, if I want to add 24 hours, i.e. 86,400 >>seconds (or indeed any other fixed time period), to a timezone-aware >>datetime in Python, how do I do it? It would appear that, without >>converting to UTC before doing the calculation, you can't. > > Which is probably the recommended means to do just that. Yes, as I've already mentioned it is good advice to always use UTC when doing date/time calculations and only convert to another timezone for display. However it is somewhat surprising that Python's datetime simply *does not work* when doing arithmetic on timezone-aware objects. It's not "disrecommended", it's straight-up broken. > The only thing that is most noticeable about UTC is the incorporation > of leap-seconds. I've never yet managed to find an application where leap-seconds matter ;-) From PythonList at DancesWithMice.info Sat Apr 16 21:53:07 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 17 Apr 2022 13:53:07 +1200 Subject: Proposal: Syntax for attribute initialisation in __init__ methods In-Reply-To: References: Message-ID: <04553d03-7d71-1022-0a82-39321bd2ec83@DancesWithMice.info> On 17/04/2022 09.20, Sam Ezeh wrote: >> Perhaps I'm missing the point, but what functionality or advantage(s) >> does this give, over data-classes? > > One advantage is maintaining control over the __init__ function without > having to write extra code to do so. In the linked discussion from > python-ideas, it was mentioned that keyword-only and positional-only > arguments can't be used with dataclasses [1]. > >> Maybe Dataclasses are not being used as much as one might hope, but they >> are relatively new, and many Python-Masters simply carry-on constructing >> classes the way they have for years... > > I think one concern I have is that even if this is useful, it might > still fall to the same fate. Don't be discouraged by that - and that thread was not the first of such discussions! The way Python is being applied is continually changing... I'm not sure about the criticism of dataclasses though. Starting with 'explicit over implicit', once a parameter-list is more than two or three long, shouldn't we be using 'labels' in order to avoid (potential) confusion, ie keyword-parameters? This removes the order/sequence of arguments from the list of potential problems/gotchas one can fall into! In which case, I'm wondering just how often the criticism applies 'in real life'? So, now the question becomes: what are the cases/examples which require/desire improvement over the 'traditional' __init__ of attributes, and facilities offered through dataclasses? -- Regards, =dn From hjp-python at hjp.at Sun Apr 17 03:26:51 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 17 Apr 2022 09:26:51 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> Message-ID: <20220417072651.6tcttzdx4mhptv2v@hjp.at> On 2022-04-16 20:35:22 -0000, Jon Ribbens via Python-list wrote: > On 2022-04-16, Peter J. Holzer wrote: > > On 2022-04-16 14:22:04 -0000, Jon Ribbens via Python-list wrote: > >> ... although now having looked into the new 'zoneinfo' module slightly, > >> it really should have a giant red flashing notice at the top of it > >> saying "BEWARE, TIMEZONES IN PYTHON ARE UTTERLY BROKEN, NEVER USE THEM". > >> > >> Suppose we do this: > >> > >> >>> import datetime, zoneinfo > >> >>> LOS_ANGELES = zoneinfo.ZoneInfo('America/Los_Angeles') > >> >>> UTC = zoneinfo.ZoneInfo('UTC') > >> >>> d = datetime.datetime(2020, 10, 31, 12, tzinfo=LOS_ANGELES) > >> >>> print(d) > >> 2020-10-31 12:00:00-07:00 > >> >>> d1 = d + datetime.timedelta(days=1) > >> >>> print(d1) > >> 2020-11-01 12:00:00-08:00 > >> > >> d1 is *wrong*. > > > > No, this is correct. That's the result you want. > > I can categorically guarantee you it is not. But let's put it a > different way, if you like, if I want to add 24 hours, i.e. 86,400 > seconds (or indeed any other fixed time period), to a timezone-aware > datetime in Python, how do I do it? What you *should* be able to do is use datetime.timedelta(hours=24). Unfortunately, you can't, because somebody decided to add a normalization rule to timedelta which turns this into timedelta(days=1, hours=0). > It would appear that, without converting to UTC before doing the > calculation, you can't. When doing calculations of this kind I frankly prefer converting to "seconds since the epoch" and doing simple arithmetic. (Yes, leap seconds, I know .. I just ignore those) > > So why didn't this work for me (I also used Python 3.9)? My guess is > > that astimezone() doesn't pick the correct time zone. > > astimezone() doesn't pick a time zone at all. It works out the current > local offset from UTC. The timezone object it returns also includes a timezone string ("CET" in my example). So it's not *just* the offset. The result is misleading, though. You get something which looks like it's a timezone object for Central European Time, but isn't. > It doesn't know anything about when or if that > offset ever changes. astimezone() doesn't have to. It just has to pick the correct timezone object. That object then knows about offset changes. > >> timedelta(days=1) is 24 hours (as you can check by > >> calling timedelta(days=1).total_seconds() ), > > > > It shouldn't be. 1 Day is not 24 hours in the real world. > > Nevertheless, timedelta is a fixed time period so that is the only > definition possible. Yeah, you keep repeating that. I think we are talking at cross-purposes here. You are talking about how timedelta is implemented while I'm talking what semantics it *should* have. > >> It appears that with Python it's not so much a guideline as an > >> absolute concrete rule, and not because programmers will introduce > >> bugs, but because you need to avoid bugs in the standard library! > > > > As a programmer you must always adapt to the problem. Saying "I must do > > it the wrong way because my library is buggy" is just lazy. > > I didn't say any of that. I said you must do it the conservative way, > and it's not "my library" that's buggy, it's the language's built-in > *standard library* that's buggy. With "your library" I meant "the library you have" not "the library you wrote". And while having a buggy (or just badly designed) standard library is especially annoying, you still aren't forced to use it if if doesn't fit your needs. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Sun Apr 17 04:15:54 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 17 Apr 2022 10:15:54 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: <20220417081554.wewkrvvl2xmiygsm@hjp.at> On 2022-04-17 06:08:54 +1000, Chris Angelico wrote: > On Sun, 17 Apr 2022 at 03:37, Peter J. Holzer wrote: > > Datetime arithmetic in the real world is typically not done in seconds, > > but in calendaric units: Hours, days, weeks, months, years, ... > > The problem is that several of these have varying lengths: > > > > * 1 minute may be 60 or 61 seconds (theoretically also 59, but that > > hasn't happened yet). > > * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica, > > where it's even weirder). > > I think Troll still only has days that consist of 23-25 hours; the > weird part is that they move their clocks forward for Oslo's summer, > which is their winter. According to Wikipedia they switch between UTC+2 and UTC+0, so the switchover days would be 22 and 26 hours, respectively. > > Therefore a new class (provisionally called timedeltacal, because it is > > calendaric, not absolute) should be added to datetime: > > > > Internally it stores months, days, seconds and microseconds as ints. > > > > The seconds and microseconds split is mostly for compatibility with > > datetime and timedelta. We could store seconds as a float instead. > > > > We don't store minutes since leap seconds aren't usually represented in > > "computer time", so they are unlikely to be useful in a timedeltacal > > object. > > > > Days are stored since they aren't a fixed multiple of any smaller unit. > > Months are stored since they aren't a fixed multiple of any smaller unit. > > > > Hours, weeks and years aren't stored since they are always 60 minutes, 7 > > days and 12 months respectively. > > It sounds like you're planning for annual DST changes, but what about > other shifts? What about when a location adopts standard time, which > could change their UTC offset (yes, I'm aware that most places adopted > standard time before UTC was a thing, but we still usually call it a > UTC offset rather than messing with GMT-UTC changeover) by an > arbitrary amount, even minutes? Yes, I think you are right. I first thought it wouldn't matter because you'd have to look it up in the database anyway, but that's a non-sequitur. Clearly, when you cities switched from local times to timezones, one hour had to be longer or shorter than 3600 seconds. Similarily if India decided to switch to a whole-hour offset, then they would have one hour of 30 or 90 minutes. > It might be cleaner to simply have all of the arguments that datetime > has: year, month, day, hour, minute, second, microsecond (with the > possibility of merging second/usec into a single float). Yup. > > When adding a timedeltacal object to a datetime, the fields are added > > from most to least significant: First a new date is computed by > > advancing the number of months specified [TODO: Research how other > > systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't > > exist)] > > Quick test in Pike: [...] > Subtracting seventeen days from today gets us to the 31st of March, > and adding one month to that gives us the 30th of April. Subtracting > eighteen days gets us to the 30th of March, and adding a month to that > _also_ gives us the 30th of April. Same for PostgreSQL. > > then advance the number of days. Finally add the number of > > seconds and microseconds, taking into accout daylight savings time > > switches if the datetime is time zone aware. > > Here's the local DST switchover: [results I expected] > > Subtracting a timedeltacal object from a datetime is the same, just in > > the opposite direction. > > > > Note that t + d - d is in general not equal to t. > > By "in general", do you mean "there will be some odd exceptions", or > "this is usually going to be unequal"? The former. > For instance, going back to the month boundary case, since it's not > possible for "add one month" from two different dates to give the same > result, obviously subtracting a month from that result can't give both > the originals. But for the most part, I would expect t + d - d to be > equal to t, modulo rounding error and possible DST corrections. > Crossing a DST boundary shouldn't break this pattern; only landing in > the actual gap/fold should cause issues. > Is that the intention? Yes, exactly. > > We can't cnange the semantics of datetime - datetime, so there must be a > > function to compute the difference between to datetimes as a > > timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u > > like in Go) or a constructor which takes two datetime objects. > > > > In any case I think that u + (t - u) == t should hold. [TODO: Check that > > this is possible] > > > > Isn't that the exact same thing as saying that t + d - d == t? No, because the overflow handling isn't reversible. Using the semantics from Pike or Postgres: 2022-03-31 + 1 month == 2022-04-30. But 2022-04-30 - 1 month == 2022-03-30. If "spill over" extra days (IIRC, PHP does that but I'd have to check) 2022-03-31 + 1 month == 2022-05-01 2022-05-01 - 1 month == 2022-04-01 So t + d - d is not always == t. (If you fix this special case you'll break some more common cases). But I think (but haven't yet proven) that for any pair of datetimes t0 and t1 there should always exist at least one delta d such that t0 + d == t1. 2022-03-31 + 30 days = 2022-04-30 2022-03-30 + 1 month = 2022-04-30 2022-03-31 + 31 days == 2022-05-01 2022-03-31 + 1 month + 1 day == 2022-05-01 2022-03-31 + 2 months - 30 days == 2022-05-01 Not sure which of the last three should be the canonical one. I can make an argument for each of them. > Or are you saying that, when you subtract two timestamps, you can > never get one of the odd exceptions that would cause problems? Because > I'd believe that; the net result would be that u+(t-u) == t, but > u+((t+d)-(u+d)) might not equal t. Putting it another way: Shift > invariance should *normally* hold, but there may be some exceptions at > month ends (basically rounding error when you add/subtract a month) > and DST switches. Yes. > When the time comes, if you need a hand putting together a PEP, feel > free to reach out to me. Thanks. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From rosuav at gmail.com Sun Apr 17 06:13:13 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 17 Apr 2022 20:13:13 +1000 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220417081554.wewkrvvl2xmiygsm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> <20220417081554.wewkrvvl2xmiygsm@hjp.at> Message-ID: On Sun, 17 Apr 2022 at 18:17, Peter J. Holzer wrote: > > On 2022-04-17 06:08:54 +1000, Chris Angelico wrote: > > On Sun, 17 Apr 2022 at 03:37, Peter J. Holzer wrote: > > > Datetime arithmetic in the real world is typically not done in seconds, > > > but in calendaric units: Hours, days, weeks, months, years, ... > > > The problem is that several of these have varying lengths: > > > > > > * 1 minute may be 60 or 61 seconds (theoretically also 59, but that > > > hasn't happened yet). > > > * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica, > > > where it's even weirder). > > > > I think Troll still only has days that consist of 23-25 hours; the > > weird part is that they move their clocks forward for Oslo's summer, > > which is their winter. > > According to Wikipedia they switch between UTC+2 and UTC+0, so the > switchover days would be 22 and 26 hours, respectively. Ah, hmm. I'll have to play around with the Antarctica/Troll timezone a bit, but it could be that they track Oslo time when only Norwegians are there, and UTC when there are others? In any case, there are *plenty* of bizarre cases. Whether Troll itself is one of those or not, there certainly is no shortage of weird changeover to be found. > > > Subtracting a timedeltacal object from a datetime is the same, just in > > > the opposite direction. > > > > > > Note that t + d - d is in general not equal to t. > > > > By "in general", do you mean "there will be some odd exceptions", or > > "this is usually going to be unequal"? > > The former. Okay, cool. My lengthy explanation of the question was unnecessary then :) > > Isn't that the exact same thing as saying that t + d - d == t? > > No, because the overflow handling isn't reversible. > > > Or are you saying that, when you subtract two timestamps, you can > > never get one of the odd exceptions that would cause problems? > > Yes. > Perfect then. So if I've understood correctly, what you're looking for is a thing that can be added onto a timezone-aware datetime which will have the semantics of adding onto each component individually, and then normalizing. That seems internally consistent, and useful. It's also a natural continuation of Python's migration from "datetime kinda sorta supports timezones, but only if you get a third-party package" to "datetime actually does support timezones" (in the same way that Pike and PostgreSQL do). ChrisA From Karsten.Hilbert at gmx.net Sun Apr 17 06:58:04 2022 From: Karsten.Hilbert at gmx.net (Karsten Hilbert) Date: Sun, 17 Apr 2022 12:58:04 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: Am Sun, Apr 17, 2022 at 11:10:01AM +1200 schrieb Greg Ewing: > On 17/04/22 9:17 am, Karsten Hilbert wrote: > > Take this medication for 1 month ! > > > >is quite likely to mean "take it for 28 days". > > Except when your doctor prescribes 90 days worth of tablets, It *still* means "take for 28 days" :-) Karsten -- GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B From hjp-python at hjp.at Sun Apr 17 10:34:01 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 17 Apr 2022 16:34:01 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220417081554.wewkrvvl2xmiygsm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> <20220417081554.wewkrvvl2xmiygsm@hjp.at> Message-ID: <20220417143401.ppevrrtawkybafq3@hjp.at> On 2022-04-17 10:15:54 +0200, Peter J. Holzer wrote: > On 2022-04-17 06:08:54 +1000, Chris Angelico wrote: > > On Sun, 17 Apr 2022 at 03:37, Peter J. Holzer wrote: > > > Therefore a new class (provisionally called timedeltacal, because it is > > > calendaric, not absolute) should be added to datetime: > > > > > > Internally it stores months, days, seconds and microseconds as ints. > > > > > > The seconds and microseconds split is mostly for compatibility with > > > datetime and timedelta. We could store seconds as a float instead. > > > > > > We don't store minutes since leap seconds aren't usually represented in > > > "computer time", so they are unlikely to be useful in a timedeltacal > > > object. > > > > > > Days are stored since they aren't a fixed multiple of any smaller unit. > > > Months are stored since they aren't a fixed multiple of any smaller unit. > > > > > > Hours, weeks and years aren't stored since they are always 60 minutes, 7 > > > days and 12 months respectively. > > > > It sounds like you're planning for annual DST changes, but what about > > other shifts? What about when a location adopts standard time, which > > could change their UTC offset (yes, I'm aware that most places adopted > > standard time before UTC was a thing, but we still usually call it a > > UTC offset rather than messing with GMT-UTC changeover) by an > > arbitrary amount, even minutes? > > Yes, I think you are right. I first thought it wouldn't matter because > you'd have to look it up in the database anyway, but that's a > non-sequitur. Clearly, when you cities switched from local times to > timezones, one hour had to be longer or shorter than 3600 seconds. > Similarily if India decided to switch to a whole-hour offset, then they > would have one hour of 30 or 90 minutes. Thinking about it some more (while writing test cases) I've changed my mind again. I think "1 hour" should always be 3600 seconds (disregarding leap seconds), not "the time until the hour hand has advanced by 30? and the minute hand is in the same position". If I sit at a bar at 00:30 on the last Sunday in March, and I continue to sit there for 2 hours, then it's 03:30 when I get out of the bar, not 02:30. 02:30 doesn't even exist. That might be considered an inconsistency, but I think it "does the right thing" in most cases. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From hjp-python at hjp.at Mon Apr 18 07:58:31 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 18 Apr 2022 13:58:31 +0200 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: <20220418115831.asm56xd453zu3mpy@hjp.at> On 2022-04-16 20:25:45 +0100, Barry wrote: > Suggest that you start with the use cases that you want supported. > Then you can turn them into a set of tests to check that the solution works. Writing test cases is always a good idea :-) I have now written a first set of test cases: https://git.hjp.at:3000/hjp/timedeltacal (together with a quick and dirty implementation that passes them). That's not complete yet. If covers addition of timezone aware datetime values and timedeltacal values fairly well, and also tests the t0 + (t1 - t0) == t1 property I alluded to elsewhere in this thread. It doesn't test canonicalization yet (and indeed the prototype implementation is a mess in this regard) and subtracting timedeltacals from datetimes is also still missing. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From barry at barrys-emacs.org Mon Apr 18 09:47:40 2022 From: barry at barrys-emacs.org (Barry) Date: Mon, 18 Apr 2022 14:47:40 +0100 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220418115831.asm56xd453zu3mpy@hjp.at> References: <20220418115831.asm56xd453zu3mpy@hjp.at> Message-ID: > On 18 Apr 2022, at 13:01, Peter J. Holzer wrote: > > ?On 2022-04-16 20:25:45 +0100, Barry wrote: >> Suggest that you start with the use cases that you want supported. >> Then you can turn them into a set of tests to check that the solution works. > > Writing test cases is always a good idea :-) Did you write the use cases? Without them how can anyone review the tests? Barry > > I have now written a first set of test cases: > https://git.hjp.at:3000/hjp/timedeltacal > (together with a quick and dirty implementation that passes them). > > That's not complete yet. > > If covers addition of timezone aware datetime values and timedeltacal > values fairly well, and also tests the t0 + (t1 - t0) == t1 property I > alluded to elsewhere in this thread. > > It doesn't test canonicalization yet (and indeed the prototype > implementation is a mess in this regard) and subtracting timedeltacals > from datetimes is also still missing. > > hp > > -- > _ | Peter J. Holzer | Story must make more sense than reality. > |_|_) | | > | | | hjp at hjp.at | -- Charles Stross, "Creative writing > __/ | http://www.hjp.at/ | challenge!" > -- > https://mail.python.org/mailman/listinfo/python-list From eryksun at gmail.com Mon Apr 18 10:41:18 2022 From: eryksun at gmail.com (Eryk Sun) Date: Mon, 18 Apr 2022 09:41:18 -0500 Subject: No shortcut Icon on Desktop In-Reply-To: <6259883a.1c69fb81.9c6d4.988b@mx.google.com> References: <555e5h9j2pcbd5964r9828id2cphqv4igi@4ax.com> <62586B1A.9040702@googlemail.com> <6258b6f3.1c69fb81.57df2.744c@mx.google.com> <6259883a.1c69fb81.9c6d4.988b@mx.google.com> Message-ID: On 4/15/22, Grant Edwards wrote: > > The problem is that people run the installer, don't see a desktop > icon, and think nothing has been installed. Such people need to learn how to use the start menu, where all of Python's shortcuts are installed in a folder named "Python ". One can also press the Windows key and type "python" to get a filtered view of the application shortcuts. > Or they think the installer "is python", and run it over and over > again trying to "run Python". I'm not opposed to renaming the installer to something that makes it more obvious that it's only an installer. But, to put this in perspective, I think you're talking about a small number of people out of the millions of users who I presume install and use Python without a problem. It could be that thousands of people install Python and give up without complaining when they can't use it, but I doubt it. > If the installer, by default, created an IDLE desktop shortcut and a > cmd.exe shortcut that ran Python, I believe it would eliminate most of > those problems. The installed shortcuts are to IDLE (via "pythonw.exe") and "python.exe". IDLE is a graphical integrated development environment (shell, editor, debugger) that by default runs an interactive shell. The "python.exe" executable is a console (terminal) application that by default runs an interactive shell if its arguments do not specify a script file, -m module, or -c command to run. A console application is attached to a console session, a resource that's hosted by an instance of "conhost.exe" or (in a tab of Windows Terminal) "openconsole.exe". It connects to the console session via files on the ConDrv device (e.g. "\Device\ConDrv\Connect", "\Device\ConDrv\Input", "\Device\ConDrv\Output"). If an application executable is flagged as a console application, such as "python.exe", and no console session was inherited from the parent process, and the process wasn't spawned with the DETACHED_PROCESS flag, then the Windows base API automatically allocates and attaches to a new console session at startup during the initialization of kernelbase.dll. If an application executable is flagged as a graphical application, such as "pythonw.exe", then a console session is never inherited and never automatically allocated, but one can be manually allocated or acquired via AllocConsole() or AttachConsole(dwProcessId). From Marco.Sulla.Python at gmail.com Mon Apr 18 11:06:53 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Mon, 18 Apr 2022 17:06:53 +0200 Subject: Suggestion for Linux Distro (from PSA: Linux vulnerability) In-Reply-To: <20220416151251.uljjmka7nroxj3ow@hjp.at> References: <877d8xnej9.fsf@hornfels.zedat.fu-berlin.de> <87pmm6kxo4.fsf@munus.decebal.nl> <20220328220302.n2pjqqbu7qf3aslf@hjp.at> <20220413180300.qrnneczjdftb2kdq@hjp.at> <20220416081405.ux34uzdhxdgsoggk@hjp.at> <20220416151251.uljjmka7nroxj3ow@hjp.at> Message-ID: On Sat, 16 Apr 2022 at 17:14, Peter J. Holzer wrote: > > On 2022-04-16 16:49:17 +0200, Marco Sulla wrote: > > Furthermore, you didn't answer my simple question: why does the > > security update package contain metadata about Debian patches, if the > > Ubuntu security team did not benefit from Debian security patches but > > only from internal work? > > It DOES NOT contain metadata about Debian patches. You are > misinterpreting the name "debian". The directory has this name because > the tools (dpkg, quilt, etc.) were originally written by the Debian team > for the Debian distribution. Ubuntu uses the same tools. They didn't > bother to rename the directory (why should they?), so the directory is > still called "debian" on Ubuntu (and yes I know this because I've built > numerous .deb packages on Ubuntu systems). Ah ok, now I understand. Sorry for the confusion. From wh2099 at outlook.com Sun Apr 17 05:17:52 2022 From: wh2099 at outlook.com (=?iso-2022-jp?B?GyRCMiYbKEIgGyRCOShJXBsoQg==?=) Date: Sun, 17 Apr 2022 09:17:52 +0000 Subject: is there somebody that have experince with python and canopen In-Reply-To: References: Message-ID: More information plz. WH-2099 ________________________________ From: Python-list on behalf of luca72.b... at gmail.com Sent: Saturday, April 16, 2022 1:18:33 AM To: python-list at python.org Subject: is there somebody that have experince with python and canopen We are searching for someone that can develop a python program for use servomotor for automotive. -- https://nam12.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.python.org%2Fmailman%2Flistinfo%2Fpython-list&data=04%7C01%7C%7C09d5bd1f71984d617a7108da1f119560%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637856457645434752%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=lMZ%2Bfpc5AsKEtFfgM9BPNAo4U81eKYxxgsjq2Jdas1E%3D&reserved=0 From antoon.pardon at vub.be Tue Apr 19 07:02:16 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Tue, 19 Apr 2022 13:02:16 +0200 Subject: Tuple unpacking inside lambda expressions In-Reply-To: References: Message-ID: Op 16/04/2022 om 23:36 schreef Sam Ezeh: > Two questions here. > > Firstly, does anybody know of existing discussions (e.g. on here or on > python-ideas) relating to unpacking inside lambda expressions? > > I found myself wanting to write the following. > > ``` > map( > lambda (module, data): result.process(module, data), > jobs > ) > ``` > However, it's of course not legal Python syntax. Why not write: itertools.starmap(result.process, jobs) From loris.bennett at fu-berlin.de Tue Apr 19 07:11:53 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 19 Apr 2022 13:11:53 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> Message-ID: <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> "Peter J. Holzer" writes: > On 2022-04-16 20:35:22 -0000, Jon Ribbens via Python-list wrote: >> On 2022-04-16, Peter J. Holzer wrote: >> > On 2022-04-16 14:22:04 -0000, Jon Ribbens via Python-list wrote: >> >> ... although now having looked into the new 'zoneinfo' module slightly, >> >> it really should have a giant red flashing notice at the top of it >> >> saying "BEWARE, TIMEZONES IN PYTHON ARE UTTERLY BROKEN, NEVER USE THEM". >> >> >> >> Suppose we do this: >> >> >> >> >>> import datetime, zoneinfo >> >> >>> LOS_ANGELES = zoneinfo.ZoneInfo('America/Los_Angeles') >> >> >>> UTC = zoneinfo.ZoneInfo('UTC') >> >> >>> d = datetime.datetime(2020, 10, 31, 12, tzinfo=LOS_ANGELES) >> >> >>> print(d) >> >> 2020-10-31 12:00:00-07:00 >> >> >>> d1 = d + datetime.timedelta(days=1) >> >> >>> print(d1) >> >> 2020-11-01 12:00:00-08:00 >> >> >> >> d1 is *wrong*. >> > >> > No, this is correct. That's the result you want. >> >> I can categorically guarantee you it is not. But let's put it a >> different way, if you like, if I want to add 24 hours, i.e. 86,400 >> seconds (or indeed any other fixed time period), to a timezone-aware >> datetime in Python, how do I do it? > > What you *should* be able to do is use datetime.timedelta(hours=24). > > Unfortunately, you can't, because somebody decided to add a > normalization rule to timedelta which turns this into timedelta(days=1, > hours=0). > >> It would appear that, without converting to UTC before doing the >> calculation, you can't. > > When doing calculations of this kind I frankly prefer converting to > "seconds since the epoch" and doing simple arithmetic. (Yes, leap > seconds, I know .. I just ignore those) > > >> > So why didn't this work for me (I also used Python 3.9)? My guess is >> > that astimezone() doesn't pick the correct time zone. >> >> astimezone() doesn't pick a time zone at all. It works out the current >> local offset from UTC. > > The timezone object it returns also includes a timezone string ("CET" in > my example). So it's not *just* the offset. The result is misleading, > though. You get something which looks like it's a timezone object for > Central European Time, but isn't. > >> It doesn't know anything about when or if that >> offset ever changes. > > astimezone() doesn't have to. It just has to pick the correct timezone > object. That object then knows about offset changes. > > >> >> timedelta(days=1) is 24 hours (as you can check by >> >> calling timedelta(days=1).total_seconds() ), >> > >> > It shouldn't be. 1 Day is not 24 hours in the real world. >> >> Nevertheless, timedelta is a fixed time period so that is the only >> definition possible. > > Yeah, you keep repeating that. I think we are talking at cross-purposes > here. You are talking about how timedelta is implemented while I'm > talking what semantics it *should* have. > > >> >> It appears that with Python it's not so much a guideline as an >> >> absolute concrete rule, and not because programmers will introduce >> >> bugs, but because you need to avoid bugs in the standard library! >> > >> > As a programmer you must always adapt to the problem. Saying "I must do >> > it the wrong way because my library is buggy" is just lazy. >> >> I didn't say any of that. I said you must do it the conservative way, >> and it's not "my library" that's buggy, it's the language's built-in >> *standard library* that's buggy. > > With "your library" I meant "the library you have" not "the library you > wrote". And while having a buggy (or just badly designed) standard > library is especially annoying, you still aren't forced to use it if if > doesn't fit your needs. > > hp I now realise that timedelta is not really what I need. I am interested solely in pure periods, i.e. numbers of seconds, that I can convert back and forth from a format such as 11-22::44:55 (These are the lengths of time a job has run on an HPC system - leap seconds and time zones are of no relevance). It is obviously fairly easy to rustle up something to do this, but I am surprised that this is not baked into Python (such a class also seems to be missing from R). I would have thought that periods crop up all over the place and therefore formatting as strings and parsing of string would be supported natively by most modern languages. Apparently not. Cheers, Loris -- This signature is currently under construction. From jon+usenet at unequivocal.eu Tue Apr 19 08:04:10 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 19 Apr 2022 12:04:10 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On 2022-04-19, Loris Bennett wrote: > I now realise that timedelta is not really what I need. I am interested > solely in pure periods, i.e. numbers of seconds, That's exactly what timedelta is. > that I can convert back and forth from a format such as > > 11-22::44:55 I don't recognise that format and can't work out what it means. It should be trivial to write functions to parse whatever format you wanted and convert between it and timedelta objects though. > It is obviously fairly easy to rustle up something to do this, but I am > surprised that this is not baked into Python (such a class also seems to > be missing from R). I would be very surprised if any language supported the arbitrary format above you happen to be interested in! > I would have thought that periods crop up all over > the place and therefore formatting as strings and parsing of string > would be supported natively by most modern languages. Apparently not. I think most languages think that a simple number suffices to represent a fixed time period (commonly seconds or milliseconds). And if you want more dynamic intervals (e.g. x months y days) then there is insufficient consensus as to what that actually means. From loris.bennett at fu-berlin.de Tue Apr 19 08:54:57 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 19 Apr 2022 14:54:57 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <8735i944im.fsf@hornfels.zedat.fu-berlin.de> Jon Ribbens writes: > On 2022-04-19, Loris Bennett wrote: >> I now realise that timedelta is not really what I need. I am interested >> solely in pure periods, i.e. numbers of seconds, > > That's exactly what timedelta is. > >> that I can convert back and forth from a format such as >> >> 11-22::44:55 > > I don't recognise that format and can't work out what it means. > It should be trivial to write functions to parse whatever format > you wanted and convert between it and timedelta objects though. days-hours:minutes:seconds >> It is obviously fairly easy to rustle up something to do this, but I am >> surprised that this is not baked into Python (such a class also seems to >> be missing from R). > > I would be very surprised if any language supported the arbitrary format > above you happen to be interested in! But most languages support fairly arbitrary formatting of timedate-style objects. It doesn't seem unreasonable to me that such formatting might be available for simple periods. >> I would have thought that periods crop up all over >> the place and therefore formatting as strings and parsing of string >> would be supported natively by most modern languages. Apparently not. > > I think most languages think that a simple number suffices to represent > a fixed time period (commonly seconds or milliseconds). And if you want > more dynamic intervals (e.g. x months y days) then there is insufficient > consensus as to what that actually means. Maybe. It just seems to me that once you get up to more than a few hundred seconds, the ability to convert and from a more readable format becomes very useful. The length of a month may be unclear, but the definitions for year, week, day, hours, and minute are all trivial. Cheers, Loris -- This signature is currently under construction. From jon+usenet at unequivocal.eu Tue Apr 19 09:15:15 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 19 Apr 2022 13:15:15 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On 2022-04-19, Loris Bennett wrote: > Jon Ribbens writes: >> On 2022-04-19, Loris Bennett wrote: >>> I now realise that timedelta is not really what I need. I am interested >>> solely in pure periods, i.e. numbers of seconds, >> >> That's exactly what timedelta is. >> >>> that I can convert back and forth from a format such as >>> >>> 11-22::44:55 >> >> I don't recognise that format and can't work out what it means. >> It should be trivial to write functions to parse whatever format >> you wanted and convert between it and timedelta objects though. > > days-hours:minutes:seconds If by 'days' it means '86,400 seconds' then that's very easily convertible to and from timedelta. >> I would be very surprised if any language supported the arbitrary format >> above you happen to be interested in! > > But most languages support fairly arbitrary formatting of timedate-style > objects. It doesn't seem unreasonable to me that such formatting might > be available for simple periods. > >>> I would have thought that periods crop up all over >>> the place and therefore formatting as strings and parsing of string >>> would be supported natively by most modern languages. Apparently not. >> >> I think most languages think that a simple number suffices to represent >> a fixed time period (commonly seconds or milliseconds). And if you want >> more dynamic intervals (e.g. x months y days) then there is insufficient >> consensus as to what that actually means. > > Maybe. It just seems to me that once you get up to more than a few > hundred seconds, the ability to convert and from a more readable format > becomes very useful. The length of a month may be unclear, but the > definitions for year, week, day, hours, and minute are all trivial. Eh? The definitions for "year, week, day" are not in the slightest bit trivial (unless you define 'day' as '86,400 seconds', in which case 'year' is still not remotely trivial). I think the issue is simply lack of consensus. Even though ISO 8601, which is extremely common (possibly even ubiquitous, for anything modern) for the format of date/times, also defines a format for durations (e.g. 'P4Y3M' for '4 years 3 months'), I don't think I have ever seen it used in practice - not least because apparently it doesn't define what it actually means. So there isn't one simple standard agreed by everyone that is an obvious candidate for inclusion in language standard libraries. From loris.bennett at fu-berlin.de Tue Apr 19 09:51:09 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 19 Apr 2022 15:51:09 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <87r15t2nci.fsf@hornfels.zedat.fu-berlin.de> Jon Ribbens writes: > On 2022-04-19, Loris Bennett wrote: >> Jon Ribbens writes: >>> On 2022-04-19, Loris Bennett wrote: >>>> I now realise that timedelta is not really what I need. I am interested >>>> solely in pure periods, i.e. numbers of seconds, >>> >>> That's exactly what timedelta is. >>> >>>> that I can convert back and forth from a format such as >>>> >>>> 11-22::44:55 >>> >>> I don't recognise that format and can't work out what it means. >>> It should be trivial to write functions to parse whatever format >>> you wanted and convert between it and timedelta objects though. >> >> days-hours:minutes:seconds > > If by 'days' it means '86,400 seconds' then that's very easily > convertible to and from timedelta. > >>> I would be very surprised if any language supported the arbitrary format >>> above you happen to be interested in! >> >> But most languages support fairly arbitrary formatting of timedate-style >> objects. It doesn't seem unreasonable to me that such formatting might >> be available for simple periods. >> >>>> I would have thought that periods crop up all over >>>> the place and therefore formatting as strings and parsing of string >>>> would be supported natively by most modern languages. Apparently not. >>> >>> I think most languages think that a simple number suffices to represent >>> a fixed time period (commonly seconds or milliseconds). And if you want >>> more dynamic intervals (e.g. x months y days) then there is insufficient >>> consensus as to what that actually means. >> >> Maybe. It just seems to me that once you get up to more than a few >> hundred seconds, the ability to convert and from a more readable format >> becomes very useful. The length of a month may be unclear, but the >> definitions for year, week, day, hours, and minute are all trivial. > > Eh? The definitions for "year, week, day" are not in the slightest bit > trivial (unless you define 'day' as '86,400 seconds', in which case > 'year' is still not remotely trivial). Yes, I do mean just the trivial definitions from https://docs.python.org/3/library/datetime.html i.e. A millisecond is converted to 1000 microseconds. A minute is converted to 60 seconds. An hour is converted to 3600 seconds. A week is converted to 7 days. plus a 24-hour day and a 365-day year. > I think the issue is simply lack of consensus. Even though ISO 8601, > which is extremely common (possibly even ubiquitous, for anything > modern) for the format of date/times, also defines a format for > durations (e.g. 'P4Y3M' for '4 years 3 months'), I don't think > I have ever seen it used in practice - not least because apparently > it doesn't define what it actually means. So there isn't one simple > standard agreed by everyone that is an obvious candidate for inclusion > in language standard libraries. If I am merely trying to represent part a very large number of seconds as a number of years, 365 days per year does not seem that controversial to me. Obviously there are issues if you expect all periods of an integer number of years which start on a given date to all end on the same date. In my little niche, I just need a very simple period and am anyway not bothered about years, since in my case the number of days is usually capped at 14 and only in extremely exceptional circumstances could it get up to anywhere near 100. However, surely there are plenty of people measuring durations of a few hours or less who don't want to have to deal with seconds all the time (I am in fact also in this other group when I record my working hours). Cheers, Loris -- This signature is currently under construction. From jon+usenet at unequivocal.eu Tue Apr 19 10:01:48 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 19 Apr 2022 14:01:48 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> <87r15t2nci.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On 2022-04-19, Loris Bennett wrote: > If I am merely trying to represent part a very large number of seconds > as a number of years, 365 days per year does not seem that controversial > to me. Obviously there are issues if you expect all periods of an > integer number of years which start on a given date to all end on the > same date. > > In my little niche, I just need a very simple period and am anyway not > bothered about years, since in my case the number of days is usually > capped at 14 and only in extremely exceptional circumstances could it > get up to anywhere near 100. > > However, surely there are plenty of people measuring durations of a few > hours or less who don't want to have to deal with seconds all the time > (I am in fact also in this other group when I record my working hours). Well, that's my point. Everyone's all in their own slightly-different little niches. There isn't one straightforward standard that makes all or even most of them happy. From loris.bennett at fu-berlin.de Tue Apr 19 10:19:49 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 19 Apr 2022 16:19:49 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> <87r15t2nci.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <87lew12m0q.fsf@hornfels.zedat.fu-berlin.de> Jon Ribbens writes: > On 2022-04-19, Loris Bennett wrote: >> If I am merely trying to represent part a very large number of seconds >> as a number of years, 365 days per year does not seem that controversial >> to me. Obviously there are issues if you expect all periods of an >> integer number of years which start on a given date to all end on the >> same date. >> >> In my little niche, I just need a very simple period and am anyway not >> bothered about years, since in my case the number of days is usually >> capped at 14 and only in extremely exceptional circumstances could it >> get up to anywhere near 100. >> >> However, surely there are plenty of people measuring durations of a few >> hours or less who don't want to have to deal with seconds all the time >> (I am in fact also in this other group when I record my working hours). > > Well, that's my point. Everyone's all in their own slightly-different > little niches. There isn't one straightforward standard that makes all > or even most of them happy. I'm sure you're right. I just strikes me as a little odd that so much effort has gone into datetime to make things work (almost) properly for (almost) everyone, whereas timedelta has remained rather rudimentary, at least in terms of formatting. It seems to me that periods on the order of hours would have quite generic applications, but maybe that's just the view from my niche. Cheers, Loris -- This signature is currently under construction. From rosuav at gmail.com Tue Apr 19 13:12:15 2022 From: rosuav at gmail.com (Chris Angelico) Date: Wed, 20 Apr 2022 03:12:15 +1000 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> Message-ID: On Wed, 20 Apr 2022 at 02:16, Loris Bennett wrote: > I now realise that timedelta is not really what I need. I am interested > solely in pure periods, i.e. numbers of seconds, that I can convert back > and forth from a format such as > > 11-22::44:55 > > (These are the lengths of time a job has run on an HPC system - leap > seconds and time zones are of no relevance). Thing is, there's a huge difference between: 1) "Eleven days, twenty-two hours, forty-four minutes, and fifty-five seconds" 2) "The period between 2nd May 2009 at 6AM and 5th June 2010 at 9AM" 3) "The period between 20th Feb 2016 at 10PM in New York and 30th Mar 2016 at 1AM in New York" 3b) "The period between 23rd Jan 1918 and 15th Feb 1918 in Moscow" The first one is an abstract distance of time, and could be considered broadly equivalent to the difference between two TIA timestamps or two Unix times. Or UTC, as long as you don't care about inaccuracy around leap seconds. The second is a specific time period without a time zone. If assumed to be UTC, or on an abstract calendar, it can be converted to and from the first form, but if it's assumed to be local time, then it's underspecified. It's affected by leap years, so you have to specify the full date. The third, and possibly fourth, are affected by civil time. (3b is also potentially affected by a calendar switch; for people in Russia at the time, the 23rd of January was a Julian date and the 15th of February was a Gregorian date, so they were closer together than on either calendar consistently. But I'd be fine with ignoring that, and requiring the use of the Gregorian (or ISO, which is derived from it) calendar.) Civil time is modified by regular adjustments (mostly DST), official changes to time zone (eg the introduction or abolition of DST, or choosing to align one's timezone with a neighbour), adoption of standard time (often adjusting by a few minutes and/or seconds to align with an hour boundary), etc, etc, etc. The only way to handle civil time is (a) with full timestamps including the year, and (b) with a complete timezone database listing all conversions. At this point, the time period no longer has any abstract meaning, and its sole meaning is "the time between these instants"; as such, it's probably best calculated by converting the timestamps to UTC, converting to Unix time, and taking the difference in seconds. With the first option, there's no real meaning to it until you figure out what you can actually *do* with that time period. I believe ISO 8601 timestamps are about the most general you'll ever need, with the possible exception of "9pm to 10pm second Saturday of every month, if His Sufficiency feels like meeting with you, otherwise never". (Though, to be fair, you could probably represent that with a simple "Never" and it'd be just as correct.) It's worth noting that pure seconds can easily be used as timedeltas. If you want your form to be convertible back and forth with a number of seconds, it's easy enough to subtract two datetimes by their Unix times. But before defining the class, it's essential to define what you want to do with it. Not all operations are equally meaningful. ChrisA From wlfraed at ix.netcom.com Tue Apr 19 14:23:11 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Tue, 19 Apr 2022 14:23:11 -0400 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> <87r15t2nci.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> On Tue, 19 Apr 2022 15:51:09 +0200, "Loris Bennett" declaimed the following: >If I am merely trying to represent part a very large number of seconds >as a number of years, 365 days per year does not seem that controversial The Explanatory Supplement to the Astronomical Almanac (table 15.3) defines the /day/ as 24hrs->1440mins->86400secs BUT defines the Julian /year/ as 365.25 days. It goes on to also give (for my copy -- length of year at 1990): Tropical (equinox to equinox) 365.2421897 days * Sidereal (fixed star to fixed star) 365.25636 days Anomalistic (perihelion to perihelion) 365.25964 days Eclipse (moon's node to moon's node) 346.26005 Gaussian (Kepler's law /a/=1) 365.25690 Julian 365.25 Length of the month (I interpret this as lunar month): Synodic (new moon to new moon) 29.53059 days Tropical (as with year) 27.32158 Sidereal (as with year) 27.32166 Anomalistic (perigee to perigee) 27.55455 Draconic (node to node) 27.21222 * I /think/ this is the year used for leap-day calculations, and why some leap centuries are skipped as it is really less than a quarter day per year, so eventually one gets to over-correcting by a day. Of course, this book also has a footnote giving the speed of light as 1.80261750E12 Furlongs/Fortnight However, as soon you incorporate units that are not SI seconds you have to differentiate between pure duration (based on SI seconds) and civil time (which may jump when leap seconds are added/subtracted, time zones are crossed, or daylight savings time goes into [or out of] effect). For the most part, Python's datetime module seems to account for civil time concepts, not monotonic durations. The Ada standard separates "duration" (as a measure of elapsed time, in fixed point seconds) from "time" (a private type in Ada.Calendar -- which does NOT define hours/minutes... It has Year 1901..2399, Month 1..12, Day 1..31, Day_duration 0.0..86400.0). There are functions to create a Time from components, split a Time into components, compare two times, add a Duration to a Time, subtract a Duration from a Time, and subtract a Time from a Time (getting a Duration). Oh, and a function to get Time from system clock. Per the standard, the Time Zone used is implementation defined (so one needs to read the implementation manual to find out what a Time really notates). Of note: """ 26.a/1 To be honest: {8652/0106} {AI95-00160-01} By "proper date" above we mean that the given year has a month with the given day. For example, February 29th is a proper date only for a leap year. We do not mean to include the Seconds in this notion; in particular, we do not mean to require implementations to check for the ?missing hour? that occurs when Daylight Savings Time starts in the spring. """ """ 43 type Duration is delta implementation-defined range implementation-defined; """ GNAT provides an extension package GNAT.Calendar that adds hour/minute/day-of-week and some other utilities... BUT """ procedure Split_At_Locale (Date : Ada.Calendar.Time; Year : out Ada.Calendar.Year_Number; Month : out Ada.Calendar.Month_Number; Day : out Ada.Calendar.Day_Number; Hour : out Hour_Number; Minute : out Minute_Number; Second : out Second_Number; Sub_Second : out Second_Duration); -- Split a standard Ada.Calendar.Time value in date data (Year, Month, Day) -- and Time data (Hour, Minute, Second, Sub_Second). This version of Split -- utilizes the time zone and DST bias of the locale (equivalent to Clock). -- Due to this simplified behavior, the implementation does not require -- expensive system calls on targets such as Windows. -- WARNING: Split_At_Locale is no longer aware of historic events and may -- produce inaccurate results over DST changes which occurred in the past. """ -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From python at mrabarnett.plus.com Tue Apr 19 16:06:20 2022 From: python at mrabarnett.plus.com (MRAB) Date: Tue, 19 Apr 2022 21:06:20 +0100 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> References: <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> <87r15t2nci.fsf@hornfels.zedat.fu-berlin.de> <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> Message-ID: <99e46fb0-390d-cea6-5fe4-5befe786a56a@mrabarnett.plus.com> On 2022-04-19 19:23, Dennis Lee Bieber wrote: > On Tue, 19 Apr 2022 15:51:09 +0200, "Loris Bennett" > declaimed the following: > >>If I am merely trying to represent part a very large number of seconds >>as a number of years, 365 days per year does not seem that controversial > > The Explanatory Supplement to the Astronomical Almanac (table 15.3) > defines the /day/ as 24hrs->1440mins->86400secs BUT defines the Julian > /year/ as 365.25 days. > So, a /day/ is a solar day, as distinct from a sidereal day. What's the difference? Well, a "sidereal day" is how long it takes for the Earth to rotate on its axis, but as it's also orbiting the Sun in the same direction, midday won't happen until a little later, hence "solar day". [snip] From barry at barrys-emacs.org Tue Apr 19 16:53:02 2022 From: barry at barrys-emacs.org (Barry) Date: Tue, 19 Apr 2022 21:53:02 +0100 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> References: <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> Message-ID: > On 19 Apr 2022, at 19:38, Dennis Lee Bieber wrote: > > * I /think/ this is the year used for leap-day calculations, and why some > leap centuries are skipped as it is really less than a quarter day per > year, so eventually one gets to over-correcting by a day. Leap century is skip unless it?s a leap quadra century. Barry From jon+usenet at unequivocal.eu Tue Apr 19 17:36:57 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Tue, 19 Apr 2022 21:36:57 -0000 (UTC) Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> Message-ID: On 2022-04-19, Barry wrote: >> On 19 Apr 2022, at 19:38, Dennis Lee Bieber wrote: >> * I /think/ this is the year used for leap-day calculations, and >> why some leap centuries are skipped as it is really less than a >> quarter day per year, so eventually one gets to over-correcting >> by a day. > > Leap century is skip unless it?s a leap quadra century. Indeed, which is why "leap=not year & 3" works for years in range(1901, 2100). Which I have found useful before when programming in an assembly language that has no division operation ;-) From random832 at fastmail.com Tue Apr 19 18:10:11 2022 From: random832 at fastmail.com (Random832) Date: Tue, 19 Apr 2022 18:10:11 -0400 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? In-Reply-To: <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <19bc3cf1-cd89-4f88-82ae-09983a502b9e@www.fastmail.com> On Tue, Apr 19, 2022, at 07:11, Loris Bennett wrote: > I now realise that timedelta is not really what I need. I am interested > solely in pure periods, i.e. numbers of seconds, that I can convert back > and forth from a format such as A timedelta *is* a pure period. A timedelta of one day is 86400 seconds. The thing you *think* timedelta does [making a day act as 23 or 25 hours across daylight saving boundaries etc], that you *don't* want it to do, is something it *does not actually do*. I don't know how this can be made more clear to you. timedelta is what you need. if you think it's not, it's because you're using datetime incorrectly. The real problem is that naive datetime objects [without using either a fixed timezone offset like the built-in utc, or a library like pytz] are not fit for any purpose. If you use pytz correctly [which is unfortunately awkward due to leaky abstractions and mismatches between the datetime model works and how most people expect datetimes with timezones to work], you will indeed get 24 hours from timedelta(days=1) >>> et = pytz.timezone('America/New_York') >>> et.normalize(et.localize(datetime.datetime(2022,3,12,12,0,0)) + datetime.timedelta(days=1)) datetime.datetime(2022, 3, 13, 13, 0, tzinfo=) you can see here that 2022-03-12T12:00-0500 + timedelta(days=1) correctly becomes 2022-03-13T13:00-0400, 24 hours later. As far as I know, Python doesn't even have a way to represent "1 day" [or 1 month, 1 year] as a context-dependent-length interval (the thing you think timedelta does), at least not within the standard library and the datetime model. > 11-22::44:55 > > (These are the lengths of time a job has run on an HPC system - leap > seconds and time zones are of no relevance). > > It is obviously fairly easy to rustle up something to do this, but I am > surprised that this is not baked into Python (such a class also seems to > be missing from R). I would have thought that periods crop up all over > the place and therefore formatting as strings and parsing of string > would be supported natively by most modern languages. Apparently not. > > Cheers, > > Loris > > -- > This signature is currently under construction. > -- > https://mail.python.org/mailman/listinfo/python-list From random832 at fastmail.com Tue Apr 19 18:19:59 2022 From: random832 at fastmail.com (Random832) Date: Tue, 19 Apr 2022 18:19:59 -0400 Subject: Pre-Pre-PEP: The datetime.timedeltacal class In-Reply-To: <20220416173551.fk6voaa3o25iuewm@hjp.at> References: <20220416173551.fk6voaa3o25iuewm@hjp.at> Message-ID: <4bf6b4bf-f2b5-4a59-a72c-e7bfaa84293f@www.fastmail.com> On Sat, Apr 16, 2022, at 13:35, Peter J. Holzer wrote: > When adding a timedeltacal object to a datetime, the fields are added > from most to least significant: First a new date is computed by > advancing the number of months specified [TODO: Research how other > systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't > exist)], then advance the number of days. Finally add the number of > seconds and microseconds, taking into accout daylight savings time > switches if the datetime is time zone aware. > > Subtracting a timedeltacal object from a datetime is the same, just in > the opposite direction. > > Note that t + d - d is in general not equal to t. I'm not sure there's a guarantee that t + n day + m second may not be equal to t + m second + n day, either. This is possibly also something that we can look at what existing implementations do, though I'm concerned that the choice of "fold" rather than "isdst" may come back to bite us here [C actually uses a three-state isdst input for mktime which performs these operations] Also, what about hours? "12 calendar hours" may be 13 or 11 hours depending on if a DST transition is included in the given time. From sam.z.ezeh at gmail.com Wed Apr 20 06:46:23 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Wed, 20 Apr 2022 11:46:23 +0100 Subject: Proposal: Syntax for attribute initialisation in __init__ methods In-Reply-To: <04553d03-7d71-1022-0a82-39321bd2ec83@DancesWithMice.info> References: <04553d03-7d71-1022-0a82-39321bd2ec83@DancesWithMice.info> Message-ID: I'll see if I can find out how positional only and keyword only arguments are used in __init__ methods in the wild and I'll see if there have been any other discussions talking about what this approach could offer. On Sun, 17 Apr 2022 at 02:54, dn wrote: > > On 17/04/2022 09.20, Sam Ezeh wrote: > >> Perhaps I'm missing the point, but what functionality or advantage(s) > >> does this give, over data-classes? > > > > One advantage is maintaining control over the __init__ function without > > having to write extra code to do so. In the linked discussion from > > python-ideas, it was mentioned that keyword-only and positional-only > > arguments can't be used with dataclasses [1]. > > > >> Maybe Dataclasses are not being used as much as one might hope, but they > >> are relatively new, and many Python-Masters simply carry-on constructing > >> classes the way they have for years... > > > > I think one concern I have is that even if this is useful, it might > > still fall to the same fate. > > > Don't be discouraged by that - and that thread was not the first of such > discussions! The way Python is being applied is continually changing... > > I'm not sure about the criticism of dataclasses though. Starting with > 'explicit over implicit', once a parameter-list is more than two or > three long, shouldn't we be using 'labels' in order to avoid (potential) > confusion, ie keyword-parameters? > > This removes the order/sequence of arguments from the list of potential > problems/gotchas one can fall into! > > In which case, I'm wondering just how often the criticism applies 'in > real life'? > > So, now the question becomes: what are the cases/examples which > require/desire improvement over the 'traditional' __init__ of > attributes, and facilities offered through dataclasses? > -- > Regards, > =dn > -- > https://mail.python.org/mailman/listinfo/python-list From sam.z.ezeh at gmail.com Wed Apr 20 06:57:18 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Wed, 20 Apr 2022 11:57:18 +0100 Subject: Enums and nested classes Message-ID: Hello everyone, Has anyone here used or attempted to use a nested class inside an enum? If so, how did you find it? (what did you expect to happen and did your expectations align with resulting behaviour etc.) Here are two examples describing the situation I'm talking about ``` class Outer(Enum): a = 1 b = 2 class Inner(Enum): foo = 10 bar = 11 ``` ``` class Outer(Enum): a = 1 b = 2 class Inner: c = None def __init__(self): .... ``` Kind Regards, Sam Ezeh From sam.z.ezeh at gmail.com Wed Apr 20 06:59:12 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Wed, 20 Apr 2022 11:59:12 +0100 Subject: Tuple unpacking inside lambda expressions In-Reply-To: References: Message-ID: This also works great! Kind Regards, Sam Ezeh On Tue, 19 Apr 2022 at 12:03, Antoon Pardon wrote: > > Op 16/04/2022 om 23:36 schreef Sam Ezeh: > > Two questions here. > > > > Firstly, does anybody know of existing discussions (e.g. on here or on > > python-ideas) relating to unpacking inside lambda expressions? > > > > I found myself wanting to write the following. > > > > ``` > > map( > > lambda (module, data): result.process(module, data), > > jobs > > ) > > ``` > > However, it's of course not legal Python syntax. > > Why not write: > > itertools.starmap(result.process, jobs) > > -- > https://mail.python.org/mailman/listinfo/python-list From sam.z.ezeh at gmail.com Wed Apr 20 07:01:23 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Wed, 20 Apr 2022 12:01:23 +0100 Subject: Tuple unpacking inside lambda expressions In-Reply-To: References: Message-ID: I went back to the code recently and I remembered what the problem was. I was using multiprocessing.Pool.pmap which takes a callable (the lambda here) so I wasn't able to use comprehensions or starmap Is there anything for situations like these? Kind Regards, Sam Ezeh On Sat, 16 Apr 2022 at 22:36, Sam Ezeh wrote: > > Two questions here. > > Firstly, does anybody know of existing discussions (e.g. on here or on > python-ideas) relating to unpacking inside lambda expressions? > > I found myself wanting to write the following. > > ``` > map( > lambda (module, data): result.process(module, data), > jobs > ) > ``` > However, it's of course not legal Python syntax. > > The following were potential options but I felt they removed some of > the meaning from the code, making it less understandable for other > people. > > ``` > map( > lambda job: result.process(job[0], job[1]), > jobs > ) > ``` > > ``` > map( > lambda job: result.process(*job), > jobs > ) > ``` > > Secondly, for situations like these, do you have any go-to methods of > rewriting these while maintaining clarity? > > Kind Regards, > Sam Ezeh From loris.bennett at fu-berlin.de Wed Apr 20 02:18:00 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 20 Apr 2022 08:18:00 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <0b6be8d41b466ddd60787ddaecd26d063e961fc0.camel@anode.ca> <20220416084411.kkfjtz2bjl5wqo5o@hjp.at> <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <19bc3cf1-cd89-4f88-82ae-09983a502b9e@www.fastmail.com> Message-ID: <87sfq8nuqv.fsf@hornfels.zedat.fu-berlin.de> Random832 writes: > On Tue, Apr 19, 2022, at 07:11, Loris Bennett wrote: >> I now realise that timedelta is not really what I need. I am >> interested solely in pure periods, i.e. numbers of seconds, that I >> can convert back and forth from a format such as > > A timedelta *is* a pure period. A timedelta of one day is 86400 > seconds. > > The thing you *think* timedelta does [making a day act as 23 or 25 > hours across daylight saving boundaries etc], that you *don't* want it > to do, is something it *does not actually do*. I don't know how this > can be made more clear to you. I have now understood this. > timedelta is what you need. if you think it's not, it's because you're > using datetime incorrectly. It is what I need. It just doesn't do the trivial format conversion I (apparently incorrectly) expected. However, I can implement the format conversion myself. [snip (35 lines)] -- This signature is currently under construction. From loris.bennett at fu-berlin.de Wed Apr 20 02:35:24 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Wed, 20 Apr 2022 08:35:24 +0200 Subject: Why does datetime.timedelta only have the attributes 'days' and 'seconds'? References: <20220416160028.tmedahn64gdpzsov@hjp.at> <20220417072651.6tcttzdx4mhptv2v@hjp.at> <87ee1t49ae.fsf@hornfels.zedat.fu-berlin.de> <8735i944im.fsf@hornfels.zedat.fu-berlin.de> <87r15t2nci.fsf@hornfels.zedat.fu-berlin.de> <54pt5h55ee3b81oct6j35put5na51lk56h@4ax.com> Message-ID: <87o80wntxv.fsf@hornfels.zedat.fu-berlin.de> Dennis Lee Bieber writes: > On Tue, 19 Apr 2022 15:51:09 +0200, "Loris Bennett" > declaimed the following: > >>If I am merely trying to represent part a very large number of seconds >>as a number of years, 365 days per year does not seem that controversial > > The Explanatory Supplement to the Astronomical Almanac (table 15.3) > defines the /day/ as 24hrs->1440mins->86400secs BUT defines the Julian > /year/ as 365.25 days. That is interesting. However, I am not claiming that the definition of a year as 365 24-hour days is in any way correct, merely that it is a possible definition and one that is potentially handy if one wants to represent large numbers of seconds in a more readable way. > It goes on to also give (for my copy -- length of year at 1990): > Tropical (equinox to equinox) 365.2421897 days * > Sidereal (fixed star to fixed star) 365.25636 days > Anomalistic (perihelion to perihelion) 365.25964 days > Eclipse (moon's node to moon's node) 346.26005 > Gaussian (Kepler's law /a/=1) 365.25690 > Julian 365.25 > > Length of the month (I interpret this as lunar month): > Synodic (new moon to new moon) 29.53059 days > Tropical (as with year) 27.32158 > Sidereal (as with year) 27.32166 > Anomalistic (perigee to perigee) 27.55455 > Draconic (node to node) 27.21222 > > * I /think/ this is the year used for leap-day calculations, and why some > leap centuries are skipped as it is really less than a quarter day per > year, so eventually one gets to over-correcting by a day. > > Of course, this book also has a footnote giving the speed of light as > 1.80261750E12 Furlongs/Fortnight And of course I should have been asking why timedelta doesn't provide an easy way to format the period as a number of fortnights :-) > However, as soon you incorporate units that are not SI seconds you have > to differentiate between pure duration (based on SI seconds) and civil time > (which may jump when leap seconds are added/subtracted, time zones are > crossed, or daylight savings time goes into [or out of] effect). > > For the most part, Python's datetime module seems to account for civil > time concepts, not monotonic durations. That indeed seems to be the case and the lack of trivial formatting options for monotonic durations is what surprises me. > The Ada standard separates "duration" (as a measure of elapsed time, in > fixed point seconds) from "time" (a private type in Ada.Calendar -- which > does NOT define hours/minutes... It has Year 1901..2399, Month 1..12, Day > 1..31, Day_duration 0.0..86400.0). There are functions to create a Time > from components, split a Time into components, compare two times, add a > Duration to a Time, subtract a Duration from a Time, and subtract a Time > from a Time (getting a Duration). Oh, and a function to get Time from > system clock. Per the standard, the Time Zone used is implementation > defined (so one needs to read the implementation manual to find out what a > Time really notates). Of note: > """ > 26.a/1 > To be honest: {8652/0106} {AI95-00160-01} By "proper date" above we mean > that the given year has a month with the given day. For example, February > 29th is a proper date only for a leap year. We do not mean to include the > Seconds in this notion; in particular, we do not mean to require > implementations to check for the ?missing hour? that occurs when Daylight > Savings Time starts in the spring. > """ > """ > 43 > type Duration is delta implementation-defined range > implementation-defined; > """ > > GNAT provides an extension package GNAT.Calendar that adds > hour/minute/day-of-week and some other utilities... BUT > """ > procedure Split_At_Locale > (Date : Ada.Calendar.Time; > Year : out Ada.Calendar.Year_Number; > Month : out Ada.Calendar.Month_Number; > Day : out Ada.Calendar.Day_Number; > Hour : out Hour_Number; > Minute : out Minute_Number; > Second : out Second_Number; > Sub_Second : out Second_Duration); > -- Split a standard Ada.Calendar.Time value in date data (Year, Month, > Day) > -- and Time data (Hour, Minute, Second, Sub_Second). This version of > Split > -- utilizes the time zone and DST bias of the locale (equivalent to > Clock). > -- Due to this simplified behavior, the implementation does not require > -- expensive system calls on targets such as Windows. > -- WARNING: Split_At_Locale is no longer aware of historic events and > may > -- produce inaccurate results over DST changes which occurred in the > past. > """ -- This signature is currently under construction. From Joseph.Schachner at Teledyne.com Wed Apr 20 13:54:27 2022 From: Joseph.Schachner at Teledyne.com (Schachner, Joseph) Date: Wed, 20 Apr 2022 17:54:27 +0000 Subject: lambda issues Message-ID: Re: "...which takes a callable (the lambda here)" Python lamdas have some severe restrictions. In any place that takes a callable, if a lambda can't serve, just use def to write a function and use the function name. ---- Joseph S. Teledyne Confidential; Commercially Sensitive Business Data -----Original Message----- From: Python-list On Behalf Of python-list-request at python.org Sent: Wednesday, April 20, 2022 12:00 PM To: python-list at python.org Subject: Python-list Digest, Vol 223, Issue 20 ---External Email--- Send Python-list mailing list submissions to python-list at python.org To subscribe or unsubscribe via the World Wide Web, visit https://mail.python.org/mailman/listinfo/python-list or, via email, send a message with subject or body 'help' to python-list-request at python.org You can reach the person managing the list at python-list-owner at python.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Python-list digest..." From arj.python at gmail.com Wed Apr 20 14:22:04 2022 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Wed, 20 Apr 2022 22:22:04 +0400 Subject: Why no list as dict key? Message-ID: Greetings list, Using Python3.9, i cannot assign a list [1, 2] as key to a dictionary. Why is that so? Thanks in advanced! Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From sjeik_appie at hotmail.com Wed Apr 20 14:23:55 2022 From: sjeik_appie at hotmail.com (Albert-Jan Roskam) Date: Wed, 20 Apr 2022 20:23:55 +0200 Subject: Tuple unpacking inside lambda expressions In-Reply-To: Message-ID: On Apr 20, 2022 13:01, Sam Ezeh wrote: I went back to the code recently and I remembered what the problem was. I was using multiprocessing.Pool.pmap which takes a callable (the lambda here) so I wasn't able to use comprehensions or starmap Is there anything for situations like these? ===== Could it simply be: multiprocessing.Pool.pmap(lambda job: result.process(*job), jobs) From larry.martell at gmail.com Wed Apr 20 14:25:58 2022 From: larry.martell at gmail.com (Larry Martell) Date: Wed, 20 Apr 2022 14:25:58 -0400 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On Wed, Apr 20, 2022 at 2:23 PM Abdur-Rahmaan Janhangeer wrote: > > Greetings list, > > Using Python3.9, i cannot assign a list [1, 2] as key > to a dictionary. Why is that so? Thanks in advanced! Dict keys cannot be mutable. Use a tuple instead. From rosuav at gmail.com Wed Apr 20 14:28:41 2022 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 21 Apr 2022 04:28:41 +1000 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On Thu, 21 Apr 2022 at 04:23, Abdur-Rahmaan Janhangeer wrote: > > Greetings list, Greetings tuple, > Using Python3.9, i cannot assign a list [1, 2] as key > to a dictionary. Why is that so? Thanks in advanced! > Because a list can be changed, which would change what it's equal to: >>> spam = [1, 2] >>> ham = [1, 2, 3] >>> spam == ham False >>> spam.append(3) >>> spam == ham True If you use spam as a dict key, then mutate it in any way, it would break dict invariants of all kinds (eg you could also have used ham as a key, and then you'd have duplicate keys). Instead, use a tuple, which can't be mutated, is always equal to the same things, and is hashable, which means it can be used as a key: >>> spam = (1, 2) >>> ham = (1, 2, 3) >>> {spam: "spam", ham: "ham"} {(1, 2): 'spam', (1, 2, 3): 'ham'} ChrisA From sam.z.ezeh at gmail.com Wed Apr 20 15:28:41 2022 From: sam.z.ezeh at gmail.com (Sam Ezeh) Date: Wed, 20 Apr 2022 20:28:41 +0100 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: Repeating the above points, here is an example of what would happen if you tried. Dictionaries require their keys to be immutable as under-the-hood they use hash tables and they'd fail when the underlying values are allowed to change. ``` [sam at samtop]: ~>$ python Python 3.10.2 (main, Jan 15 2022, 19:56:27) [GCC 11.1.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import functools >>> import operator >>> class HashableList(list): ... def __hash__(self): ... return functools.reduce(operator.xor, [key * value for key, value in enumerate(self)], 5) ... >>> x = HashableList([1,2,3]) >>> y = HashableList([1,2,3]) >>> dictionary = {x: 5} >>> dictionary {[1, 2, 3]: 5} >>> dictionary[x] 5 >>> dictionary[y] 5 >>> x.append(4) >>> dictionary {[1, 2, 3, 4]: 5} >>> dictionary[x] Traceback (most recent call last): File "", line 1, in KeyError: [1, 2, 3, 4] >>> dictionary[y] Traceback (most recent call last): File "", line 1, in KeyError: [1, 2, 3] >>> ``` On Wed, 20 Apr 2022 at 19:23, Abdur-Rahmaan Janhangeer wrote: > > Greetings list, > > Using Python3.9, i cannot assign a list [1, 2] as key > to a dictionary. Why is that so? Thanks in advanced! > > Kind Regards, > > Abdur-Rahmaan Janhangeer > about | blog > > github > Mauritius > -- > https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Wed Apr 20 15:49:33 2022 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 21 Apr 2022 05:49:33 +1000 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On Thu, 21 Apr 2022 at 05:30, Sam Ezeh wrote: > > Repeating the above points, here is an example of what would happen if > you tried. Dictionaries require their keys to be immutable as > under-the-hood they use hash tables and they'd fail when the > underlying values are allowed to change. > > ``` > >>> class HashableList(list): > ... def __hash__(self): > ... return functools.reduce(operator.xor, [key * value for > key, value in enumerate(self)], 5) Quickie: I'd be inclined to define hash on top of a tuple's hash, rather than try to design my own and hope that it's suitable. "return hash(tuple(self))" is a good demonstration of the parallel. Otherwise, good demonstration of the problem. ChrisA From avigross at verizon.net Wed Apr 20 16:18:49 2022 From: avigross at verizon.net (Avi Gross) Date: Wed, 20 Apr 2022 20:18:49 +0000 (UTC) Subject: Why no list as dict key? In-Reply-To: References: Message-ID: <1278120400.1002892.1650485929612@mail.yahoo.com> This does raise an issue, Chris, if you use the method of making a tuple?companion for a list at a specific time just for use as a dictionary key,?then later change the list, you can end up with various situations. Obviously the changed list can not only not access the stored item, but if converted?again to a tuple, may address a different item. I can see many scenarios with?abandoned dictionary items that are never deleted and can only be reached?by examining all items in the dictionary. So mutability is only one concern. If you actually mutate your data, ... I am thinking as an example about a program I wrote ages ago that?deals with equations in symbolic form and maintains a collection of?forms of the equation it is trying to take a derivative or integral of?by applying an assortment of typographic rules. I mean commutative lawand others. You do not want to? keep adding the same item into the data structure?(such as a queue) repeatedly. So something like a dictionary (or set) can be a?good way to store unique items. But the items are some complex lists so the?above discussion qualifies. Of course the tuple conversion for a nested structure?would need to have made a deep copy.? The question in the above is how to make sure that taking a next attempt off the?queue deals with the dictionary of tried items. In this case, unless you use it to find?a solution, keeping it in the dictionary to avoid repeating, makes sense.? And another thought is that mapping a list to a tuple has another possible drawback. What if I have both a list and tuple with the same structure which I want as keys? I can imagine then converting the list in some imaginative ways. For example,?embed the list in another list whose first item is "from-tuple" or something.? Life is complicated. Then you die. -----Original Message----- From: Chris Angelico To: python-list at python.org Sent: Wed, Apr 20, 2022 3:49 pm Subject: Re: Why no list as dict key? On Thu, 21 Apr 2022 at 05:30, Sam Ezeh wrote: > > Repeating the above points, here is an example of what would happen if > you tried. Dictionaries require their keys to be immutable as > under-the-hood they use hash tables and they'd fail when the > underlying values are allowed to change. > > ``` > >>> class HashableList(list): > ...? ? def __hash__(self): > ...? ? ? ? ? ? return functools.reduce(operator.xor, [key * value for > key, value in enumerate(self)], 5) Quickie: I'd be inclined to define hash on top of a tuple's hash, rather than try to design my own and hope that it's suitable. "return hash(tuple(self))" is a good demonstration of the parallel. Otherwise, good demonstration of the problem. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From rosuav at gmail.com Wed Apr 20 16:43:00 2022 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 21 Apr 2022 06:43:00 +1000 Subject: Why no list as dict key? In-Reply-To: <1278120400.1002892.1650485929612@mail.yahoo.com> References: <1278120400.1002892.1650485929612@mail.yahoo.com> Message-ID: On Thu, 21 Apr 2022 at 06:20, Avi Gross via Python-list wrote: > > This does raise an issue, Chris, if you use the method of making a tuple companion for a list at a specific time just for use as a dictionary key, then later change the list, you can end up with various situations. > Yes. And those situations are *exactly* why you can't use a list as a key. > Obviously the changed list can not only not access the stored item, but if converted again to a tuple, may address a different item. I can see many scenarios with abandoned dictionary items that are never deleted and can only be reached by examining all items in the dictionary. > So mutability is only one concern. If you actually mutate your data, ... And if you don't mutate your data, use a tuple. ChrisA From greg.ewing at canterbury.ac.nz Wed Apr 20 19:06:31 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 21 Apr 2022 11:06:31 +1200 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On 21/04/22 6:22 am, Abdur-Rahmaan Janhangeer wrote: > Using Python3.9, i cannot assign a list [1, 2] as key > to a dictionary. Why is that so? If the contents of the list were to change after using it as a key, its hash value would no longer match its position in the dict, so subsequent lookups could fail to find it. -- Greg From greg.ewing at canterbury.ac.nz Wed Apr 20 22:05:12 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Thu, 21 Apr 2022 14:05:12 +1200 Subject: Why no list as dict key? In-Reply-To: References: <1278120400.1002892.1650485929612@mail.yahoo.com> Message-ID: On 21/04/22 8:18 am, Avi Gross wrote: > I am thinking as an example about a program I wrote ages ago that?deals with equations in symbolic form and maintains a collection of?forms of the equation it is trying to take a derivative or integral of?by applying an assortment of typographic rules. It sounds like you would be better off making all your equation data structures immutable. Instead of mutating the equation when making a transformation, return a new equation. Then you can use sets and dicts to cache them etc. without any problems. -- Greg From arj.python at gmail.com Wed Apr 20 22:22:53 2022 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Thu, 21 Apr 2022 06:22:53 +0400 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: Thanks everybody, In the the event spam is appended a value, then looking for [1,2] does not return anything but looking for [1,2,3] yes. But i gather the way dictionaries are implemented makes it difficult to do so ... Maybe hashes should point to an object rather than being the hash of an object themselves. Maybe the speed drop is not worth it. Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius On Wed, Apr 20, 2022 at 10:35 PM Chris Angelico wrote: > On Thu, 21 Apr 2022 at 04:23, Abdur-Rahmaan Janhangeer > wrote: > > > > Greetings list, > > Greetings tuple, > > > Using Python3.9, i cannot assign a list [1, 2] as key > > to a dictionary. Why is that so? Thanks in advanced! > > > > Because a list can be changed, which would change what it's equal to: > > >>> spam = [1, 2] > >>> ham = [1, 2, 3] > >>> spam == ham > False > >>> spam.append(3) > >>> spam == ham > True > > If you use spam as a dict key, then mutate it in any way, it would > break dict invariants of all kinds (eg you could also have used ham as > a key, and then you'd have duplicate keys). > > Instead, use a tuple, which can't be mutated, is always equal to the > same things, and is hashable, which means it can be used as a key: > > >>> spam = (1, 2) > >>> ham = (1, 2, 3) > >>> {spam: "spam", ham: "ham"} > {(1, 2): 'spam', (1, 2, 3): 'ham'} > > ChrisA > -- > https://mail.python.org/mailman/listinfo/python-list > From 2QdxY4RzWzUUiLuE at potatochowder.com Wed Apr 20 22:48:37 2022 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Wed, 20 Apr 2022 21:48:37 -0500 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On 2022-04-21 at 06:22:53 +0400, Abdur-Rahmaan Janhangeer wrote: > Maybe hashes should point to an object rather than being the hash of an > object themselves. > Maybe the speed drop is not worth it. Then you have a different problem. x = [1, 2, 3] y = [n for n in 1, 2, 3] Those two lists (x and y) are separate but equal objects. Being separate, pointers to them would not be equal. Being equal, they have to have the same hash. From arj.python at gmail.com Wed Apr 20 23:21:57 2022 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Thu, 21 Apr 2022 07:21:57 +0400 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: Assumes checking for object equality before inserting. If they are they same, do we need different hashes? Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius On Thu, Apr 21, 2022 at 7:15 AM <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > On 2022-04-21 at 06:22:53 +0400, > Abdur-Rahmaan Janhangeer wrote: > > > Maybe hashes should point to an object rather than being the hash of an > > object themselves. > > Maybe the speed drop is not worth it. > > Then you have a different problem. > > x = [1, 2, 3] > y = [n for n in 1, 2, 3] > > Those two lists (x and y) are separate but equal objects. Being > separate, pointers to them would not be equal. Being equal, they have > to have the same hash. > -- > https://mail.python.org/mailman/listinfo/python-list > From drsalists at gmail.com Wed Apr 20 23:28:46 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 20 Apr 2022 20:28:46 -0700 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On Wed, Apr 20, 2022 at 7:23 PM Abdur-Rahmaan Janhangeer < arj.python at gmail.com> wrote: > Maybe hashes should point to an object rather than being the hash of an > object themselves. > Maybe the speed drop is not worth it. > If you need mutable keys, you /might/ create a dict-like-object using what functional languages call an association list. But these have O(n) lookups, not O(1) like a dict (AKA hash table). And even then, if you have keys a and b, a != b, and you modify b to look just like a, you could get a bit of a mess from the two equal keys mapping to two different values. It is possible to have a dict that allows duplicates though. Usually that's not what you want, but sometimes it is, EG: https://stromberg.dnsalias.org/~strombrg/dupdict_mod/ Trees have much the same issue as a dict (hash table) in this case. These are O(logn) or so. The problem is hash tables and trees don't want keys changing "out from under them". It causes things they're assuming are invariant, to vary. From rosuav at gmail.com Thu Apr 21 01:00:03 2022 From: rosuav at gmail.com (Chris Angelico) Date: Thu, 21 Apr 2022 15:00:03 +1000 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: On Thu, 21 Apr 2022 at 13:23, Abdur-Rahmaan Janhangeer wrote: > > Assumes checking for object equality before inserting. > If they are they same, do we need different hashes? > The point of the hash is to find things that are equal. That's why 1234, 1234.0, and 0j+1234.0 all have the same hash. If equality changes, the hash does too. It's certainly possible to have the hash come from object identity, but then so must equality. If you want that, it's easy to do - just create your own object for the state, rather than using a list. But then you have to use the original object to look things up, instead of matching by the data. Hashes are simply a short-hand for equality. That's all. ChrisA From arj.python at gmail.com Thu Apr 21 01:29:52 2022 From: arj.python at gmail.com (Abdur-Rahmaan Janhangeer) Date: Thu, 21 Apr 2022 09:29:52 +0400 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: As clear as daylight, thanks! Kind Regards, Abdur-Rahmaan Janhangeer about | blog github Mauritius From __peter__ at web.de Thu Apr 21 09:53:01 2022 From: __peter__ at web.de (Peter Otten) Date: Thu, 21 Apr 2022 15:53:01 +0200 Subject: Tuple unpacking inside lambda expressions In-Reply-To: References: Message-ID: <021e6ba1-d718-ae9e-efe9-3a8521b57b19@web.de> On 20/04/2022 13:01, Sam Ezeh wrote: > I went back to the code recently and I remembered what the problem was. > > I was using multiprocessing.Pool.pmap which takes a callable (the > lambda here) so I wasn't able to use comprehensions or starmap > > Is there anything for situations like these? Hm, I don't see pmap, but there is a starmap(): https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool.starmap From ojomooluwatolami675 at gmail.com Thu Apr 21 13:01:32 2022 From: ojomooluwatolami675 at gmail.com (Tola Oj) Date: Thu, 21 Apr 2022 18:01:32 +0100 Subject: code issue Message-ID: given a number n, for each integer i in the range from 1 to n inclusive, print one value per line as follows: . if i is a multiple of both 3 but not 5, print fizz. .if i is a multiple of 5 but not 3, print buzz .if i is not a multiple of 3 or 5, print the value of i. the above is the question. the below is my answer, but it keeps saying I'm failing it and this is the output my code keeps giving me: it passes my input n (Which was 13) and starts to print from 1 again. please help - 1 - 2 - Fizz - 4 - Buzz - Fizz - 7 - 8 - Fizz - Buzz - 11 - Fizz - 13 - 1 - 2 - Fizz - 4 - Buzz - Fizz - 7 - 8 - Fizz - Buzz - 11 - Fizz - 13 - 14 - Fizzbuzz for i in range(1, n+1): if i % 3 == 0 and i % 5 == 0: print("Fizzbuzz") elif i % 3 == 0: print("Fizz") elif i % 5 == 0: print("Buzz") else: print(i) print(i, sep='\n') fizzbuzz(13) From rosuav at gmail.com Thu Apr 21 13:09:25 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 22 Apr 2022 03:09:25 +1000 Subject: code issue In-Reply-To: References: Message-ID: On Fri, 22 Apr 2022 at 03:02, Tola Oj wrote: > > for i in range(1, n+1): > if i % 3 == 0 and i % 5 == 0: > print("Fizzbuzz") > elif i % 3 == 0: > print("Fizz") > elif i % 5 == 0: > print("Buzz") > else: > print(i) > print(i, sep='\n') > > fizzbuzz(13) This can't be your complete code, because it won't run like this. Have a very careful read through of your code, and consider adding some extra print statements to see what's happening; but if you're asking for help, you'll definitely need to post the entire program. ChrisA From tdldev at gmail.com Thu Apr 21 14:17:54 2022 From: tdldev at gmail.com (Jack Dangler) Date: Thu, 21 Apr 2022 14:17:54 -0400 Subject: code issue In-Reply-To: References: Message-ID: On 4/21/22 13:09, Chris Angelico wrote: > On Fri, 22 Apr 2022 at 03:02, Tola Oj wrote: >> for i in range(1, n+1): >> if i % 3 == 0 and i % 5 == 0: >> print("Fizzbuzz") >> elif i % 3 == 0: >> print("Fizz") >> elif i % 5 == 0: >> print("Buzz") >> else: >> print(i) >> print(i, sep='\n') >> >> fizzbuzz(13) > This can't be your complete code, because it won't run like this. Have > a very careful read through of your code, and consider adding some > extra print statements to see what's happening; but if you're asking > for help, you'll definitely need to post the entire program. > > ChrisA fizzbuzz is one of Angela Yu's lab assignments in her py course.If you ask her, she'll gladly tell you where you are going wrong and even supply an entirely correct version, if you want it... From rosuav at gmail.com Thu Apr 21 14:20:16 2022 From: rosuav at gmail.com (Chris Angelico) Date: Fri, 22 Apr 2022 04:20:16 +1000 Subject: code issue In-Reply-To: References: Message-ID: On Fri, 22 Apr 2022 at 04:19, Jack Dangler wrote: > > > On 4/21/22 13:09, Chris Angelico wrote: > > On Fri, 22 Apr 2022 at 03:02, Tola Oj wrote: > >> for i in range(1, n+1): > >> if i % 3 == 0 and i % 5 == 0: > >> print("Fizzbuzz") > >> elif i % 3 == 0: > >> print("Fizz") > >> elif i % 5 == 0: > >> print("Buzz") > >> else: > >> print(i) > >> print(i, sep='\n') > >> > >> fizzbuzz(13) > > This can't be your complete code, because it won't run like this. Have > > a very careful read through of your code, and consider adding some > > extra print statements to see what's happening; but if you're asking > > for help, you'll definitely need to post the entire program. > > > > ChrisA > fizzbuzz is one of Angela Yu's lab assignments in her py course.If you > ask her, she'll gladly tell you where you are going wrong and even > supply an entirely correct version, if you want it... Fizz Buzz is a very common assignment. The point isn't to get a correct version, the point is to understand what it's doing :) ChrisA From greg.ewing at canterbury.ac.nz Thu Apr 21 17:58:41 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 22 Apr 2022 09:58:41 +1200 Subject: code issue In-Reply-To: References: Message-ID: On 22/04/22 5:09 am, Chris Angelico wrote: > This can't be your complete code, because it won't run like this. Also, the output you showed contains blank lines and lines with hyphens, and there is nothing in the code you posted which does that. If I had to guess, I'd say you have a loop which is supposed to repeatedly read a value for n and then compute fizzbuzz, and you have the input statement in the wrong place. -- Greg From greg.ewing at canterbury.ac.nz Thu Apr 21 18:00:43 2022 From: greg.ewing at canterbury.ac.nz (Greg Ewing) Date: Fri, 22 Apr 2022 10:00:43 +1200 Subject: Enums and nested classes In-Reply-To: References: Message-ID: On 20/04/22 10:57 pm, Sam Ezeh wrote: > Has anyone here used or attempted to use a nested class inside an enum? > > If so, how did you find it? (what did you expect to happen and did > your expectations align with resulting behaviour etc.) That's a pretty open-ended question. Is there something about its current behaviour that you think should be different? -- Greg From gd75291 at gmail.com Thu Apr 21 21:57:24 2022 From: gd75291 at gmail.com (Greg) Date: Thu, 21 Apr 2022 21:57:24 -0400 Subject: Having trouble getting Hello World to appear In-Reply-To: References: Message-ID: I downloaded and installed the auto version of the software. I go to the director C:\google-python-exercises> *python hello.py* I am running Windows. What am I doing incorrectly? I had the zip file installed under my One Drive and then moved it to my C drive Patiently waiting, Greg From ethan at stoneleaf.us Thu Apr 21 22:19:36 2022 From: ethan at stoneleaf.us (Ethan Furman) Date: Thu, 21 Apr 2022 19:19:36 -0700 Subject: Enums and nested classes In-Reply-To: References: Message-ID: On 4/21/22 15:00, Greg Ewing wrote: > On 20/04/22 10:57 pm, Sam Ezeh wrote: >> Has anyone here used or attempted to use a nested class inside an enum? >> >> If so, how did you find it? (what did you expect to happen and did >> your expectations align with resulting behaviour etc.) > > That's a pretty open-ended question. Is there something about > its current behaviour that you think should be different? Indeed -- the point of the question is to (hopefully) find out what folks have already tried, and whether they found the current behavior surprising. We're looking for what happened in practice, not for what should happen in theory. ;-) And of course, no one using enums that way means we can change how that bit works fairly easily. -- ~Ethan~ From python at mrabarnett.plus.com Thu Apr 21 22:33:51 2022 From: python at mrabarnett.plus.com (MRAB) Date: Fri, 22 Apr 2022 03:33:51 +0100 Subject: Having trouble getting Hello World to appear In-Reply-To: References: Message-ID: <0d0f32c6-a89f-6a83-ad88-24484c9a5d48@mrabarnett.plus.com> On 2022-04-22 02:57, Greg wrote: > I downloaded and installed the auto version of the software. > "auto version"? > I go to the director C:\google-python-exercises> *python hello.py* > > I am running Windows. > > > > What am I doing incorrectly? > I don't know, because you didn't say what did or didn't happen. Did it say it couldn't find Python? If yes, try the Python Launcher instead: py hello.py > > > I had the zip file installed under my One Drive and then moved it to my C > drive > From ojomooluwatolami675 at gmail.com Fri Apr 22 06:11:32 2022 From: ojomooluwatolami675 at gmail.com (Tola Oj) Date: Fri, 22 Apr 2022 11:11:32 +0100 Subject: struggle to upgrade pip on visual studio code Message-ID: hello, i successfully installed openpyxl but it is saying this about my pip: WARNING: You are using pip version 22.0.2; however, version 22.0.4 is available.You should consider upgrading via the 'C:\Program Files\Python310\python.exe -m pip install --upgrade pip' command. And then when I try to upgrade using 'C:\Program Files\Python310\python.exe -m pip install --upgrade pip command it says this: C:\Program : The term 'C:\Program' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + C:\Program Files\Python310\python.exe -m pip install --upgrade pip+ ~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (C:\Program:String) [], Comma ndNotFoundException + FullyQualifiedErrorId : CommandNotFoundException please what do I do? From Richard at Damon-Family.org Fri Apr 22 06:50:42 2022 From: Richard at Damon-Family.org (Richard Damon) Date: Fri, 22 Apr 2022 06:50:42 -0400 Subject: struggle to upgrade pip on visual studio code In-Reply-To: References: Message-ID: <4b7a96c7-339c-e1fa-25ae-2c4201a1e83e@Damon-Family.org> On 4/22/22 6:11 AM, Tola Oj wrote: > hello, i successfully installed openpyxl but it is saying this about my pip: > > WARNING: You are using pip version 22.0.2; however, version 22.0.4 is > available.You should consider upgrading via the 'C:\Program > Files\Python310\python.exe -m pip install --upgrade pip' command. > > And then when I try to upgrade using 'C:\Program Files\Python310\python.exe > -m pip install --upgrade pip command it says this: > > C:\Program : The term 'C:\Program' is not recognized as the name of a > > cmdlet, function, script file, or operable program. Check the spelling of > > the name, or if a path was included, verify that the path is correct and > > try again. > At line:1 char:1 > + C:\Program Files\Python310\python.exe -m pip install --upgrade pip+ > ~~~~~~~~~~ > + CategoryInfo : ObjectNotFound: (C:\Program:String) [], Comma > > ndNotFoundException > + FullyQualifiedErrorId : CommandNotFoundException > > please what do I do? When a program name/path includes spaces, you need to put the whole name in quotes, like "C:\Program Files\Python310\python.exe" -m pip install --upgrade Now, if python is on your path (and 3.10 is the first python found), you should be able to simpify that to python -m pip install --upgrade -- Richard Damon From krlinus at yahoo.com Fri Apr 22 01:28:52 2022 From: krlinus at yahoo.com (Sunil KR) Date: Fri, 22 Apr 2022 05:28:52 +0000 (UTC) Subject: How to have python 2 and 3 both on windows? In-Reply-To: <961537273.97366.1650604079384@mail.yahoo.com> References: <961537273.97366.1650604079384.ref@mail.yahoo.com> <961537273.97366.1650604079384@mail.yahoo.com> Message-ID: <1766896259.80347.1650605332904@mail.yahoo.com> I have some scripts that are old and won't work under python2 and at the same time I am writing new scripts which will use python3. However, if python 2 and 3 cannot co-exist in a windows box it will be impossible to transition What I try:- remove all pythons and launchers- Use windows installer and install python2 in python27 directory- Use windows installer and install python3 in python310 directory- When installing python3 I opt in to install the launcher- Test with py -2 and py -3 and see that I get the expected prompt- just typing python gets me python2 From barry at barrys-emacs.org Fri Apr 22 12:57:03 2022 From: barry at barrys-emacs.org (Barry) Date: Fri, 22 Apr 2022 17:57:03 +0100 Subject: How to have python 2 and 3 both on windows? In-Reply-To: <1766896259.80347.1650605332904@mail.yahoo.com> References: <1766896259.80347.1650605332904@mail.yahoo.com> Message-ID: <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> > On 22 Apr 2022, at 17:10, Sunil KR via Python-list wrote: > > ?I have some scripts that are old and won't work under python2 and at the same time I am writing new scripts which will use python3. However, if python 2 and 3 cannot co-exist in a windows box it will be impossible to transition > What I try:- remove all pythons and launchers- Use windows installer and install python2 in python27 directory- Use windows installer and install python3 in python310 directory- When installing python3 I opt in to install the launcher- Test with py -2 and py -3 and see that I get the expected prompt- just typing python gets me python2 As you have proved you can install many versions of python at the same time on windows. In your scripts set the shebang to run the python version you want. E.g #!/usr/bin/python2 Or #!/usr/bin/python3 The python launcher py.exe will then do the right thing after looking at en shebang line. Also you can edit the INI file of the py.exe launcher to set the defaults the way you want them. Do a search for ?py.exe ini? to file the path to the file, I do not have it my finger tips. Tip ?py.exe -0? will list the state of installed pythons. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From krlinus at yahoo.com Fri Apr 22 13:17:52 2022 From: krlinus at yahoo.com (Sunil KR) Date: Fri, 22 Apr 2022 17:17:52 +0000 (UTC) Subject: How to have python 2 and 3 both on windows? In-Reply-To: <1766896259.80347.1650605332904@mail.yahoo.com> References: <961537273.97366.1650604079384.ref@mail.yahoo.com> <961537273.97366.1650604079384@mail.yahoo.com> <1766896259.80347.1650605332904@mail.yahoo.com> Message-ID: <404643965.199417.1650647872236@mail.yahoo.com> Please excuse the formatting in my previous message. And it is not complete even, so here is the rest of it. What happens after I follow the above steps: - Upon running one of my python 2 scripts (using python2), I see this error: ? ? """? ? ? ?^SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 237-238: truncated \uXXXX escape I tried for a bit, but I could not isolate the content of the file that may be causing this problem. But any idea about this problem would be greatly appreciated. Removing python3 solves this issue.. Sunil On Friday, April 22, 2022, 09:09:22 AM PDT, Sunil KR via Python-list wrote: I have some scripts that are old and won't work under python2 and at the same time I am writing new scripts which will use python3. However, if python 2 and 3 cannot co-exist in a windows box it will be impossible to transition What I try:- remove all pythons and launchers- Use windows installer and install python2 in python27 directory- Use windows installer and install python3 in python310 directory- When installing python3 I opt in to install the launcher- Test with py -2 and py -3 and see that I get the expected prompt- just typing python gets me python2 -- https://mail.python.org/mailman/listinfo/python-list From gisle.vanem at gmail.com Fri Apr 22 13:40:11 2022 From: gisle.vanem at gmail.com (Gisle Vanem) Date: Fri, 22 Apr 2022 19:40:11 +0200 Subject: How to have python 2 and 3 both on windows? In-Reply-To: <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> Message-ID: <158e681e-51da-f120-5a05-05249981e82d@gmail.com> Barry wrote: > Tip ?py.exe -0? will list the state of installed pythons. Not here; 'py.exe -0' gives: Requested Python version (0) not installed Which PyInstaller version support this '-0' option? -- --gv From mats at wichmann.us Fri Apr 22 14:16:20 2022 From: mats at wichmann.us (Mats Wichmann) Date: Fri, 22 Apr 2022 12:16:20 -0600 Subject: How to have python 2 and 3 both on windows? In-Reply-To: <158e681e-51da-f120-5a05-05249981e82d@gmail.com> References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> <158e681e-51da-f120-5a05-05249981e82d@gmail.com> Message-ID: <2251d888-fcd5-6359-f3c4-0cedee45e2d6@wichmann.us> On 4/22/22 11:40, Gisle Vanem wrote: > Barry wrote: > >> Tip ?py.exe -0? will list the state of installed pythons. > Not here; 'py.exe -0' gives: > ? Requested Python version (0) not installed > > Which PyInstaller version support this '-0' option? > Looks like this got added around 3.7... https://bugs.python.org/issue30362 From michael.stemper at gmail.com Fri Apr 22 15:36:27 2022 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Fri, 22 Apr 2022 14:36:27 -0500 Subject: Style for docstring Message-ID: I'm writing a function that is nearly self-documenting by its name, but still want to give it a docstring. Which of these would be best from a stylistic point of view: Tells caller whether or not a permutation is even. Determines if a permutation is even. (Alternative is that it's odd.) Returns True if permutation is even, False if it is odd. (Before somebody suggests it, I'm not going to put six weeks' worth of a course in group theory in there to help somebody who doesn't know what those standard terms mean.) -- Michael F. Stemper 87.3% of all statistics are made up by the person giving them. From rosuav at gmail.com Fri Apr 22 15:59:05 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 23 Apr 2022 05:59:05 +1000 Subject: Style for docstring In-Reply-To: References: Message-ID: On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper wrote: > > I'm writing a function that is nearly self-documenting by its name, > but still want to give it a docstring. Which of these would be > best from a stylistic point of view: > > > Tells caller whether or not a permutation is even. > > Determines if a permutation is even. (Alternative is that it's odd.) > > Returns True if permutation is even, False if it is odd. > > > (Before somebody suggests it, I'm not going to put six weeks' worth > of a course in group theory in there to help somebody who doesn't > know what those standard terms mean.) > I'd go with the third one, but "Return" rather than "Returns". Or possibly "Test whether a permutation is even". That's just one opinion though, others may disagree :) ChrisA From ethan at stoneleaf.us Fri Apr 22 16:00:26 2022 From: ethan at stoneleaf.us (Ethan Furman) Date: Fri, 22 Apr 2022 13:00:26 -0700 Subject: Style for docstring In-Reply-To: References: Message-ID: <8209d20c-3953-abb0-3acf-694d52b80434@stoneleaf.us> On 4/22/22 12:36, Michael F. Stemper wrote: > ? Tells caller whether or not a permutation is even. > > ? Determines if a permutation is even. (Alternative is that it's odd.) > > ? Returns True if permutation is even, False if it is odd. Third option. -- ~Ethan~ From michael.stemper at gmail.com Fri Apr 22 16:35:15 2022 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Fri, 22 Apr 2022 15:35:15 -0500 Subject: Style for docstring In-Reply-To: References: Message-ID: On 22/04/2022 14.59, Chris Angelico wrote: > On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper > wrote: >> >> I'm writing a function that is nearly self-documenting by its name, >> but still want to give it a docstring. Which of these would be >> best from a stylistic point of view: >> >> >> Tells caller whether or not a permutation is even. >> >> Determines if a permutation is even. (Alternative is that it's odd.) >> >> Returns True if permutation is even, False if it is odd. > > I'd go with the third one, but "Return" rather than "Returns". Or > possibly "Test whether a permutation is even". "So let it be written. So let it be done." > That's just one opinion though, others may disagree :) Two for two. Thanks. -- Michael F. Stemper Always remember that you are unique. Just like everyone else. From alister.ware at ntlworld.com Fri Apr 22 17:12:56 2022 From: alister.ware at ntlworld.com (alister) Date: Fri, 22 Apr 2022 21:12:56 -0000 (UTC) Subject: Style for docstring References: Message-ID: On Fri, 22 Apr 2022 14:36:27 -0500, Michael F. Stemper wrote: > I'm writing a function that is nearly self-documenting by its name, > but still want to give it a docstring. Which of these would be best from > a stylistic point of view: > > > Tells caller whether or not a permutation is even. > > Determines if a permutation is even. (Alternative is that it's odd.) > > Returns True if permutation is even, False if it is odd. > > > (Before somebody suggests it, I'm not going to put six weeks' worth of a > course in group theory in there to help somebody who doesn't know what > those standard terms mean.) four guidance I would sugest Pep257 as a start point which would suggest "Return True if permutation is even" -- I think my career is ruined! From barry at barrys-emacs.org Fri Apr 22 17:58:31 2022 From: barry at barrys-emacs.org (Barry) Date: Fri, 22 Apr 2022 22:58:31 +0100 Subject: How to have python 2 and 3 both on windows? In-Reply-To: <158e681e-51da-f120-5a05-05249981e82d@gmail.com> References: <158e681e-51da-f120-5a05-05249981e82d@gmail.com> Message-ID: > On 22 Apr 2022, at 18:43, Gisle Vanem wrote: > > ?Barry wrote: > >> Tip ?py.exe -0? will list the state of installed pythons. > Not here; 'py.exe -0' gives: > Requested Python version (0) not installed > > Which PyInstaller version support this '-0' option? I do not when it was first added all the installs I have done in the last few years have it working. Barry > > -- > --gv > -- > https://mail.python.org/mailman/listinfo/python-list From 2QdxY4RzWzUUiLuE at potatochowder.com Fri Apr 22 18:22:33 2022 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Fri, 22 Apr 2022 17:22:33 -0500 Subject: Style for docstring In-Reply-To: References: Message-ID: On 2022-04-22 at 15:35:15 -0500, "Michael F. Stemper" wrote: > On 22/04/2022 14.59, Chris Angelico wrote: > > On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper > > wrote: > > > > > > I'm writing a function that is nearly self-documenting by its name, > > > but still want to give it a docstring. Which of these would be > > > best from a stylistic point of view: > > > > > > > > > Tells caller whether or not a permutation is even. > > > > > > Determines if a permutation is even. (Alternative is that it's odd.) > > > > > > Returns True if permutation is even, False if it is odd. > > > > > > I'd go with the third one, but "Return" rather than "Returns". Or > > possibly "Test whether a permutation is even". > > "So let it be written. So let it be done." "Test whether a permutation is even," while technically factual, leaves the reader to wonder what form the result takes, and what happens to that result. Yes, we'd all like to think that programmers are smart enough to *assume* that the function returns the result of the test. I've also seen functions that perform tests and then print the results out, or write them to a database, or simply execute the tests for their side effects (or leave it up to the individual tests to do something with the result). Do you want callers of the function also to assume that True means that the permutation is even? There are other reasonable strategies, such as an enumerated type (whose items are Even, Odd, and FileNotFound), or throwing an exception if the permutation is odd. I prefer the "return" (rather than "returns") version of the third option. Assuming that the programmers are familiar with the domain, the other two leave out important information. From ojomooluwatolami675 at gmail.com Fri Apr 22 18:22:56 2022 From: ojomooluwatolami675 at gmail.com (Tola Oj) Date: Fri, 22 Apr 2022 23:22:56 +0100 Subject: upgrade pip Message-ID: im trying to upgrade my pip so i can install openpyxl. i though i had successfully upgraded pip, and then I was trying to install openpyxl, but I was getting this: C:\Users\ojomo>"C:\Program Files\Python310\python.exe" -m pip install --upgrade Traceback (most recent call last): File "C:\Program Files\Python310\lib\runpy.py", line 196, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Program Files\Python310\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\__main__.py", line 29, in from pip._internal.cli.main import main as _main File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\cli\main.py", line 9, in from pip._internal.cli.autocompletion import autocomplete File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\cli\autocompletion.py", line 10, in from pip._internal.cli.main_parser import create_main_parser File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\cli\main_parser.py", line 8, in from pip._internal.cli import cmdoptions File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\cli\cmdoptions.py", line 23, in from pip._internal.cli.parser import ConfigOptionParser File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\cli\parser.py", line 12, in from pip._internal.configuration import Configuration, ConfigurationError File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\configuration.py", line 20, in from pip._internal.exceptions import ( File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_internal\exceptions.py", line 13, in from pip._vendor.requests.models import Request, Response File "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_vendor\requests\__init__.py", line 43, in from pip._vendor import urllib3 ImportError: cannot import name 'urllib3' from 'pip._vendor' (C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\_vendor\__init__.py) and then I realised no matter what I type into the terminal (for example if I'm trying to check what version pip is, or I'm to import another module), it will print out this same specific lines of code. From rosuav at gmail.com Fri Apr 22 18:33:37 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 23 Apr 2022 08:33:37 +1000 Subject: Style for docstring In-Reply-To: References: Message-ID: On Sat, 23 Apr 2022 at 08:24, <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > > On 2022-04-22 at 15:35:15 -0500, > "Michael F. Stemper" wrote: > > > On 22/04/2022 14.59, Chris Angelico wrote: > > > On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper > > > wrote: > > > > > > > > I'm writing a function that is nearly self-documenting by its name, > > > > but still want to give it a docstring. Which of these would be > > > > best from a stylistic point of view: > > > > > > > > > > > > Tells caller whether or not a permutation is even. > > > > > > > > Determines if a permutation is even. (Alternative is that it's odd.) > > > > > > > > Returns True if permutation is even, False if it is odd. > > > > > > > > > > I'd go with the third one, but "Return" rather than "Returns". Or > > > possibly "Test whether a permutation is even". > > > > "So let it be written. So let it be done." > > "Test whether a permutation is even," while technically factual, leaves > the reader to wonder what form the result takes, and what happens to > that result. While it's definitely possible to have other results and other ways to deliver them, the return of a boolean would be the most obvious default. > Do you want callers of the function also to assume that True means that > the permutation is even? There are other reasonable strategies, such as > an enumerated type (whose items are Even, Odd, and FileNotFound), or > throwing an exception if the permutation is odd. I'm assuming that the function is called something like "is_even()" and that it either is a method on a permutation object, or its parameters make it very clear what the permutation is. If it returns an enumeration, I would say that in the docstring. If the docstring doesn't say, I would assume it returns True or False. > I prefer the "return" (rather than "returns") version of the third > option. Assuming that the programmers are familiar with the domain, the > other two leave out important information. Core Python methods and functions seem to prefer either "Return ..." or "Verb the thing" where the result is implicit (eg str.zfill.__doc__ which says "Pad a numeric string..."). Both are used extensively. Neither form leaves out anything that wouldn't be the obvious default. We don't need to say "Figures out algorithmically whether the permutation is even. If it is, will return True; if it isn't, will return False; if something goes wrong, will raise an exception". This is Python; we know that if something goes wrong, an exception is raised. (Though it can help to say WHICH exception will be raised under WHAT circumstances). Some things are obvious. ChrisA From 2QdxY4RzWzUUiLuE at potatochowder.com Fri Apr 22 19:01:43 2022 From: 2QdxY4RzWzUUiLuE at potatochowder.com (2QdxY4RzWzUUiLuE at potatochowder.com) Date: Fri, 22 Apr 2022 18:01:43 -0500 Subject: Style for docstring In-Reply-To: References: Message-ID: On 2022-04-23 at 08:33:37 +1000, Chris Angelico wrote: > On Sat, 23 Apr 2022 at 08:24, <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > > > > On 2022-04-22 at 15:35:15 -0500, > > "Michael F. Stemper" wrote: > > > > > On 22/04/2022 14.59, Chris Angelico wrote: > > > > On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper > > > > wrote: > > > > > > > > > > I'm writing a function that is nearly self-documenting by its name, > > > > > but still want to give it a docstring. Which of these would be > > > > > best from a stylistic point of view: > > > > > > > > > > > > > > > Tells caller whether or not a permutation is even. > > > > > > > > > > Determines if a permutation is even. (Alternative is that it's odd.) > > > > > > > > > > Returns True if permutation is even, False if it is odd. > > > > > > > > > > > > > > I'd go with the third one, but "Return" rather than "Returns". Or > > > > possibly "Test whether a permutation is even". > > > > > > "So let it be written. So let it be done." > > > > "Test whether a permutation is even," while technically factual, leaves > > the reader to wonder what form the result takes, and what happens to > > that result. > > While it's definitely possible to have other results and other ways to > deliver them, the return of a boolean would be the most obvious > default. Maybe, depending on the context and purpose of the application. > > Do you want callers of the function also to assume that True means that > > the permutation is even? There are other reasonable strategies, such as > > an enumerated type (whose items are Even, Odd, and FileNotFound), or > > throwing an exception if the permutation is odd. > > I'm assuming that the function is called something like "is_even()" > and that it either is a method on a permutation object, or its > parameters make it very clear what the permutation is. > > If it returns an enumeration, I would say that in the docstring. If > the docstring doesn't say, I would assume it returns True or False. I think we're agreeing, but the OP didn't provide that information. I've seen enough oddball (yes, that's my professional opinion :-)) APIs (and worked with enough programmers from enough backgrounds) to know that "most obvious default" is subjective. > > I prefer the "return" (rather than "returns") version of the third > > option. Assuming that the programmers are familiar with the domain, > > the other two leave out important information. [...] > We don't need to say "Figures out algorithmically whether the > permutation is even. If it is, will return True; if it isn't, will > return False; if something goes wrong, will raise an exception". This > is Python; we know that if something goes wrong, an exception is > raised. (Though it can help to say WHICH exception will be raised > under WHAT circumstances). Some things are obvious. No, we don't need to say it that way. I believe that we do need to say what the function returns under what circumstances. If, in fact, the function in question is named is_permutation_even, then it *is* as simple as the OP's third option, but not simpler. From rob.cliffe at btinternet.com Fri Apr 22 19:25:11 2022 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Sat, 23 Apr 2022 00:25:11 +0100 Subject: Style for docstring In-Reply-To: References: Message-ID: <5cb9890e-02f4-9746-3e80-784aa95adf4c@btinternet.com> I don't use docstrings much; instead I put a line or two of comments after the `def ` line. But my practice in such situations is as per the OP's 3rd suggestion, e.g. ??? # Returns True if ..... I'm curious as to why so many people prefer "Return" to "Returns". Checking out help() on a few functions in the stdlib, they all used "Return" or a grammatical equivalent, so this does seem to be a Python cultural thing.? But why?? To me, "Returns" begins a description as to what the function does, whereas "Return" is an imperative.? But who is it addresed to?? Is a function considered to be a sentient entity that can respond to a command?? Is it an invocation to the lines of code following the docstring: "Do this!" Might not the programmer mistakenly think (if only for a moment) that the imperative is addressed to him? Best wishes Rob Cliffe From rosuav at gmail.com Fri Apr 22 19:59:13 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sat, 23 Apr 2022 09:59:13 +1000 Subject: Style for docstring In-Reply-To: <5cb9890e-02f4-9746-3e80-784aa95adf4c@btinternet.com> References: <5cb9890e-02f4-9746-3e80-784aa95adf4c@btinternet.com> Message-ID: On Sat, 23 Apr 2022 at 09:31, Rob Cliffe via Python-list wrote: > > I don't use docstrings much; instead I put a line or two of comments > after the `def ` line. > But my practice in such situations is as per the OP's 3rd suggestion, e.g. > # Returns True if ..... The point of docstrings is that they can be read by various tools. Otherwise, they are every bit as good as comments. > I'm curious as to why so many people prefer "Return" to "Returns". > Checking out help() on a few functions in the stdlib, they all used > "Return" or a grammatical equivalent, so this does seem to be a Python > cultural thing. But why? To me, "Returns" begins a description as to > what the function does, whereas "Return" is an imperative. But who is > it addresed to? Is a function considered to be a sentient entity that > can respond to a command? Is it an invocation to the lines of code > following the docstring: "Do this!" Might not the programmer mistakenly > think (if only for a moment) that the imperative is addressed to him? That's a very broad convention; for instance, git commit messages are conventionally written imperatively, too. You can think of a commit message as "If applied, this patch will blah blah blah", and a docstring as "When called, this function will blah blah blah". Aside from the initial capital letter, an imperative sentence will nicely complete those descriptions. ChrisA From cs at cskk.id.au Fri Apr 22 20:23:09 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Sat, 23 Apr 2022 10:23:09 +1000 Subject: Style for docstring In-Reply-To: References: Message-ID: On 22Apr2022 17:22, Dan Sommers <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: >"Test whether a permutation is even," while technically factual, leaves >the reader to wonder what form the result takes, and what happens to >that result. Yes, we'd all like to think that programmers are smart >enough to *assume* that the function returns the result of the test. >I've also seen functions that perform tests and then print the results >out, or write them to a database, or simply execute the tests for their >side effects (or leave it up to the individual tests to do something >with the result). Yeah, this. I've got lots of "test and return a Boolean" functions named "is_something" and some "test and raise value error if bad" functions named "validate_something". Those latter are so that I can concisely write stuff like: def foo(bah): validate_bahlike(bah) ... do stuff with bah ... to get a sensible ValueError from foo() if bah is invalid. (And validate_something() often calls is_something() when I want both flavors depending on circumstance.) So I also like option 3, though I also usually write it imperatively: Return `True` if `permutation` is even, `False` otherwise. I'm in two minds about "otherwise" rather than being explicit about the dual of the test. Usually "otherwise" is my choice, but I can imagine being more explicit if there were some third (probably invalid) input choice. "Otherwise" also works well when there are a few valid choices: Return `True` if the weekday is Wednesday or the moon is full, `False` otherwise. Cheers Cameron Simpson From python at mrabarnett.plus.com Fri Apr 22 20:57:13 2022 From: python at mrabarnett.plus.com (MRAB) Date: Sat, 23 Apr 2022 01:57:13 +0100 Subject: Style for docstring In-Reply-To: <5cb9890e-02f4-9746-3e80-784aa95adf4c@btinternet.com> References: <5cb9890e-02f4-9746-3e80-784aa95adf4c@btinternet.com> Message-ID: <120ff739-fecd-ad31-bc7d-5f5ff65bf4c1@mrabarnett.plus.com> On 2022-04-23 00:25, Rob Cliffe via Python-list wrote: > I don't use docstrings much; instead I put a line or two of comments > after the `def ` line. > But my practice in such situations is as per the OP's 3rd suggestion, e.g. > ??? # Returns True if ..... > I'm curious as to why so many people prefer "Return" to "Returns". > Checking out help() on a few functions in the stdlib, they all used > "Return" or a grammatical equivalent, so this does seem to be a Python > cultural thing.? But why?? To me, "Returns" begins a description as to > what the function does, whereas "Return" is an imperative.? But who is > it addresed to?? Is a function considered to be a sentient entity that > can respond to a command?? Is it an invocation to the lines of code > following the docstring: "Do this!" Might not the programmer mistakenly > think (if only for a moment) that the imperative is addressed to him? Maybe it's because the function name is often also an imperative, e.g.: >>> import re >>> help(re.search) Help on function search in module re: search(pattern, string, flags=0) Scan through string looking for a match to the pattern, returning a Match object, or None if no match was found. Note "Scan", not "scans". I was going to use 'print' as the example: >>> help(print) Help on built-in function print in module builtins: print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream. but it says "Prints", not "Print"... From avigross at verizon.net Fri Apr 22 22:58:05 2022 From: avigross at verizon.net (Avi Gross) Date: Sat, 23 Apr 2022 02:58:05 +0000 (UTC) Subject: Style for docstring In-Reply-To: References: Message-ID: <1761313929.296888.1650682685708@mail.yahoo.com> Python does have a concept of "truthy" that includes meaning for?not just the standard Booleans but for 0 and non-zero and the empty string?and many more odd things such as an object that defines __bool__ (). But saying it returns a Boolean True/False valuesounds direct and simple and informative enough if that is True. What bothers me is the assumption that anyone knows not so?muchjust group theory??but what the argument to the function looks like as?a Python object of some?kind.? Does the function accept only some permutation object managed by?a specific module? Will it accept some alternate representation such as a?list structure or other iterator? Obviously deeper details would normally be in a manual page or other?documentation but as "permutations" are likely not to be what most people?think about before breakfast, or even? after, odd as that may seem, ... And, yes, I know what it means and some users will too. But as all permutations?must be even or odd, errors thrown might be based on whether the data structure?has valid contents or is so complex that it uses up all system resources, I?would think. So the docstring could be fairly short and something like: Given a permutation in
Returns the Boolean value True if it is graded?as or False if or an exception if the argument is not valid. As noted by others, Many things can be returned including multiple?values where perhaps the second one tells if there was an error but thatthe user can ignore or not even catch. -----Original Message----- From: Chris Angelico To: python-list at python.org Sent: Fri, Apr 22, 2022 6:33 pm Subject: Re: Style for docstring On Sat, 23 Apr 2022 at 08:24, <2QdxY4RzWzUUiLuE at potatochowder.com> wrote: > > On 2022-04-22 at 15:35:15 -0500, > "Michael F. Stemper" wrote: > > > On 22/04/2022 14.59, Chris Angelico wrote: > > > On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper > > > wrote: > > > > > > > > I'm writing a function that is nearly self-documenting by its name, > > > > but still want to give it a docstring. Which of these would be > > > > best from a stylistic point of view: > > > > > > > > > > > >? ? Tells caller whether or not a permutation is even. > > > > > > > >? ? Determines if a permutation is even. (Alternative is that it's odd.) > > > > > > > >? ? Returns True if permutation is even, False if it is odd. > > > > > > > > > > I'd go with the third one, but "Return" rather than "Returns". Or > > > possibly "Test whether a permutation is even". > > > > "So let it be written. So let it be done." > > "Test whether a permutation is even," while technically factual, leaves > the reader to wonder what form the result takes, and what happens to > that result. While it's definitely possible to have other results and other ways to deliver them, the return of a boolean would be the most obvious default. > Do you want callers of the function also to assume that True means that > the permutation is even?? There are other reasonable strategies, such as > an enumerated type (whose items are Even, Odd, and FileNotFound), or > throwing an exception if the permutation is odd. I'm assuming that the function is called something like "is_even()" and that it either is a method on a permutation object, or its parameters make it very clear what the permutation is. If it returns an enumeration, I would say that in the docstring. If the docstring doesn't say, I would assume it returns True or False. > I prefer the "return" (rather than "returns") version of the third > option.? Assuming that the programmers are familiar with the domain, the > other two leave out important information. Core Python methods and functions seem to prefer either "Return ..." or "Verb the thing" where the result is implicit (eg str.zfill.__doc__ which says "Pad a numeric string..."). Both are used extensively. Neither form leaves out anything that wouldn't be the obvious default. We don't need to say "Figures out algorithmically whether the permutation is even. If it is, will return True; if it isn't, will return False; if something goes wrong, will raise an exception". This is Python; we know that if something goes wrong, an exception is raised. (Though it can help to say WHICH exception will be raised under WHAT circumstances). Some things are obvious. ChrisA -- https://mail.python.org/mailman/listinfo/python-list From avigross at verizon.net Fri Apr 22 23:26:57 2022 From: avigross at verizon.net (Avi Gross) Date: Sat, 23 Apr 2022 03:26:57 +0000 (UTC) Subject: Style for docstring In-Reply-To: <120ff739-fecd-ad31-bc7d-5f5ff65bf4c1@mrabarnett.plus.com> References: <5cb9890e-02f4-9746-3e80-784aa95adf4c@btinternet.com> <120ff739-fecd-ad31-bc7d-5f5ff65bf4c1@mrabarnett.plus.com> Message-ID: <2098309954.284734.1650684417423@mail.yahoo.com> We know some people using "professional" language make things shorteror talk from a point of view different than others and often in otherwise?incomprehensible jargon. If a programmer is taking about the algorithm that a function implements,?then, yes, they may write "scan" and "return". But if they realize the darn documentation is for PEOPLE asking how?to use the darn thing, and want to write in more informal and?understandable English, I think it makes more sense to say what?the function does as in "scans" and importantly what it "returns" to?the user as a result. So if you are taking a programming course and the instructor or?textbook is giving imperitave commands, they may well tell youto scan something then calculate something and use a return statement?a certain way. I can read many ways and am not particularly bothered by either style?but when documenting what is, I prefer proper English (or any otherlanguage) in communicating what it does for them. As with many such things, if you work for a company or with groups of?others, it is wise to find out what is expected and do the same as much?as reasonable. -----Original Message----- From: MRAB To: python-list at python.org Sent: Fri, Apr 22, 2022 8:57 pm Subject: Re: Style for docstring On 2022-04-23 00:25, Rob Cliffe via Python-list wrote: > I don't use docstrings much; instead I put a line or two of comments > after the `def ` line. > But my practice in such situations is as per the OP's 3rd suggestion, e.g. >? ??? # Returns True if ..... > I'm curious as to why so many people prefer "Return" to "Returns". > Checking out help() on a few functions in the stdlib, they all used > "Return" or a grammatical equivalent, so this does seem to be a Python > cultural thing.? But why?? To me, "Returns" begins a description as to > what the function does, whereas "Return" is an imperative.? But who is > it addresed to?? Is a function considered to be a sentient entity that > can respond to a command?? Is it an invocation to the lines of code > following the docstring: "Do this!" Might not the programmer mistakenly > think (if only for a moment) that the imperative is addressed to him? Maybe it's because the function name is often also an imperative, e.g.: >>> import re >>> help(re.search) Help on function search in module re: search(pattern, string, flags=0) ? ? Scan through string looking for a match to the pattern, returning ? ? a Match object, or None if no match was found. Note "Scan", not "scans". I was going to use 'print' as the example: >>> help(print) Help on built-in function print in module builtins: print(...) ? ? print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) ? ? Prints the values to a stream, or to sys.stdout by default. ? ? Optional keyword arguments: ? ? file:? a file-like object (stream); defaults to the current sys.stdout. ? ? sep:? string inserted between values, default a space. ? ? end:? string appended after the last value, default a newline. ? ? flush: whether to forcibly flush the stream. but it says "Prints", not "Print"... -- https://mail.python.org/mailman/listinfo/python-list From eryksun at gmail.com Sat Apr 23 09:44:09 2022 From: eryksun at gmail.com (Eryk Sun) Date: Sat, 23 Apr 2022 08:44:09 -0500 Subject: upgrade pip In-Reply-To: References: Message-ID: On 4/22/22, Tola Oj wrote: > im trying to upgrade my pip so i can install openpyxl. i though i had > successfully upgraded pip, and then I was trying to install openpyxl, but I > was getting this: > > C:\Users\ojomo>"C:\Program Files\Python310\python.exe" -m pip install > --upgrade > > [...] > > "C:\Users\ojomo\AppData\Roaming\Python\Python310\site-packages\pip\__main__.py", > line 29, in You have pip installed for the current user, but Python is installed for all users. I'd delete the package directory "%AppData%\Python\Python310\site-packages\pip". Then run ensurepip and upgrade from an administrator shell. This will install and update pip for all users. https://docs.python.org/3/library/ensurepip.html From michael.stemper at gmail.com Sat Apr 23 08:57:07 2022 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Sat, 23 Apr 2022 07:57:07 -0500 Subject: Style for docstring In-Reply-To: References: <1761313929.296888.1650682685708@mail.yahoo.com> Message-ID: On 22/04/2022 21.58, Avi Gross wrote: > Python does have a concept of "truthy" that includes meaning for?not just the standard Booleans but for 0 and non-zero and the empty string?and many more odd things such as an object that defines __bool__ (). > But saying it returns a Boolean True/False valuesounds direct and simple and informative enough if that is True. > What bothers me is the assumption that anyone knows not so?muchjust group theory??but what the argument to the function looks like as?a Python object of some?kind. > Does the function accept only some permutation object managed by?a specific module? Will it accept some alternate representation such as a?list structure or other iterator? That's a fair point. However, this function will be the 22nd one in a module for dealing with permutations and groups of permutations. The module has a lengthy docstring explaining the several ways provided to specify a permutation. That way, the same information doesn't need to be written twenty-plus times. > Obviously deeper details would normally be in a manual page or other?documentation but as "permutations" are likely not to be what most people?think about before breakfast, or even? after, odd as that may seem, ... I see what you did there :-> -- Michael F. Stemper Psalm 94:3-6 From michael.stemper at gmail.com Sat Apr 23 10:50:47 2022 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Sat, 23 Apr 2022 09:50:47 -0500 Subject: Style for docstring In-Reply-To: References: Message-ID: On 22/04/2022 16.12, alister wrote: > On Fri, 22 Apr 2022 14:36:27 -0500, Michael F. Stemper wrote: > >> I'm writing a function that is nearly self-documenting by its name, >> but still want to give it a docstring. Which of these would be best from >> a stylistic point of view: > for guidance I would sugest Pep257 as a start point > which would suggest "Return True if permutation is even" I'll take a look at the PEP. Thanks. -- Michael F. Stemper This email is to be read by its intended recipient only. Any other party reading is required by the EULA to send me $500.00. From avigross at verizon.net Sat Apr 23 13:43:06 2022 From: avigross at verizon.net (Avi Gross) Date: Sat, 23 Apr 2022 17:43:06 +0000 (UTC) Subject: Style for docstring In-Reply-To: References: <1761313929.296888.1650682685708@mail.yahoo.com> Message-ID: <214129016.357437.1650735786870@mail.yahoo.com> Given what you added, Michael, your function is part of a larger?collection of functions and being compatible with the others is?a valid consideration. Whatever you decide, would ideally be?done consistently with all or most of them. And, of course, it others in the collection also can handle?multiple ways to specify a permutation, it may be simpler?to have each call something like as.permutation() that handlesmultiple forms and converts to the one easiest for you to use. I am not sure that is needed as I suspect the simplest storage?is something like a list:? [0,3,2,4,5,6,7,1,9,8] but could also?be shown with each cycle as a sub-list or something like anumpy vector or a customized class. Clearly if you control the package and how it is used, errors?from bad data may not be a concern. But like many Boolean?return(s) it is always a problem how to deal with a third?possibility. -----Original Message----- From: Michael F. Stemper To: python-list at python.org Sent: Sat, Apr 23, 2022 8:57 am Subject: Re: Style for docstring On 22/04/2022 21.58, Avi Gross wrote: > Python does have a concept of "truthy" that includes meaning for?not just the standard Booleans but for 0 and non-zero and the empty string?and many more odd things such as an object that defines __bool__ (). > But saying it returns a Boolean True/False valuesounds direct and simple and informative enough if that is True. > What bothers me is the assumption that anyone knows not so?muchjust group theory??but what the argument to the function looks like as?a Python object of some?kind. > Does the function accept only some permutation object managed by?a specific module? Will it accept some alternate representation such as a?list structure or other iterator? That's a fair point. However, this function will be the 22nd one in a module for dealing with permutations and groups of permutations. The module has a lengthy docstring explaining the several ways provided to specify a permutation. That way, the same information doesn't need to be written twenty-plus times. > Obviously deeper details would normally be in a manual page or other?documentation but as "permutations" are likely not to be what most people?think about before breakfast, or even? after, odd as that may seem, ... I see what you did there :-> -- Michael F. Stemper Psalm 94:3-6 -- https://mail.python.org/mailman/listinfo/python-list From Marco.Sulla.Python at gmail.com Sat Apr 23 14:35:11 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 23 Apr 2022 20:35:11 +0200 Subject: tail Message-ID: What about introducing a method for text streams that reads the lines from the bottom? Java has also a ReversedLinesFileReader with Apache Commons IO. From drsalists at gmail.com Sat Apr 23 14:42:51 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Sat, 23 Apr 2022 11:42:51 -0700 Subject: Style for docstring In-Reply-To: References: Message-ID: On Fri, Apr 22, 2022 at 12:56 PM Michael F. Stemper < michael.stemper at gmail.com> wrote: > I'm writing a function that is nearly self-documenting by its name, > but still want to give it a docstring. Which of these would be > best from a stylistic point of view: > > > Tells caller whether or not a permutation is even. > > Determines if a permutation is even. (Alternative is that it's odd.) > > Returns True if permutation is even, False if it is odd. > > > (Before somebody suggests it, I'm not going to put six weeks' worth > of a course in group theory in there to help somebody who doesn't > know what those standard terms mean.) > Maybe try pydocstyle? From rosuav at gmail.com Sat Apr 23 14:57:20 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 04:57:20 +1000 Subject: tail In-Reply-To: References: Message-ID: On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: > > What about introducing a method for text streams that reads the lines > from the bottom? Java has also a ReversedLinesFileReader with Apache > Commons IO. It's fundamentally difficult to get precise. In general, there are three steps to reading the last N lines of a file: 1) Find out the size of the file (currently, if it's being grown) 2) Seek to the end of the file, minus some threshold that you hope will contain a number of lines 3) Read from there to the end of the file, split it into lines, and keep the last N Reading the preceding N lines is basically a matter of repeating the same exercise, but instead of "end of the file", use the byte position of the line you last read. The problem is, seeking around in a file is done by bytes, not characters. So if you know for sure that you can resynchronize (possible with UTF-8, not possible with some other encodings), then you can do this, but it's probably best to build it yourself (opening the file in binary mode). This is quite inefficient in general. It would be far FAR easier to do this instead: 1) Read the entire file and decode bytes to text 2) Split into lines 3) Iterate backwards over the lines Tada! Done. And in Python, quite easy. The downside, of course, is that you have to store the entire file in memory. So it's up to you: pay the memory price, or pay the complexity price. Personally, unless the file is tremendously large and I know for sure that I'm not going to end up iterating over it all, I would pay the memory price. ChrisA From rtm443x at googlemail.com Sat Apr 23 15:09:11 2022 From: rtm443x at googlemail.com (jan) Date: Sat, 23 Apr 2022 20:09:11 +0100 Subject: Style for docstring In-Reply-To: References: Message-ID: "return true iff this". I like this. jan On 23/04/2022, Stefan Ram wrote: > Rob Cliffe writes: >>I'm curious as to why so many people prefer "Return" to "Returns". > > The commands, er, names of functions, use the imperative mood > ("print", not "prints"). So, "return" aligns with that mood > as a paraphrase of such names. > > In Java, at one point, they decided to start to use the > third person at one point and then half-heartedly converted > all the documentation, as in > > |void println(boolean x) > |Prints a boolean and then terminate the line. > > , where they modified "print" but did not bother do modify > "terminate". > > And instead of "return true if this, false if not this", > I might be inclined to write "return true iff this". > > BTW: As a language element that helps to construct a boolean > expression from a file name, some languages, like SQL, use > "EXISTS", while others, like MS-DOS-batch, use "EXIST". > > > -- > https://mail.python.org/mailman/listinfo/python-list > From skip.montanaro at gmail.com Sat Apr 23 15:36:48 2022 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Sat, 23 Apr 2022 14:36:48 -0500 Subject: Receive a signal when waking or suspending? Message-ID: It's not clear there is a straightforward way to catch a signal or get an event notification when my computer (Dell running XUbuntu 20.04) is about to sleep or when it's just awakened. The app uses tkinter. Is there some more-or-less easy way to do this? Mac support would be nice (I have my eye on a new MacBook one of these days). I suppose bonus points for something which works on Windows, but that's not a platform I actually care about. Thx, Skip From Marco.Sulla.Python at gmail.com Sat Apr 23 16:17:00 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 23 Apr 2022 22:17:00 +0200 Subject: Receive a signal when waking or suspending? In-Reply-To: References: Message-ID: I don't know in Python, but maybe you can create a script that writes on a named pipe and read it from Python? https://askubuntu.com/questions/226278/run-script-on-wakeup From Marco.Sulla.Python at gmail.com Sat Apr 23 16:41:18 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 23 Apr 2022 22:41:18 +0200 Subject: tail In-Reply-To: References: Message-ID: On Sat, 23 Apr 2022 at 20:59, Chris Angelico wrote: > > On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: > > > > What about introducing a method for text streams that reads the lines > > from the bottom? Java has also a ReversedLinesFileReader with Apache > > Commons IO. > > It's fundamentally difficult to get precise. In general, there are > three steps to reading the last N lines of a file: > > 1) Find out the size of the file (currently, if it's being grown) > 2) Seek to the end of the file, minus some threshold that you hope > will contain a number of lines > 3) Read from there to the end of the file, split it into lines, and > keep the last N > > Reading the preceding N lines is basically a matter of repeating the > same exercise, but instead of "end of the file", use the byte position > of the line you last read. > > The problem is, seeking around in a file is done by bytes, not > characters. So if you know for sure that you can resynchronize > (possible with UTF-8, not possible with some other encodings), then > you can do this, but it's probably best to build it yourself (opening > the file in binary mode). Well, indeed I have an implementation that does more or less what you described for utf8 only. The only difference is that I just started from the end of file -1. I'm just wondering if this will be useful in the stdlib. I think it's not too difficult to generalise for every encoding. > This is quite inefficient in general. Why inefficient? I think that readlines() will be much slower, not only more time consuming. From rosuav at gmail.com Sat Apr 23 16:58:29 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 06:58:29 +1000 Subject: tail In-Reply-To: References: Message-ID: On Sun, 24 Apr 2022 at 06:41, Marco Sulla wrote: > > On Sat, 23 Apr 2022 at 20:59, Chris Angelico wrote: > > > > On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: > > > > > > What about introducing a method for text streams that reads the lines > > > from the bottom? Java has also a ReversedLinesFileReader with Apache > > > Commons IO. > > > > It's fundamentally difficult to get precise. In general, there are > > three steps to reading the last N lines of a file: > > > > 1) Find out the size of the file (currently, if it's being grown) > > 2) Seek to the end of the file, minus some threshold that you hope > > will contain a number of lines > > 3) Read from there to the end of the file, split it into lines, and > > keep the last N > > > > Reading the preceding N lines is basically a matter of repeating the > > same exercise, but instead of "end of the file", use the byte position > > of the line you last read. > > > > The problem is, seeking around in a file is done by bytes, not > > characters. So if you know for sure that you can resynchronize > > (possible with UTF-8, not possible with some other encodings), then > > you can do this, but it's probably best to build it yourself (opening > > the file in binary mode). > > Well, indeed I have an implementation that does more or less what you > described for utf8 only. The only difference is that I just started > from the end of file -1. I'm just wondering if this will be useful in > the stdlib. I think it's not too difficult to generalise for every > encoding. > > > This is quite inefficient in general. > > Why inefficient? I think that readlines() will be much slower, not > only more time consuming. It depends on which is more costly: reading the whole file (cost depends on size of file) or reading chunks and splitting into lines (cost depends on how well you guess at chunk size). If the lines are all *precisely* the same number of bytes each, you can pick a chunk size and step backwards with near-perfect efficiency (it's still likely to be less efficient than reading a file forwards, on most file systems, but it'll be close); but if you have to guess, adjust, and keep going, then you lose efficiency there. I don't think this is necessary in the stdlib. If anything, it might be good on PyPI, but I for one have literally never wanted this. ChrisA From Marco.Sulla.Python at gmail.com Sat Apr 23 17:12:29 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sat, 23 Apr 2022 23:12:29 +0200 Subject: tail In-Reply-To: References: Message-ID: On Sat, 23 Apr 2022 at 23:00, Chris Angelico wrote: > > > This is quite inefficient in general. > > > > Why inefficient? I think that readlines() will be much slower, not > > only more time consuming. > > It depends on which is more costly: reading the whole file (cost > depends on size of file) or reading chunks and splitting into lines > (cost depends on how well you guess at chunk size). If the lines are > all *precisely* the same number of bytes each, you can pick a chunk > size and step backwards with near-perfect efficiency (it's still > likely to be less efficient than reading a file forwards, on most file > systems, but it'll be close); but if you have to guess, adjust, and > keep going, then you lose efficiency there. Emh, why chunks? My function simply reads byte per byte and compares it to b"\n". When it find it, it stops and do a readline(): def tail(filepath): """ @author Marco Sulla @date May 31, 2016 """ try: filepath.is_file fp = str(filepath) except AttributeError: fp = filepath with open(fp, "rb") as f: size = os.stat(fp).st_size start_pos = 0 if size - 1 < 0 else size - 1 if start_pos != 0: f.seek(start_pos) char = f.read(1) if char == b"\n": start_pos -= 1 f.seek(start_pos) if start_pos == 0: f.seek(start_pos) else: for pos in range(start_pos, -1, -1): f.seek(pos) char = f.read(1) if char == b"\n": break return f.readline() This is only for one line and in utf8, but it can be generalised. From rosuav at gmail.com Sat Apr 23 17:15:58 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 07:15:58 +1000 Subject: tail In-Reply-To: References: Message-ID: On Sun, 24 Apr 2022 at 07:13, Marco Sulla wrote: > > On Sat, 23 Apr 2022 at 23:00, Chris Angelico wrote: > > > > This is quite inefficient in general. > > > > > > Why inefficient? I think that readlines() will be much slower, not > > > only more time consuming. > > > > It depends on which is more costly: reading the whole file (cost > > depends on size of file) or reading chunks and splitting into lines > > (cost depends on how well you guess at chunk size). If the lines are > > all *precisely* the same number of bytes each, you can pick a chunk > > size and step backwards with near-perfect efficiency (it's still > > likely to be less efficient than reading a file forwards, on most file > > systems, but it'll be close); but if you have to guess, adjust, and > > keep going, then you lose efficiency there. > > Emh, why chunks? My function simply reads byte per byte and compares it to b"\n". When it find it, it stops and do a readline(): > > def tail(filepath): > """ > @author Marco Sulla > @date May 31, 2016 > """ > > try: > filepath.is_file > fp = str(filepath) > except AttributeError: > fp = filepath > > with open(fp, "rb") as f: > size = os.stat(fp).st_size > start_pos = 0 if size - 1 < 0 else size - 1 > > if start_pos != 0: > f.seek(start_pos) > char = f.read(1) > > if char == b"\n": > start_pos -= 1 > f.seek(start_pos) > > if start_pos == 0: > f.seek(start_pos) > else: > for pos in range(start_pos, -1, -1): > f.seek(pos) > > char = f.read(1) > > if char == b"\n": > break > > return f.readline() > > This is only for one line and in utf8, but it can be generalised. > Ah. Well, then, THAT is why it's inefficient: you're seeking back one single byte at a time, then reading forwards. That is NOT going to play nicely with file systems or buffers. Compare reading line by line over the file with readlines() and you'll see how abysmal this is. If you really only need one line (which isn't what your original post suggested), I would recommend starting with a chunk that is likely to include a full line, and expanding the chunk until you have that newline. Much more efficient than one byte at a time. ChrisA From PythonList at DancesWithMice.info Sat Apr 23 17:44:27 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 24 Apr 2022 09:44:27 +1200 Subject: Receive a signal when waking or suspending? In-Reply-To: References: Message-ID: <7a911f9e-9c85-05b3-02f4-ddf877ddb75d@DancesWithMice.info> On 24/04/2022 07.36, Skip Montanaro wrote: > It's not clear there is a straightforward way to catch a signal or get > an event notification when my computer (Dell running XUbuntu 20.04) is > about to sleep or when it's just awakened. The app uses tkinter. Is > there some more-or-less easy way to do this? Mac support would be nice > (I have my eye on a new MacBook one of these days). I suppose bonus > points for something which works on Windows, but that's not a platform > I actually care about. https://duckduckgo.com/?t=ffab&q=python+up+time pointed-out the "uptime ? Cross-platform uptime library" - TLDR; I'm not sure if "uptime" and "boot" relate only to a 'cold-start' or if they include bringing the machine out of 'stand-by' or 'hibernation' https://duckduckgo.com/?t=ffab&q=python+battery+status pointed-out several ideas which require MS-Windows, but apparently the psutil library could be bent to your will: https://www.geeksforgeeks.org/python-script-to-shows-laptop-battery-percentage/ Please let us know how you get on... -- Regards, =dn From skip.montanaro at gmail.com Sat Apr 23 17:58:24 2022 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Sat, 23 Apr 2022 16:58:24 -0500 Subject: Receive a signal when waking or suspending? In-Reply-To: References: Message-ID: > I don't know in Python, but maybe you can create a script that writes > on a named pipe and read it from Python? > https://askubuntu.com/questions/226278/run-script-on-wakeup Thanks, that gives me something to munch on. From hjp-python at hjp.at Sat Apr 23 18:02:29 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 24 Apr 2022 00:02:29 +0200 Subject: tail In-Reply-To: References: Message-ID: <20220423220229.6lvry4nwsbk2llcd@hjp.at> On 2022-04-24 04:57:20 +1000, Chris Angelico wrote: > On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: > > What about introducing a method for text streams that reads the lines > > from the bottom? Java has also a ReversedLinesFileReader with Apache > > Commons IO. > > It's fundamentally difficult to get precise. In general, there are > three steps to reading the last N lines of a file: > > 1) Find out the size of the file (currently, if it's being grown) > 2) Seek to the end of the file, minus some threshold that you hope > will contain a number of lines > 3) Read from there to the end of the file, split it into lines, and > keep the last N [...] > This is quite inefficient in general. It would be far FAR easier to do > this instead: > > 1) Read the entire file and decode bytes to text > 2) Split into lines > 3) Iterate backwards over the lines Which one is more efficient depends very much on the size of the file. For a file of a few kilobytes, the second solution is probably more efficient. But for a few gigabytes, that's almost certainly not the case. > Tada! Done. And in Python, quite easy. The downside, of course, is > that you have to store the entire file in memory. Not just memory. You have to read the whole file in the first place. Which is hardly efficient if you only need a tiny fraction. > Personally, unless the file is tremendously large and I know for sure > that I'm not going to end up iterating over it all, I would pay the > memory price. Me, too. Problem with a library function (as Marco proposes) is that you don't know how it will be used. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From PythonList at DancesWithMice.info Sat Apr 23 18:04:35 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 24 Apr 2022 10:04:35 +1200 Subject: tail In-Reply-To: References: Message-ID: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> On 24/04/2022 09.15, Chris Angelico wrote: > On Sun, 24 Apr 2022 at 07:13, Marco Sulla wrote: >> >> On Sat, 23 Apr 2022 at 23:00, Chris Angelico wrote: >>>>> This is quite inefficient in general. >>>> >>>> Why inefficient? I think that readlines() will be much slower, not >>>> only more time consuming. >>> >>> It depends on which is more costly: reading the whole file (cost >>> depends on size of file) or reading chunks and splitting into lines >>> (cost depends on how well you guess at chunk size). If the lines are >>> all *precisely* the same number of bytes each, you can pick a chunk >>> size and step backwards with near-perfect efficiency (it's still >>> likely to be less efficient than reading a file forwards, on most file >>> systems, but it'll be close); but if you have to guess, adjust, and >>> keep going, then you lose efficiency there. >> >> Emh, why chunks? My function simply reads byte per byte and compares it to b"\n". When it find it, it stops and do a readline(): ... > Ah. Well, then, THAT is why it's inefficient: you're seeking back one > single byte at a time, then reading forwards. That is NOT going to > play nicely with file systems or buffers. > > Compare reading line by line over the file with readlines() and you'll > see how abysmal this is. > > If you really only need one line (which isn't what your original post > suggested), I would recommend starting with a chunk that is likely to > include a full line, and expanding the chunk until you have that > newline. Much more efficient than one byte at a time. Disagreeing with @Chris in the sense that I use tail very frequently, and usually in the context of server logs - but I'm talking about the Linux implementation, not Python code! Agree with @Chris' assessment of the (in)efficiency. It is more likely than not, that you will have a good idea of the length of each line. Even if the line-length is highly-variable (thinking of some of my applications of the Python logging module!), one can still 'take a stab at it' (a "thumb suck" as an engineer-colleague used to say - apparently not an electrical engineer!) by remembering that lines exceeding 80-characters become less readable and thus have likely?hopefully been split into two. Thus, N*(80+p) where N is the number of lines desired and p is a reasonable 'safety'/over-estimation percentage, would give a good chunk size. Binar-ily grab that much of the end of the file, split on line-ending, and take the last N elements from that list. (with 'recovery code' just in case the 'chunk' wasn't large-enough). Adding to the efficiency (of the algorithm, but not the dev-time), consider that shorter files are likely to be more easily--handled by reading serially from the beginning. To side-step @Chris' criticism, use a generator to produce the individual lines (lazy evaluation and low storage requirement) and feed them into a circular-queue which is limited to N-entries. QED, as fast as the machine's I/O, and undemanding of storage-space! Running a few timing trials should reveal the 'sweet spot', at which one algorithm takes-over from the other! NB quite a few of IBM's (extensively researched) algorithms which formed utility program[me]s on mainframes, made similar such algorithmic choices, in the pursuit of efficiencies. -- Regards, =dn From rosuav at gmail.com Sat Apr 23 18:11:39 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 08:11:39 +1000 Subject: tail In-Reply-To: <20220423220229.6lvry4nwsbk2llcd@hjp.at> References: <20220423220229.6lvry4nwsbk2llcd@hjp.at> Message-ID: On Sun, 24 Apr 2022 at 08:03, Peter J. Holzer wrote: > > On 2022-04-24 04:57:20 +1000, Chris Angelico wrote: > > On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: > > > What about introducing a method for text streams that reads the lines > > > from the bottom? Java has also a ReversedLinesFileReader with Apache > > > Commons IO. > > > > It's fundamentally difficult to get precise. In general, there are > > three steps to reading the last N lines of a file: > > > > 1) Find out the size of the file (currently, if it's being grown) > > 2) Seek to the end of the file, minus some threshold that you hope > > will contain a number of lines > > 3) Read from there to the end of the file, split it into lines, and > > keep the last N > [...] > > This is quite inefficient in general. It would be far FAR easier to do > > this instead: > > > > 1) Read the entire file and decode bytes to text > > 2) Split into lines > > 3) Iterate backwards over the lines > > Which one is more efficient depends very much on the size of the file. > For a file of a few kilobytes, the second solution is probably more > efficient. But for a few gigabytes, that's almost certainly not the > case. Yeah. I said "easier", not necessarily more efficient. Which is more efficient is a virtually unanswerable question (will you need to iterate over the whole file or stop part way? Is the file stored contiguously? Can you memory map it in some way?), so it's going to depend a lot on your use-case. > > Tada! Done. And in Python, quite easy. The downside, of course, is > > that you have to store the entire file in memory. > > Not just memory. You have to read the whole file in the first place. Which is > hardly efficient if you only need a tiny fraction. Right - if that's the case, then the chunked form, even though it's harder, would be worth doing. > > Personally, unless the file is tremendously large and I know for sure > > that I'm not going to end up iterating over it all, I would pay the > > memory price. > > Me, too. Problem with a library function (as Marco proposes) is that you > don't know how it will be used. > Yup. And there may be other options worth considering, like maintaining an index (a bunch of "line 142857 is at byte position 3141592" entries) which would allow random access... but at some point, if your file is that big, you probably shouldn't be storing it as a file of lines of text. Use a database instead. Reading a text file backwards by lines is, by definition, hard. Every file format I know of that involves starting at the end of the file is defined in binary, so you can actually seek, and is usually defined with fixed-size structures (so you just go "read the last 768 bytes of the file" or something). ChrisA From cs at cskk.id.au Sat Apr 23 18:09:44 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 24 Apr 2022 08:09:44 +1000 Subject: tail In-Reply-To: References: Message-ID: On 24Apr2022 07:15, Chris Angelico wrote: >On Sun, 24 Apr 2022 at 07:13, Marco Sulla wrote: >> Emh, why chunks? My function simply reads byte per byte and compares >> it to b"\n". When it find it, it stops and do a readline(): [...] >> This is only for one line and in utf8, but it can be generalised. For some encodings that generalisation might be hard. But mostly, yes. >Ah. Well, then, THAT is why it's inefficient: you're seeking back one >single byte at a time, then reading forwards. That is NOT going to >play nicely with file systems or buffers. An approach I think you both may have missed: mmap the file and use mmap.rfind(b'\n') to locate line delimiters. https://docs.python.org/3/library/mmap.html#mmap.mmap.rfind Avoids sucking the whole file into memory in the usualy sense, instead the file is paged in as needed. Far more efficient that a seek/read single byte approach. If the file's growing you can do this to start with, then do a normal file open from your end point to follow accruing text. (Or reuse the descriptor you sues for the mmap, but using s.read().) Cheers, Cameron Simpson From rosuav at gmail.com Sat Apr 23 18:19:36 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 08:19:36 +1000 Subject: tail In-Reply-To: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> Message-ID: On Sun, 24 Apr 2022 at 08:06, dn wrote: > > On 24/04/2022 09.15, Chris Angelico wrote: > > On Sun, 24 Apr 2022 at 07:13, Marco Sulla wrote: > >> > >> On Sat, 23 Apr 2022 at 23:00, Chris Angelico wrote: > >>>>> This is quite inefficient in general. > >>>> > >>>> Why inefficient? I think that readlines() will be much slower, not > >>>> only more time consuming. > >>> > >>> It depends on which is more costly: reading the whole file (cost > >>> depends on size of file) or reading chunks and splitting into lines > >>> (cost depends on how well you guess at chunk size). If the lines are > >>> all *precisely* the same number of bytes each, you can pick a chunk > >>> size and step backwards with near-perfect efficiency (it's still > >>> likely to be less efficient than reading a file forwards, on most file > >>> systems, but it'll be close); but if you have to guess, adjust, and > >>> keep going, then you lose efficiency there. > >> > >> Emh, why chunks? My function simply reads byte per byte and compares it to b"\n". When it find it, it stops and do a readline(): > ... > > > Ah. Well, then, THAT is why it's inefficient: you're seeking back one > > single byte at a time, then reading forwards. That is NOT going to > > play nicely with file systems or buffers. > > > > Compare reading line by line over the file with readlines() and you'll > > see how abysmal this is. > > > > If you really only need one line (which isn't what your original post > > suggested), I would recommend starting with a chunk that is likely to > > include a full line, and expanding the chunk until you have that > > newline. Much more efficient than one byte at a time. > > > Disagreeing with @Chris in the sense that I use tail very frequently, > and usually in the context of server logs - but I'm talking about the > Linux implementation, not Python code! tail(1) doesn't read a single byte at a time. It works in chunks, more-or-less the way I described. (That's where I borrowed the technique from.) It finds one block of lines, and displays those; it doesn't iterate backwards. (By the way, the implementation of "tail -f" is actually less complicated than you might think, as long as inotify is available. That's been much more useful to me than reading a file backwards.) > Agree with @Chris' assessment of the (in)efficiency. It is more likely > than not, that you will have a good idea of the length of each line. > Even if the line-length is highly-variable (thinking of some of my > applications of the Python logging module!), one can still 'take a stab > at it' (a "thumb suck" as an engineer-colleague used to say - apparently > not an electrical engineer!) by remembering that lines exceeding > 80-characters become less readable and thus have likely?hopefully been > split into two. > > Thus, > > N*(80+p) > > where N is the number of lines desired and p is a reasonable > 'safety'/over-estimation percentage, would give a good chunk size. > Binar-ily grab that much of the end of the file, split on line-ending, > and take the last N elements from that list. (with 'recovery code' just > in case the 'chunk' wasn't large-enough). Yup, that's the broad idea of the chunked read. If you know how many lines you're going to need, that's not too bad. If you need to iterate backwards over the file (as the original question suggested), that gets complicated fast. > Adding to the efficiency (of the algorithm, but not the dev-time), > consider that shorter files are likely to be more easily--handled by > reading serially from the beginning. To side-step @Chris' criticism, use > a generator to produce the individual lines (lazy evaluation and low > storage requirement) and feed them into a circular-queue which is > limited to N-entries. QED, as fast as the machine's I/O, and undemanding > of storage-space! Still needs to read the whole file though. > Running a few timing trials should reveal the 'sweet spot', at which one > algorithm takes-over from the other! Unfortunately, the sweet spot will depend on a lot of things other than just the file size. Is it stored contiguously? Is it on hard drive or SSD? Can it be read from the disk cache? How frequently do the chunk size guesses fail, and how often do they grab more than is necessary? It's basically unknowable, so the best you can do is judge your own app, pick one, and go with it. > NB quite a few of IBM's (extensively researched) algorithms which formed > utility program[me]s on mainframes, made similar such algorithmic > choices, in the pursuit of efficiencies. Indeed. Just make a choice and run with it, and accept that there will be situations where it'll be inefficient. ChrisA From rosuav at gmail.com Sat Apr 23 18:21:34 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 08:21:34 +1000 Subject: tail In-Reply-To: References: Message-ID: On Sun, 24 Apr 2022 at 08:18, Cameron Simpson wrote: > > On 24Apr2022 07:15, Chris Angelico wrote: > >On Sun, 24 Apr 2022 at 07:13, Marco Sulla wrote: > >> Emh, why chunks? My function simply reads byte per byte and compares > >> it to b"\n". When it find it, it stops and do a readline(): > [...] > >> This is only for one line and in utf8, but it can be generalised. > > For some encodings that generalisation might be hard. But mostly, yes. > > >Ah. Well, then, THAT is why it's inefficient: you're seeking back one > >single byte at a time, then reading forwards. That is NOT going to > >play nicely with file systems or buffers. > > An approach I think you both may have missed: mmap the file and use > mmap.rfind(b'\n') to locate line delimiters. > https://docs.python.org/3/library/mmap.html#mmap.mmap.rfind Yeah, I made a vague allusion to use of mmap, but didn't elaborate because I actually have zero idea of how efficient this would be. Would it be functionally equivalent to the chunking, but with the chunk size defined by the system as whatever's most optimal? It would need to be tested. I've never used mmap for this kind of job, so it's not something I'm comfortable predicting the performance of. ChrisA From PythonList at DancesWithMice.info Sat Apr 23 19:23:13 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 24 Apr 2022 11:23:13 +1200 Subject: Style for docstring In-Reply-To: References: Message-ID: <6e66877b-8965-bb9a-3c72-e4a82e73d77a@DancesWithMice.info> On 23/04/2022 08.35, Michael F. Stemper wrote: > On 22/04/2022 14.59, Chris Angelico wrote: >> On Sat, 23 Apr 2022 at 05:56, Michael F. Stemper >> wrote: >>> >>> I'm writing a function that is nearly self-documenting by its name, >>> but still want to give it a docstring. Which of these would be >>> best from a stylistic point of view: >>> >>> >>> ??? Tells caller whether or not a permutation is even. >>> >>> ??? Determines if a permutation is even. (Alternative is that it's odd.) >>> >>> ??? Returns True if permutation is even, False if it is odd. > > >> >> I'd go with the third one, but "Return" rather than "Returns". Or >> possibly "Test whether a permutation is even". > > "So let it be written. So let it be done." > >> That's just one opinion though, others may disagree :) > > Two for two. Thanks. I've always taken the PEP somewhat for granted (with belated thanks and respect to the authors and others who exerted effort (or would that be, efforts?) to publish the finished work. One of the things that I've taken-as-read, is WHY we use docstrings. That rationale is wider than Python. Like many others, I just brought that sort thinking with me. Have you noticed that the PEP doesn't discuss this? It has taken this thread to make me realise such. The elephant in the style room is PEP-008. It's quite old in 'Python-years'! As time went by, PEP-257 became relevant - and I don't recall which was 'chicken' and which 'egg', between the PEP and the docutils/help/etc tools which depend upon a level of docstring uniformity. No matter, together they represent a step of progress, after PEP-008. Since then we have added typing. Where once there was an extensive documentation system to clarify the use of parameters and the definition of return-values, now much of that can be done on the def-line (or equivalent). Another 'development' (I'd prefer 'natural progression') is that as computers have become more powerful and storage cheaper, we have been able to first justify, and now habitually, use longer identifier-names. This step of progress should enable more descriptive and readable code. So, we can consider that there are (now) three aspects which overlap, considerably: 1 the name of the function - descriptive and readable (see OP's assurance on this point) 2 typing - description and distinction of parameters and return-values 3 docstring - even more information about the function, how the author intends it be used, embedded assumptions, etc Thus, aren't there situations where a short, sharp, DRY, and SRP, function; once well-named and accurately typed, could stand on its own merits without a docstring. (yes, others will suck in their breath and start preparing a bon-fire, at the utterance of such 'heresy'...) We all hate 'boiler-plate', ie feeling forced to type stuff 'just because', and particularly when it seems like duplication/repetition (see recent thread(s) 'here' about __init__() and dataclasses). In fact, one reason why we have functions is to reduce/remove (code) duplication! So, why would we indulge in documental 'duplication' just-because we should?must have a docstring? While I'm tilting at windmills, wasn't option-2 the best? (ooh, those flames are starting to warm my feet...) Why? First, see other discussion about "imperatives". My habit is to take the Statement of Requirements and copy it into a brand-new __main__. As development proceeds, various details will be extracted and copied into function and class docstrings. The language of a specification should be imperative, ie you will *do* 'this'. A second reason, is that the docstring should document the function, which is subtly-different from describing the return-value (and that has become a task for typing anyway). (OK, the flames are getting-good, and it's time to break-out the marsh-mallows and crumpets...) So, 'nr2' describes what the function DOES! PS would you mind passing-over the fire-extinguisher? -- Regards, =dn From cs at cskk.id.au Sat Apr 23 20:03:13 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Sun, 24 Apr 2022 10:03:13 +1000 Subject: tail In-Reply-To: References: Message-ID: On 24Apr2022 08:21, Chris Angelico wrote: >On Sun, 24 Apr 2022 at 08:18, Cameron Simpson wrote: >> An approach I think you both may have missed: mmap the file and use >> mmap.rfind(b'\n') to locate line delimiters. >> https://docs.python.org/3/library/mmap.html#mmap.mmap.rfind > >Yeah, I made a vague allusion to use of mmap, but didn't elaborate >because I actually have zero idea of how efficient this would be. >Would it be functionally equivalent to the chunking, but with the >chunk size defined by the system as whatever's most optimal? It would >need to be tested. True. I'd expect better than single byte seek/read though. >I've never used mmap for this kind of job, so it's not something I'm >comfortable predicting the performance of. Fair. But it would be much easier to read code. Cheers, Cameron Simpson From rosuav at gmail.com Sat Apr 23 20:39:48 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 10:39:48 +1000 Subject: tail In-Reply-To: References: Message-ID: On Sun, 24 Apr 2022 at 10:04, Cameron Simpson wrote: > > On 24Apr2022 08:21, Chris Angelico wrote: > >On Sun, 24 Apr 2022 at 08:18, Cameron Simpson wrote: > >> An approach I think you both may have missed: mmap the file and use > >> mmap.rfind(b'\n') to locate line delimiters. > >> https://docs.python.org/3/library/mmap.html#mmap.mmap.rfind > > > >Yeah, I made a vague allusion to use of mmap, but didn't elaborate > >because I actually have zero idea of how efficient this would be. > >Would it be functionally equivalent to the chunking, but with the > >chunk size defined by the system as whatever's most optimal? It would > >need to be tested. > > True. I'd expect better than single byte seek/read though. > Yeah, I think pretty much *anything* would be better than single byte seeks. ChrisA From krlinus at yahoo.com Sat Apr 23 21:19:38 2022 From: krlinus at yahoo.com (Sunil KR) Date: Sun, 24 Apr 2022 01:19:38 +0000 (UTC) Subject: How to have python 2 and 3 both on windows? In-Reply-To: <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> Message-ID: <1897585274.397040.1650763178034@mail.yahoo.com> I am happy with how the python starts up. When I use python I get python 2.? I am ok with using py -3 for my new scripts, even using the shebang like #!py -3 I don't want to put a unix (or for that matter windows) path in the shebang, as it is not platform portable But the real question/s for me is/are -- Why are my strings being sent to python3, so that I get the unicode related error? -- in other cases I see error pertaining to the print function In my case, I don't own the python2 scripts and so I am not allowed to change any part of them. And I wouldn't need to either, if I can make python 2 and 3 coexist on my system > On 22 Apr 2022, at 17:10, Sunil KR via Python-list wrote: > > ?I have some scripts that are old and won't work under python2 and at the same time I am writing new scripts which will use python3. However, if python 2 and 3 cannot co-exist in a windows box it will be impossible to transition > What I try:- remove all pythons and launchers- Use windows installer and install python2 in python27 directory- Use windows installer and install python3 in python310 directory- When installing python3 I opt in to install the launcher- Test with py -2 and py -3 and see that I get the expected prompt- just typing python gets me python2 As you have proved you can install many versions of python at the same time on windows. In your scripts set the shebang to run the python version you want. E.g #!/usr/bin/python2 Or #!/usr/bin/python3 The python launcher py.exe will then do the right thing after looking at en shebang line. Also you can edit the INI file of the py.exe launcher to set the defaults the way you want them. Do a search for ?py.exe ini? to file the path to the file, I do not have it my finger tips. Tip ?py.exe -0? will list the state of installed pythons. Barry > -- > https://mail.python.org/mailman/listinfo/python-list > From wlfraed at ix.netcom.com Sat Apr 23 23:44:21 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Sat, 23 Apr 2022 23:44:21 -0400 Subject: How to have python 2 and 3 both on windows? References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> <1897585274.397040.1650763178034@mail.yahoo.com> Message-ID: On Sun, 24 Apr 2022 01:19:38 +0000 (UTC), Sunil KR declaimed the following: > >-- Why are my strings being sent to python3, so that I get the unicode related error? >-- in other cases I see error pertaining to the print function In python2, the default for strings is BYTES -- you must explicitly ask for unicode (for literals, using u'literal' notation). Python3 strings are, by default, interpreted as unicode (with the encoding for source code [and hence, literals] specified somewhere via a special comment). Getting a normal python2 string requires using the b'literal' notation to indicate /bytes/. Also, in Python2, print is a language statement, not a function. If you have any print statements that do not have ( ) surrounding the output items, it WILL fail in Python3. >In my case, I don't own the python2 scripts and so I am not allowed to change any part of them. And I wouldn't need to either, if I can make python 2 and 3 coexist on my system > Even if you are not "allowed to change" those scripts, have you tried feeding them through the 2to3 conversion script just to see what type of changes would be required? https://docs.python.org/3/library/2to3.html -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From krlinus at yahoo.com Sun Apr 24 03:29:55 2022 From: krlinus at yahoo.com (Sunil KR) Date: Sun, 24 Apr 2022 07:29:55 +0000 (UTC) Subject: How to have python 2 and 3 both on windows? In-Reply-To: References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> <1897585274.397040.1650763178034@mail.yahoo.com> Message-ID: <1696294318.365982.1650785395131@mail.yahoo.com> The question is not one of conversion. The question is this: When I have both python 2 and python3, why is my python 2 script breaking? And when I remove python3 the problem goes away? In both cases (regardless of installing python 3 or not) I am using only python 2 to run the python2 script. Why does the installation of python3 affect the python2, and how can I get them to work without stepping on one another? On Saturday, April 23, 2022, 09:59:46 PM PDT, Dennis Lee Bieber wrote: On Sun, 24 Apr 2022 01:19:38 +0000 (UTC), Sunil KR declaimed the following: > >-- Why are my strings being sent to python3, so that I get the unicode related error? >-- in other cases I see error pertaining to the print function ??? In python2, the default for strings is BYTES -- you must explicitly ask for unicode (for literals, using u'literal' notation). Python3 strings are, by default, interpreted as unicode (with the encoding for source code [and hence, literals] specified somewhere via a special comment). Getting a normal python2 string requires using the b'literal' notation to indicate /bytes/. ??? Also, in Python2, print is a language statement, not a function. If you have any print statements that do not have ( ) surrounding the output items, it WILL fail in Python3. >In my case, I don't own the python2 scripts and so I am not allowed to change any part of them. And I wouldn't need to either, if I can make python 2 and 3 coexist on my system > ??? Even if you are not "allowed to change" those scripts, have you tried feeding them through the 2to3 conversion script just to see what type of changes would be required? https://docs.python.org/3/library/2to3.html -- ??? Wulfraed? ? ? ? ? ? ? ? Dennis Lee Bieber? ? ? ? AF6VN ??? wlfraed at ix.netcom.com? ? http://wlfraed.microdiversity.freeddns.org/ -- https://mail.python.org/mailman/listinfo/python-list From hjp-python at hjp.at Sun Apr 24 04:14:24 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Sun, 24 Apr 2022 10:14:24 +0200 Subject: How to have python 2 and 3 both on windows? In-Reply-To: <1897585274.397040.1650763178034@mail.yahoo.com> References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> <1897585274.397040.1650763178034@mail.yahoo.com> Message-ID: <20220424081424.wwea2oeltkakkbje@hjp.at> On 2022-04-24 01:19:38 +0000, Sunil KR via Python-list wrote: > But the real question/s for me is/are > > -- Why are my strings being sent to python3, so that I get the unicode related error? You haven't shown us how you invoke those scripts, so we can't answer that question with the information you gave us. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From roel at roelschroeven.net Sun Apr 24 05:19:43 2022 From: roel at roelschroeven.net (Roel Schroeven) Date: Sun, 24 Apr 2022 11:19:43 +0200 Subject: tail In-Reply-To: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> Message-ID: dn schreef op 24/04/2022 om 0:04: > Disagreeing with @Chris in the sense that I use tail very frequently, > and usually in the context of server logs - but I'm talking about the > Linux implementation, not Python code! If I understand Marco correctly, what he want is to read the lines from bottom to top, i.e. tac instead of tail, despite his subject. I use tail very frequently too, but tac is something I almost never use. -- "Peace cannot be kept by force. It can only be achieved through understanding." -- Albert Einstein From antoon.pardon at vub.be Sun Apr 24 07:09:21 2022 From: antoon.pardon at vub.be (Antoon Pardon) Date: Sun, 24 Apr 2022 13:09:21 +0200 Subject: tail In-Reply-To: References: Message-ID: <25955416-d16e-2ac3-3fc9-d0dba80b61cd@vub.be> Op 23/04/2022 om 20:57 schreef Chris Angelico: > On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: >> What about introducing a method for text streams that reads the lines >> from the bottom? Java has also a ReversedLinesFileReader with Apache >> Commons IO. > > 1) Read the entire file and decode bytes to text > 2) Split into lines > 3) Iterate backwards over the lines > > Tada! Done. And in Python, quite easy. The downside, of course, is > that you have to store the entire file in memory. Why not just do: tail = collections.deque(text_stream, maxlen = nr_of_lines) tail.reverse() ... -- Antoon Pardon From rosuav at gmail.com Sun Apr 24 07:32:11 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 24 Apr 2022 21:32:11 +1000 Subject: tail In-Reply-To: <25955416-d16e-2ac3-3fc9-d0dba80b61cd@vub.be> References: <25955416-d16e-2ac3-3fc9-d0dba80b61cd@vub.be> Message-ID: On Sun, 24 Apr 2022 at 21:11, Antoon Pardon wrote: > > > > Op 23/04/2022 om 20:57 schreef Chris Angelico: > > On Sun, 24 Apr 2022 at 04:37, Marco Sulla wrote: > >> What about introducing a method for text streams that reads the lines > >> from the bottom? Java has also a ReversedLinesFileReader with Apache > >> Commons IO. > > > > 1) Read the entire file and decode bytes to text > > 2) Split into lines > > 3) Iterate backwards over the lines > > > > Tada! Done. And in Python, quite easy. The downside, of course, is > > that you have to store the entire file in memory. > > Why not just do: > > tail = collections.deque(text_stream, maxlen = nr_of_lines) > tail.reverse() > ... > You still need to read the entire file, and you also restrict the max line count, so you can't iterate this to take the next block of lines. ChrisA From avigross at verizon.net Sun Apr 24 08:06:54 2022 From: avigross at verizon.net (Avi Gross) Date: Sun, 24 Apr 2022 12:06:54 +0000 (UTC) Subject: tail In-Reply-To: References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> Message-ID: <1591457160.427112.1650802014390@mail.yahoo.com> I have been getting confused by how many interpretations and conditions?for chasing tail people seem to be talking about. A fairly normal task is to want to see just the last N lines of a text-based?file.? A variant is the "tail -f" command from UNIX that continues to follow?a growing file, often into a pipeline for further processing. The variant now being mentioned is a sort of "reverse" that has nothing?to do with that kind of "tail" except if the implementation is to read the?file backwards. A very straightforward way to reverse a file takes perhaps?two lines of Python code by reading forward to fill a list with lines of text then?using an index that reverses it. The issues being considered are memory and whether to read the entire file. I would think reading a file forwards in big chunks to be far faster and simpler?than various schemes mentioned here for reading it backwards. It only makes?sense if the goal is not reversal of all the contents. Also noted is that memory use can be minimized various ways so that only thefinal results are kept around. And if you really want more random access to files?that you view as being organized as lines of text with a fixed or maximum width,then storing in some database format, perhaps indexed, may be a way to go. A time stamped log file is a good example. So which problem is really supposed to be solved for the original question? -----Original Message----- From: Roel Schroeven To: python-list at python.org Sent: Sun, Apr 24, 2022 5:19 am Subject: Re: tail dn schreef op 24/04/2022 om 0:04: > Disagreeing with @Chris in the sense that I use tail very frequently, > and usually in the context of server logs - but I'm talking about the > Linux implementation, not Python code! If I understand Marco correctly, what he want is to read the lines from bottom to top, i.e. tac instead of tail, despite his subject. I use tail very frequently too, but tac is something I almost never use. -- "Peace cannot be kept by force. It can only be achieved through understanding." ? ? ? ? -- Albert Einstein -- https://mail.python.org/mailman/listinfo/python-list From eryksun at gmail.com Sun Apr 24 10:18:27 2022 From: eryksun at gmail.com (Eryk Sun) Date: Sun, 24 Apr 2022 09:18:27 -0500 Subject: How to have python 2 and 3 both on windows? In-Reply-To: <1897585274.397040.1650763178034@mail.yahoo.com> References: <1766896259.80347.1650605332904@mail.yahoo.com> <1A496C85-0E6A-432B-B455-581F70F648FD@barrys-emacs.org> <1897585274.397040.1650763178034@mail.yahoo.com> Message-ID: On 4/23/22, Sunil KR via Python-list wrote: > > I am happy with how the python starts up. When I use python I get > python 2. I am ok with using py -3 for my new scripts, even using the > shebang like #!py -3 `#!py -3` is not a valid shebang for the py launcher. Use `#!python3` to run a script with the highest version of Python 3 that's registered on your system. Or for cross-platform support, use `#!/usr/bin/python3`. > I don't want to put a unix (or for that matter windows) path in the shebang, > as it is not platform portable The launcher supports builtin virtual shebangs, including: * #!python[X[.Y][-32|-64]] * #!/usr/bin/python[X[.Y][-32|-64]] * #!/usr/bin/env python[X[.Y][-32|-64]] * #!/usr/local/bin/python[X[.Y][-32|-64]] The implementation of the `/usr/bin/env` virtual shebang searches PATH for a given command that's exactly "python" (no version spec) or any command that doesn't start with "python". If a "python" command has a version spec, then PATH is not searched, and it works the same as a `#!pythonX[.Y]` shebang. The latter is because a normal Python installation doesn't include versioned executable names, so the launcher doesn't even try to search PATH for something like "python3.11.exe". You can set the default version to use via the PY_PYTHON environment variable, e.g. `set PY_PYTHON=3.9`. If Python 3 is requested without a specific version (e.g. via `py -3` at the command line, or the shebang `#!python3`), then the default 3.x version to run can be set via the PY_PYTHON3 environment variable, e.g. `set PY_PYTHON3=3.10`. The default for Python 2 is set similarly via PY_PYTHON2. The launcher also supports real file paths in shebangs. Generally you'd only use a real path in order to run in a virtual environment, such as #!"C:\Path\to\venv\Scripts\python.exe". From Marco.Sulla.Python at gmail.com Sun Apr 24 11:47:20 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 24 Apr 2022 17:47:20 +0200 Subject: tail In-Reply-To: References: Message-ID: On Sat, 23 Apr 2022 at 23:18, Chris Angelico wrote: > Ah. Well, then, THAT is why it's inefficient: you're seeking back one > single byte at a time, then reading forwards. That is NOT going to > play nicely with file systems or buffers. > > Compare reading line by line over the file with readlines() and you'll > see how abysmal this is. > > If you really only need one line (which isn't what your original post > suggested), I would recommend starting with a chunk that is likely to > include a full line, and expanding the chunk until you have that > newline. Much more efficient than one byte at a time. > Well, I would like to have a sort of tail, so to generalise to more than 1 line. But I think that once you have a good algorithm for one line, you can repeat it N times. I understand that you can read a chunk instead of a single byte, so when the newline is found you can return all the cached chunks concatenated. But will this make the search of the start of the line faster? I suppose you have always to read byte by byte (or more, if you're using urf16 etc) and see if there's a newline. From Marco.Sulla.Python at gmail.com Sun Apr 24 11:56:18 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 24 Apr 2022 17:56:18 +0200 Subject: tail In-Reply-To: References: Message-ID: On Sun, 24 Apr 2022 at 00:19, Cameron Simpson wrote: > An approach I think you both may have missed: mmap the file and use > mmap.rfind(b'\n') to locate line delimiters. > https://docs.python.org/3/library/mmap.html#mmap.mmap.rfind > Ah, I played very little with mmap, I didn't know about this. So I suppose you can locate the newline and at that point read the line without using chunks? From rosuav at gmail.com Sun Apr 24 11:58:37 2022 From: rosuav at gmail.com (Chris Angelico) Date: Mon, 25 Apr 2022 01:58:37 +1000 Subject: tail In-Reply-To: References: Message-ID: On Mon, 25 Apr 2022 at 01:47, Marco Sulla wrote: > > > > On Sat, 23 Apr 2022 at 23:18, Chris Angelico wrote: >> >> Ah. Well, then, THAT is why it's inefficient: you're seeking back one >> single byte at a time, then reading forwards. That is NOT going to >> play nicely with file systems or buffers. >> >> Compare reading line by line over the file with readlines() and you'll >> see how abysmal this is. >> >> If you really only need one line (which isn't what your original post >> suggested), I would recommend starting with a chunk that is likely to >> include a full line, and expanding the chunk until you have that >> newline. Much more efficient than one byte at a time. > > > Well, I would like to have a sort of tail, so to generalise to more than 1 line. But I think that once you have a good algorithm for one line, you can repeat it N times. > Not always. If you know you want to read 5 lines, it's much more efficient than reading 1 line, then going back to the file, five times. Disk reads are the costliest part, with the possible exception of memory usage (but usually only because it can cause additional disk *writes*). > I understand that you can read a chunk instead of a single byte, so when the newline is found you can return all the cached chunks concatenated. But will this make the search of the start of the line faster? I suppose you have always to read byte by byte (or more, if you're using urf16 etc) and see if there's a newline. > Massively massively faster. Try it. Especially, try it on an artificially slow file system, so you can see what it costs. But you can't rely on any backwards reads unless you know for sure that the encoding supports this. UTF-8 does (you have to scan backwards for a start byte), UTF-16 does (work with pairs of bytes and check for surrogates), and fixed-width encodings do, but otherwise, you won't necessarily know when you've found a valid start point. So any reverse-read algorithm is going to be restricted to specific encodings. ChrisA From Marco.Sulla.Python at gmail.com Sun Apr 24 12:00:11 2022 From: Marco.Sulla.Python at gmail.com (Marco Sulla) Date: Sun, 24 Apr 2022 18:00:11 +0200 Subject: tail In-Reply-To: References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> Message-ID: On Sun, 24 Apr 2022 at 11:21, Roel Schroeven wrote: > dn schreef op 24/04/2022 om 0:04: > > Disagreeing with @Chris in the sense that I use tail very frequently, > > and usually in the context of server logs - but I'm talking about the > > Linux implementation, not Python code! > If I understand Marco correctly, what he want is to read the lines from > bottom to top, i.e. tac instead of tail, despite his subject. > I use tail very frequently too, but tac is something I almost never use. > Well, the inverse reader is only a secondary suggestion. I suppose a tail is much more useful. From pjfarley3 at earthlink.net Sun Apr 24 12:21:36 2022 From: pjfarley3 at earthlink.net (pjfarley3 at earthlink.net) Date: Sun, 24 Apr 2022 12:21:36 -0400 Subject: tail In-Reply-To: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> Message-ID: <006501d857f7$5f6801e0$1e3805a0$@earthlink.net> > -----Original Message----- > From: dn > Sent: Saturday, April 23, 2022 6:05 PM > To: python-list at python.org > Subject: Re: tail > > NB quite a few of IBM's (extensively researched) algorithms which formed utility > program[me]s on mainframes, made similar such algorithmic choices, in the > pursuit of efficiencies. WRT the mentioned IBM utility program[me]s, the non-Posix part of the IBM mainframe file system has always provided record-managed storage since the late 1960's (as opposed to the byte-managed storage of *ix systems) so searching for line endings was (and is) irrelevant and unnecessary in that environment. That operating system also provides basic "kernel-level" read-backwards API's for the record-managed file system, so there was never any need to build reverse-read into your code for that environment. The byte-managed file storage used by the Posix kernel running under the actually-in-charge IBM mainframe operating system is, of course, subject to the same constraints and (in)efficiencies discussed in this thread. Peter -- From michael.stemper at gmail.com Sun Apr 24 09:24:40 2022 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Sun, 24 Apr 2022 08:24:40 -0500 Subject: Style for docstring In-Reply-To: References: <1761313929.296888.1650682685708@mail.yahoo.com> <214129016.357437.1650735786870@mail.yahoo.com> Message-ID: On 23/04/2022 12.43, Avi Gross wrote: > Given what you added, Michael, your function is part of a larger?collection of functions and being compatible with the others is?a valid consideration. Whatever you decide, would ideally be?done consistently with all or most of them. > And, of course, it others in the collection also can handle?multiple ways to specify a permutation, it may be simpler?to have each call something like as.permutation() that handlesmultiple forms and converts to the one easiest for you to use. > I am not sure that is needed as I suspect the simplest storage?is something like a list:? [0,3,2,4,5,6,7,1,9,8] but could also?be shown with each cycle as a sub-list or something like anumpy vector or a customized class. Since you ask, I'm using dictionaries as the internal representation. If you think about it, a python dictionary *is* a function from one finite set to another, mathematically. And a (finite) permutation is a bijection from a (finite) set to itself. For convenience, the module provides two methods of defining a permutation other than just entering a dictionary: >>> import PermGroups as pg >>> a = {'1':'2', '2':'1', '3':'3'} >>> b = pg.ParsePerm( '(12)(3)' ) >>> c = pg.ParseDomImg( '123', '213' ) >>> a==b True >>> b==c True >>> All of the other functions work on these dictionaries. I had thought about defining a permutation object, but the conceptual match between "dict" and "permutation" was too good to discard. > Clearly if you control the package and how it is used, errors?from bad data may not be a concern. An invalidly-constructed permutation will cause an exception, so the function won't return. >>> d = {'1':'2', '2':'2', '3':'3'} >>> pg.ValidateDict(d) False >>> If I was to do it over, I would have named this function something like IsValidPermutation(), hiding the internal representation as well as making the function's Boolean nature explicit. -- Michael F. Stemper No animals were harmed in the composition of this message. From michael.stemper at gmail.com Sun Apr 24 10:12:35 2022 From: michael.stemper at gmail.com (Michael F. Stemper) Date: Sun, 24 Apr 2022 09:12:35 -0500 Subject: Style for docstring In-Reply-To: References: <1761313929.296888.1650682685708@mail.yahoo.com> <214129016.357437.1650735786870@mail.yahoo.com> Message-ID: On 24/04/2022 08.24, Michael F. Stemper wrote: > On 23/04/2022 12.43, Avi Gross wrote: >> Given what you added, Michael, your function is part of a larger?collection of functions and being compatible with the others is?a valid consideration. Whatever you decide, would ideally be?done consistently with all or most of them. >> And, of course, it others in the collection also can handle?multiple ways to specify a permutation, it may be simpler?to have each call something like as.permutation() that handlesmultiple forms and converts to the one easiest for you to use. >> I am not sure that is needed as I suspect the simplest storage?is something like a list:? [0,3,2,4,5,6,7,1,9,8] but could also?be shown with each cycle as a sub-list or something like anumpy vector or a customized class. > > Since you ask, I'm using dictionaries as the internal representation. > If you think about it, a python dictionary *is* a function from one > finite set to another, mathematically. And a (finite) permutation is > a bijection from a (finite) set to itself. > > For convenience, the module provides two methods of defining a permutation > other than just entering a dictionary: > > ?>>> import PermGroups as pg > ?>>> a = {'1':'2', '2':'1', '3':'3'} > ?>>> b = pg.ParsePerm( '(12)(3)' ) > ?>>> c = pg.ParseDomImg( '123', '213' ) > ?>>> a==b > ?True > ?>>> b==c > ?True > ?>>> > > All of the other functions work on these dictionaries. > > I had thought about defining a permutation object, but the conceptual > match between "dict" and "permutation" was too good to discard. > >> Clearly if you control the package and how it is used, errors?from bad data may not be a concern. > > An invalidly-constructed permutation will cause an exception, so > the function won't return. The below was *not* intended to illustrate what I said above. It shows the validation function provided by the module. This allows the user to avoid the consequences of an invalidly-constructed permutation. (It's only for users who don't subscribe to "EAFP", of course.) > ?>>> d = {'1':'2', '2':'2', '3':'3'} > ?>>> pg.ValidateDict(d) > ?False > ?>>> > > If I was to do it over, I would have named this function something > like IsValidPermutation(), hiding the internal representation as > well as making the function's Boolean nature explicit. > -- Michael F. Stemper Psalm 82:3-4 From wlfraed at ix.netcom.com Sun Apr 24 13:12:42 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Sun, 24 Apr 2022 13:12:42 -0400 Subject: tail References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> <006501d857f7$5f6801e0$1e3805a0$@earthlink.net> Message-ID: On Sun, 24 Apr 2022 12:21:36 -0400, declaimed the following: > >WRT the mentioned IBM utility program[me]s, the non-Posix part of the IBM mainframe file system has always provided record-managed storage since the late 1960's (as opposed to the byte-managed storage of *ix systems) so searching for line endings was (and is) irrelevant and unnecessary in that environment. That operating system also provides basic "kernel-level" read-backwards API's for the record-managed file system, so there was never any need to build reverse-read into your code for that environment. > IBM wasn't the only one... Xerox Sigma running CP/V default for text files (those created using a text editor) used numeric ISAM keys (as record numbers -- which is how their FORTRAN IV compiler did random access I/O without requiring fixed length records). The system supported three access methods: consecutive (similar to UNIX "stream" files, for files that didn't require editing, these saved disk space as the ISAM headers could be disposed of), the aforesaid keyed, and "random" (on this system, "random" meant the ONLY thing the OS did was know where the file was on disk -- files had to be contiguous and pre-allocated, and what data was in the file was strictly up to the application to manage). VAX/VMS had lots of different file structures managed by the RMS system services. The default for FORTRAN text files was a segmented model, making use of chunks of around 250 bytes [it has been years and I no longer have the documentation] in which the start of each chunk had a code for "first chunk", "last chunk", "intermediate chunk" (and maybe length of data in the chunk). A record that fit completely within one chunk would have both "first" and "last" codes set (intermediate chunks have neither code). One had to go out of their way to create a "stream" file in DEC FORTRAN 77 (open the file with CARRIAGECONTROL=CARRIAGERETURN). Other languages on the OS had different default file structures, but RMS would handle all of them transparently. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From PythonList at DancesWithMice.info Sun Apr 24 15:52:04 2022 From: PythonList at DancesWithMice.info (dn) Date: Mon, 25 Apr 2022 07:52:04 +1200 Subject: Style for docstring In-Reply-To: References: <1761313929.296888.1650682685708@mail.yahoo.com> <214129016.357437.1650735786870@mail.yahoo.com> Message-ID: <42c27e30-fa42-0740-f170-5970c7989cef@DancesWithMice.info> On 25/04/2022 01.24, Michael F. Stemper wrote: > On 23/04/2022 12.43, Avi Gross wrote: >> Given what you added, Michael, your function is part of a >> larger?collection of functions and being compatible with the others >> is?a valid consideration. Whatever you decide, would ideally be?done >> consistently with all or most of them. >> And, of course, it others in the collection also can handle?multiple >> ways to specify a permutation, it may be simpler?to have each call >> something like as.permutation() that handlesmultiple forms and >> converts to the one easiest for you to use. >> I am not sure that is needed as I suspect the simplest storage?is >> something like a list:? [0,3,2,4,5,6,7,1,9,8] but could also?be shown >> with each cycle as a sub-list or something like anumpy vector or a >> customized class. > > Since you ask, I'm using dictionaries as the internal representation. > If you think about it, a python dictionary *is* a function from one > finite set to another, mathematically. And a (finite) permutation is > a bijection from a (finite) set to itself. > > For convenience, the module provides two methods of defining a permutation > other than just entering a dictionary: > > ?>>> import PermGroups as pg > ?>>> a = {'1':'2', '2':'1', '3':'3'} > ?>>> b = pg.ParsePerm( '(12)(3)' ) > ?>>> c = pg.ParseDomImg( '123', '213' ) > ?>>> a==b > ?True > ?>>> b==c > ?True > ?>>> > > All of the other functions work on these dictionaries. > > I had thought about defining a permutation object, but the conceptual > match between "dict" and "permutation" was too good to discard. > >> Clearly if you control the package and how it is used, errors?from bad >> data may not be a concern. > > An invalidly-constructed permutation will cause an exception, so > the function won't return. > > ?>>> d = {'1':'2', '2':'2', '3':'3'} > ?>>> pg.ValidateDict(d) > ?False > ?>>> > > If I was to do it over, I would have named this function something > like IsValidPermutation(), hiding the internal representation as > well as making the function's Boolean nature explicit. Yes, we live and learn! (but 'technical debt'...) Naming something based upon its implementation, eg ValidateDict(), rather than its purpose, is a definite no-no - and while I'm nit-picking, is that a function? (and thus validate_dict()) The idea of representing perms as dicts is good-thinking! Please review UserDict (https://docs.python.org/3/library/collections.html#collections.UserDict). Sub-classing UserDict gives the advantages of a dict, without some of the methods you don't want/need, and the ability to gather custom permutation-methods into the class. For a discussion about sub-classing dict or using UserDict, may I recommend Trey Hunner's analysis, aka "there's no such thing as a free lunch" (https://treyhunner.com/2019/04/why-you-shouldnt-inherit-from-list-and-dict-in-python/) Since then, we've been given (and I haven't had a reason to try it, yet) "PEP 589 ? TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys" which may offer an alternate approach. This comes with the advantage of 'compile-time' static analysis/checking (https://peps.python.org/pep-0589/). When I get around to experimenting with this, I'll be referring to "TypedDict vs dataclasses in Python" (https://dev.to/meeshkan/typeddict-vs-dataclasses-in-python-epic-typing-battle-onb) -- Regards, =dn From PythonList at DancesWithMice.info Sun Apr 24 16:08:17 2022 From: PythonList at DancesWithMice.info (dn) Date: Mon, 25 Apr 2022 08:08:17 +1200 Subject: tail In-Reply-To: <006501d857f7$5f6801e0$1e3805a0$@earthlink.net> References: <55a04f90-8fb8-c585-afae-aca73c7d641f@DancesWithMice.info> <006501d857f7$5f6801e0$1e3805a0$@earthlink.net> Message-ID: On 25/04/2022 04.21, pjfarley3 at earthlink.net wrote: >> -----Original Message----- >> From: dn >> Sent: Saturday, April 23, 2022 6:05 PM >> To: python-list at python.org >> Subject: Re: tail >> > >> NB quite a few of IBM's (extensively researched) algorithms which formed utility >> program[me]s on mainframes, made similar such algorithmic choices, in the >> pursuit of efficiencies. > > WRT the mentioned IBM utility program[me]s, the non-Posix part of the IBM mainframe file system has always provided record-managed storage since the late 1960's (as opposed to the byte-managed storage of *ix systems) so searching for line endings was (and is) irrelevant and unnecessary in that environment. That operating system also provides basic "kernel-level" read-backwards API's for the record-managed file system, so there was never any need to build reverse-read into your code for that environment. > > The byte-managed file storage used by the Posix kernel running under the actually-in-charge IBM mainframe operating system is, of course, subject to the same constraints and (in)efficiencies discussed in this thread. Thanks for the clarification (and @wlfraed's addition). Apologies if misunderstood. The above comment was about utilities which would choose between algorithms, based on some rapid, initial, assessment of the task. It was not about 'tail' utility/ies specifically - and I don't recall using a 'tail' on mainframes, but... Thus, the observation that the OP may find that a serial, read-the-entire-file approach is faster is some situations (relatively short files). Conversely, with longer files, some sort of 'last chunk' approach would be superior. -- Regards, =dn From avigross at verizon.net Sun Apr 24 16:25:21 2022 From: avigross at verizon.net (Avi Gross) Date: Sun, 24 Apr 2022 20:25:21 +0000 (UTC) Subject: Style for docstring In-Reply-To: <1544037392.402731.1650831735675@mail.yahoo.com> References: <1761313929.296888.1650682685708@mail.yahoo.com> <214129016.357437.1650735786870@mail.yahoo.com> <1544037392.402731.1650831735675@mail.yahoo.com> Message-ID: <876237568.425159.1650831921456@mail.yahoo.com> Yes, Michael, a dictionary is an excellent way to represent a closed set of transitions?which your permutations are. You examples use numerals but obviously a dictionary will allow transformations?of anything that can be hashed which mostly is items that are not mutable. Of course for the purposes you may be using these permutations, accessing them may?be done carefully as you need to have nothing else in the dictionary and must access?all the keys and make sure you know which keys have already been visited from another?item. Some other data structures may work better or faster on smaller examples. I think you have satisfied my curiosity and your main and only question really was?on suggested wording of a Docstring. Now if only the Docstring idea was replaced by a Dictionary too! Things like: Dictstring = {"Purpose": "Text", "Args": "Text", "Return(s)": "Text", "Optional-Note": "Text", "French version": DocStringFrench} Too late to seriously change the language now! -----Original Message----- From: Michael F. Stemper To: python-list at python.org Sent: Sun, Apr 24, 2022 9:24 am Subject: Re: Style for docstring On 23/04/2022 12.43, Avi Gross wrote: > Given what you added, Michael, your function is part of a larger?collection of functions and being compatible with the others is?a valid consideration. Whatever you decide, would ideally be?done consistently with all or most of them. > And, of course, it others in the collection also can handle?multiple ways to specify a permutation, it may be simpler?to have each call something like as.permutation() that handlesmultiple forms and converts to the one easiest for you to use. > I am not sure that is needed as I suspect the simplest storage?is something like a list:? [0,3,2,4,5,6,7,1,9,8] but could also?be shown with each cycle as a sub-list or something like anumpy vector or a customized class. Since you ask, I'm using dictionaries as the internal representation. If you think about it, a python dictionary *is* a function from one finite set to another, mathematically. And a (finite) permutation is a bijection from a (finite) set to itself. For convenience, the module provides two methods of defining a permutation other than just entering a dictionary: ? >>> import PermGroups as pg ? >>> a = {'1':'2', '2':'1', '3':'3'} ? >>> b = pg.ParsePerm( '(12)(3)' ) ? >>> c = pg.ParseDomImg( '123', '213' ) ? >>> a==b ? True ? >>> b==c ? True ? >>> All of the other functions work on these dictionaries. I had thought about defining a permutation object, but the conceptual match between "dict" and "permutation" was too good to discard. > Clearly if you control the package and how it is used, errors?from bad data may not be a concern. An invalidly-constructed permutation will cause an exception, so the function won't return. ? >>> d = {'1':'2', '2':'2', '3':'3'} ? >>> pg.ValidateDict(d) ? False ? >>> If I was to do it over, I would have named this function something like IsValidPermutation(), hiding the internal representation as well as making the function's Boolean nature explicit. -- Michael F. Stemper No animals were harmed in the composition of this message. -- https://mail.python.org/mailman/listinfo/python-list From lal at solute.de Mon Apr 25 09:13:19 2022 From: lal at solute.de (Lars Liedtke) Date: Mon, 25 Apr 2022 15:13:19 +0200 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: May I stupidly ask, why one would want to use an iterable (even immutable) as dict key? I thought keys were meant to be something "singular". And yes you could also combine a string to be a key, and if you combine a string it would be somehow the same as a tuple. But anyways I still fail to see the application for that, which is most propably to ignorance rather than criticism. Cheers Lars -- Lars Liedtke Software Entwickler Phone: Fax: +49 721 98993- E-mail: lal at solute.de solute GmbH Zeppelinstra?e 15 76185 Karlsruhe Germany Marken der solute GmbH | brands of solute GmbH billiger.de | Shopping.de Gesch?ftsf?hrer | Managing Director: Dr. Thilo Gans, Bernd Vermaaten Webseite | www.solute.de Sitz | Registered Office: Karlsruhe Registergericht | Register Court: Amtsgericht Mannheim Registernummer | Register No.: HRB 110579 USt-ID | VAT ID: DE234663798 Informationen zum Datenschutz | Information about privacy policy http://solute.de/ger/datenschutz/grundsaetze-der-datenverarbeitung.php Am 21.04.22 um 07:00 schrieb Chris Angelico: > On Thu, 21 Apr 2022 at 13:23, Abdur-Rahmaan Janhangeer > wrote: >> Assumes checking for object equality before inserting. >> If they are they same, do we need different hashes? >> > The point of the hash is to find things that are equal. That's why > 1234, 1234.0, and 0j+1234.0 all have the same hash. > > If equality changes, the hash does too. It's certainly possible to > have the hash come from object identity, but then so must equality. If > you want that, it's easy to do - just create your own object for the > state, rather than using a list. But then you have to use the original > object to look things up, instead of matching by the data. > > Hashes are simply a short-hand for equality. That's all. > > ChrisA From hjp-python at hjp.at Mon Apr 25 09:54:31 2022 From: hjp-python at hjp.at (Peter J. Holzer) Date: Mon, 25 Apr 2022 15:54:31 +0200 Subject: Why no list as dict key? In-Reply-To: References: Message-ID: <20220425135431.tffgmtsugp5z5yj5@hjp.at> On 2022-04-25 15:13:19 +0200, Lars Liedtke wrote: > May I stupidly ask, why one would want to use an iterable (even immutable) > as dict key? A string is also an immutable iterable, so this is probably even the most common case. As for more complex data structures: * Tuples or immutable dicts are a good fit if want to group records by subset of their attributes (think "group by" in SQL) * Objects in general are often though of as units, even if they have composite values and you might want to look up something by that value. hp -- _ | Peter J. Holzer | Story must make more sense than reality. |_|_) | | | | | hjp at hjp.at | -- Charles Stross, "Creative writing __/ | http://www.hjp.at/ | challenge!" -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: From lal at solute.de Mon Apr 25 10:20:09 2022 From: lal at solute.de (Lars Liedtke) Date: Mon, 25 Apr 2022 16:20:09 +0200 Subject: Why no list as dict key? In-Reply-To: <20220425135431.tffgmtsugp5z5yj5@hjp.at> References: <20220425135431.tffgmtsugp5z5yj5@hjp.at> Message-ID: <257b57ef-d549-5c29-b75a-6987185f480e@solute.de> Thx, didn't see it that way yet. -- Lars Liedtke Software Entwickler Phone: Fax: +49 721 98993- E-mail: lal at solute.de solute GmbH Zeppelinstra?e 15 76185 Karlsruhe Germany Marken der solute GmbH | brands of solute GmbH billiger.de | Shopping.de Gesch?ftsf?hrer | Managing Director: Dr. Thilo Gans, Bernd Vermaaten Webseite | www.solute.de Sitz | Registered Office: Karlsruhe Registergericht | Register Court: Amtsgericht Mannheim Registernummer | Register No.: HRB 110579 USt-ID | VAT ID: DE234663798 Informationen zum Datenschutz | Information about privacy policy http://solute.de/ger/datenschutz/grundsaetze-der-datenverarbeitung.php Am 25.04.22 um 15:54 schrieb Peter J. Holzer: > On 2022-04-25 15:13:19 +0200, Lars Liedtke wrote: >> May I stupidly ask, why one would want to use an iterable (even immutable) >> as dict key? > A string is also an immutable iterable, so this is probably even the > most common case. > > As for more complex data structures: > > * Tuples or immutable dicts are a good fit if want to group records by > subset of their attributes (think "group by" in SQL) > > * Objects in general are often though of as units, even if they have > composite values and you might want to look up something by that > value. > > hp > > From skip.montanaro at gmail.com Mon Apr 25 12:21:22 2022 From: skip.montanaro at gmail.com (Skip Montanaro) Date: Mon, 25 Apr 2022 11:21:22 -0500 Subject: Receive a signal when waking or suspending? In-Reply-To: <7a911f9e-9c85-05b3-02f4-ddf877ddb75d@DancesWithMice.info> References: <7a911f9e-9c85-05b3-02f4-ddf877ddb75d@DancesWithMice.info> Message-ID: > https://duckduckgo.com/?t=ffab&q=python+up+time pointed-out the > "uptime ? Cross-platform uptime library" > - TLDR; I'm not sure if "uptime" and "boot" relate only to a > 'cold-start' or if they include bringing the machine out of 'stand-by' > or 'hibernation' Yeah, that won't help. uptime(1) gives the time since the last boot. Wake/suspend doesn't change the system's notion of boot time. > https://duckduckgo.com/?t=ffab&q=python+battery+status pointed-out > several ideas which require MS-Windows, but apparently the psutil > library could be bent to your will: > https://www.geeksforgeeks.org/python-script-to-shows-laptop-battery-percentage/ I actually already have psutil installed. It gives you details about various system bits (like battery status, which is why I installed it). It doesn't seem to have anything that will notify about state changes, just the current state (or ? for example ? continuous values like the battery state of charge). I didn't see anything regarding wake/suspend, but I might have missed it. Since my tool can't run while the system is suspended, it would always see the system as "awake" but not know for how long it was in that state. (I'm sure I could track in my tick routine and pay attention to unusually long gaps.) I think Marco's response gives me a bit better handle on what I need(*). Maybe just an easier way to do things. For example, just before suspending and just after waking, all scripts in /usr/lib/systemd/system-sleep/ are executed. The only difference is the arguments with which they are called. A script to suit my needs can just write a stream of records with timestamps. It took just a minute or so: #!/bin/sh echo "`date --iso-8601=seconds` $1 $2" >> /tmp/suspensions chmod 0644 /tmp/suspensions Here's what /tmp/suspensions looks like after a couple cycles: root at montanaro:/usr/lib/systemd/system-sleep# cat /tmp/suspensions 2022-04-23T19:17:41-05:00 pre suspend 2022-04-23T19:17:54-05:00 post suspend 2022-04-23T19:18:48-05:00 pre suspend 2022-04-23T19:19:04-05:00 post suspend My tool can monitor that file for changes and keep track of the times of state changes. It can thus track rest intervals across system suspensions and know if I've been resting for a long enough period of time to allow me to subject my wrists to further agony with the keyboard and mouse. Skip (*) man systemd-sleep contains this admonition: Note that scripts or binaries dropped in /lib/systemd/system-sleep/ are intended for local use only and *should be considered hacks*. If applications want to react to system suspend/hibernation and resume, they should rather use the Inhibitor interface[1]. A hack should suit my needs just fine. I'll leave more elegant solutions to others. :-) From gd75291 at gmail.com Sun Apr 24 13:59:53 2022 From: gd75291 at gmail.com (Greg) Date: Sun, 24 Apr 2022 13:59:53 -0400 Subject: Verifying I installed Python correctly Message-ID: I am trying to get Hello World to appear under my directory. The files of *C:\Users\gd752>cd C:\google-python-exercises> python hello.py* *The system cannot find the path specified.* *C:\Users\gd752>cd C:\google-python-exercises>* *The syntax of the command is incorrect.* I installed version 3.10. I am stuck and could use some help. Thx, [image: directory pic.png] From info at egenix.com Mon Apr 25 06:33:49 2022 From: info at egenix.com (eGenix Team) Date: Mon, 25 Apr 2022 12:33:49 +0200 Subject: ANN: eGenix Antispam Bot for Telegram 0.3.0 Message-ID: ________________________________________________________________________ ANNOUNCING eGenix Antispam Bot for Telegram Version 0.3.0 A simple, yet effective bot implementation to address Telegram signup spam. This announcement is also available on our web-site for online reading: https://www.egenix.com/company/news/eGenix-Antispam-Bot-for-Telegram-0.3.0-GA.html ________________________________________________________________________ INTRODUCTION eGenix has long been running a local user group meeting in D?sseldorf called Python Meeting D?sseldorf and we are using a Telegram group for most of our communication. In the early days, the group worked well and we only had few spammers joining it, which we could well handle manually. More recently, this has changed dramatically. We are seeing between 2-5 spam signups per day, often at night. Furthermore, the signups accounts are not always easy to spot as spammers, since they often come with profile images, descriptions, etc. With the bot, we now have a more flexible way of dealing with the problem. Please see our project page for details and download links: https://www.egenix.com/library/telegram-antispam-bot/ ________________________________________________________________________ FEATURES * Low impact mode of operation: the bot tries to keep noise in the group to a minimum * Several challenge mechanisms to choose from, more can be added as needed * Flexible and easy to use configuration * Only needs a few MB of RAM, so can easily be put into a container or run on a Raspberry Pi * Can handle quite a bit of load due to the async implementation * Works with Python 3.9+ * MIT open source licensed ________________________________________________________________________ NEWS The 0.3.0 release fixes a few bugs and adds more features: * Added new challenge ListItemChallenge * Added new config variables MAX_FAILED_CHALLENGES to limit the number of failed challenge responses. Defaults to 3. * Added docker-compose config example to sources * Fixed display of the user name to always show the full name, where available. * Added work-around for pyrogram to not create session files inside the package dir when running the bot in -m mode * Fixed bug to make file logging work * Fixed bug in ban time handling; this now works correctly It has been battle-tested in production for more than two months already and is proving to be a really useful tool to help with Telegram group administration. _______________________________________________________________________ INFORMATION About eGenix (http://www.egenix.com/): eGenix is a database focused software project, consulting and product company delivering expert services and professional quality products for companies, Python users and developers. About Python (http://www.python.org/): Python is an object-oriented Open Source programming language which runs on all modern platforms. By integrating ease-of-use, clarity in coding, enterprise application connectivity and rapid application design, Python establishes an ideal programming platform for today's IT challenges. Enjoy, -- Marc-Andre Lemburg eGenix.com Professional Python Services directly from the Experts (#1, Apr 25 2022) >>> Python Projects, Coaching and Support ... https://www.egenix.com/ >>> Python Product Development ... https://consulting.egenix.com/ ________________________________________________________________________ ::: We implement business ideas - efficiently in both time and costs ::: eGenix.com Software, Skills and Services GmbH Pastor-Loeh-Str.48 D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg Registered at Amtsgericht Duesseldorf: HRB 46611 https://www.egenix.com/company/contact/ https://www.malemburg.com/ From barry at barrys-emacs.org Mon Apr 25 14:16:13 2022 From: barry at barrys-emacs.org (Barry) Date: Mon, 25 Apr 2022 19:16:13 +0100 Subject: Verifying I installed Python correctly In-Reply-To: References: Message-ID: <7F41FA19-DEE4-4DB1-B6B5-3F86BB9CFEF5@barrys-emacs.org> > On 25 Apr 2022, at 18:51, Greg wrote: > > ?I am trying to get Hello World to appear under my directory. The files of > > *C:\Users\gd752>cd C:\google-python-exercises> python hello.py* > *The system cannot find the path specified.* Use can use py instead of python as a command and it should work. py hello.py Barry > > *C:\Users\gd752>cd C:\google-python-exercises>* > *The syntax of the command is incorrect.* > > I installed version 3.10. I am stuck and could use some help. > Thx, > > > [image: directory pic.png] > -- > https://mail.python.org/mailman/listinfo/python-list > From krlinus at yahoo.com Mon Apr 25 15:33:06 2022 From: krlinus at yahoo.com (Sunil KR) Date: Mon, 25 Apr 2022 19:33:06 +0000 (UTC) Subject: Verifying I installed Python correctly In-Reply-To: References: Message-ID: <825253146.28233.1650915186135@mail.yahoo.com> cd C:\google-python-exercises> python hello.py this doesn't looks like a valid command. However, is it because a newline got swallowed by misformatting? For clarity, I am reproducing the correct version of the steps: cd /d??C:\google-python-exercises python hello.py The error is:??The system cannot find the path specified. If the above version of the steps is what you actually performed, I think that by "path" it may be referring to the python command. For the system to be able to find python, its location should be updated in the "PATH" environment variable.? If you would rather not distract yourself with modifying the PATH variable?you can do what Barry says and just use py, because py is installed in a location already specified in PATH If you want to fix your PATH environment variable there is more than one way to do this and you may find this out by googling, as you may get a better illustrated answer than it would be possible on this forum Sunil On Monday, April 25, 2022, 10:50:52 AM PDT, Greg wrote: I am trying to get Hello World to appear under my directory. The files of *C:\Users\gd752>cd C:\google-python-exercises> python hello.py* *The system cannot find the path specified.* *C:\Users\gd752>cd C:\google-python-exercises>* *The syntax of the command is incorrect.* I installed version 3.10. I am stuck and could use some help. Thx, [image: directory pic.png] -- https://mail.python.org/mailman/listinfo/python-list From wlfraed at ix.netcom.com Mon Apr 25 15:42:26 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Mon, 25 Apr 2022 15:42:26 -0400 Subject: Verifying I installed Python correctly References: Message-ID: <4usd6hh0iloe8n10n3j5k2rgpcmvhrfk3j@4ax.com> tOn Sun, 24 Apr 2022 13:59:53 -0400, Greg declaimed the following: >I am trying to get Hello World to appear under my directory. The files of > >*C:\Users\gd752>cd C:\google-python-exercises> python hello.py* >*The system cannot find the path specified.* > >*C:\Users\gd752>cd C:\google-python-exercises>* >*The syntax of the command is incorrect.* > >I installed version 3.10. I am stuck and could use some help. >Thx, > > >[image: directory pic.png] Text only, no images on this forum. Cut&Paste the TEXT from your console window, not a screen grab. And... with that... show us the exact text. The text you show above IS invalid -- paths do not end with > character (that, when shown at the start of a command, is the prompt delimiter) and (normally space separated) is the output redirection operator when it follows a command. Your SECOND line, assuming the prompt string is just "C:\Users\gd752>" is trying to change directory to a path of "C:\google-python-exercises>" which is not valid. Take off the trailing > 05/29/2018 09:58 AM wekafiles 06/18/2020 09:43 PM workspace_v10 08/23/2018 11:25 AM workspace_v6_0 01/08/2018 01:45 PM workspace_v7 07/08/2019 12:10 PM workspace_v9 67 File(s) 355,065,731 bytes 44 Dir(s) 650,737,876,992 bytes free C:\Users\Wulfraed>cd wekafiles> The syntax of the command is incorrect. C:\Users\Wulfraed>cd wekafiles C:\Users\Wulfraed\wekafiles> Actually, based upon C:\Users\Wulfraed\wekafiles>cd .. C:\Users\Wulfraed>cd wekafiles> test.dat C:\Users\Wulfraed\wekafiles> the > is acceptable -- AS OUTPUT REDIRECTION, but the your second line does not specify the target for said redirection (not that CD has much in the way of output). This means your first line is attempting to do a CD with output redirection to a file with a questionable name C:\Users\Wulfraed>cd wekafiles> python anything.dat The system cannot find the path specified. C:\Users\Wulfraed>dir python Volume in drive C is OS Volume Serial Number is 4ACC-3CB4 Directory of C:\Users\Wulfraed 04/25/2022 03:29 PM 0 python 1 File(s) 0 bytes 0 Dir(s) 650,748,653,568 bytes free C:\Users\Wulfraed> It appears to have created a file with the name python, and then failed attempting to parse the anything.dat So... To run your script you have two choices... DIRECT invocation (from anywhere -- hence "prompt" could show anything) prompt> python C:\google-python-exercises\hello.py INDIRECT prompt> cd C:\google-python-exercises C:\google-python-exercises> python hello.py (note that the prompt has changed to reflect the CD of the first line) In neither of those do you ever type a > character. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From tdldev at gmail.com Mon Apr 25 16:11:39 2022 From: tdldev at gmail.com (Jack Dangler) Date: Mon, 25 Apr 2022 16:11:39 -0400 Subject: Verifying I installed Python correctly In-Reply-To: References: Message-ID: <584b739b-0b08-7b15-a678-c24f9abade52@gmail.com> On 4/24/22 13:59, Greg wrote: > I am trying to get Hello World to appear under my directory. The files of > > *C:\Users\gd752>cd C:\google-python-exercises> python hello.py* > *The system cannot find the path specified.* > > *C:\Users\gd752>cd C:\google-python-exercises>* > *The syntax of the command is incorrect.* > > I installed version 3.10. I am stuck and could use some help. > Thx, > > > [image: directory pic.png] Have you tried python3 hello.py From barry at barrys-emacs.org Mon Apr 25 16:49:05 2022 From: barry at barrys-emacs.org (Barry) Date: Mon, 25 Apr 2022 21:49:05 +0100 Subject: Verifying I installed Python correctly In-Reply-To: <584b739b-0b08-7b15-a678-c24f9abade52@gmail.com> References: <584b739b-0b08-7b15-a678-c24f9abade52@gmail.com> Message-ID: <0D48A034-6A50-478A-B1CD-D1CCDC1B13F8@barrys-emacs.org> > On 25 Apr 2022, at 21:14, Jack Dangler wrote: > > ? >> On 4/24/22 13:59, Greg wrote: >> I am trying to get Hello World to appear under my directory. The files of >> >> *C:\Users\gd752>cd C:\google-python-exercises> python hello.py* >> *The system cannot find the path specified.* >> >> *C:\Users\gd752>cd C:\google-python-exercises>* >> *The syntax of the command is incorrect.* >> >> I installed version 3.10. I am stuck and could use some help. >> Thx, >> >> >> [image: directory pic.png] > > Have you tried > > python3 hello.py Will not work on windows. Python is always installed as python.exe and py.exe only. Barry > > -- > https://mail.python.org/mailman/listinfo/python-list > From eryksun at gmail.com Mon Apr 25 17:49:47 2022 From: eryksun at gmail.com (Eryk Sun) Date: Mon, 25 Apr 2022 16:49:47 -0500 Subject: Verifying I installed Python correctly In-Reply-To: <0D48A034-6A50-478A-B1CD-D1CCDC1B13F8@barrys-emacs.org> References: <584b739b-0b08-7b15-a678-c24f9abade52@gmail.com> <0D48A034-6A50-478A-B1CD-D1CCDC1B13F8@barrys-emacs.org> Message-ID: On 4/25/22, Barry wrote: > >> On 25 Apr 2022, at 21:14, Jack Dangler wrote: > >> Have you tried >> >> python3 hello.py > > Will not work on windows. Python is always installed as python.exe and > py.exe only. Yes, except the app versions installed from the Microsoft Store do create appexec aliases for python.exe, python3.exe, and python3.x.exe (e.g. python3.10.exe). The aliases for installed versions can be toggled separately, so "python.exe" could be enabled to run 3.9, while "python3.exe" is enabled to run 3.10. The same applies to the "pip*" and "idle*" aliases. From wlfraed at ix.netcom.com Mon Apr 25 16:56:36 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Mon, 25 Apr 2022 16:56:36 -0400 Subject: Verifying I installed Python correctly References: <584b739b-0b08-7b15-a678-c24f9abade52@gmail.com> <0D48A034-6A50-478A-B1CD-D1CCDC1B13F8@barrys-emacs.org> Message-ID: On Mon, 25 Apr 2022 21:49:05 +0100, Barry declaimed the following: > > >> On 25 Apr 2022, at 21:14, Jack Dangler wrote: >> Have you tried >> >> python3 hello.py > >Will not work on windows. Python is always installed as python.exe and py.exe only. > Microsoft Windows [Version 10.0.19044.1645] (c) Microsoft Corporation. All rights reserved. C:\Users\Wulfraed>python3 Python ActivePython 3.8.2 (ActiveState Software Inc.) based on on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Wulfraed>python3.8 Python ActivePython 3.8.2 (ActiveState Software Inc.) based on on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Wulfraed> C:\Users\Wulfraed>echo %path% C:\Python38\;C:\Python38\DLLs\;C:\Python38\Scripts\;C:\Python38\Tools\;C:\Python38\Tools\ninja\;C:\Program Files\PuTTY\;C:\Apps\SQLite3\;C:\Apps\Firebird_4_0;C:\Apps\gnuplot\bin;C:\Apps\R\R-4.0.5\bin\x64;C:\Program Files (x86)\SciTE;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\rexx.org\Regina;C:\Apps\Rexx-Extensi C:\Users\Wulfraed>dir c:\Python38\*.exe Volume in drive C is OS Volume Serial Number is 4ACC-3CB4 Directory of c:\Python38 08/25/2020 06:52 PM 998,328 py.exe 08/25/2020 06:53 PM 102,328 python.exe 08/25/2020 06:53 PM 102,336 python3.8.exe 08/25/2020 06:53 PM 102,336 python3.exe 08/25/2020 06:53 PM 26,568 pythonservice.exe 08/25/2020 06:53 PM 100,800 pythonw.exe 08/25/2020 06:53 PM 999,352 pyw.exe 10/08/2020 05:24 PM 587,776 Removepywin32.exe 08/25/2020 06:55 PM 123,848 update_check.exe 9 File(s) 3,143,672 bytes 0 Dir(s) 650,737,926,144 bytes free C:\Users\Wulfraed> Yes, it is an older version of the ActiveState release, but they did install with the various versioned names. All I had to do was ensure the directory was on the system PATH. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From cs at cskk.id.au Mon Apr 25 18:34:34 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 26 Apr 2022 08:34:34 +1000 Subject: Style for docstring In-Reply-To: <2098309954.284734.1650684417423@mail.yahoo.com> References: <2098309954.284734.1650684417423@mail.yahoo.com> Message-ID: On 23Apr2022 03:26, Avi Gross wrote: >We know some people using "professional" language make things shorteror >talk from a point of view different than others and often in >otherwise?incomprehensible jargon. >If a programmer is taking about the algorithm that a function implements,?then, yes, they may write "scan" and "return". >But if they realize the darn documentation is for PEOPLE asking how?to use the darn thing, and want to write in more informal and?understandable English, I think it makes more sense to say what?the function does as in "scans" and importantly what it "returns" to?the user as a result. I'm in the imperative camp. But if I think the function requires some elaboration, _then_ I provide description: def f(x): ''' Return the frobnangle of `x`. This iterates over the internals of `x` in blah order gathering the earliest items which are frobby and composes a nangle of the items. ''' I very much like the concise imperative opening sentence, sometimes 2 sentences. Then the elaboration if the function isn't trivially obvious. Cheers, Cameron Simpson From cs at cskk.id.au Mon Apr 25 18:54:55 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Tue, 26 Apr 2022 08:54:55 +1000 Subject: tail In-Reply-To: References: Message-ID: On 25Apr2022 08:08, DL Neil wrote: >Thus, the observation that the OP may find that a serial, >read-the-entire-file approach is faster is some situations (relatively >short files). Conversely, with longer files, some sort of 'last chunk' >approach would be superior. If you make the chunk big enough, they're the same algorithm! It sound silly, but if you make your chunk size as big as your threshold for "this file is too big to read serially in its entirety, you may as well just write the "last chunk" flavour. Cheers, Cameron Simpson From PythonList at DancesWithMice.info Mon Apr 25 19:39:47 2022 From: PythonList at DancesWithMice.info (dn) Date: Tue, 26 Apr 2022 11:39:47 +1200 Subject: tail In-Reply-To: References: Message-ID: <8690dd6e-f26d-7165-be63-d80d03e06555@DancesWithMice.info> On 26/04/2022 10.54, Cameron Simpson wrote: > On 25Apr2022 08:08, DL Neil wrote: >> Thus, the observation that the OP may find that a serial, >> read-the-entire-file approach is faster is some situations (relatively >> short files). Conversely, with longer files, some sort of 'last chunk' >> approach would be superior. > > If you make the chunk big enough, they're the same algorithm! > > It sound silly, but if you make your chunk size as big as your threshold > for "this file is too big to read serially in its entirety, you may as > well just write the "last chunk" flavour. I like it! Yes, in the context of memory-limited mainframes being in-the-past, and our thinking has, or needs to, moved-on; memory is so much 'cheaper' and thus available for use! That said, it depends on file-size and what else is going-on in the machine/total-application. (and that's 'probably not much' as far as resource-mix is concerned!) However, I can't speak for the OP, the reason behind the post, and/or his circumstances... -- Regards, =dn From mats at wichmann.us Mon Apr 25 19:46:47 2022 From: mats at wichmann.us (Mats Wichmann) Date: Mon, 25 Apr 2022 17:46:47 -0600 Subject: Style for docstring In-Reply-To: References: <2098309954.284734.1650684417423@mail.yahoo.com> Message-ID: <9a41cbcb-c59a-4b7c-1c67-5532563f53bd@wichmann.us> On 4/25/22 16:34, Cameron Simpson wrote: > On 23Apr2022 03:26, Avi Gross wrote: >> We know some people using "professional" language make things shorteror >> talk from a point of view different than others and often in >> otherwise?incomprehensible jargon. >> If a programmer is taking about the algorithm that a function implements,?then, yes, they may write "scan" and "return". >> But if they realize the darn documentation is for PEOPLE asking how?to use the darn thing, and want to write in more informal and?understandable English, I think it makes more sense to say what?the function does as in "scans" and importantly what it "returns" to?the user as a result. > > I'm in the imperative camp. But if I think the function requires some > elaboration, _then_ I provide description: Just as another data point, if nothing else to prove there will never be consensus :) - Google's style guide is pretty explicit about what they expect: > The docstring should be descriptive-style ("""Fetches rows from a Bigtable.""") rather than imperative-style ("""Fetch rows from a Bigtable."""). From rob.cliffe at btinternet.com Mon Apr 25 19:47:14 2022 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Tue, 26 Apr 2022 00:47:14 +0100 Subject: Style for docstring In-Reply-To: References: <2098309954.284734.1650684417423@mail.yahoo.com> Message-ID: <480a4160-41b7-7995-f38f-186f99840e5d@btinternet.com> Well, de gustibus non est disputandum.? For me, the switch from the imperative mode to the descriptive mode produces a mild cognitive dissonance. Best wishes Rob Cliffe On 25/04/2022 23:34, Cameron Simpson wrote: > On 23Apr2022 03:26, Avi Gross wrote: >> We know some people using "professional" language make things shorteror >> talk from a point of view different than others and often in >> otherwise?incomprehensible jargon. >> If a programmer is taking about the algorithm that a function implements,?then, yes, they may write "scan" and "return". >> But if they realize the darn documentation is for PEOPLE asking how?to use the darn thing, and want to write in more informal and?understandable English, I think it makes more sense to say what?the function does as in "scans" and importantly what it "returns" to?the user as a result. > I'm in the imperative camp. But if I think the function requires some > elaboration, _then_ I provide description: > > def f(x): > ''' Return the frobnangle of `x`. > > This iterates over the internals of `x` in blah order > gathering the earliest items which are frobby and composes a > nangle of the items. > ''' > > I very much like the concise imperative opening sentence, sometimes 2 > sentences. Then the elaboration if the function isn't trivially obvious. > > Cheers, > Cameron Simpson From PythonList at DancesWithMice.info Mon Apr 25 21:59:53 2022 From: PythonList at DancesWithMice.info (dn) Date: Tue, 26 Apr 2022 13:59:53 +1200 Subject: Style for docstring In-Reply-To: <480a4160-41b7-7995-f38f-186f99840e5d@btinternet.com> References: <2098309954.284734.1650684417423@mail.yahoo.com> <480a4160-41b7-7995-f38f-186f99840e5d@btinternet.com> Message-ID: On 26/04/2022 11.47, Rob Cliffe via Python-list wrote: > Well, de gustibus non est disputandum.? For me, the switch from the > imperative mode to the descriptive mode produces a mild cognitive > dissonance. Disagree! When coding, to whom?what are you talking? When writing documentation - same question? This is the reason why (typically) coders are pretty bad at, or disagree with a need for, 'documentation' - and particularly documentation that doesn't fit inside a code-module! (no insult, pure observation) See earlier when I described taking a set of Requirements and progressively applying specific clauses or requirements to a function. One's thinking is in requirement-satisfaction-mode or 'design-mode'. Later, when implementing the function, one can work in 'coding-mode'. Separating tasks/roles removes the dissonance. No split-personality required! However, I know what you mean, and earlier today was writing to someone about why I may not bother with a docstring if I'm in coding-mode and wanting to 'keep going'. However, I see such as 'technical debt', justified only in the hope that when I do get back to it (presumably when the code is working, and I'm basking in the joys of (my own) success, I'll be in more of a 'documentation' frame of mind... (and pigs might fly!) > On 25/04/2022 23:34, Cameron Simpson wrote: >> On 23Apr2022 03:26, Avi Gross wrote: >>> We know some people using "professional" language make things shorteror >>> talk from a point of view different than others and often in >>> otherwise?incomprehensible jargon. >>> If a programmer is taking about the algorithm that a function >>> implements,?then, yes, they may write "scan" and "return". >>> But if they realize the darn documentation is for PEOPLE asking >>> how?to use the darn thing, and want to write in more informal >>> and?understandable English, I think it makes more sense to say >>> what?the function does as in "scans" and importantly what it >>> "returns" to?the user as a result. >> I'm in the imperative camp. But if I think the function requires some >> elaboration, _then_ I provide description: >> >> ???? def f(x): >> ???????? ''' Return the frobnangle of `x`. >> >> ???????????? This iterates over the internals of `x` in blah order >> ???????????? gathering the earliest items which are frobby and composes a >> ???????????? nangle of the items. >> ???????? ''' >> >> I very much like the concise imperative opening sentence, sometimes 2 >> sentences. Then the elaboration if the function isn't trivially obvious. >> >> Cheers, >> Cameron Simpson > -- Regards, =dn From loris.bennett at fu-berlin.de Tue Apr 26 04:19:50 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 26 Apr 2022 10:19:50 +0200 Subject: matplotlib: scatterplot and histogram with same colour scale Message-ID: <87k0bci7dl.fsf@hornfels.zedat.fu-berlin.de> Hi, I am using matplotlib to create scatterplot where the colour depends on the y-value. Additionally I want to project the y-values onto a rotated histogram along the right side of the scatterplot. My problem is that with my current code, the colours used for the histogram are normalised to the range of actual y-values. These don't match the colours in the scatterplot, which are based on the absolute y-value in the range 0-100. Can anyone tell me what I am doing wrong (code below)? Cheers, Loris import matplotlib.pyplot as plt import numpy as np efficiencies = [69, 48, 21, 28, 28, 26, 28] core_hours = [3, 8, 10, 13, 14, 18, 20] figure, axis = plt.subplots(ncols=2, nrows=1, sharey=True, gridspec_kw={'width_ratios': [10, 1]}) cm = plt.cm.RdYlGn n_bins = 10 colours = plt.get_cmap(cm)(np.linspace(0, 1, n_bins)) axis[0].scatter(core_hours, efficiencies, c=efficiencies, cmap=cm, vmin=0, vmax=100) axis[0].set_xlabel("core-hours") axis[0].set_ylabel("CPU efficiency [%]") axis[0].set_ylim(ymin=-5, ymax=105) n, bins, patches = axis[1].hist(efficiencies, n_bins, histtype='bar', orientation='horizontal') for patch, colour in zip(patches, colours): patch.set_facecolor(colour) axis[1].set_xlabel("jobs") plt.tight_layout() plt.show() plt.close() -- This signature is currently under construction. From loris.bennett at fu-berlin.de Tue Apr 26 04:36:10 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Tue, 26 Apr 2022 10:36:10 +0200 Subject: matplotlib: scatterplot and histogram with same colour scale References: <87k0bci7dl.fsf@hornfels.zedat.fu-berlin.de> Message-ID: <87fsm0i6md.fsf@hornfels.zedat.fu-berlin.de> "Loris Bennett" writes: > Hi, > > I am using matplotlib to create scatterplot where the colour depends on > the y-value. Additionally I want to project the y-values onto a rotated > histogram along the right side of the scatterplot. > > My problem is that with my current code, the colours used for the > histogram are normalised to the range of actual y-values. These don't > match the colours in the scatterplot, which are based on the absolute > y-value in the range 0-100. > > Can anyone tell me what I am doing wrong (code below)? Now I have written down the problem with MWE I can see that the mapping of the colours to the patches of the histogram is wrong. The following values illustrate the problem much better efficiencies = [51, 52, 53, 54, 55, 56, 57, 58, 59] core_hours = [ 5, 10, 15, 20, 25, 30, 35, 40, 45] The histogram is just being constructed over the actual data, which is reasonable. However, I want the histogram over the entire range 0-100, so I just need to add the 'range' parameter: n, bins, patches = axis[1].hist(efficiencies, n_bins, range=(0, 100), histtype='bar', orientation='horizontal') D'oh! > Cheers, > > Loris > > > > import matplotlib.pyplot as plt > import numpy as np > > efficiencies = [69, 48, 21, 28, 28, 26, 28] > core_hours = [3, 8, 10, 13, 14, 18, 20] > > figure, axis = plt.subplots(ncols=2, nrows=1, sharey=True, gridspec_kw={'width_ratios': [10, 1]}) > > cm = plt.cm.RdYlGn > > n_bins = 10 > colours = plt.get_cmap(cm)(np.linspace(0, 1, n_bins)) > > axis[0].scatter(core_hours, efficiencies, c=efficiencies, > cmap=cm, vmin=0, vmax=100) > axis[0].set_xlabel("core-hours") > axis[0].set_ylabel("CPU efficiency [%]") > axis[0].set_ylim(ymin=-5, ymax=105) > > n, bins, patches = axis[1].hist(efficiencies, n_bins, > histtype='bar', orientation='horizontal') > for patch, colour in zip(patches, colours): > patch.set_facecolor(colour) > axis[1].set_xlabel("jobs") > > plt.tight_layout() > plt.show() > plt.close() -- Dr. Loris Bennett (Herr/Mr) ZEDAT, Freie Universit?t Berlin Email loris.bennett at fu-berlin.de From kodjoafanou2001 at gmail.com Wed Apr 27 06:09:45 2022 From: kodjoafanou2001 at gmail.com (Julian Bikarm) Date: Wed, 27 Apr 2022 10:09:45 +0000 Subject: Please can i have your attention Message-ID: Dear , Please can I have your attention and possibly help me for humanity's sake please. I am writing this message with a heavy heart filled with sorrows and sadness. Please if you can respond, i have an issue that i will be most grateful if you could help me deal with it please. Julian From lars_martin4 at hotmail.com Wed Apr 27 15:45:34 2022 From: lars_martin4 at hotmail.com (Lars Martin Hambro) Date: Wed, 27 Apr 2022 19:45:34 +0000 Subject: windows 11 what is wrong? In-Reply-To: References: Message-ID: Repair passed but pip3 and pip did not find pip.exe and missing modules. Lars Martin hambro ________________________________ Fra: Lars Martin Hambro Sendt: onsdag 27. april 2022, 21:31 Til: python-list at python.org Emne: windows 11 what is wrong? [cid:image001.png at 01D85A7E.07A48030] [cid:image002.png at 01D85A7E.107B8820] [cid:image005.png at 01D85A7E.2DF045D0] Lars Martin Hambro From tamarp540 at gmail.com Wed Apr 27 15:44:00 2022 From: tamarp540 at gmail.com (=?UTF-8?B?16rXnteoINeV15XXodeU?=) Date: Wed, 27 Apr 2022 12:44:00 -0700 (PDT) Subject: logging library python Message-ID: <04dcd013-0c87-4405-a54c-28487c704d68n@googlegroups.com> hello, we have many scripts of one project. what is the right way to define the logger to all scripts? we tried to create class that define the logger configuration+generic function (handler functions to write generic log message), and each script define an instance of the class. But the log info is reference to the class script and not the right script. Should we need not to use the class ? should we need define logger to each script ? From wlfraed at ix.netcom.com Wed Apr 27 19:43:48 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Wed, 27 Apr 2022 19:43:48 -0400 Subject: windows 11 what is wrong? References: Message-ID: On Wed, 27 Apr 2022 19:45:34 +0000, Lars Martin Hambro declaimed the following: >Repair passed but pip3 and pip did not find pip.exe and missing modules. > This forum only accepts text. Do not attach screen grabs of windows, just highlight the console TEXT and cut/paste same. The most likely guess would be that these items are not defined in your PATH environment variable. -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From drsalists at gmail.com Wed Apr 27 21:04:20 2022 From: drsalists at gmail.com (Dan Stromberg) Date: Wed, 27 Apr 2022 18:04:20 -0700 Subject: logging library python In-Reply-To: <04dcd013-0c87-4405-a54c-28487c704d68n@googlegroups.com> References: <04dcd013-0c87-4405-a54c-28487c704d68n@googlegroups.com> Message-ID: You probably want getLogger(__name__) ...or something close to it. ?On Wed, Apr 27, 2022 at 12:58 PM ???? ?????? wrote:? > hello, > we have many scripts of one project. what is the right way to define the > logger to all scripts? we tried to create class that define the logger > configuration+generic function (handler functions to write generic log > message), and each script define an instance of the class. But the log > info is reference to the class script and not the right script. Should we > need not to use the class ? should we need define logger to each script ? > -- > https://mail.python.org/mailman/listinfo/python-list > From stephen_tucker at sil.org Thu Apr 28 07:32:22 2022 From: stephen_tucker at sil.org (Stephen Tucker) Date: Thu, 28 Apr 2022 12:32:22 +0100 Subject: Printing Unicode strings in a list Message-ID: Hi PythonList Members, Consider the following log from a run of IDLE: ================== Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32 Type "copyright", "credits" or "license()" for more information. >>> print (u"\u2551") ? >>> print ([u"\u2551"]) [u'\u2551'] >>> ================== Yes, I am still using Python 2.x - I have good reasons for doing so and will be moving to Python 3.x in due course. I have the following questions arising from the log: 1. Why does the second print statement not produce [ ?] or ["?"] ? 2. Should the second print statement produce [ ?] or ["?"] ? 3. Given that I want to print a list of Unicode strings so that their characters are displayed (instead of their Unicode codepoint definitions), is there a more Pythonic way of doing it than concatenating them into a single string and printing that? 4. Does Python 3.x exhibit the same behaviour as Python 2.x in this respect? Thanks in anticipation. Stephen Tucker. From cs at cskk.id.au Thu Apr 28 07:58:21 2022 From: cs at cskk.id.au (Cameron Simpson) Date: Thu, 28 Apr 2022 21:58:21 +1000 Subject: Printing Unicode strings in a list In-Reply-To: References: Message-ID: On 28Apr2022 12:32, Stephen Tucker wrote: >Consider the following log from a run of IDLE: >================== > >Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] >on win32 >Type "copyright", "credits" or "license()" for more information. >>>> print (u"\u2551") >? >>>> print ([u"\u2551"]) >[u'\u2551'] >>>> >================== > >Yes, I am still using Python 2.x - I have good reasons for doing so and >will be moving to Python 3.x in due course. Love to hear those reasons. Not suggesting that they are invalid. >I have the following questions arising from the log: >1. Why does the second print statement not produce [ ?] or ["?"] ? Because print() prints the str() or each of its arguments, and str() of a list if the same as its repr(), which is a list of the repr()s of every item in the list. Repr of a Unicode string looks like what you have in Python 2. >2. Should the second print statement produce [ ?] or ["?"] ? Well, to me its behaviour is correct. Do you _want_ to get your Unicode glyph? in quotes? That is up to you. But consider: what would be sane output if the list contained the string "], [3," ? >3. Given that I want to print a list of Unicode strings so that their >characters are displayed (instead of their Unicode codepoint definitions), >is there a more Pythonic way of doing it than concatenating them into a >single string and printing that? You could print them with empty separators: print(s1, s2, ......, sep='') To do that in Python 2 you need to: from __future__ import print_function at the top of your Python file. Then you've have a Python 3 string print function. In Python 2, pint is normally a statement and you don't need the brackets: print u"\u2551" but print() is genuinely better as a function anyway. >4. Does Python 3.x exhibit the same behaviour as Python 2.x in this respect? Broadly yes, except that all strings are Unicode strings and we don't bothing with the leading "u" prefix. Cheers, Cameron Simpson From stephen_tucker at sil.org Thu Apr 28 09:27:44 2022 From: stephen_tucker at sil.org (Stephen Tucker) Date: Thu, 28 Apr 2022 14:27:44 +0100 Subject: Printing Unicode strings in a list In-Reply-To: References: Message-ID: To Cameron Simpson, Thanks for your in-depth and helpful reply. I have noted it and will be giving it close attention when I can. The main reason why I am still using Python 2.x is that my colleagues are still using a GIS system that has a Python programmer's interface - and that interface uses Python 2.x. The team are moving to an updated version of the system whose Python interface is Python 3.x. However, I am expecting to retire over the next 8 months or so, so I do not need to be concerned with Python 3.x - my successor will be doing that. Stephen. On Thu, Apr 28, 2022 at 2:07 PM Cameron Simpson wrote: > On 28Apr2022 12:32, Stephen Tucker wrote: > >Consider the following log from a run of IDLE: > >================== > > > >Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] > >on win32 > >Type "copyright", "credits" or "license()" for more information. > >>>> print (u"\u2551") > >? > >>>> print ([u"\u2551"]) > >[u'\u2551'] > >>>> > >================== > > > >Yes, I am still using Python 2.x - I have good reasons for doing so and > >will be moving to Python 3.x in due course. > > Love to hear those reasons. Not suggesting that they are invalid. > > >I have the following questions arising from the log: > >1. Why does the second print statement not produce [ ?] or ["?"] ? > > Because print() prints the str() or each of its arguments, and str() of > a list if the same as its repr(), which is a list of the repr()s of > every item in the list. Repr of a Unicode string looks like what you > have in Python 2. > > >2. Should the second print statement produce [ ?] or ["?"] ? > > Well, to me its behaviour is correct. Do you _want_ to get your Unicode > glyph? in quotes? That is up to you. But consider: what would be sane > output if the list contained the string "], [3," ? > > >3. Given that I want to print a list of Unicode strings so that their > >characters are displayed (instead of their Unicode codepoint definitions), > >is there a more Pythonic way of doing it than concatenating them into a > >single string and printing that? > > You could print them with empty separators: > > print(s1, s2, ......, sep='') > > To do that in Python 2 you need to: > > from __future__ import print_function > > at the top of your Python file. Then you've have a Python 3 string print > function. In Python 2, pint is normally a statement and you don't need > the brackets: > > print u"\u2551" > > but print() is genuinely better as a function anyway. > > >4. Does Python 3.x exhibit the same behaviour as Python 2.x in this > respect? > > Broadly yes, except that all strings are Unicode strings and we don't > bothing with the leading "u" prefix. > > Cheers, > Cameron Simpson > -- > https://mail.python.org/mailman/listinfo/python-list > From jon+usenet at unequivocal.eu Thu Apr 28 07:52:56 2022 From: jon+usenet at unequivocal.eu (Jon Ribbens) Date: Thu, 28 Apr 2022 11:52:56 -0000 (UTC) Subject: Printing Unicode strings in a list References: Message-ID: On 2022-04-28, Stephen Tucker wrote: > Hi PythonList Members, > > Consider the following log from a run of IDLE: > >================== > > Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] > on win32 > Type "copyright", "credits" or "license()" for more information. >>>> print (u"\u2551") > ? >>>> print ([u"\u2551"]) > [u'\u2551'] >>>> > >================== > > Yes, I am still using Python 2.x - I have good reasons for doing so and > will be moving to Python 3.x in due course. > > I have the following questions arising from the log: > > 1. Why does the second print statement not produce [ ?] or ["?"] ? print(x) implicitly calls str(x) to convert 'x' to a string for output. lists don't have their own str converter, so fall back to repr instead, which outputs '[', followed by the repr of each list item separated by ', ', followed by ']'. > 2. Should the second print statement produce [ ?] or ["?"] ? There's certainly no obvious reason why it *should*, and pretty decent reasons why it shouldn't (it would be a hybrid mess of Python-syntax repr output and raw string output). > 3. Given that I want to print a list of Unicode strings so that their > characters are displayed (instead of their Unicode codepoint definitions), > is there a more Pythonic way of doing it than concatenating them into a > single string and printing that? print(' '.join(list_of_strings)) is probably most common. I suppose you could do print(*list_of_strings) if you like, but I'm not sure I'd call it "pythonic" as I've never seen anyone do that (that doesn't mean of course that other people haven't seen it done!) Personally I only tend to use print() for debugging output. > 4. Does Python 3.x exhibit the same behaviour as Python 2.x in this respect? Yes. From ethan at stoneleaf.us Thu Apr 28 09:55:56 2022 From: ethan at stoneleaf.us (Ethan Furman) Date: Thu, 28 Apr 2022 06:55:56 -0700 Subject: Async SIG post Message-ID: Anybody interested in asynchronous programming may want to check out async-sig at python.org as it has an interesting post about ASGI and PEPs 3156 and 3333. Sign up at https://mail.python.org/mailman3/lists/async-sig.python.org/ and see the archive at https://mail.python.org/archives/list/async-sig at python.org/ -- ~Ethan~ From rob.cliffe at btinternet.com Thu Apr 28 16:37:49 2022 From: rob.cliffe at btinternet.com (Rob Cliffe) Date: Thu, 28 Apr 2022 21:37:49 +0100 Subject: Printing Unicode strings in a list In-Reply-To: References: Message-ID: On 28/04/2022 14:27, Stephen Tucker wrote: > To Cameron Simpson, > > Thanks for your in-depth and helpful reply. I have noted it and will be > giving it close attention when I can. > > The main reason why I am still using Python 2.x is that my colleagues are > still using a GIS system that has a Python programmer's interface - and > that interface uses Python 2.x. > > The team are moving to an updated version of the system whose Python > interface is Python 3.x. > > However, I am expecting to retire over the next 8 months or so, so I do not > need to be concerned with Python 3.x - my successor will be doing that. > > Still, if you're feeling noble, you could start the work of making your code Python 3 compatible.? Best wishes Rob Cliffe From george at fischhof.hu Fri Apr 29 05:31:47 2022 From: george at fischhof.hu (George Fischhof) Date: Fri, 29 Apr 2022 11:31:47 +0200 Subject: Testing an app protected by Okta authorization code with PKCE flow Message-ID: Hi Folks, has anyone of you a working solution for testing an app protected by Okta authorization code with PKCE flow? Meaning to get a bearer token? I saw / read several articles about it on the net, and several hacks (that is not problem now ;) ), but it seems that neither of them works with Okta. We are using Okta's .net backend stuff and Angular widget BR, George From loris.bennett at fu-berlin.de Fri Apr 29 09:02:46 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Fri, 29 Apr 2022 15:02:46 +0200 Subject: Instatiating module / Reusing module of command-line tool Message-ID: <87o80kxcsp.fsf@hornfels.zedat.fu-berlin.de> Hi, I have a command-line script in Python to get the correct salutation for a user name in either English or German from a 'salutation server': $ get_salutation alice Dear Professor M?ller $ get_salutation alice -l de Sehr geehrte Frau Professorin M?ller The hostname, port, user and password for the 'salutation server' can be given as options on the command-line, but if omitted are read from a configuration file. The program is implemented in two modules without any classes: main.py: ... parse command-line options, read config file ... salutation = my_mailer.salutations.get_salutation(args.user, args.lang, args.host, args.port, args.user, args.secret) salutations.py def get_salutation(uid, lang, host, port, user, secret): ... I have another program that is intended to run as a cron job and send an email to certain users. This is implemented as a number of modules without any classes and will need to use the 'get_salutation' function from the first module. My question: What is the analogue to initialising an object via the constructor for a module? My understanding is that a module is a singleton of the class 'module'. So do I just write a method which reads the config file, or is there some more standardised way which corresponds to instantiating an object via my_object = MyClass() in the case of a class. Cheers, Loris -- This signature is currently under construction. From loris.bennett at fu-berlin.de Fri Apr 29 03:49:47 2022 From: loris.bennett at fu-berlin.de (Loris Bennett) Date: Fri, 29 Apr 2022 09:49:47 +0200 Subject: Match.groupdict: Meaning of default argument? Message-ID: <877d78z5us.fsf@hornfels.zedat.fu-berlin.de> Hi, If I do import re pattern = re.compile(r'(?P\d*)(-?)(?P\d\d):(?P\d\d):(?P\d\d)') s = '104-02:47:06' match = pattern.search(s) match_dict = match.groupdict('0') I get match_dict {'days': '104', 'hours': '02', 'minutes': '47', 'seconds': '06'} However, if the string has no initial part (corresponding to the number of days), e.g. s = '02:47:06' match = pattern.search(s) match_dict = match.groupdict('0') I get match_dict {'days': '', 'hours': '02', 'minutes': '47', 'seconds': '06'} I thought that 'days' would default to '0'. What am I doing wrong? Cheers, Loris -- This signature is currently under construction. From vlastimil.brom at gmail.com Sat Apr 30 10:02:22 2022 From: vlastimil.brom at gmail.com (Vlastimil Brom) Date: Sat, 30 Apr 2022 16:02:22 +0200 Subject: Printing Unicode strings in a list In-Reply-To: References: Message-ID: ?t 28. 4. 2022 v 13:33 odes?latel Stephen Tucker napsal: > > Hi PythonList Members, > > Consider the following log from a run of IDLE: > > ================== > > Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] > on win32 > Type "copyright", "credits" or "license()" for more information. > >>> print (u"\u2551") > ? > >>> print ([u"\u2551"]) > [u'\u2551'] > >>> > > ================== > > Yes, I am still using Python 2.x - I have good reasons for doing so and > will be moving to Python 3.x in due course. > > I have the following questions arising from the log: > > 1. Why does the second print statement not produce [ ?] or ["?"] ? > > 2. Should the second print statement produce [ ?] or ["?"] ? > > 3. Given that I want to print a list of Unicode strings so that their > characters are displayed (instead of their Unicode codepoint definitions), > is there a more Pythonic way of doing it than concatenating them into a > single string and printing that? > > 4. Does Python 3.x exhibit the same behaviour as Python 2.x in this respect? > > Thanks in anticipation. > > Stephen Tucker. > -- > https://mail.python.org/mailman/listinfo/python-list Hi, I'm not sure, whether I am not misunderstanding the 4th question or the answers to it (it is not clear to me, whether the focus is on character printing or the quotation marks...); in either case, in python3 the character glyphs are printed in these cases, instead of the codepoint number notation, cf.: ================== Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit ( AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> print ([u"\u2551"]) ['?'] >>> >>> print([u"\u2551"]) ['?'] >>> print("\u2551") ? >>> print("?") ? >>> print(repr("\u2551")) '?' >>> print(ascii("\u2551")) '\u2551' >>> ================== (Even the redundant u prefix from your python2 sample is apparently accepted, maybe for compatibility reasons.) hth, vbr From rosuav at gmail.com Sat Apr 30 10:35:23 2022 From: rosuav at gmail.com (Chris Angelico) Date: Sun, 1 May 2022 00:35:23 +1000 Subject: Printing Unicode strings in a list In-Reply-To: References: Message-ID: On Sun, 1 May 2022 at 00:03, Vlastimil Brom wrote: > (Even the redundant u prefix from your python2 sample is apparently > accepted, maybe for compatibility reasons.) Yes, for compatibility reasons. It wasn't accepted in Python 3.0, but 3.3 re-added it to make porting easier. It doesn't do anything. ChrisA From brent at brenthunter.tv Sat Apr 30 18:37:35 2022 From: brent at brenthunter.tv (Brent Hunter) Date: Sat, 30 Apr 2022 22:37:35 +0000 Subject: Python Question re Executing a Script Message-ID: Hello, I just purchased a new Windows 11 computer and installed Python 3.10.4 (64 bit). I can't figure out from your documentation, how do I: 1. Run a python script that is located in the same directory ( C:\Users\Brent\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.10 ) 1. How do I automatically run a python app at Windows startup? Thank you! Brent Hunter From PythonList at DancesWithMice.info Sat Apr 30 20:47:52 2022 From: PythonList at DancesWithMice.info (dn) Date: Sun, 1 May 2022 12:47:52 +1200 Subject: Python Question re Executing a Script In-Reply-To: References: Message-ID: <53812267-c467-bc22-b762-1aa31d06d1c1@DancesWithMice.info> On 01/05/2022 10.37, Brent Hunter wrote: > Hello, > > I just purchased a new Windows 11 computer and installed Python 3.10.4 (64 bit). I can't figure out from your documentation, how do I: > > > 1. Run a python script that is located in the same directory ( C:\Users\Brent\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.10 ) > > > 1. How do I automatically run a python app at Windows startup? > > Thank you! > > Brent Hunter Please start with https://docs.python.org/3/using/windows.html -- Regards, =dn From wlfraed at ix.netcom.com Sat Apr 30 19:44:56 2022 From: wlfraed at ix.netcom.com (Dennis Lee Bieber) Date: Sat, 30 Apr 2022 19:44:56 -0400 Subject: Python Question re Executing a Script References: Message-ID: On Sat, 30 Apr 2022 22:37:35 +0000, Brent Hunter declaimed the following: >Hello, > >I just purchased a new Windows 11 computer and installed Python 3.10.4 (64 bit). I can't figure out from your documentation, how do I: > > > 1. Run a python script that is located in the same directory ( C:\Users\Brent\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.10 ) > ONE: that path indicates that you installed Python "for current user only". TWO: that is the path for the short cut entry that shows up on the Windows "Start Menu" (whatever that looks like on Win11). It is NOT a location for user scripts. Python, at heart, is a language interpreter that is invoked from a command line shell. (Use to exit the interpreter if you are trying the below examples -- otherwise you'd add the path/name of the script file to the command line) -=-=- Microsoft Windows [Version 10.0.19044.1645] (c) Microsoft Corporation. All rights reserved. C:\Users\Wulfraed>python Python ActivePython 3.8.2 (ActiveState Software Inc.) based on on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Wulfraed>py Python ActivePython 3.8.2 (ActiveState Software Inc.) based on on win32 Type "help", "copyright", "credits" or "license" for more information. >>> C:\Users\Wulfraed> -=-=- It can run from scripts invoked by double-clicking on the file in the "file explorer" but often the results are not as desired (it will pop up a console window -- but that window closes as soon as the script exits!). Scripts written using one of the graphical libraries (Tkinter, wxPython, etc.) are typically given a .pyw extension -- .pyw is normally associated with an alternate start-up module which suppresses the console window. Editing of scripts can be done with one's favorite programming text editor. If one can't live without having some sort of IDE, look for something called IDLE to be on your start menu (IDLE is actually a Python script using Tkinter). > > 1. How do I automatically run a python app at Windows startup? Short answer: the same way you would run ANY application at start-up. Longer answer: this is a feature of the OS, not Python. You will need to learn how to use the OS. Maybe start with https://www.google.com/search?q=run+application+at+startup+windows+11&source=hp&ei=t1htYpm0K5OtqtsPiMKMwAc&iflsig=AJiK0e8AAAAAYm1mx0aL7YbWlEj0j-yPiL8J4H8HFoxo&ved=0ahUKEwjZ6-T3j7z3AhWTlmoFHQghA3gQ4dUDCAk&uact=5&oq=run+application+at+startup+windows+11&gs_lcp=Cgdnd3Mtd2l6EAMyBQghEKsCMgUIIRCrAjIFCCEQqwIyCAghEBYQHRAeOgUIABCABDoOCC4QgAQQsQMQgwEQ1AI6CAgAEIAEELEDOhEILhCABBCxAxCDARDHARDRAzoICC4QgAQQsQM6CwgAEIAEELEDEIMBOggILhCxAxCDAToFCC4QgAQ6EQguEIAEELEDEIMBEMcBEKMCOgsILhCABBDHARCjAjoICC4QgAQQ1AI6CwguEIAEELEDEIMBOgsILhCABBCxAxDUAjoOCC4QsQMQgwEQxwEQowI6DgguEIAEELEDEMcBENEDOg4ILhCABBCxAxCDARDJAzoICAAQsQMQgwE6BwgAEIAEEAo6CAgAEIAEEMkDOgYIABAWEB46BQgAEIYDUL0NWNRZYO9caAFwAHgBgAHYAYgBpx6SAQcyNC4xMi4xmAEAoAEBsAEA&sclient=gws-wiz > >Thank you! > >Brent Hunter -- Wulfraed Dennis Lee Bieber AF6VN wlfraed at ix.netcom.com http://wlfraed.microdiversity.freeddns.org/ From miked at dewhirst.com.au Sat Apr 30 22:15:01 2022 From: miked at dewhirst.com.au (Mike Dewhirst) Date: Sun, 1 May 2022 12:15:01 +1000 Subject: Python Question re Executing a Script In-Reply-To: References: Message-ID: <179f20f3-fe04-2c2c-6f61-e7e4b71127ef@dewhirst.com.au> On 1/05/2022 8:37 am, Brent Hunter wrote: > Hello, > > I just purchased a new Windows 11 computer and installed Python 3.10.4 (64 bit). I can't figure out from your documentation, how do I: > > > 1. Run a python script that is located in the same directory ( C:\Users\Brent\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Python 3.10 ) > > > 1. How do I automatically run a python app at Windows startup? https://www.windowscentral.com/how-launch-apps-automatically-during-login-windows-11 Personally, I write a batch file containing the 'python /location/of/script.py' command line and call that batch file. That assumes python.exe is on the Windows path. Once tested and working it lets me edit the batch file to adjust the payload without having to touch the Windows stuff again. > > Thank you! > > Brent Hunter > -- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Just ask and I'll send it to you. Your email software can handle signing. -------------- next part -------------- A non-text attachment was scrubbed... Name: OpenPGP_signature Type: application/pgp-signature Size: 495 bytes Desc: OpenPGP digital signature URL: