diff --git a/.gitignore b/.gitignore index 057dcb0..998895f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,8 @@ irrelevant/.ipynb_checkpoints/ irrelevant/.python-version .idea/ +.vscode/ + +# Virtual envitonments +venv/ +.venv/ diff --git a/README.md b/README.md index 17851d0..2c6b043 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,10 @@ -

+

+ + + + Shows a wtfpython logo. + +

What the f*ck Python! 😱

Exploring and understanding Python through surprising snippets.

@@ -352,7 +358,14 @@ Makes sense, right? * All length 0 and length 1 strings are interned. * Strings are interned at compile time (`'wtf'` will be interned but `''.join(['w', 't', 'f'])` will not be interned) * Strings that are not composed of ASCII letters, digits or underscores, are not interned. This explains why `'wtf!'` was not interned due to `!`. CPython implementation of this rule can be found [here](https://github.com/python/cpython/blob/3.6/Objects/codeobject.c#L19) - ![image](/images/string-intern/string_intern.png) +

+ + + + Shows a string interning process. + +

+ + When `a` and `b` are set to `"wtf!"` in the same line, the Python interpreter creates a new object, then references the second variable at the same time. If you do it on separate lines, it doesn't "know" that there's already `"wtf!"` as an object (because `"wtf!"` is not implicitly interned as per the facts mentioned above). It's a compile-time optimization. This optimization doesn't apply to 3.7.x versions of CPython (check this [issue](https://github.com/satwikkansal/wtfpython/issues/100) for more discussion). + A compile unit in an interactive environment like IPython consists of a single statement, whereas it consists of the entire module in case of modules. `a, b = "wtf!", "wtf!"` is single statement, whereas `a = "wtf!"; b = "wtf!"` are two statements in a single line. This explains why the identities are different in `a = "wtf!"; b = "wtf!"`, and also explain why they are same when invoked in `some_file.py` + The abrupt change in the output of the fourth snippet is due to a [peephole optimization](https://en.wikipedia.org/wiki/Peephole_optimization) technique known as Constant folding. This means the expression `'a'*20` is replaced by `'aaaaaaaaaaaaaaaaaaaa'` during compilation to save a few clock cycles during runtime. Constant folding only occurs for strings having a length of less than 21. (Why? Imagine the size of `.pyc` file generated as a result of the expression `'a'*10**10`). [Here's](https://github.com/python/cpython/blob/3.6/Python/peephole.c#L288) the implementation source for the same. @@ -975,11 +988,23 @@ We didn't assign three `"X"`s, did we? When we initialize `row` variable, this visualization explains what happens in the memory -![image](/images/tic-tac-toe/after_row_initialized.png) +

+ + + + Shows a memory segment after row is initialized. + +

And when the `board` is initialized by multiplying the `row`, this is what happens inside the memory (each of the elements `board[0]`, `board[1]` and `board[2]` is a reference to the same list referred by `row`) -![image](/images/tic-tac-toe/after_board_initialized.png) +

+ + + + Shows a memory segment after board is initialized. + +

We can avoid this scenario here by not using `row` variable to generate `board`. (Asked in [this](https://github.com/satwikkansal/wtfpython/issues/68) issue). diff --git a/images/expanding-brain-meme.jpg b/images/expanding-brain-meme.jpg deleted file mode 100644 index 9437c2f..0000000 Binary files a/images/expanding-brain-meme.jpg and /dev/null differ diff --git a/images/logo-dark.png b/images/logo-dark.png deleted file mode 100644 index 9d7791f..0000000 Binary files a/images/logo-dark.png and /dev/null differ diff --git a/images/logo.png b/images/logo.png deleted file mode 100644 index 014a63a..0000000 Binary files a/images/logo.png and /dev/null differ diff --git a/images/logo.svg b/images/logo.svg new file mode 100755 index 0000000..6ec5eda --- /dev/null +++ b/images/logo.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/logo_dark_theme.svg b/images/logo_dark_theme.svg new file mode 100755 index 0000000..f89e797 --- /dev/null +++ b/images/logo_dark_theme.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/images/string-intern/string_intern.png b/images/string-intern/string_intern.png deleted file mode 100644 index 6511978..0000000 Binary files a/images/string-intern/string_intern.png and /dev/null differ diff --git a/images/string-intern/string_interning.svg b/images/string-intern/string_interning.svg new file mode 100755 index 0000000..0572a9e --- /dev/null +++ b/images/string-intern/string_interning.svg @@ -0,0 +1,4 @@ + + + +
PyStringObject
PyStringObject
"wtf!"
"wtf!"
a
a
PyStringObject
PyStringObject
"wtf!"
"wtf!"
b
b
PyStringObject
PyStringObject
"wtf!"
"wtf!"
a
a
b
b
Text is not SVG - cannot display
diff --git a/images/string-intern/string_interning_dark_theme.svg b/images/string-intern/string_interning_dark_theme.svg new file mode 100755 index 0000000..69c32e4 --- /dev/null +++ b/images/string-intern/string_interning_dark_theme.svg @@ -0,0 +1,4 @@ + + + +
PyStringObject
PyStringObject
"wtf!"
"wtf!"
a
a
PyStringObject
PyStringObject
"wtf!"
"wtf!"
b
b
PyStringObject
PyStringObject
"wtf!"
"wtf!"
a
a
b
b
Text is not SVG - cannot display
diff --git a/images/tic-tac-toe.png b/images/tic-tac-toe.png deleted file mode 100644 index 9c25117..0000000 Binary files a/images/tic-tac-toe.png and /dev/null differ diff --git a/images/tic-tac-toe/after_board_initialized.png b/images/tic-tac-toe/after_board_initialized.png deleted file mode 100644 index 616747f..0000000 Binary files a/images/tic-tac-toe/after_board_initialized.png and /dev/null differ diff --git a/images/tic-tac-toe/after_board_initialized.svg b/images/tic-tac-toe/after_board_initialized.svg new file mode 100755 index 0000000..02b1dad --- /dev/null +++ b/images/tic-tac-toe/after_board_initialized.svg @@ -0,0 +1,4 @@ + + + +
" "
" "
" "
" "
" "
" "
row
row
board[0]
board[0]
board[1]
board[1]
board[2]
board[2]
Text is not SVG - cannot display
\ No newline at end of file diff --git a/images/tic-tac-toe/after_board_initialized_dark_theme.svg b/images/tic-tac-toe/after_board_initialized_dark_theme.svg new file mode 100755 index 0000000..3218ad0 --- /dev/null +++ b/images/tic-tac-toe/after_board_initialized_dark_theme.svg @@ -0,0 +1,4 @@ + + + +
" "
" "
" "
" "
" "
" "
row
row
board[0]
board[0]
board[1]
board[1]
board[2]
board[2]
Text is not SVG - cannot display
\ No newline at end of file diff --git a/images/tic-tac-toe/after_row_initialized.png b/images/tic-tac-toe/after_row_initialized.png deleted file mode 100644 index 520d700..0000000 Binary files a/images/tic-tac-toe/after_row_initialized.png and /dev/null differ diff --git a/images/tic-tac-toe/after_row_initialized.svg b/images/tic-tac-toe/after_row_initialized.svg new file mode 100755 index 0000000..92eb02c --- /dev/null +++ b/images/tic-tac-toe/after_row_initialized.svg @@ -0,0 +1,4 @@ + + + +
" "
" "
" "
" "
" "
" "
row
row
Text is not SVG - cannot display
\ No newline at end of file diff --git a/images/tic-tac-toe/after_row_initialized_dark_theme.svg b/images/tic-tac-toe/after_row_initialized_dark_theme.svg new file mode 100755 index 0000000..2404958 --- /dev/null +++ b/images/tic-tac-toe/after_row_initialized_dark_theme.svg @@ -0,0 +1,4 @@ + + + +
" "
" "
" "
" "
" "
" "
row
row
Text is not SVG - cannot display
\ No newline at end of file diff --git a/irrelevant/wtf.ipynb b/irrelevant/wtf.ipynb index a3147e1..4ea2333 100644 --- a/irrelevant/wtf.ipynb +++ b/irrelevant/wtf.ipynb @@ -4,7 +4,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "

\"\"

\n", + "\"wtfpython\n", "

What the f*ck Python! \ud83d\ude31

\n", "

Exploring and understanding Python through surprising snippets.

\n", "\n", @@ -355,7 +355,7 @@ " * All length 0 and length 1 strings are interned.\n", " * Strings are interned at compile time (`'wtf'` will be interned but `''.join(['w', 't', 'f'])` will not be interned)\n", " * Strings that are not composed of ASCII letters, digits or underscores, are not interned. This explains why `'wtf!'` was not interned due to `!`. CPython implementation of this rule can be found [here](https://github.com/python/cpython/blob/3.6/Objects/codeobject.c#L19)\n", - " ![image](/images/string-intern/string_intern.png)\n", + "\"Shows\n", "+ When `a` and `b` are set to `\"wtf!\"` in the same line, the Python interpreter creates a new object, then references the second variable at the same time. If you do it on separate lines, it doesn't \"know\" that there's already `\"wtf!\"` as an object (because `\"wtf!\"` is not implicitly interned as per the facts mentioned above). It's a compile-time optimization. This optimization doesn't apply to 3.7.x versions of CPython (check this [issue](https://github.com/satwikkansal/wtfpython/issues/100) for more discussion).\n", "+ A compile unit in an interactive environment like IPython consists of a single statement, whereas it consists of the entire module in case of modules. `a, b = \"wtf!\", \"wtf!\"` is single statement, whereas `a = \"wtf!\"; b = \"wtf!\"` are two statements in a single line. This explains why the identities are different in `a = \"wtf!\"; b = \"wtf!\"`, and also explain why they are same when invoked in `some_file.py`\n", "+ The abrupt change in the output of the fourth snippet is due to a [peephole optimization](https://en.wikipedia.org/wiki/Peephole_optimization) technique known as Constant folding. This means the expression `'a'*20` is replaced by `'aaaaaaaaaaaaaaaaaaaa'` during compilation to save a few clock cycles during runtime. Constant folding only occurs for strings having a length of less than 21. (Why? Imagine the size of `.pyc` file generated as a result of the expression `'a'*10**10`). [Here's](https://github.com/python/cpython/blob/3.6/Python/peephole.c#L288) the implementation source for the same.\n", @@ -2947,11 +2947,11 @@ "\n", "When we initialize `row` variable, this visualization explains what happens in the memory\n", "\n", - "![image](/images/tic-tac-toe/after_row_initialized.png)\n", + "\"Shows\n", "\n", "And when the `board` is initialized by multiplying the `row`, this is what happens inside the memory (each of the elements `board[0]`, `board[1]` and `board[2]` is a reference to the same list referred by `row`)\n", "\n", - "![image](/images/tic-tac-toe/after_board_initialized.png)\n", + "\"Shows\n", "\n", "We can avoid this scenario here by not using `row` variable to generate `board`. (Asked in [this](https://github.com/satwikkansal/wtfpython/issues/68) issue).\n", "\n" @@ -13475,4 +13475,4 @@ "metadata": {}, "nbformat": 4, "nbformat_minor": 2 -} \ No newline at end of file +} diff --git a/translations/ru-russian/README.md b/translations/ru-russian/README.md index d8dff4a..1936149 100644 --- a/translations/ru-russian/README.md +++ b/translations/ru-russian/README.md @@ -1,4 +1,10 @@ -

+

+ + + + Π›ΠΎΠ³ΠΎΡ‚ΠΈΠΏ wtfpython + +

What the f*ck Python! 😱

Π˜Π·ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ Python с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² повСдСния.

@@ -408,7 +414,13 @@ False - ВсС строки Π΄Π»ΠΈΠ½ΠΎΠΉ 0 ΠΈΠ»ΠΈ 1 символа ΠΈΠ½Ρ‚Π΅Ρ€Π½ΠΈΡ€ΡƒΡŽΡ‚ΡΡ. - Π‘Ρ‚Ρ€ΠΎΠΊΠΈ ΠΈΠ½Ρ‚Π΅Ρ€Π½ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π²ΠΎ врСмя компиляции (`'wtf'` Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Ρ€Π½ΠΈΡ€ΠΎΠ²Π°Π½Π°, Π½ΠΎ `''.join(['w'', 't', 'f'])` - Π½Π΅Ρ‚) - Π‘Ρ‚Ρ€ΠΎΠΊΠΈ, Π½Π΅ состоящиС ΠΈΠ· Π±ΡƒΠΊΠ² ASCII, Ρ†ΠΈΡ„Ρ€ ΠΈΠ»ΠΈ Π·Π½Π°ΠΊΠΎΠ² подчСркивания, Π½Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π½ΠΈΡ€ΡƒΡŽΡ‚ΡΡ. Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π²Ρ‹ΡˆΠ΅ `'wtf!'` Π½Π΅ интСрнируСтся ΠΈΠ·-Π·Π° `!`. Π Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ этого ΠΏΡ€Π°Π²ΠΈΠ»Π° Π² CPython ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ [здСсь](https://github.com/python/cpython/blob/3.6/Objects/codeobject.c#L19) - ![image](/images/string-intern/string_intern.png) +

+ + + + ΠŸΡ€ΠΎΡ†Π΅ΡΡ интСрнирования строк. + +

- Когда ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ `a` ΠΈ `b` ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ `"wtf!"` Π² ΠΎΠ΄Π½ΠΎΠΉ строкС, ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€ Python создаСт Π½ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ссылаСтся Π½Π° Π²Ρ‚ΠΎΡ€ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ. Если это выполняСтся Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… строках, ΠΎΠ½ Π½Π΅ "Π·Π½Π°Π΅Ρ‚", Ρ‡Ρ‚ΠΎ ΡƒΠΆΠ΅ сущСствуСт `"wtf!"` ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ `"wtf!"` Π½Π΅ являСтся нСявно ΠΈΠ½Ρ‚Π΅Ρ€Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π² соотвСтствии с Ρ„Π°ΠΊΡ‚Π°ΠΌΠΈ, упомянутыми Π²Ρ‹ΡˆΠ΅). Π­Ρ‚ΠΎ оптимизация Π²ΠΎ врСмя компиляции, Π½Π΅ примСняСтся ΠΊ вСрсиям CPython 3.7.x (Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ обсуТдСниС смотритС [здСсь](https://github.com/satwikkansal/wtfpython/issues/100)). - Π•Π΄ΠΈΠ½ΠΈΡ†Π° компиляции Π² ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΉ срСдС IPython состоит ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π°, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ Π² случаС ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΉ ΠΎΠ½Π° состоит ΠΈΠ· всСго модуля. `a, b = "wtf!", "wtf!"` - это ΠΎΠ΄Π½ΠΎ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅, Ρ‚ΠΎΠ³Π΄Π° ΠΊΠ°ΠΊ `a = "wtf!"; b = "wtf!"` - это Π΄Π²Π° утвСрТдСния Π² ΠΎΠ΄Π½ΠΎΠΉ строкС. Π­Ρ‚ΠΎ ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚, ΠΏΠΎΡ‡Π΅ΠΌΡƒ тоТдСства Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ Π² `a = "wtf!"; b = "wtf!"`, Π½ΠΎ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Π² ΠΌΠΎΠ΄ΡƒΠ»Π΅. - Π Π΅Π·ΠΊΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π² Π²Ρ‹Π²ΠΎΠ΄Π΅ Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠ³ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π° связано с [peephole optimization](https://en.wikipedia.org/wiki/Peephole_optimization) Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΎΠΉ, извСстной ΠΊΠ°ΠΊ складываниС констант (Π°Π½Π³Π». Constant folding). Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ `'a'*20` замСняСтся Π½Π° `'aaaaaaaaaaaaaaaaaaaa'` Π²ΠΎ врСмя компиляции, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΡΠΊΠΎΠ½ΠΎΠΌΠΈΡ‚ΡŒ нСсколько Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π²ΠΎ врСмя выполнСния. Π‘ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π½ΠΈΠ΅ констант происходит Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для строк Π΄Π»ΠΈΠ½ΠΎΠΉ ΠΌΠ΅Π½Π΅Π΅ 21. (ΠŸΠΎΡ‡Π΅ΠΌΡƒ? ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅ сСбС Ρ€Π°Π·ΠΌΠ΅Ρ€ Ρ„Π°ΠΉΠ»Π° `.pyc`, созданного Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ выполнСния выраТСния `'a'*10**10`). [Π’ΠΎΡ‚](https://github.com/python/cpython/blob/3.6/Python/peephole.c#L288) исходный тСкст Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ для этого. @@ -1038,11 +1050,23 @@ board = [row] * 3 Когда ΠΌΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ `row`, эта визуализация ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ происходит Π² памяти -![image](/images/tic-tac-toe/after_row_initialized.png) +

+ + + + Π―Ρ‡Π΅ΠΉΠΊΠ° памяти послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ пСрСмСнная row ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π°. + +

А ΠΊΠΎΠ³Π΄Π° пСрСмСнная `board` инициализируСтся ΠΏΡƒΡ‚Π΅ΠΌ умноТСния `row`, Π²ΠΎΡ‚ Ρ‡Ρ‚ΠΎ происходит Π² памяти (ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· элСмСнтов `board[0]`, `board[1]` ΠΈ `board[2]` являСтся ссылкой Π½Π° Ρ‚ΠΎΡ‚ ΠΆΠ΅ список, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ссылаСтся `row`) -![image](/images/tic-tac-toe/after_board_initialized.png) +

+ + + + Π―Ρ‡Π΅ΠΉΠΊΠ° памяти послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ пСрСмСнная board ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π°. + +

ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ этого сцСнария, Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ `row` для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ `board`. (ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ Π² [issue](https://github.com/satwikkansal/wtfpython/issues/68)).