
1. Variables
1.1. It is just a identifier like a name
1.2. identifiers doesn't have type. Just objects have type.
1.3. Copy
1.3.1. Alias
1.3.1.1. a = [1,2,3] b = a
1.3.2. Shallow copy
1.3.2.1. a = [1,2,3] b = a.copy()
1.3.2.1.1. It's created a new List and put the same references of the elements of **a**. So if one element is mutable, a change in a element in b will be affect in a.
1.3.3. Deep copy
1.3.3.1. import copy a = [1,2,3] b = copy.deepcopy(a)
1.3.3.1.1. It's created a new List and also create a copy of each object in a.
2. Types of Functions
2.1. Functions with return
2.1.1. Normal function
2.1.1.1. Basic information
2.1.1.1.1. abstraction
2.1.1.1.2. reusability
2.1.1.1.3. modularity
2.1.1.1.4. namespace separation
2.1.1.2. Parameter / Arguments
2.1.1.2.1. For some reason, they are called sometimes parameters, sometimes arguments.
2.1.1.2.2. Positional arguments
2.1.1.2.3. Keyword arguments
2.1.1.2.4. Mutable default parameter
2.1.1.2.5. Argument Tuple unpacking
2.1.1.2.6. Argument Dictionary unpacking
2.2. Lambda Function
2.2.1. created inline like an expression
2.2.2. lambda x: x lambda a,b: a,b lambda: print()
2.3. Functions with yield
2.3.1. Generator function
2.3.1.1. Basic information
2.3.1.1.1. it's a object
2.3.1.1.2. it returns a lazy **iterator**
2.3.1.1.3. It sabes its state
2.3.1.1.4. it's a functions that uses yield keyword or a Generator Expression
2.3.1.1.5. Generator Expression
2.3.1.1.6. It execute until yiled or rerturn is found. Next execution it continues after the last yield.
2.3.1.1.7. Raises StopIteratoin at the end
2.3.1.1.8. Memory
2.3.1.1.9. Speed
2.3.1.2. Definition
2.3.1.2.1. def infinite_sequence(): num = 0 while True: yield num num += 1
3. Operators
3.1. Arithimetic
3.2. Comparison
3.2.1. Equality
3.2.1.1. ==
3.2.1.1.1. Compare using ⎽⎽eq⎽⎽() Magic Method
3.2.2. Condidional comprehension
3.2.2.1. it's like ternary operator
3.2.2.2. exp1 if condition else exp2
3.2.2.3. exp1 if condition else exp2 if condition else exp3
3.2.3. Structural Pattern Matching
3.2.3.1. match command.split(): case ["quit"]: print("Goodbye!") quit_game() case ["look"]: current_room.describe() case ["get", obj]: character.get(obj, current_room) case ["go", direction]: current_room = current_room.neighbor(direction) # The rest of your commands go here
3.3. Logical
3.4. Identity
3.4.1. is
3.4.1.1. Compare memory address
3.4.1.2. used to verify if it is the same object in memory
3.5. Walrus
3.5.1. identifier := expression
3.5.2. assign expression operator
3.5.3. can be used in comprehension, expressions, etc
3.5.4. it assign the value and return the value
3.5.5. it works better with parenteses
3.5.6. (test := 2) # returns 2
4. Keywords
4.1. None
4.1.1. It's a object
4.1.2. Type: NoneType
4.1.3. Comparison
4.1.3.1. Use is
4.1.3.1.1. Dont use == because it can be overrided
4.2. Global
5. Data Model
5.1. Basic information
5.1.1. it's like a framework to process data in objects
5.1.2. a group o methods (that can be implemented in custom classes) used by the compiler and/or by built-in functions
5.1.3. a Protocol specifies Special Methods to be implemented
5.1.3.1. the compiler or built-in functions call the Special Methods
5.1.3.2. they are writed with leading and trailing underscores ⎽⎽getiitem⎽⎽()
5.2. Protocols
5.2.1. Iterable protocol
5.2.1.1. Basic information
5.2.1.1.1. Objects that we can iterate over it
5.2.1.2. Methods
5.2.1.2.1. **⎽⎽iter()⎽⎽**
5.2.1.2.2. Sequence protocol
5.2.2. Sequence protocol
5.2.2.1. Basic information
5.2.2.1.1. store items ordered
5.2.2.1.2. The data structure must support item look up by index
5.2.2.1.3. it can use the index operator [] and the sequence operations +=
5.2.2.1.4. Python can iterate over it because it creates a **iterator** automatically
5.2.2.2. Methods
5.2.2.2.1. ⎽⎽getitem⎽⎽(self, index)
5.2.2.2.2. ⎽⎽len⎽⎽()
5.2.3. Iterator protocol
5.2.3.1. Basic information
5.2.3.1.1. it allows iterate over collections of data
5.2.3.1.2. The data structure doesn't need to support item look up by index
5.2.3.1.3. implements the iterator design pattern
5.2.3.1.4. it yield each item while mantain the state of the iteration
5.2.3.1.5. memory efficient
5.2.3.2. Methods
5.2.3.2.1. ⎽⎽iter()⎽⎽
5.2.3.2.2. ⎽⎽next()⎽⎽
5.2.3.3. Pros
5.2.3.3.1. generate and yield data on demand
5.2.3.3.2. can pause the iteration
5.2.3.3.3. memory efficient
5.2.3.3.4. work with infinite data streams
5.2.3.4. Cons
5.2.3.4.1. can iterate just one time
5.2.3.4.2. can't be reseted
5.2.3.4.3. moves only forward
5.2.3.4.4. it can't know the length without iterate over all data
5.2.3.4.5. dont support sequence operations
5.2.3.5. Built-in functions good to know
5.2.3.5.1. iter(object)
5.2.3.5.2. next()
5.2.3.5.3. enumerate(iterable, start=0)
5.2.3.5.4. zip(*iterables)
5.2.4. Comparison protocol
5.2.4.1. it should return True or False
5.2.4.2. Magic methods
5.2.4.2.1. ⎽⎽eq⎽⎽() ==
5.2.4.2.2. ⎽⎽ne⎽⎽() !=
5.2.4.2.3. ⎽⎽lt⎽⎽() <
5.2.4.2.4. ⎽⎽gt⎽⎽() >
5.2.4.2.5. ⎽⎽le⎽⎽() <=
5.2.4.2.6. ⎽⎽ge⎽⎽() >=
5.2.4.2.7. ⎽⎽cmp()⎽⎽ all
5.2.4.3. How types are compared
5.2.4.3.1. strings
6. a = [1,2,3] b = ['a','b','c'] list( zip(a,b) ) # [ (1,'a'), (2,'b'), (3,'c') ]
7. The relation between Iterable protocol and Iterator protocol
7.1. The **Iterator design pattern** states that the data structure should be decoupled from the iteration algorith.
7.2. So, the **Iterable protocol** is to be used by the data structure
7.2.1. that's why the **⎽⎽iter()⎽⎽** method from Iterable protocol should return a **Iterator**. This way it returns the correct iterator to be used with this data structure.
7.3. And the **Iterator protocol** is to be used by the iteration algorithm
8. Development Experience
8.1. REPL
8.1.1. Useful to little snipets
8.2. IDE
8.3. Jupyter Notebook
8.4. JupyterLab
8.4.1. Better version of Jupyter Notebooks
9. Versions
9.1. 2.x
9.1.1. Old
9.1.2. Does'nt have support to Unicode
9.1.2.1. It will truncate all text like ç~á
9.2. 3.x
9.2.1. Newer
9.2.2. Support to Unicode
10. Data Types
10.1. Basic information
10.1.1. Objects are assigned to identifiers
10.1.1.1. Identifiers are the same as variables in other languages
10.1.2. All objects are children from the class "object"
10.1.3. Everything is an object
10.1.4. In CPython implementation, each object is stored in a PyObject
10.1.4.1. PyObject Atributes
10.1.4.1.1. Type: Type of the object
10.1.4.1.2. Value: The object itself
10.1.4.1.3. Reference Count: The count of identifiers assigned to this object. Used to Garbage Collection.
10.1.5. Python object creation
10.1.5.1. x = 2378
10.1.5.2. 1) Create a PyObject (CPython)
10.1.5.3. 2) Set **typecode ** to integer
10.1.5.4. 3) Set **Value** to 2378
10.1.5.5. 4) Create **identifier** called X
10.1.5.6. 5) Assign X to the new object
10.1.5.7. 6) Increase **refcount** by 1
10.2. Mutable / Immutable types
10.2.1. All types are object, so the mutabilty is definied by the object itself
10.2.2. To define a immutable class, the definition should prevent change its members and/or return a new object
10.2.3. by default, all object are mutable
10.2.3.1. we can add/change its members just by assigning to it
10.2.4. Example:
10.2.4.1. n1 = 10 # create 10; assignt it to n1
10.2.4.2. n2 = n1 # assign 10 to n2
10.2.4.3. n2 = 20 # create 20; assign it to n2
10.2.4.4. n1 # keep assigned to 10
10.3. Pass by Value / Pass by Reference / **Pass By Assign**
10.3.1. this term is from another languages, like c, Java, C#
10.3.2. It's different un Python.
10.3.3. In Python just exist **Pass By Assign**
10.3.4. What define if a object could have its content changed is its mutability
10.4. Basic Built-in Data Types
10.4.1. Numeric
10.4.1.1. Complex numbers
10.4.1.1.1. Immutable
10.4.1.2. Boolean
10.4.1.2.1. Immutable
10.4.1.2.2. Type name: **bool**
10.4.1.2.3. It is a numeric type
10.4.1.2.4. Short-circuit
10.4.1.2.5. Operator overloading
10.4.1.2.6. Python don't implement XOR built-in
10.4.1.2.7. Chaining comparision
10.4.1.2.8. Truthy or Falsy
10.4.1.3. Integer
10.4.1.3.1. Immutable
10.4.1.4. Float
10.4.1.4.1. Immutable
10.4.1.4.2. Infinite
10.4.2. Sequence
10.4.2.1. Types
10.4.2.1.1. String
10.4.2.1.2. List
10.4.2.1.3. Tuple
10.4.2.2. Operations
10.4.2.2.1. +
10.4.2.2.2. *
10.4.2.2.3. [ **i** ]
10.4.2.2.4. [ **start** : **end** ]
10.4.2.2.5. [ **start** : **end** : **step** ]
10.4.2.2.6. Important Cases
10.4.2.2.7. Copy of Sequences
10.4.2.3. Sequence Protocol Magic Methods
10.4.3. Dictionary
10.4.3.1. Mapping of elements
10.4.3.2. Mutable
10.4.3.3. Members
10.4.3.3.1. Mutable
10.4.3.3.2. ordered
10.4.3.3.3. heterogeneous
10.4.3.3.4. duplicates
10.4.3.4. Use curly brackets {}
10.4.3.5. Creation
10.4.3.5.1. Primary
10.4.3.5.2. List of Tuples
10.4.3.5.3. Dict of keywords
10.4.3.5.4. Map function
10.4.3.5.5. Dictionary comprehension
10.4.3.6. Reading / Updating
10.4.3.6.1. use brackets []
10.4.3.6.2. d['a'] #reading d['a'] = 6 # updating d[ a ] # without apostrophe '' not work d[ 1 ] # only work if key is integer
10.4.3.7. Delete
10.4.3.7.1. del d['a']
10.4.3.8. **In** operator
10.4.3.8.1. It works with the keys
10.4.3.8.2. useful in short-circuit evaluation
10.4.3.9. Buillt-in methods
10.4.3.9.1. .items()
10.4.3.9.2. .keys()
10.4.3.9.3. .values()
10.4.3.9.4. .popitem()
10.4.3.9.5. .pop(key, default)
10.4.3.10. Merge Dicts
10.4.3.10.1. Update method
10.4.3.10.2. Unpacking
10.4.3.10.3. collection.ChainMap
10.4.3.10.4. itertools.chain
10.4.3.11. Missing keys
10.4.3.11.1. key in dict idiom
10.4.3.11.2. try except
10.4.3.11.3. .get(key, default)
10.4.3.11.4. .setdefault(key, default)
10.4.3.11.5. collections.defaultdict(list)
10.4.3.11.6. collections.defaultdict X .setdefault
10.4.3.11.7. Count values in a list using dictonary
10.4.4. Set
10.4.4.1. group of elements
10.4.4.2. Mutable
10.4.4.3. Members
10.4.4.3.1. Immutable
10.4.4.3.2. unordered
10.4.4.3.3. heterogeneous
10.4.4.3.4. no duplicates
10.4.4.4. Creation
10.4.4.4.1. set function
10.4.4.4.2. curly braces
10.4.4.5. Operations
10.4.4.5.1. Comparative table
10.4.4.5.2. Union
10.4.4.5.3. Intersection
10.4.4.5.4. difference
10.4.4.5.5. Symetric_difference
10.4.4.5.6. isdisjoint
10.4.4.5.7. issubset
10.4.4.5.8. issuperset
11. Slice
12. Slice
13. Distributions
13.1. Anaconda Platform
13.1.1. Better to DataScience and Machine Learning
13.1.2. Pre-installed DS and ML libraries
13.1.3. Use Cpython
13.2. Cpython
13.2.1. The default implementation
13.2.2. Python was created programmed in C
13.2.3. Some built-in functions are just wrapers of C functions
13.3. Miniconda
13.3.1. Leightweight versio of Anaconda
13.4. PyPy
13.4.1. faster than CPython
13.5. Mojo
13.5.1. A lot faster than CPython and PyPy
14. Built-in packages
14.1. Math
14.1.1. Infinite
14.1.1.1. positive: +math.inf
14.1.1.2. negative: -math.inf
14.1.2. math.nan
14.1.2.1. used to show that a value that should be number was corrupted or something
14.1.2.2. used a lot with Pandas
15. ⎽⎽()⎽⎽
16. Classes
16.1. Definition
16.1.1. class Dog: species = "Canis" def ⎽⎽init()⎽⎽(self, name, sound): self.name = name self.sound = sound def ⎽⎽str()⎽⎽(self): return f'Name {self.name}' def speak(self, sound): return f'Says {sound}' class Bulldog(Dog): def speak(self, sound = 'Arf'): return super().speak(sound) # search for parent's method
16.2. Attributes
16.2.1. Class attributes
16.2.1.1. class Test: num_instances = 0 def ⎽⎽init()⎽⎽(self): #with the name of the class it could read, create and set class attribute. **Test**.num_instances += 1 with the self it could read the class attribute. Set overwrite the class attribute in the instance. **self**.num_instances = 999
16.2.2. Instance attributes
16.2.2.1. Only inside methods with self
17. Namespace / Scope
17.1. LEGB Rule
17.1.1. 1) Local
17.1.2. 2) Enclosing
17.1.3. 3) Global
17.1.4. 4) Built-in
17.2. Global Keyword
17.2.1. x = 2 def test(): global x # global x = 5 dont work x = 5
18. Exceptions
18.1. Raising exceptions
18.1.1. raise keyword
18.1.1.1. raise Exception('message')
18.1.2. assert keyword
18.1.2.1. assert (type(a) == int), 'Message'
18.2. Catching
18.2.1. try: func() except AssertionError as error: print(e)
19. Files
19.1. Modes
19.1.1. r - read
19.1.2. w - write
19.1.2.1. reader.write()
19.1.2.1.1. write a string
19.1.2.2. reader.writelines()
19.1.2.2.1. write a list of strings
19.1.3. a - append
19.1.4. rb / wr - for bytes
20. Sorting
20.1. Basic information
20.1.1. string: case sensitive. Cased letters come first.
20.1.2. Use the ⎽⎽lt⎽⎽() magic method of the object to sort
20.2. Sorted built-in function
20.2.1. Dont change in place
20.2.2. Return sorted list
20.2.3. Sort ascending
20.2.3.1. sorted(list1)
20.2.4. Sort descending
20.2.4.1. sorted(list1, reverse=True)
20.2.5. **key** argument
20.2.5.1. Basic information
20.2.5.1.1. a function to be aplied to each value
20.2.5.1.2. it works like this
20.2.5.2. Examples
20.2.5.2.1. string sort
20.2.5.2.2. Tuple sort
20.2.5.2.3. Attribute sorting
20.2.5.2.4. Custom sort
20.2.5.2.5. Python 2 cmp_to_key() function
20.2.5.2.6. Dict sorting
20.3. .sort() method
20.3.1. Change in place
20.3.2. it works like sorted()
21. How to read
21.1. with open('doc.txt', 'r') as reader: for line in reader: print(line, end='')
21.1.1. faster
21.1.2. memory efficient
21.1.3. then **end=''** part is needed because without it would have printed 2 new lines. 1 from the file, another from the print.
21.2. with open('doc.txt', 'r') as reader: while line != '': #EOF is a empty string print(line, end='') line = reader.readline()
21.3. with open('doc.txt', 'r') as reader: for line in reader.readlines(): print(line, end='')
21.3.1. it creates a list object in memory with all the lines.
21.3.2. if file is large, it could not work.