diff --git a/1-Intro/1-CM-Intro.pdf b/1-Intro/1-CM-Intro.pdf
index 2a335ebe314e5a25542da164b993f1aaf90ed340..8cb509a6a49b05bbd6fa713c2535bc2c9a175b41 100644
Binary files a/1-Intro/1-CM-Intro.pdf and b/1-Intro/1-CM-Intro.pdf differ
diff --git a/1-Intro/1-TP-Init_python.pdf b/1-Intro/1-TP-Init_python.pdf
index ef69c598b140f40569a14d9d56cf15c33e427369..c4ba2102fb98bd02112289d31fd494e7d97804bd 100644
Binary files a/1-Intro/1-TP-Init_python.pdf and b/1-Intro/1-TP-Init_python.pdf differ
diff --git a/1-Intro/tp1.py b/1-Intro/tp1.py
new file mode 100644
index 0000000000000000000000000000000000000000..10c60414ecb679a6d5d4bd5bcb468071dcf5629b
--- /dev/null
+++ b/1-Intro/tp1.py
@@ -0,0 +1,221 @@
+""" TP1 where we learn a bit of Python"""
+
+# First test
+print("Hello World!")
+
+# Variable and if
+my_variable = True
+if my_variable:
+    print("Hello World!")
+
+# Create a list
+my_list = [1, 1, 2, 3, 5, 8, 13, 21]
+print(my_list)
+
+# Add something in a list
+my_list = [1, 1, 2, 3, 5, 8, 13, 21]
+my_list.append(42)
+print(my_list)
+
+# Access to a subpart of a list
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[0:5])
+
+# Get the size of a list
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+size_list = len(my_list)
+print(size_list)
+
+# Access to a subpart of a list
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+size_list = len(my_list)
+print(my_list[5:size_list])
+
+# Access to last elements
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[-1])
+
+# Access to the second last element
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[-2])
+
+# Notion of step: going from index 3 to the end
+# but every 2 values
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[3:len(my_list):2])
+
+# Notion of step: going from index 3 to the end
+# but every 2 values
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[3::2])
+
+# Step in list
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+for i in my_list[3:len(my_list):2]:
+    print(i)
+
+# Reverse the order
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[::-1])
+
+# Reverse the order, with start/end
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[7:2:-1])
+
+# Reverse the order, with start/end and step
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+print(my_list[7:2:-2])
+
+# Concatenate two lists
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+my_other_list = ["Hello", "World", "Pwet"]
+result = my_list + my_other_list
+print(result)
+
+# Strings are lists
+my_char = "Hi all!"
+print(my_char[5:2:-1])
+
+# List are objects
+my_list = [1, 2, 3]
+my_other_list = my_list
+my_other_list.append(5)
+print(my_list)
+
+# Correct way of creating a copy of a list
+my_list = [1, 2, 3]
+my_other_list = list(my_list)
+my_other_list.append(5)
+print(my_list)
+
+
+
+
+
+
+# Simple for
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+for i in my_list:
+    print(i)
+
+# For with step/beg/end
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+for i in my_list[7:2:-1]:
+    print(i)
+
+# While loop
+my_list = [1, 1, 2, 3, 5, 8, 13, 21, 42]
+i = 0
+while i < len(my_list):
+    print(my_list[i])
+    i += 1
+
+
+
+
+
+# Example of dict
+my_dict = {}
+my_dict["keys1"] = 5
+my_dict["keys2"] = 6
+my_dict[42] = "Pwet"
+print(my_dict)
+print(my_dict[42])
+
+# Print keys or values of a dict
+print(my_dict.keys())
+print(my_dict.values())
+
+# Play with values
+for i in my_dict.values():
+    print(i)
+
+
+
+
+
+# Import a module
+import random
+# Define a new function
+def my_function():
+    # Get a random number between 2 and 5
+    my_rand = random.randint(2, 5)
+    # If this number is 4...
+    if my_rand == 4:
+        # Print something
+        print("Random")
+# Execute the function
+my_function()
+
+
+# Argument in functions
+def my_function(arg):
+    # If the string version of arg is not Pwet
+    if str(arg) != "Pwet":
+        # Print it
+        print(arg)
+    else:
+        # Else, print something else
+        print("Zbla")
+# Try the function
+my_function(3)
+my_function("Poulpe")
+my_function("Pwet")
+
+
+# Return a value
+def my_function(arg):
+    # The variable that will be returned
+    ret = "Zbla"
+    # If the string version of arg is not Pwet
+    if str(arg) != "Pwet":
+        # Modify the variable
+        ret = arg
+    # Return it
+    return ret
+# Try the function
+print(my_function(3))
+print(my_function("Poulpe"))
+print(my_function("Pwet"))
+
+
+# Return several values
+def my_function(arg):
+    ret = "Zbla"
+    # If the string version of arg is not Pwet
+    if str(arg) != "Pwet":
+        # Modify the variable
+        ret = arg
+    # Return it and its length
+    return ret, len(str(ret))
+# Try the function
+print(my_function("Pwet"))
+# Access like a list to returned values
+print(my_function("Pwet")[0])
+print(my_function("Pwet")[1])
+
+
+
+
+class MyObject:
+    """ Creating a new simple object """
+    # Initialize the object
+    def __init__(self, arg1, arg2=None): # Arg2 is optional
+        self.arg1 = arg1
+        self.arg2 = arg2
+        # If arg2 does not exist, initialize a list
+        if self.arg2 is None:
+            self.arg2 = []
+
+    # self representation for print
+    def __repr__(self):
+        return f"Arg1 is {self.arg1}\nArg2 has a size of {len(self.arg2)}"
+
+    def a_function(self, a_value):
+        """ Internal function of the object """
+        # Return the concatenation arg1 and a_value
+        return str(self.arg1) + str(a_value)
+
+test = MyObject("Pwet", [0, 1, 3])
+print(test)
+print(test.a_function(10))