Re: Extract lines from file, add to new files
On 2024-01-13 at 02:02:39 +0100, Left Right via Python-list wrote: > Actually, after some Web search. I think, based on this: > https://docs.python.org/3/reference/simple_stmts.html#grammar-token-python-grammar-augtarget > that in Python you call this "augmented assignment target". The term > isn't in the glossary, but so are many others. The Python term, at least colloquially, is "tuple unpacking." HTH. -- https://mail.python.org/mailman/listinfo/python-list
Re: Extract lines from file, add to new files
On Sat, 13 Jan 2024 at 13:11, Left Right via Python-list wrote: > > Very few > languages allow arbitrary complex expressions in the same place they > allow variable introduction. What do you mean by this? Most languages I've worked with allow variables to be initialized with arbitrary expressions, and a lot of languages allow narrowly-scoped variables. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: Extract lines from file, add to new files
Actually, after some Web search. I think, based on this: https://docs.python.org/3/reference/simple_stmts.html#grammar-token-python-grammar-augtarget that in Python you call this "augmented assignment target". The term isn't in the glossary, but so are many others. On Sat, Jan 13, 2024 at 1:45 AM Left Right wrote: > > > surprising for me: > > Surprise is subjective, it's based on personal experience. Very few > languages allow arbitrary complex expressions in the same place they > allow variable introduction. The fact that "i" is not defined is > irrelevant to this example. Most programmers who haven't memorized > Python grammar by heart, but expect the language to behave similar to > the languages in the same category would be surprised this code is > valid (i.e. can be parsed), whether it results in error or not is of > no consequence. > > > There's no destructuring going on here > > I use the term "destructuring" in the same way Hyperspec uses it. > It's not a Python term. I don't know what you call the same thing in > Python. I'm not sure what you understand from it. > > On Sat, Jan 13, 2024 at 12:37 AM Greg Ewing via Python-list > wrote: > > > > On 13/01/24 12:11 am, Left Right wrote: > > > x = [...] > > > for x[i] in x: print(i) > > > > I suspect you've misremembered something, because this doesn't > > do anything surprising for me: > > > > >>> x = [1, 2, 3] > > >>> for x[i] in x: print(i) > > ... > > Traceback (most recent call last): > >File "", line 1, in > > NameError: name 'i' is not defined > > > > There's no destructuring going on here, just assignment to a > > sequence item. > > > > -- > > Greg > > -- > > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Extract lines from file, add to new files
> surprising for me: Surprise is subjective, it's based on personal experience. Very few languages allow arbitrary complex expressions in the same place they allow variable introduction. The fact that "i" is not defined is irrelevant to this example. Most programmers who haven't memorized Python grammar by heart, but expect the language to behave similar to the languages in the same category would be surprised this code is valid (i.e. can be parsed), whether it results in error or not is of no consequence. > There's no destructuring going on here I use the term "destructuring" in the same way Hyperspec uses it. It's not a Python term. I don't know what you call the same thing in Python. I'm not sure what you understand from it. On Sat, Jan 13, 2024 at 12:37 AM Greg Ewing via Python-list wrote: > > On 13/01/24 12:11 am, Left Right wrote: > > x = [...] > > for x[i] in x: print(i) > > I suspect you've misremembered something, because this doesn't > do anything surprising for me: > > >>> x = [1, 2, 3] > >>> for x[i] in x: print(i) > ... > Traceback (most recent call last): >File "", line 1, in > NameError: name 'i' is not defined > > There's no destructuring going on here, just assignment to a > sequence item. > > -- > Greg > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: Extract lines from file, add to new files
On 13/01/24 12:11 am, Left Right wrote: x = [...] for x[i] in x: print(i) I suspect you've misremembered something, because this doesn't do anything surprising for me: >>> x = [1, 2, 3] >>> for x[i] in x: print(i) ... Traceback (most recent call last): File "", line 1, in NameError: name 'i' is not defined There's no destructuring going on here, just assignment to a sequence item. -- Greg -- https://mail.python.org/mailman/listinfo/python-list
Re: Extract lines from file, add to new files
To people discussing BNF: The grammar language Python uses is *very* far from BNF. It's more similar to PEG, but even then it's still quite far. Python's grammar is just its own thing, which makes it harder to read, if you are already familiar with other more popular formats. I've also found bugs in Python parser before, so had this turned out to be a real issue, this wouldn't have been the first time. There are plenty of weird corners in Python grammar that allow unexpected programs to parse (and sometimes even run!), and these are very often connected to assignments, because, in general, assignments in Python are very elaborate and hard to describe / conceptualize about. The most popular example I've even seen used in coding interviews (which I think is a silly gimmick, but that's kind of the whole point of a lot of these interviews...) is: x = [...] for x[i] in x: print(i) Which is not an assignment by itself, but the "weirdness" results from the loop syntax sharing definitions with the "destructuring bind" style of assignment (i.e. where the left-hand side can be an arbitrary complex expression). I was surprised, for example, to learn that "as" in "with_stmt" isn't shared with "as" in "except_block" (so, from the grammar perspective, these are two different keywords), and that asterisk in "except_block" isn't shared with "star_target" (also weird, since you'd think these should be the same thing). In general, and by and large, if you look at Python's grammar there are many "weird" choices that it makes to describe the language which seem counterintuitive to the programmer who tries to learn the language from examples (i.e. context-depending meaning of parenthesis, of asterisk, of period etc.) Having been exposed to this, you'd start to expect that some of this weirdness will eventually result in bugs, or at least in unexpected behavior. Anyways. To the OP: I'm sorry to hijack your question. Below is the complete program: with ( open('example.txt', 'r') as e, open('emails.txt', 'w') as m, open('salutations.txt', 'w') as s, ): for line in e: if line.strip(): (m if '@' in line else s).write(line) it turned out to be not quite the golfing material I was hoping for. But, perhaps a somewhat interesting aspect of this program you don't see used a lot in the wild is the parenthesis in the "with" head. So, it's not a total write-off from the learning perspective. I.e. w/o looking at the grammar, and had I have this code in a coding interview question, I wouldn't be quite sure whether this code would work or not: one way to interpret what's going on here is to think that the expression inside parentheses is a tuple, and since tuples aren't context managers, it wouldn't have worked (or maybe not even parsed as "as" wouldn't be allowed inside tuple definition since there's no "universal as-expression" in Python it's hard to tell what the rules are). But, it turns out there's a form of "with" that has parentheses for decoration purposes, and that's why it parses and works to the desired effect. Since it looks like you are doing this for educational reasons, I think there's a tiny bit of value to my effort. On Fri, Jan 12, 2024 at 8:08 AM Grizzy Adams via Python-list wrote: > > Thursday, January 11, 2024 at 10:44, Rich Shepard via Python-list wrote: > Re: Extract lines from file, add to (at least in part) > > >On Thu, 11 Jan 2024, MRAB via Python-list wrote: > > >> From the look of it: > >> 1. If the line is empty, ignore it. > >> 2. If the line contains "@", it's an email address. > >> 3. Otherwise, it's a name. > > If that is it all? a simple Grep would do (and save on the blank line) > -- > https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
RE: Extract lines from file, add to new files
On Fri, 12 Jan 2024, AVI GROSS via Python-list wrote: But is the solution a good one for some purpose? The two output files may end up being out of sync for all kinds of reasons. One of many "errors" can happen if multiple lines in a row do not have an "@" or a person's name does, for example. What if someone supplied more than one email address with a comma separator? This may not be expected but could cause problems. Avi, For my use 1) the salutation and email address (always with an '@') are sequential and 2) I'm developing the script to extract both from the same file. Regards, Rich -- https://mail.python.org/mailman/listinfo/python-list
RE: Extract lines from file, add to new files
If the data in the input file is exactly as described and consists of alternating lines containing a name and email address, or perhaps an optional blank line, then many solutions are possible using many tools including python programs. But is the solution a good one for some purpose? The two output files may end up being out of sync for all kinds of reasons. One of many "errors" can happen if multiple lines in a row do not have an "@" or a person's name does, for example. What if someone supplied more than one email address with a comma separator? This may not be expected but could cause problems. Some of the other tools mentioned would not care and produce garbage. Grep as an example could be run twice asking for lines with an "@" and then lines without. In this case, that would be trivial. Blank lines, or ones with just whitespace, might need another pass to be omitted. But a real challenge would be to parse the file in a language like Python and find all VALID stretches in the data and construct a data structure containing either a valid name or something specific like "ANONYMOUS" alongside an email address. These may be written out as soon as it is considered valid, or collected in something like a list. You can do further processing if you want the results in some order or remove duplicates or bad email addresses and so on. In that scenario, the two files would be written out at the end. Python can do the above while some of the other tools mentioned are not really designed for it. Further, many of the tools are not generally available everywhere. Another question is why it makes sense to produce two output files to contain the data that may not be linked and would not be easy to edit and keep synchronized such as to remove or add entries. There are many ways to save the data that might be more robust for many purposes. It looks like the application intended is a sort of form letter merge where individual emails will be sent that contain a personalized greeting. Unless that application has already been written, there are many other ways that make sense. One obvious one is to save the data in a databases as columns in a table. Other ones are to write one file with entries easily parsed out such as: NAME: name | EMAIL: email Whatever the exact design, receiving software could parse that out as needed by the simpler act of reading one line at a time. And, of course, there are endless storage formats such as a CSV file or serializing your list of objects to a file so that the next program can load them in and operate from memory on all the ones it wants. The two file solution may seem simpler but harks back to how some computing was done in early days when list of objects might be handled by having multiple arrays with each containing one aspect of the object and updating required rememebreing to touch each array the same way.. That can still be a useful technique when some operations being done in a vectoried manner might be faster than an array of objects, but is more often a sign of poor code. -Original Message- From: Python-list On Behalf Of Grizzy Adams via Python-list Sent: Friday, January 12, 2024 1:59 AM To: Rich Shepard via Python-list ; Rich Shepard Subject: Re: Extract lines from file, add to new files Thursday, January 11, 2024 at 10:44, Rich Shepard via Python-list wrote: Re: Extract lines from file, add to (at least in part) >On Thu, 11 Jan 2024, MRAB via Python-list wrote: >> From the look of it: >> 1. If the line is empty, ignore it. >> 2. If the line contains "@", it's an email address. >> 3. Otherwise, it's a name. If that is it all? a simple Grep would do (and save on the blank line) -- https://mail.python.org/mailman/listinfo/python-list -- https://mail.python.org/mailman/listinfo/python-list
Re: mypy question
Op 29/12/2023 om 16:02 schreef Karsten Hilbert via Python-list: Am Fri, Dec 29, 2023 at 07:49:17AM -0700 schrieb Mats Wichmann via Python-list: I am not sure why mypy thinks this gmPG2.py:554: error: Argument "queries" to "run_rw_queries" has incompatible type "List[Dict[str, str]]"; expected "List[Dict[str, Union[str, List[Any], Dict[str, Any" [arg-type] rows, idx = run_rw_queries(link_obj = conn, queries = queries, return_data = True) ^~~ should be flagged. The intent is for "queries" to be a list of dicts with keys of str and values of str OR list of anything OR dict with keys of str and values of anything I'd have thunk list[dict[str,str]] matches that ? Dict[str, str] means the key type and value type should both be strings, Indeed, I know that much, list[dict[str, str]] is what is getting passed in in this particular invocation of run_rw_queries(). For what it's worth here's the signature of that function: def run_rw_queries ( link_obj:_TLnkObj=None, queries:list[dict[str, str | list | dict[str, Any]]]=None, end_tx:bool=False, return_data:bool=None, get_col_idx:bool=False, verbose:bool=False ) -> tuple[list[dbapi.extras.DictRow], dict[str, int] | None]: Given that I would have thought that passing in list[dict[str, str]] for "queries" ought to be type safe. Mypy indicates otherwise which I am not grokking as to why. but in your retelling above you indicate lots of possible value types... actually the mypy guess seems to be a pretty good recreation of your psuedo-code description. I agree that mypy's grasp of my intent from queries:list[dict[str, str | list | dict[str, Any]]]=None, into "List[Dict[str, Union[str, List[Any], Dict[str, Any" seems accurate. I just don't understand why list[dict[str, str]] should not pass that construct. Sorry for the late reaction and may be I am missing something, but I was wondering if your type hint for queries shouldn't be the following. queries:list[dict[str,str]|dict[str,list]|dict[str,dict[str, dict[str, Ant]]] My impression at this moment is that you are write something like: dict[str, str | int] as as shorthand for dict[str, str] | dict[str, int]. But those two are different types. -- Antoon Pardon. -- https://mail.python.org/mailman/listinfo/python-list