Extract lines from file, add to new files

dn PythonList at DancesWithMice.info
Sat Jan 13 22:41:44 EST 2024


On 13/01/24 00:11, Left Right via Python-list wrote:
> 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.

Second time to ameliorate wording-dispute in this thread! The original 
phrase was: "[modified] BNF". Some of us have worked with various forms 
and evolutions of BNF since back in the days of COBOL-60 proposals, and 
know it when we see it!

 From the 'book of words': <<<The descriptions of lexical analysis and 
syntax use a modified Backus–Naur form (BNF) grammar notation.>>>
https://docs.python.org/3/reference/introduction.html#notation

Yes it is hard to read - and even harder to learn-from; which is why 
@Chris gave advice about preferring tutorials/text.

Just because there are other (more popular?) formats, doesn't make the 
one used here 'wrong'. In the same way that Python code differs from 
'the same' in other languages.

Putting it another way: if what Python is doing is wrong in your 
opinion, you are in the wrong place (for you).

That is not to say that Python has everything 'right'. One of my own 
bug-bears is very similar - that the string formatting 'mini-language' 
(https://docs.python.org/3/library/string.html#formatspec) does not 
follow the same rules about white-space as everything covered by the PEG 
Parser.

BTW the PEG Parser is relatively new to Python. IIRC there was comment 
at the time of its first application, that some 'other' areas of Python 
might take a while to be converted-over.


> I've also found bugs in Python parser before, so had this turned out

Sorry, didn't recognise your email-handle - not that I'm a Python 
Core-Dev, and pretty much ignore the "Ideas" list these days. Must have 
missed your previous contributions...


> 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).

You're right. (also about stupid 'interviewing' ideas) If someone asked 
me this, I'd respond by asking if that was the standard of code they 
work towards - and depending upon that answer would either walk-out or 
refer the matter to a more senior manager!


In Python, everything is an object. As long as the LHS is a legal-object 
which  makes sense for the situation, it can be used.

Also, an identifier (whether x, i, or x[ i ]) should not only be 
considered to be its own object, but is best regarded as a pointer to 
some value. This is how we can have an 'immutable' tuple 'containing' a 
mutable list (for example) - such that elements of that list may be 
changed, despite being 'part of' an immutable construct!

Programs are read by people. If something is a "weirdness", then 
chances-are it won't survive a CodeReview/a professional team's 
expected-standard. Not limited to Python-code!


> 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.

You're right. It is potentially confusing when the same word/symbol is 
used in different contexts.

I've heard similar questions from learners, but not had anyone trying to 
mis-use something extrapolating from how the 'same' is used elsewhere. YMMV!

It's the context part that's important to remember. If someone calls you 
"mate", that has different connotations depending upon whether you're 
friends, you're on a Navy ship, or in a more intimate situation - indeed 
there are some cultures in which the word "mate" is not used to mean 
'friend' at all. Which is (more) right? Which wrong?

Perhaps you're aiming for, or even used to, a more perfect and 
predictable language?


> ----
> 
> 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)

Please see responses elsewhere which say why this sort of thing, whilst 
possible and 'easy', is not recommendable.


> 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.

Again, context! All that is important 'here' is how to 'link' the 
file-descriptor with an identifier. Similarly, whilst we could write:

a, b, c = 1, 2, 3

(and BTW that is legal Python - for anyone seeing such for the first time)
and whilst it is shorter (and I've been known to write such), the need 
to read carefully in order to pair-up the relative positions make it 
less readable than

a = 1; b = 2; c = 3

(and some would argue, quite reasonably, that it would be better were 
they on separate lines)

Similarly, many dev.teams have a 'standard' which suggests that once a 
function/method has three or more arguments, relative-positioning should 
go out-the-window, in favor of named-arguments. This speeds 
comprehension and reduces errors.

In the original mental-model, the difficulty was which file-descriptor 
would be paired with which file (previously described). The multiple 
as-s make it more readable and more comprehensible.


> Since it looks like you are doing this for educational reasons, I
> think there's a tiny bit of value to my effort.

That's what we're (all) here for!
(and not forgetting that the OP described a skill-level well below that 
of most of this post and your question, which enabled (and deserved, 
IMHO) appropriate respect).

-- 
Regards,
=dn


More information about the Python-list mailing list