--- website: https://www.python.org obj: application --- # Python Python is an interpreted programming language. ## Usage Python is a interpreted language, so you will need a python interpreter. You can code python interactively or run a script with: ```shell python3 [script.py] [args] ``` Or you can prefix your script with a shebang: ```python #!/usr/bin/python3 print("Hello World") ``` ## Syntax Python hello world: ```python print("Hello World") ``` ### Comments Python lets you do comments with the `#` sign. ```python # This is a comment ``` ### Variables You can define variables like this: ```python myvar = 3 # define multiple a, b = 5, 9 ``` ### Data Types In Python, there are several built-in data types. Here are some examples: #### Numeric Types ```python # Integer my_int = 10 # Float my_float = 3.14 ``` #### String ```python my_string = "Hello, world!" ``` #### Boolean ```python my_bool = True ``` #### List ```python my_list = [1, 2, 3, 4, 5] ``` #### Tuple ```python my_tuple = (1, 2, 3) ``` #### Dictionary ```python my_dict = {'name': 'John', 'age': 30} ``` #### Set ```python my_set = {1, 2, 3} ``` #### Explicit typing Explicit typing refers to the practice of explicitly declaring the data type of variables, parameters, or return values in a programming language. While Python is dynamically typed, meaning you don't have to declare the data type of variables explicitly, there are situations where you might want to provide type hints for clarity and documentation purposes, especially in large codebases or when working in a team. Python 3.5 introduced type hints as a way to provide optional type information. Type hints are annotations that indicate the expected types of variables, function parameters, and return values. They do not affect the runtime behavior of the program but can be used by static analysis tools and IDEs to perform type checking. ```python def add(x: int, y: int) -> int: """Add two integers and return the result.""" return x + y ``` In this example, `x: int` and `y: int` indicate that `x` and `y` should be integers, and `-> int` indicates that the function returns an integer. Type hints are not enforced by the Python interpreter, so you can still pass arguments of different types to a function that has type hints. However, tools like `mypy` can be used to perform static type checking and catch type errors at compile time. ### if statements In Python, `if` statements are used for conditional execution. ```python x = 10 if x > 5: print("x is greater than 5") ``` You can also include `elif` (short for "else if") and `else` clauses for more complex conditions: ```python x = 10 if x > 10: print("x is greater than 10") elif x == 10: print("x is equal to 10") else: print("x is less than 10") ``` You can also use logical operators such as `and`, `or`, and `not` to combine conditions: ```python x = 5 y = 3 if x > 0 and y > 0: print("Both x and y are positive") elif x > 0 or y > 0: print("At least one of x or y is positive") else: print("Both x and y are non-positive") ``` Remember to use proper indentation to define blocks of code within `if`, `elif`, and `else` statements in Python. ### for statements In Python, `for` loops are used to iterate over sequences like lists, tuples, strings, or other iterable objects. Here's a basic example: ```python # Iterate over a list my_list = [1, 2, 3, 4, 5] for item in my_list: print(item) ``` You can also use the `range()` function to generate a sequence of numbers to iterate over: ```python # Iterate over a range of numbers for i in range(5): print(i) ``` You can iterate over other iterable objects as well, such as strings: ```python # Iterate over a string my_string = "Hello" for char in my_string: print(char) ``` ### break and continue statements In Python, `break` and `continue` are used to control the flow of loops. #### break statement The `break` statement is used to exit a loop prematurely. Here's an example: ```python # Break the loop when x reaches 5 x = 0 while True: print(x) x += 1 if x == 5: break ``` In this example, the loop will iterate indefinitely until `x` equals 5. Once `x` reaches 5, the `break` statement is executed, and the loop terminates. #### continue statement The `continue` statement is used to skip the rest of the code inside a loop for the current iteration and proceed to the next iteration. Here's an example: ```python # Skip even numbers and print odd numbers for i in range(10): if i % 2 == 0: continue print(i) ``` In this example, when `i` is an even number, the `continue` statement is executed, and the loop moves to the next iteration without executing the `print(i)` statement. As a result, only odd numbers are printed. ### pass statement In Python, the `pass` statement is a null operation. It is used when a statement is syntactically required but you do not want to execute any code. It acts as a placeholder. Here's an example: ```python if x < 10: pass # This block does nothing else: print("x is greater than or equal to 10") ``` ### match statement The `match` statement was introduced in Python 3.10 as a replacement for the `switch` statement. It provides a more flexible and readable way to perform pattern matching. Here's an example: ```python def weekday_name(day_num): match day_num: case 1: return "Monday" case 2: return "Tuesday" case 3: return "Wednesday" case 4: return "Thursday" case 5: return "Friday" case 6 | 7: return "Weekend" case _: return "Invalid day" print(weekday_name(3)) # Output: Wednesday print(weekday_name(6)) # Output: Weekend print(weekday_name(9)) # Output: Invalid day ``` In this example, the `match` statement takes an expression (`day_num`) and matches it against several patterns using `case` clauses. The `_` acts as a wildcard pattern that matches any value not covered by previous cases. The `|` operator allows you to match multiple patterns together, like `case 6 | 7:` which matches either 6 or 7. ### Functions In Python, functions are blocks of reusable code that perform a specific task. They allow you to break down your program into smaller, manageable pieces. #### Defining a Function You can define a function using the `def` keyword followed by the function name and parentheses containing any parameters the function takes. The function body is indented below the function definition. Here's an example: ```python def greet(name): """This function greets the person with the given name.""" print("Hello, " + name + "!") ``` In this example, `greet` is the function name, and it takes one parameter `name`. #### Calling a Function To call a function, simply use the function name followed by parentheses containing any required arguments. Here's how you call the `greet` function defined above: ```python greet("Alice") ``` Ordering of the function arguments matters, unless you use explicit named arguments: ```python def eat(food, amount): print(f"I eat {amount} {food}") # Ordering matters eat("Pizza", "3") # Output: I eat 3 Pizza eat("3", "Pizza") # Output: I eat Pizza 3 # Named arguments # Improved readability eat(food="Pizza", amount="3") # Output: I eat 3 Pizza # Ordering does not matter eat(amount="3", food="Pizza") # Output: I eat 3 Pizza ``` #### Returning Values Functions can also return values using the `return` keyword. Here's an example: ```python def add(a, b): """This function adds two numbers.""" return a + b ``` You can capture the returned value by assigning it to a variable or use it directly. Here's how you can use the `add` function: ```python result = add(3, 5) print(result) # Output: 8 ``` #### Default Parameters You can provide default values for parameters in a function. If a parameter is not provided when calling the function, it will use the default value. Here's an example: ```python def greet(name="World"): """This function greets the person with the given name.""" print("Hello, " + name + "!") ``` You can call this function with or without an argument: ```python greet() # Output: Hello, World! greet("Alice") # Output: Hello, Alice! ``` ### Lambda expressions Lambda expressions, also known as lambda functions or anonymous functions, are a way to create small, unnamed functions in Python. They are defined using the `lambda` keyword, which is followed by a list of parameters, a colon, and an expression. Lambda functions can take any number of arguments but can only have one expression. They are typically used when you need a simple function for a short period of time and don't want to define a full-fledged function using the `def` keyword. Here's the basic syntax of a lambda expression: ```python lambda arguments: expression ``` Here's an example of a lambda function that takes two arguments and returns their sum: ```python add = lambda x, y: x + y ``` You can then call this lambda function like a regular function: ```python result = add(3, 5) print(result) # Output: 8 ``` Lambda functions are often used in conjunction with built-in functions like `map()`, `filter()`, and `reduce()` to perform operations on iterables. For example, you can use a lambda function with `map()` to apply a function to each element of a list: ```python numbers = [1, 2, 3, 4, 5] squared = map(lambda x: x**2, numbers) print(list(squared)) # Output: [1, 4, 9, 16, 25] ``` ### Documentation Comments In Python, documentation comments, also known as docstrings, play a crucial role in explaining the purpose and usage of functions, classes, modules, and packages. 1. **Module-Level Docstrings**: These comments describe the module's purpose, its contents, and any important information for users. They appear at the beginning of the Python file, enclosed in triple quotes (''' or """). ```python '''This module provides utility functions for string manipulation.''' ``` 2. **Function and Method Docstrings**: These comments explain the purpose, parameters, return values, and any exceptions raised by a function or method. They are placed immediately after the function or method definition, again enclosed in triple quotes. ```python def greet(name): '''Greet the user by name. Args: name (str): The name of the user. Returns: str: A greeting message.''' return f"Hello, {name}!" ``` 3. **Class Docstrings**: Similar to function docstrings, these comments describe the purpose and usage of a class. They are placed immediately after the class definition. ```python class Calculator: '''A simple calculator class.''' def add(self, x, y): '''Add two numbers.''' return x + y ``` ### Modules In Python, a module is a file containing Python definitions and statements. The file name is the module name with the suffix `.py`. Modules are used to organize Python code into reusable units, facilitating better code management and sharing of functionality across different projects. #### Creating Modules To create a module, simply save your Python code in a file with a `.py` extension. For example, if you have a file named `my_module.py` containing the following code: ```python # my_module.py def greet(name): return f"Hello, {name}!" ``` You can now import this module in another Python script using the `import` statement: ```python import my_module print(my_module.greet("Alice")) # Output: Hello, Alice! ``` #### Module Attributes Modules can contain functions, classes, and variables. These can be accessed using dot notation (`.`) after importing the module. ```python # Accessing functions from a module import math print(math.sqrt(25)) # Output: 5.0 # Accessing variables from a module print(math.pi) # Output: 3.141592653589793 ``` #### Module Search Path When you import a module, Python searches for it in the directories listed in the `sys.path` variable. This includes the current directory, directories in the `PYTHONPATH` environment variable, and standard library directories. #### Importing Specific Attributes You can import specific attributes (functions, classes, or variables) from a module using the `from ... import ...` syntax. ```python from math import sqrt print(sqrt(25)) # Output: 5.0 ``` This method allows you to use the imported attribute directly without qualifying it with the module name. #### Aliasing Modules and Attributes You can alias module names and attributes using the `as` keyword. ```python import math as m print(m.sqrt(25)) # Output: 5.0 from math import sqrt as square_root print(square_root(25)) # Output: 5.0 ``` #### Executing Modules as Scripts When you run a Python script directly, the code in the script is executed line by line. However, sometimes you may want certain code in a module to only run when the module is executed as a script, not when it's imported. You can achieve this by adding the following block: ```python if __name__ == "__main__": # Code to run when the module is executed directly print("This code runs only when the module is executed directly.") ``` #### Modules in Folders and Multiple Python Files In larger projects, organizing code into modules within folders can enhance maintainability and scalability. Here's how you can structure your project: 1. **Creating a Folder Structure**: Organize your project files into folders based on functionality or modules. 2. **Module Files**: Each module can be contained within its own `.py` file within the appropriate folder. For example: ``` my_project/ ├── main.py ├── utils/ │ ├── __init__.py │ ├── helper_functions.py │ └── constants.py ├── models/ │ ├── __init__.py │ ├── user.py │ └── product.py ``` 3. **`__init__.py` Files**: The presence of an `__init__.py` file in a folder indicates to Python that the folder should be treated as a package. This file can be empty or contain initialization code for the package. 4. **Importing Modules from Folders**: You can import modules from folders using dot notation (`.`) to traverse the folder structure. ```python # Importing modules from folders from utils.helper_functions import some_function from models.user import User ``` ### String Formatting String formatting in Python refers to the process of creating strings with placeholders that are replaced by the values of variables or expressions. Python offers several methods for string formatting, each with its own advantages and use cases. #### Using `%` Operator (Old Style Formatting) The `%` operator is an older method of string formatting in Python. It uses a syntax similar to C's `printf` function. ```python name = "Alice" age = 30 formatted_string = "Name: %s, Age: %d" % (name, age) print(formatted_string) # Output: Name: Alice, Age: 30 ``` #### Using `str.format()` Method The `str.format()` method provides more flexibility and readability compared to the `%` operator. ```python name = "Bob" age = 25 formatted_string = "Name: {}, Age: {}".format(name, age) print(formatted_string) # Output: Name: Bob, Age: 25 ``` You can also use named placeholders for better clarity: ```python formatted_string = "Name: {name}, Age: {age}".format(name=name, age=age) ``` #### Using f-strings (Formatted String Literals) f-strings provide a concise and intuitive way to format strings by embedding expressions directly inside string literals. ```python name = "Charlie" age = 35 formatted_string = f"Name: {name}, Age: {age}" print(formatted_string) # Output: Name: Charlie, Age: 35 ``` f-strings support expressions and function calls: ```python formatted_string = f"Name: {name.upper()}, Age in 5 years: {age + 5}" ``` ### Errors and Exceptions In Python, errors and exceptions are inevitable parts of programming. Errors occur when the Python interpreter encounters a problem while executing code, while exceptions are events that disrupt the normal flow of the program due to errors. Understanding how to handle errors and exceptions is crucial for writing robust and reliable Python code. #### Syntax Errors Syntax errors, also known as parsing errors, occur when the Python interpreter encounters invalid syntax in your code. These errors prevent the interpreter from executing the code. ```python # Syntax Error: Missing colon in the if statement if x == 5 print("x is 5") ``` #### Exceptions Exceptions are errors that occur during the execution of a Python program. Common exceptions include `TypeError`, `ZeroDivisionError`, `ValueError`, `NameError`, and `FileNotFoundError`, among others. ```python # ValueError: int() argument must be a string or a number, not a list num_list = [1, 2, 3] num = int(num_list) ``` #### Handling Exceptions with try-except Blocks You can handle exceptions using `try-except` blocks, allowing you to gracefully manage errors and prevent program termination. ```python try: num = int(input("Enter a number: ")) result = 10 / num print("Result:", result) except ValueError: print("Please enter a valid number.") except ZeroDivisionError: print("Cannot divide by zero.") ``` #### Handling Multiple Exceptions You can handle multiple exceptions in a single `except` block or use separate `except` blocks for each exception type. ```python try: # Code that may raise exceptions except (ValueError, ZeroDivisionError) as e: # Handle multiple exceptions print("An error occurred:", e) ``` ```python try: # Code that may raise exceptions except ValueError as ve: print("ValueError occurred:", ve) except ZeroDivisionError as ze: print("ZeroDivisionError occurred:", ze) ``` #### Handling All Exceptions You can also use a generic `except` block to catch all exceptions. However, this approach is not recommended as it may catch unexpected errors and hide bugs. ```python try: # Code that may raise exceptions except Exception as e: # Handle all exceptions print("An unexpected error occurred:", e) ``` #### Finally Block The `finally` block is used to execute cleanup code, such as closing files or releasing resources, regardless of whether an exception occurred or not. ```python try: # Code that may raise exceptions except SomeException: # Handle exception finally: # Cleanup code ``` #### Raising Exceptions You can raise exceptions manually using the `raise` statement to indicate that an error has occurred under certain conditions. ```python x = -1 if x < 0: raise ValueError("x must be a non-negative number") ``` ### Classes In Python, a class is a blueprint for creating objects. Classes provide a way to organize and structure code by grouping related data and functionality together. Objects created from classes are instances of those classes and can have their own attributes and methods. #### Defining a Class To define a class in Python, use the `class` keyword followed by the class name and a colon (`:`). Inside the class definition, you can include attributes and methods. ```python class MyClass: """A simple example class""" # Class attribute class_variable = 10 # Constructor method (initializer) def __init__(self, name): self.name = name # Instance attribute # Instance method def greet(self): return f"Hello, {self.name}!" ``` #### Creating Objects (Instances) To create an object (instance) of a class, use the class name followed by parentheses (`()`). This calls the class's constructor method (`__init__`) to initialize the object. ```python # Creating objects of MyClass obj1 = MyClass("Alice") obj2 = MyClass("Bob") ``` #### Accessing Attributes and Methods You can access attributes and methods of an object using dot notation (`.`). ```python # Accessing attributes print(obj1.name) # Output: Alice # Accessing methods print(obj2.greet()) # Output: Hello, Bob! ``` #### Class and Instance Attributes Class attributes are shared among all instances of a class and are defined outside any method within the class. Instance attributes are unique to each instance and are typically initialized within the constructor method. ```python class Dog: species = "Canis familiaris" # Class attribute def __init__(self, name, age): self.name = name # Instance attribute self.age = age # Instance attribute ``` #### Inheritance Inheritance allows a class (subclass) to inherit attributes and methods from another class (superclass). This promotes code reuse and supports hierarchical relationships between classes. ```python class Animal: def speak(self): return "Animal speaks" class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" ``` #### Encapsulation Encapsulation is the bundling of data and methods that operate on the data within a class. It helps in hiding the internal implementation details of a class and protecting the data from external interference. ```python class BankAccount: def __init__(self, balance): self._balance = balance # Encapsulated attribute def deposit(self, amount): self._balance += amount def withdraw(self, amount): if amount <= self._balance: self._balance -= amount else: print("Insufficient funds") ``` #### Polymorphism Polymorphism allows objects of different classes to be treated as objects of a common superclass. This enables code to be written in a more generic way, promoting flexibility and extensibility. ```python class Shape: def area(self): pass class Rectangle(Shape): def __init__(self, length, width): self.length = length self.width = width def area(self): return self.length * self.width class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): import math return math.pi * self.radius ** 2 ``` #### Dataclasses Python 3.7 introduced the `dataclasses` module, which provides a decorator and functions for automatically adding special methods to classes. Dataclasses are a convenient way to create classes primarily meant to store data, with less boilerplate code. ```python from dataclasses import dataclass @dataclass class Point: x: int y: int # Usage p = Point(1, 2) print(p) # Output: Point(x=1, y=2) ``` ### Decorators Decorators are a powerful feature in Python that allow you to modify or extend the behavior of functions or methods without changing their implementation. Decorators are implemented using functions themselves and are denoted by the `@` symbol followed by the decorator function name. #### Function Decorators Function decorators are the most common type of decorators in Python. They wrap a function, allowing you to execute code before and/or after the wrapped function is called, or modify its behavior. ```python def my_decorator(func): def wrapper(): print("Something is happening before the function is called.") func() # Call the original function print("Something is happening after the function is called.") return wrapper @my_decorator def say_hello(): print("Hello!") # Calling the decorated function say_hello() ``` #### Decorator Syntax The `@decorator_function` syntax is a shorthand for `function = decorator_function(function)`. It applies the decorator function to the function immediately below it. ```python # Equivalent to: say_hello = my_decorator(say_hello) @my_decorator def say_hello(): print("Hello!") ``` #### Decorators with Arguments Decorators can accept arguments by wrapping them in an additional function. This allows you to customize the behavior of decorators based on parameters. ```python def repeat(num_times): def decorator_repeat(func): def wrapper(*args, **kwargs): for _ in range(num_times): result = func(*args, **kwargs) return result return wrapper return decorator_repeat @repeat(num_times=3) def greet(name): print(f"Hello, {name}!") # Calling the decorated function greet("Alice") ``` #### Class Decorators In addition to function decorators, Python also supports class decorators. Class decorators wrap entire classes instead of individual functions. ```python def add_methods(cls): cls.method1 = lambda self: print("Method 1 added dynamically.") cls.method2 = lambda self: print("Method 2 added dynamically.") return cls @add_methods class MyClass: pass # Creating an instance of the decorated class obj = MyClass() obj.method1() # Output: Method 1 added dynamically. ``` #### Built-in Decorators Python provides several built-in decorators, such as `@staticmethod`, `@classmethod`, and `@property`, which are commonly used in object-oriented programming. ```python class MyClass: def __init__(self, value): self._value = value @staticmethod def static_method(): print("This is a static method.") @classmethod def class_method(cls): print("This is a class method.") @property def value(self): return self._value # Using the built-in decorators MyClass.static_method() MyClass.class_method() obj = MyClass(10) print(obj.value) ``` ### Standard Library The Python Standard Library is a collection of modules and packages that provides a wide range of functionality to Python developers. These modules cover various domains such as file I/O, networking, data manipulation, web development, and more. Leveraging the Python Standard Library can save you time and effort by providing pre-built solutions for common tasks. Some of the most commonly used built-in modules include: - `os`: Operating system interfaces for file and directory manipulation. - `sys`: System-specific parameters and functions. - `datetime`: Date and time manipulation. - `random`: Random number generation. - `math`: Mathematical functions. - `json`: [JSON](../../../files/JSON.md) encoding and decoding. - `io`: Core tools for working with streams. - `os.path`: Functions for manipulating file paths. - `shutil`: High-level file operations such as copying and archiving. - `glob`: Unix-style pathname pattern expansion. - `tempfile`: Temporary file and directory creation. - `socket`: Low-level networking interface. - `http.client`: [HTTP](../../../internet/HTTP.md) client library. - `urllib`: [URL](../../../internet/URL.md) handling modules. - `ftplib`: [FTP](../../../internet/FTP.md) client library. - `smtplib`: [SMTP](../../../internet/SMTP.md) client library for sending [email](../../../internet/eMail.md). - `csv`: [CSV](../../../files/CSV.md) file reading and writing. - `pickle`: Object serialization. - `re`: [Regular expression](../../../tools/Regex.md) matching - `logging`: Flexible [logging](../../Log.md) system for Python. - `argparse`: Command-line argument parsing. - `collections`: Additional data structures beyond the built-in ones. - `concurrent`: Utilities for concurrent programming. - `multiprocessing`: Process-based parallelism ### Third Party Modules - **NumPy**: Fundamental for numerical computing. Provides high-performance multidimensional arrays. - **Pandas**: Offers data structures and tools for data manipulation and analysis, particularly with labeled data. - **Matplotlib**: Comprehensive library for creating static, animated, and interactive visualizations. - **Requests**: Simplifies making [HTTP](../../../internet/HTTP.md) requests, facilitating interaction with web services and APIs.