From b9a3bdbaa84aebb3b05efec697132b4e5020d102 Mon Sep 17 00:00:00 2001 From: j Date: Wed, 29 Mar 2023 17:34:27 +0200 Subject: [PATCH] Update page 'Day 1' --- Day 1.md | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 Day 1.md diff --git a/Day 1.md b/Day 1.md new file mode 100644 index 0000000..e5fe37d --- /dev/null +++ b/Day 1.md @@ -0,0 +1,150 @@ +# Notes on the Python Language Reference, chapters 1 and 2. + +## Chapter 1 + +1. CPython is the version of python you're most familiar with. We will only be looking at this. It's also by far the most popular version. + +2. BNF grammar is a way of saying how to take characters (in the computer sense, not in the Asian language orthography sense), and turn them into words, called *tokens*. [1] Characters come in on the right, and get turned into the tokens listed on the left. This process is called *lexing*, and is performed by a *lexical analyzer*. This is a relatively simply piece of software which simply loops through every character, sees if it matches a token definition, then outputs the token. + +The resulting tokens are consumed by a *parser*, which knows about language *grammar*. The lexer only knows about *spelling*. As a result, the lexer can output a token stream such as: + +`MAN DOG EAT` + +Which are each, individually, spelled correctly as individual words, but are in the wrong order. The *parser's* job is to check to make sure things are in the correct order, and other rules such as quoting and commenting are enforced. + +Note that the lexical definitions for most languages are more complicated than you might expect. For example, a common security issue is that numbers in many programming languages and data formats are often defined as one of four types: + +* Integers: `1`, +* Floating-point: `1.0`, +* Hexadecimal: `0x1`, and +* Complex: `(1,1)`. + +The problem is that you can combine these in unexpected ways to get past naive filters, such as decimalized hexadecimal complex numbers: `(0x1.1,0x1.1)`. + +As you can imagine, this sort of input can cause serious problems if the lexical definitions used by these fundamental language elements are not precisely defined to not allow this. + +## Chapter 2 +### 2.1.2 + +Pay close attention to the differences between the line ending characters between Windows, Traditional Macintosh, and Unix. Although the Internet has collapsed most of these down to Unix line endings, Windows still has issues opening any file that contains them, even a simple .txt file, and working with a team that uses both operating systems can cause file format issues when transferring data back and forth. In general, you don't want to do that anyway, you should use a source control repository or an Intranet system such as Sharepoint, because it knows how to automatically convert the line endings based on the recipient. + +Anything that touches the Internet should only use Unix line endings (0x0A). Finding files with other line endings on the Internet is very rare these days outside specialized commercial systems such as EDI or financial industry networks. + +Question: Why do you think Python adds a concept of a *logical line* in addition to the physical one? + +### 2.1.3 + +Question: Python doesn't have the concept of multi-line comments like other C-like languages: + +``` +/* + This is a comment. + */ +``` + +Sometimes, you want to "turn off" a large block of code this way for testing. How would you do that in Python? [2] + +### 2.1.4 + +Don't worry about that regular expression, you'll pick that up later. Just know that a regular expression, or `regex`, is a way of saying that a particular string matches some kind of filter or not. + +Exercise: Ask ChatGPT or Bing or another LLM what that regular expression is, and the reasoning why comments that match it are treated specially. See if Visual Studio Code supports this. + +### 2.1.8 + +Don't worry about getting all the formal indentation rules down, we'll cover those during class. Do read the note about spaces vs tabs, though. Note that this is a sensitive subject for some programmers. + +### 2.1.9 + +Question: why would you want to separate tokens with tabs instead of spaces? + +### 2.3 + +Uh, just ignore all of this for now. + +### 2.3.1 + +You should be able to explain what each of these keywords mean after a few weeks. + +### 2.3.3 + +Note that the underscore prefix is a general convention in most programming languages which indicates that the identifier is part of an internal implementation and code outside the current module shouldn't be messing with it. + +### 2.4.1 + +Unfortunately, you will have to memorize the BNF rules in the first two tables. It's easier than it looks, because they form patterns. + +You won't have to memorize the escape sequence rules, yet, but you should know that this is where you need to look them up when you need to put control characters in a string. + +### 2.4.3 + +The format protocol described here is a complicated topic, don't worry about understanding what a protocol is yet. I'll explain during class. + +### 2.4.5-2.4.7 + +You don't have to memorize all these rules, but you need to know where to look these up as well. + +Question: do you know why Python uses "j" for complex numbers instead of "i" like in standard mathematical notation? + +### 2.5-2.6 + +You don't have to know what these operators all do... actually I don't even recognize some of them, but you should know what a `unary operator` and `binary operator` are, and the difference between them. You can ignore the section about delimiters, that's probably included for people working on the Python interpreter itself. + +[1] You will probably never have to write BNF grammars, but you should be able to read them because it is by far the fastest way to learn a new language. + +[2] One way that I don't recommend is using triple quotes, because this still returns a string that can be cast unintentionally to a value. I asked GPT-4 for an example and it came up with what I thought was a pretty good one: + +Here's an example demonstrating an unintended side effect of using triple quotes for commenting that can change the program logic: + +Consider the following code, where we have a function that counts the number of even numbers in a given list and has a print statement to display intermediate results: + +```python +def count_evens(numbers): + count = 0 + for num in numbers: + if num % 2 == 0: + count += 1 + print(f"{num} is even.") + return count + +my_list = [1, 2, 3, 4, 5, 6] +print(f"Number of even numbers: {count_evens(my_list)}") +``` + +Now, let's say we want to comment out the print statement using triple quotes: + +```python +def count_evens(numbers): + count = 0 + for num in numbers: + if num % 2 == 0: + count += 1 + """ + print(f"{num} is even.") + """ + return count + +my_list = [1, 2, 3, 4, 5, 6] +print(f"Number of even numbers: {count_evens(my_list)}") +``` + +This code seems fine at first glance, but it introduces an unintended side effect. The triple quotes are being used inside an `if` block, which means that the multi-line string created between the triple quotes is now part of the block's content. + +The multi-line string is treated as an expression with a value, and since it's not `None`, it's considered a "truthy" value in a boolean context. This means that the presence of the multi-line string is affecting the control flow, and the `if` block is no longer only dependent on the `num % 2 == 0` condition. The logic of the program is unintentionally changed. + +To avoid this issue, you should use the hash symbol (`#`) to comment out code: + +```python +def count_evens(numbers): + count = 0 + for num in numbers: + if num % 2 == 0: + count += 1 + # print(f"{num} is even.") + return count + +my_list = [1, 2, 3, 4, 5, 6] +print(f"Number of even numbers: {count_evens(my_list)}") +``` + +By using the hash symbol to comment out the print statement, the program logic remains unchanged, and the control flow is not affected. \ No newline at end of file