WhilesomeoftheexamplesyouseebelowmaynotbeWTFsinthetruestsense, butthey'll reveal some of the interesting parts of Python that you might be unaware of. I find it a nice way to learn the internals of a programming language, and I think you'llfindtheminterestingaswell!
-Carefullyreadtheinitialcodeforsettinguptheexample. Ifyou're an experienced Python programmer, most of the times you will successfully anticipate what'sgoingtohappennext.
+When`a`and`b`aresetto`"wtf!"`inthesameline, thePythoninterpretercreatesanewobject, thenreferencesthesecondvariableatthesametime. Ifyoudoitonseparatelines, itdoesn't "know" that there'salready`wtf!`asanobject (because`"wtf!"`isnotimplicitlyinternedasperthefactsmentionedabove). It'sacompileroptimizationandspecificallyappliestotheinteractiveenvironment.
+Constantfoldingisatechniquefor [peepholeoptimization](https://en.wikipedia.org/wiki/Peephole_optimization) inPython. Thismeanstheexpression`'a'*20`isreplacedby`'aaaaaaaaaaaaaaaaaaaa'`duringcompilationtoreducefewclockcyclesduringruntime. Constantfoldingonlyoccursforstringshavinglengthlessthan20. (Why? Imaginethesizeof`.pyc`filegeneratedasaresultoftheexpression`'a'*10**10`). [Here's](https://github.com/python/cpython/blob/3.6/Python/peephole.c#L288) the implementation source for the same.
Heretheinterpreterisn't smart enough while executing `y = 257` to recognize that we'vealreadycreatedanintegerofthevalue`257,`andsoitgoesontocreateanotherobjectinthememory.
*Whenaandbaresetto`257`inthesameline, thePythoninterpretercreatesanewobject, thenreferencesthesecondvariableatthesametime. Ifyoudoitonseparatelines, itdoesn't "know" that there'salready`257`asanobject.
*It's a compiler optimization and specifically applies to the interactive environment. When you enter two lines in a live interpreter, they'recompiledseparately, thereforeoptimizedseparately. Ifyouweretotrythisexampleina`.py`file, youwouldnotseethesamebehavior, becausethefileiscompiledallatonce.
---
### ▶ A tic-tac-toe where X wins in the first attempt!
-**Note:**Thetrailingcommaproblemis [fixedinPython3.6](https://bugs.python.org/issue9232). Theremarksin [this](https://bugs.python.org/issue9232#msg248399) post discuss in brief different usages of trailing commas in Python.
+Pythonsupportsimplicit [stringliteralconcatenation](https://docs.python.org/2/reference/lexical_analysis.html#string-literal-concatenation), Example,
```
>>>print("wtf""python")
wtfpython
>>>print("wtf""") # or "wtf"""
wtf
```
+ `'''` and `"""` are also string delimiters in Python which causes a SyntaxError because the Python interpreter was expecting a terminating triple quote as delimiter while scanning the currently encountered triple quoted string literal.
---
### ▶ Midnight time doesn't exist?
```py
from datetime import datetime
midnight = datetime(2018, 1, 1, 0, 0)
midnight_time = midnight.time()
noon = datetime(2018, 1, 1, 12, 0)
noon_time = noon.time()
if midnight_time:
print("Time at midnight is", midnight_time)
if noon_time:
print("Time at noon is", noon_time)
```
**Output:**
```sh
('Time at noon is', datetime.time(12, 0))
```
The midnight time is not printed.
#### 💡 Explanation:
Before Python 3.5, the boolean value for `datetime.time` object was considered to be `False` if it represented midnight in UTC. It is error-prone when using the `if obj:` syntax to check if the `obj` is null or some equivalent of "empty."
---
### ▶ What's wrong with booleans?
1\.
```py
# A simple example to count the number of boolean and
* The integer value of `True` is `1` and that of `False` is `0`.
```py
>>> True == 1 == 1.0 and False == 0 == 0.0
True
```
* See this StackOverflow [answer](https://stackoverflow.com/a/8169049/4354153) for the rationale behind it.
---
### ▶ Class attributes and instance attributes
1\.
```py
class A:
x = 1
class B(A):
pass
class C(A):
pass
```
**Output:**
```py
>>> A.x, B.x, C.x
(1, 1, 1)
>>> B.x = 2
>>> A.x, B.x, C.x
(1, 2, 1)
>>> A.x = 3
>>> A.x, B.x, C.x
(3, 2, 3)
>>> a = A()
>>> a.x, A.x
(3, 3)
>>> a.x += 1
>>> a.x, A.x
(4, 3)
```
2\.
```py
class SomeClass:
some_var = 15
some_list = [5]
another_list = [5]
def __init__(self, x):
self.some_var = x + 1
self.some_list = self.some_list + [x]
self.another_list += [x]
```
**Output:**
```py
>>> some_obj = SomeClass(420)
>>> some_obj.some_list
[5, 420]
>>> some_obj.another_list
[5, 420]
>>> another_obj = SomeClass(111)
>>> another_obj.some_list
[5, 111]
>>> another_obj.another_list
[5, 420, 111]
>>> another_obj.another_list is SomeClass.another_list
True
>>> another_obj.another_list is some_obj.another_list
True
```
#### 💡 Explanation:
* Class variables and variables in class instances are internally handled as dictionaries of a class object. If a variable name is not found in the dictionary of the current class, the parent classes are searched for it.
* The `+=` operator modifies the mutable object in-place without creating a new object. So changing the attribute of one instance affects the other instances and the class attribute as well.
---
### ▶ yielding None
```py
some_iterable = ('a', 'b')
def some_func(val):
return "something"
```
**Output:**
```py
>>> [x for x in some_iterable]
['a', 'b']
>>> [(yield x) for x in some_iterable]
<generator object <listcomp> at 0x7f70b0a4ad58>
>>> list([(yield x) for x in some_iterable])
['a', 'b']
>>> list((yield x) for x in some_iterable)
['a', None, 'b', None]
>>> list(some_func((yield x)) for x in some_iterable)
['a', 'something', 'b', 'something']
```
#### 💡 Explanation:
- Source and explanation can be found here: https://stackoverflow.com/questions/32139885/yield-in-list-comprehensions-and-generator-expressions
- Related bug report: http://bugs.python.org/issue10544
---
### ▶ Mutating the immutable!
```py
some_tuple = ("A", "tuple", "with", "values")
another_tuple = ([1, 2], [3, 4], [5, 6])
```
**Output:**
```py
>>> some_tuple[2] = "change this"
TypeError: 'tuple' object does not support item assignment
>>> another_tuple[2].append(1000) #This throws no error
>>> another_tuple
([1, 2], [3, 4], [5, 6, 1000])
>>> another_tuple[2] += [99, 999]
TypeError: 'tuple' object does not support item assignment
>>> another_tuple
([1, 2], [3, 4], [5, 6, 1000, 99, 999])
```
But I thought tuples were immutable...
#### 💡 Explanation:
* Quoting from https://docs.python.org/2/reference/datamodel.html
> Immutable sequences
An object of an immutable sequence type cannot change once it is created. (If the object contains references to other objects, these other objects may be mutable and may be modified; however, the collection of objects directly referenced by an immutable object cannot change.)
* `+=` operator changes the list in-place. The item assignment doesn't work, but when the exception occurs, the item has already been changed in place.