# Python

### Getting Started <a href="#getting-started" id="getting-started"></a>

#### Introduction <a href="#introduction" id="introduction"></a>

* [Python](https://www.python.org/) *(python.org)*
* [Learn X in Y minutes](https://learnxinyminutes.com/docs/python/) *(learnxinyminutes.com)*
* Regex in python

#### Hello World <a href="#hello-world" id="hello-world"></a>

```python
>>> print("Hello, World!")
Hello, World!
```

The famous "Hello World" program in Python

#### Variables <a href="#variables" id="variables"></a>

```python
age = 18      # age is of type int
name = "John" # name is now of type str
print(name)
```

Python can't declare a variable without assignment.

#### Data Types <a href="#data-types" id="data-types"></a>

| `str`                              | Text     |
| ---------------------------------- | -------- |
| `int`, `float`, `complex`          | Numeric  |
| `list`, `tuple`, `range`           | Sequence |
| `dict`                             | Mapping  |
| `set`, `frozenset`                 | Set      |
| `bool`                             | Boolean  |
| `bytes`, `bytearray`, `memoryview` | Binary   |

See: [Data Types](#python-built-in-data-types)

#### Slicing String <a href="#slicing-string" id="slicing-string"></a>

```python
>>> msg = "Hello, World!"
>>> print(msg[2:5])
llo
```

See: [Strings](#python-strings)

#### Lists <a href="#lists" id="lists"></a>

```python
mylist = []
mylist.append(1)
mylist.append(2)
for item in mylist:
    print(item) # prints out 1,2
```

See: [Lists](#python-lists)

#### If Else <a href="#if-else" id="if-else"></a>

```python
num = 200
if num > 0:
    print("num is greater than 0")
else:
    print("num is not greater than 0")
```

See: [Flow control](#python-flow-control)

#### Loops <a href="#loops" id="loops"></a>

```python
for item in range(6):
    if item == 3: break
    print(item)
else:
    print("Finally finished!")
```

See: [Loops](#python-loops)

#### Functions <a href="#functions" id="functions"></a>

```python
>>> def my_function():
...     print("Hello from a function")
...
>>> my_function()
Hello from a function
```

See: [Functions](#python-functions)

#### File Handling <a href="#file-handling" id="file-handling"></a>

```python
with open("myfile.txt", "r", encoding='utf8') as file:
    for line in file:
        print(line)
```

See: [File Handling](#python-file-handling)

#### Arithmetic <a href="#arithmetic" id="arithmetic"></a>

```python
result = 10 + 30 # => 40
result = 40 - 10 # => 30
result = 50 * 5  # => 250
result = 16 / 4  # => 4.0 (Float Division)
result = 16 // 4 # => 4 (Integer Division)
result = 25 % 2  # => 1
result = 5 ** 3  # => 125
```

The `/` means quotient of x and y, and the `//` means floored quotient of x and y, also see [StackOverflow](https://stackoverflow.com/a/183870/13192320)

#### Plus-Equals <a href="#plus-equals" id="plus-equals"></a>

```python
counter = 0
counter += 10           # => 10
counter = 0
counter = counter + 10  # => 10

message = "Part 1."

# => Part 1.Part 2.
message += "Part 2."   
```

#### f-Strings (Python 3.6+) <a href="#f-strings-python-3-6" id="f-strings-python-3-6"></a>

```python
>>> website = 'Vietelligent.ME'
>>> f"Hello, {website}"
"Hello, Vietelligent.ME"

>>> num = 10
>>> f'{num} + 10 = {num + 10}'
'10 + 10 = 20'
```

See: [Python F-Strings](#python-f-strings-since-python-3-6)

### Python Built-in Data Types <a href="#python-built-in-data-types" id="python-built-in-data-types"></a>

#### Strings <a href="#strings" id="strings"></a>

```python
hello = "Hello World"
hello = 'Hello World'

multi_string = """Multiline Strings
Lorem ipsum dolor sit amet,
consectetur adipiscing elit """
```

See: [Strings](#python-strings)

#### Numbers <a href="#numbers" id="numbers"></a>

```python
x = 1    # int
y = 2.8  # float
z = 1j   # complex

>>> print(type(x))
<class 'int'>
```

#### Booleans <a href="#booleans" id="booleans"></a>

```python
my_bool = True 
my_bool = False

bool(0)     # => False
bool(1)     # => True
```

#### Lists <a href="#lists-2" id="lists-2"></a>

```python
list1 = ["apple", "banana", "cherry"]
list2 = [True, False, False]
list3 = [1, 5, 7, 9, 3]
list4 = list((1, 5, 7, 9, 3))
```

See: [Lists](#python-lists)

#### Tuple <a href="#tuple" id="tuple"></a>

```python
my_tuple = (1, 2, 3)
my_tuple = tuple((1, 2, 3))
```

Similar to List but immutable

#### Set <a href="#set" id="set"></a>

```python
set1 = {"a", "b", "c"}   
set2 = set(("a", "b", "c"))
```

Set of unique items/objects

#### Dictionary <a href="#dictionary" id="dictionary"></a>

```python
>>> empty_dict = {}
>>> a = {"one": 1, "two": 2, "three": 3}
>>> a["one"]
1
>>> a.keys()
dict_keys(['one', 'two', 'three'])
>>> a.values()
dict_values([1, 2, 3])
>>> a.update({"four": 4})
>>> a.keys()
dict_keys(['one', 'two', 'three', 'four'])
>>> a['four']
4
```

Key: Value pair, JSON like object

#### Casting <a href="#casting" id="casting"></a>

**Integers**

```python
x = int(1)   # x will be 1
y = int(2.8) # y will be 2
z = int("3") # z will be 3
```

**Floats**

```python
x = float(1)     # x will be 1.0
y = float(2.8)   # y will be 2.8
z = float("3")   # z will be 3.0
w = float("4.2") # w will be 4.2
```

**Strings**

```python
x = str("s1") # x will be 's1'
y = str(2)    # y will be '2'
z = str(3.0)  # z will be '3.0'
```

### Python Advanced Data Types <a href="#python-advanced-data-types" id="python-advanced-data-types"></a>

#### Heaps <a href="#heaps" id="heaps"></a>

```python
import heapq

myList = [9, 5, 4, 1, 3, 2]
heapq.heapify(myList) # turn myList into a Min Heap
print(myList)    # => [1, 3, 2, 5, 9, 4]
print(myList[0]) # first value is always the smallest in the heap

heapq.heappush(myList, 10) # insert 10
x = heapq.heappop(myList)  # pop and return smallest item
print(x)                   # => 1
```

**Negate all values to use Min Heap as Max Heap**

```python
myList = [9, 5, 4, 1, 3, 2]
myList = [-val for val in myList] # multiply by -1 to negate
heapq.heapify(myList)

x = heapq.heappop(myList)
print(-x) # => 9 (making sure to multiply by -1 again)
```

Heaps are binary trees for which every parent node has a value less than or equal to any of its children. Useful for accessing min/max value quickly. Time complexity: O(n) for heapify, O(log n) push and pop. See: [Heapq](https://docs.python.org/3/library/heapq.html)

#### Stacks and Queues <a href="#stacks-and-queues" id="stacks-and-queues"></a>

```python
from collections import deque

q = deque()          # empty
q = deque([1, 2, 3]) # with values

q.append(4)     # append to right side
q.appendleft(0) # append to left side
print(q)    # => deque([0, 1, 2, 3, 4])

x = q.pop() # remove & return from right
y = q.popleft() # remove & return from left
print(x)    # => 4
print(y)    # => 0
print(q)    # => deque([1, 2, 3])

q.rotate(1) # rotate 1 step to the right
print(q)    # => deque([3, 1, 2])
```

Deque is a double-ended queue with O(1) time for append/pop operations from both sides. Used as stacks and queues. See: [Deque](https://docs.python.org/3/library/collections.html#collections.deque)

### Python Strings <a href="#python-strings" id="python-strings"></a>

#### Array-like <a href="#array-like" id="array-like"></a>

```python
>>> hello = "Hello, World"
>>> print(hello[1])
e
>>> print(hello[-1])
d
```

Get the character at position 1 or last

#### Looping <a href="#looping" id="looping"></a>

```python
>>> for char in "foo":
...     print(char)
f
o
o
```

Loop through the letters in the word "foo"

#### Slicing string <a href="#slicing-string-2" id="slicing-string-2"></a>

```java
 ┌───┬───┬───┬───┬───┬───┬───┐
 | m | y | b | a | c | o | n |
 └───┴───┴───┴───┴───┴───┴───┘
 0   1   2   3   4   5   6   7
-7  -6  -5  -4  -3  -2  -1
```

***

```python
>>> s = 'mybacon'
>>> s[2:5]
'bac'
>>> s[0:2]
'my'
```

```python
>>> s = 'mybacon'
>>> s[:2]
'my'
>>> s[2:]
'bacon'
>>> s[:2] + s[2:]
'mybacon'
>>> s[:]
'mybacon'
```

```python
>>> s = 'mybacon'
>>> s[-5:-1]
'baco'
>>> s[2:6]
'baco'
```

**With a stride**

```python
>>> s = '12345' * 5
>>> s
'1234512345123451234512345'
>>> s[::5]
'11111'
>>> s[4::5]
'55555'
>>> s[::-5]
'55555'
>>> s[::-1]
'5432154321543215432154321'
```

#### String Length <a href="#string-length" id="string-length"></a>

```python
>>> hello = "Hello, World!"
>>> print(len(hello))
13
```

The len() function returns the length of a string

#### Multiple copies <a href="#multiple-copies" id="multiple-copies"></a>

```python
>>> s = '===+'
>>> n = 8
>>> s * n
'===+===+===+===+===+===+===+===+'
```

#### Check String <a href="#check-string" id="check-string"></a>

```python
>>> s = 'spam'
>>> s in 'I saw spamalot!'
True
>>> s not in 'I saw The Holy Grail!'
True

```

#### Concatenates <a href="#concatenates" id="concatenates"></a>

```python
>>> s = 'spam'
>>> t = 'egg'
>>> s + t
'spamegg'
>>> 'spam' 'egg'
'spamegg'
```

#### Formatting <a href="#formatting" id="formatting"></a>

```python
name = "John"
print("Hello, %s!" % name)
```

```python
name = "John"
age = 23
print("%s is %d years old." % (name, age))
```

**format() Method**

```python
txt1 = "My name is {fname}, I'm {age}".format(fname="John", age=36)
txt2 = "My name is {0}, I'm {1}".format("John", 36)
txt3 = "My name is {}, I'm {}".format("John", 36)
```

#### Input <a href="#input" id="input"></a>

```python
>>> name = input("Enter your name: ")
Enter your name: Tom
>>> name
'Tom'
```

Get input data from console

#### Join <a href="#join" id="join"></a>

```python
>>> "#".join(["John", "Peter", "Vicky"])
'John#Peter#Vicky'
```

#### Endswith <a href="#endswith" id="endswith"></a>

```python
>>> "Hello, world!".endswith("!")
True
```

### Python F-Strings (Since Python 3.6+) <a href="#python-f-strings-since-python-3-6" id="python-f-strings-since-python-3-6"></a>

#### f-Strings usage <a href="#f-strings-usage" id="f-strings-usage"></a>

```python
>>> website = 'Vietelligent.ME'
>>> f"Hello, {website}"
"Hello, Vietelligent.ME"

>>> num = 10
>>> f'{num} + 10 = {num + 10}'
'10 + 10 = 20'

>>> f"""He said {"I'm John"}"""
"He said I'm John"

>>> f'5 {"{stars}"}'
'5 {stars}'
>>> f'{{5}} {"stars"}'
'{5} stars'

>>> name = 'Eric'
>>> age = 27
>>> f"""Hello!
...     I'm {name}.
...     I'm {age}."""
"Hello!\n    I'm Eric.\n    I'm 27."
```

it is available since Python 3.6, also see: [Formatted string literals](https://docs.python.org/3/reference/lexical_analysis.html#f-strings)

#### f-Strings Fill Align <a href="#f-strings-fill-align" id="f-strings-fill-align"></a>

```python
>>> f'{"text":10}'     # [width]
'text      '
>>> f'{"test":*>10}'   # fill left
'******test'
>>> f'{"test":*<10}'   # fill right
'test******'
>>> f'{"test":*^10}'   # fill center
'***test***'
>>> f'{12345:0>10}'    # fill with numbers
'0000012345'
```

#### f-Strings Type <a href="#f-strings-type" id="f-strings-type"></a>

```python
>>> f'{10:b}'        # binary type
'1010'
>>> f'{10:o}'        # octal type
'12'
>>> f'{200:x}'       # hexadecimal type
'c8'
>>> f'{200:X}'
'C8'
>>> f'{345600000000:e}' # scientific notation
'3.456000e+11'
>>> f'{65:c}'       # character type
'A'
>>> f'{10:#b}'      # [type] with notation (base)
'0b1010'
>>> f'{10:#o}'
'0o12'
>>> f'{10:#x}'
'0xa'
```

#### F-Strings Others <a href="#f-strings-others" id="f-strings-others"></a>

```python
>>> f'{-12345:0=10}'  # negative numbers
'-000012345'
>>> f'{12345:010}'    # [0] shortcut (no align)
'0000012345'
>>> f'{-12345:010}'
'-000012345'
>>> import math       # [.precision]
>>> math.pi
3.141592653589793
>>> f'{math.pi:.2f}'
'3.14'
>>> f'{1000000:,.2f}' # [grouping_option]
'1,000,000.00'
>>> f'{1000000:_.2f}'
'1_000_000.00'
>>> f'{0.25:0%}'      # percentage
'25.000000%'
>>> f'{0.25:.0%}'
'25%'
```

#### F-Strings Sign <a href="#f-strings-sign" id="f-strings-sign"></a>

```python
>>> f'{12345:+}'      # [sign] (+/-)
'+12345'
>>> f'{-12345:+}'
'-12345'
>>> f'{-12345:+10}'
'    -12345'
>>> f'{-12345:+010}'
'-000012345'
```

### Python Lists <a href="#python-lists" id="python-lists"></a>

#### Defining <a href="#defining" id="defining"></a>

```python
>>> li1 = []
>>> li1
[]
>>> li2 = [4, 5, 6]
>>> li2
[4, 5, 6]
>>> li3 = list((1, 2, 3))
>>> li3
[1, 2, 3]
>>> li4 = list(range(1, 11))
>>> li4
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

#### Generate <a href="#generate" id="generate"></a>

```python
>>> list(filter(lambda x : x % 2 == 1, range(1, 20)))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

>>> [x ** 2 for x in range (1, 11) if  x % 2 == 1]
[1, 9, 25, 49, 81]

>>> [x for x in [3, 4, 5, 6, 7] if x > 5]
[6, 7]

>>> list(filter(lambda x: x > 5, [3, 4, 5, 6, 7]))
[6, 7]
```

#### Append <a href="#append" id="append"></a>

```python
>>> li = []
>>> li.append(1)
>>> li
[1]
>>> li.append(2)
>>> li
[1, 2]
>>> li.append(4)
>>> li
[1, 2, 4]
>>> li.append(3)
>>> li
[1, 2, 4, 3]
```

#### List Slicing <a href="#list-slicing" id="list-slicing"></a>

Syntax of list slicing:

```python
a_list[start:end]
a_list[start:end:step]
```

**Slicing**

```python
>>> a = ['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[2:5]
['bacon', 'tomato', 'ham']
>>> a[-5:-2]
['egg', 'bacon', 'tomato']
>>> a[1:4]
['egg', 'bacon', 'tomato']
```

**Omitting index**

```python
>>> a[:4]
['spam', 'egg', 'bacon', 'tomato']
>>> a[0:4]
['spam', 'egg', 'bacon', 'tomato']
>>> a[2:]
['bacon', 'tomato', 'ham', 'lobster']
>>> a[2:len(a)]
['bacon', 'tomato', 'ham', 'lobster']
>>> a
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[:]
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
```

**With a stride**

```python
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[0:6:2]
['spam', 'bacon', 'ham']
>>> a[1:6:2]
['egg', 'tomato', 'lobster']
>>> a[6:0:-2]
['lobster', 'tomato', 'egg']
>>> a
['spam', 'egg', 'bacon', 'tomato', 'ham', 'lobster']
>>> a[::-1]
['lobster', 'ham', 'tomato', 'bacon', 'egg', 'spam']
```

#### Remove <a href="#remove" id="remove"></a>

```python
>>> li = ['bread', 'butter', 'milk']
>>> li.pop()
'milk'
>>> li
['bread', 'butter']
>>> del li[0]
>>> li
['butter']
```

#### Access <a href="#access" id="access"></a>

```python
>>> li = ['a', 'b', 'c', 'd']
>>> li[0]
'a'
>>> li[-1]
'd'
>>> li[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
```

#### Concatenating <a href="#concatenating" id="concatenating"></a>

```python
>>> odd = [1, 3, 5]
>>> odd.extend([9, 11, 13])
>>> odd
[1, 3, 5, 9, 11, 13]
>>> odd = [1, 3, 5]
>>> odd + [9, 11, 13]
[1, 3, 5, 9, 11, 13]
```

#### Sort & Reverse <a href="#sort-reverse" id="sort-reverse"></a>

```python
>>> li = [3, 1, 3, 2, 5]
>>> li.sort()
>>> li
[1, 2, 3, 3, 5]
>>> li.reverse()
>>> li
[5, 3, 3, 2, 1]
```

#### Count <a href="#count" id="count"></a>

```python
>>> li = [3, 1, 3, 2, 5]
>>> li.count(3)
2
```

#### Repeating <a href="#repeating" id="repeating"></a>

```python
>>> li = ["re"] * 3
>>> li
['re', 're', 're']
```

### Python Flow control <a href="#python-flow-control" id="python-flow-control"></a>

#### Basic <a href="#basic" id="basic"></a>

```python
num = 5
if num > 10:
    print("num is totally bigger than 10.")
elif num < 10:
    print("num is smaller than 10.")
else:
    print("num is indeed 10.")
```

#### One line <a href="#one-line" id="one-line"></a>

```python
>>> a = 330
>>> b = 200
>>> r = "a" if a > b else "b"
>>> print(r)
a
```

#### else if <a href="#else-if" id="else-if"></a>

```python
value = True
if not value:
    print("Value is False")
elif value is None:
    print("Value is None")
else:
    print("Value is True")
```

### Python Loops <a href="#python-loops" id="python-loops"></a>

#### Basic <a href="#basic-2" id="basic-2"></a>

```python
primes = [2, 3, 5, 7]
for prime in primes:
    print(prime)
```

Prints: 2 3 5 7

#### With index <a href="#with-index" id="with-index"></a>

```python
animals = ["dog", "cat", "mouse"]
# enumerate() adds counter to an iterable
for i, value in enumerate(animals):
    print(i, value)
```

Prints: 0 dog 1 cat 2 mouse

#### While <a href="#while" id="while"></a>

```python
x = 0
while x < 4:
    print(x)
    x += 1  # Shorthand for x = x + 1
```

Prints: 0 1 2 3

#### Break <a href="#break" id="break"></a>

```python
x = 0
for index in range(10):
    x = index * 10
    if index == 5:
    	break
    print(x)
```

Prints: 0 10 20 30 40

#### Continue <a href="#continue" id="continue"></a>

```python
for index in range(3, 8): 
    x = index * 10
    if index == 5:
    	continue
    print(x)
```

Prints: 30 40 60 70

#### Range <a href="#range" id="range"></a>

```python
for i in range(4):
    print(i) # Prints: 0 1 2 3

for i in range(4, 8):
    print(i) # Prints: 4 5 6 7

for i in range(4, 10, 2):
    print(i) # Prints: 4 6 8
```

#### With zip() <a href="#with-zip" id="with-zip"></a>

```python
words = ['Mon', 'Tue', 'Wed']
nums = [1, 2, 3]
# Use zip to pack into a tuple list
for w, n in zip(words, nums):
    print('%d:%s, ' %(n, w))
```

Prints: 1:Mon, 2:Tue, 3:Wed,

#### for/else <a href="#for-else" id="for-else"></a>

```python
nums = [60, 70, 30, 110, 90]
for n in nums:
    if n > 100:
        print("%d is bigger than 100" %n)
        break
else:
    print("Not found!")
```

Also see: [Python Tips](https://book.pythontips.com/en/latest/for_-_else.html)

### Python Functions <a href="#python-functions" id="python-functions"></a>

#### Basic <a href="#basic-3" id="basic-3"></a>

```python
def hello_world():  
    print('Hello, World!')
```

#### Return <a href="#return" id="return"></a>

```python
def add(x, y):
    print("x is %s, y is %s" %(x, y))
    return x + y

add(5, 6)    # => 11
```

#### Positional arguments <a href="#positional-arguments" id="positional-arguments"></a>

```python
def varargs(*args):
    return args

varargs(1, 2, 3)  # => (1, 2, 3)
```

#### Keyword arguments <a href="#keyword-arguments" id="keyword-arguments"></a>

```python
def keyword_args(**kwargs):
    return kwargs

# => {"big": "foot", "loch": "ness"}
keyword_args(big="foot", loch="ness")
```

#### Returning multiple <a href="#returning-multiple" id="returning-multiple"></a>

```python
def swap(x, y):
    return y, x

x = 1
y = 2
x, y = swap(x, y)  # => x = 2, y = 1
```

#### Default Value <a href="#default-value" id="default-value"></a>

```python
def add(x, y=10):
    return x + y

add(5)      # => 15
add(5, 20)  # => 25
```

#### Anonymous functions <a href="#anonymous-functions" id="anonymous-functions"></a>

```python
# => True
(lambda x: x > 2)(3)

# => 5
(lambda x, y: x ** 2 + y ** 2)(2, 1)
```

### Python Modules <a href="#python-modules" id="python-modules"></a>

#### Import modules <a href="#import-modules" id="import-modules"></a>

```python
import math
print(math.sqrt(16))  # => 4.0
```

#### From a module <a href="#from-a-module" id="from-a-module"></a>

```python
from math import ceil, floor
print(ceil(3.7))   # => 4.0
print(floor(3.7))  # => 3.0
```

#### Import all <a href="#import-all" id="import-all"></a>

```python
from math import *
```

#### Shorten module <a href="#shorten-module" id="shorten-module"></a>

```python
import math as m

# => True
math.sqrt(16) == m.sqrt(16)
```

#### Functions and attributes <a href="#functions-and-attributes" id="functions-and-attributes"></a>

```python
import math
dir(math)
```

### Python File Handling <a href="#python-file-handling" id="python-file-handling"></a>

#### Read file <a href="#read-file" id="read-file"></a>

**Line by line**

```python
with open("myfile.txt") as file:
    for line in file:
        print(line)
```

**With line number**

```python
file = open('myfile.txt', 'r')
for i, line in enumerate(file, start=1):
    print("Number %s: %s" % (i, line))
```

#### String <a href="#string" id="string"></a>

**Write a string**

```python
contents = {"aa": 12, "bb": 21}
with open("myfile1.txt", "w+") as file:
    file.write(str(contents))
```

**Read a string**

```python
with open('myfile1.txt', "r+") as file:
    contents = file.read()
print(contents)
```

#### Object <a href="#object" id="object"></a>

**Write an object**

```python
contents = {"aa": 12, "bb": 21}
with open("myfile2.txt", "w+") as file:
    file.write(json.dumps(contents))
```

**Read an object**

```python
with open('myfile2.txt', "r+") as file:
    contents = json.load(file)
print(contents)
```

#### Delete a File <a href="#delete-a-file" id="delete-a-file"></a>

```python
import os
os.remove("myfile.txt")
```

#### Check and Delete <a href="#check-and-delete" id="check-and-delete"></a>

```python
import os
if os.path.exists("myfile.txt"):
    os.remove("myfile.txt")
else:
    print("The file does not exist")
```

#### Delete Folder <a href="#delete-folder" id="delete-folder"></a>

```python
import os
os.rmdir("myfolder")
```

### Python Classes & Inheritance <a href="#python-classes-inheritance" id="python-classes-inheritance"></a>

#### Defining <a href="#defining-2" id="defining-2"></a>

```python
class MyNewClass:
    pass

# Class Instantiation
my = MyNewClass()
```

#### Constructors <a href="#constructors" id="constructors"></a>

```python
class Animal:
    def __init__(self, voice):
        self.voice = voice
 
cat = Animal('Meow')
print(cat.voice)    # => Meow
 
dog = Animal('Woof') 
print(dog.voice)    # => Woof
```

#### Method <a href="#method" id="method"></a>

```python
class Dog:

    # Method of the class
    def bark(self):
        print("Ham-Ham")
 
charlie = Dog()
charlie.bark()   # => "Ham-Ham"
```

#### Class Variables <a href="#class-variables" id="class-variables"></a>

```python
class MyClass:
    class_variable = "A class variable!"

# => A class variable!
print(MyClass.class_variable)

x = MyClass()
 
# => A class variable!
print(x.class_variable)
```

#### Super() Function <a href="#super-function" id="super-function"></a>

```python
class ParentClass:
    def print_test(self):
        print("Parent Method")
 
class ChildClass(ParentClass):
    def print_test(self):
        print("Child Method")
        # Calls the parent's print_test()
        super().print_test() 
```

***

```python
>>> child_instance = ChildClass()
>>> child_instance.print_test()
Child Method
Parent Method
```

#### repr() method <a href="#repr-method" id="repr-method"></a>

```python
class Employee:
    def __init__(self, name):
        self.name = name
 
    def __repr__(self):
        return self.name
 
john = Employee('John')
print(john)  # => John
```

#### User-defined exceptions <a href="#user-defined-exceptions" id="user-defined-exceptions"></a>

```python
class CustomError(Exception):
    pass
```

#### Polymorphism <a href="#polymorphism" id="polymorphism"></a>

```python
class ParentClass:
    def print_self(self):
        print('A')
 
class ChildClass(ParentClass):
    def print_self(self):
        print('B')
 
obj_A = ParentClass()
obj_B = ChildClass()
 
obj_A.print_self() # => A
obj_B.print_self() # => B
```

#### Overriding <a href="#overriding" id="overriding"></a>

```python
class ParentClass:
    def print_self(self):
        print("Parent")
 
class ChildClass(ParentClass):
    def print_self(self):
        print("Child")
 
child_instance = ChildClass()
child_instance.print_self() # => Child
```

#### Inheritance <a href="#inheritance" id="inheritance"></a>

```python
class Animal: 
    def __init__(self, name, legs):
        self.name = name
        self.legs = legs
        
class Dog(Animal):
    def sound(self):
        print("Woof!")
 
Yoki = Dog("Yoki", 4)
print(Yoki.name) # => YOKI
print(Yoki.legs) # => 4
Yoki.sound()     # => Woof!
```

### Miscellaneous <a href="#miscellaneous" id="miscellaneous"></a>

#### Comments <a href="#comments" id="comments"></a>

```python
# This is a single line comments.
```

```python
""" Multiline strings can be written
    using three "s, and are often used
    as documentation.
"""
```

```python
''' Multiline strings can be written
    using three 's, and are often used
    as documentation.
'''
```

#### Generators <a href="#generators" id="generators"></a>

```python
def double_numbers(iterable):
    for i in iterable:
        yield i + i
```

Generators help you make lazy code.

#### Generator to list <a href="#generator-to-list" id="generator-to-list"></a>

```python
values = (-x for x in [1,2,3,4,5])
gen_to_list = list(values)

# => [-1, -2, -3, -4, -5]
print(gen_to_list)
```

#### Handle exceptions <a href="#handle-exceptions" id="handle-exceptions"></a>

```python
try:
    # Use "raise" to raise an error
    raise IndexError("This is an index error")
except IndexError as e:
    pass                 # Pass is just a no-op. Usually you would do recovery here.
except (TypeError, NameError):
    pass                 # Multiple exceptions can be handled together, if required.
else:                    # Optional clause to the try/except block. Must follow all except blocks
    print("All good!")   # Runs only if the code in try raises no exceptions
finally:                 # Execute under all circumstances
    print("We can clean up resources here")
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nvb99.gitbook.io/me/cheat-sheet/programming-language/python.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
