├── 01_getting_started_python ├── 01_intoduction_to_python │ └── Readme.md └── readme.md ├── 02_python_basics ├── 01_line_and_indentation │ ├── Readme.md │ └── main.py ├── 02_character_sets │ ├── Readme.md │ └── main.py ├── 03_tokens │ ├── Readme.md │ └── main.py ├── 04_Identifiers │ ├── Readme.md │ └── main.py ├── 05_Keywords_in_python │ ├── Readme.md │ └── main.py ├── 06_Operators_in_python │ ├── Readme.md │ └── main.py ├── 07_Delimiters │ ├── Readme.md │ └── main.py ├── 08_Data_types_in_python │ ├── Readme.md │ └── main.py ├── 09__variables_as_references │ ├── Readme.md │ └── main.py ├── 10_Type_conversion │ ├── Readme.md │ └── main.py ├── 11_decision_making_statements │ ├── Readme.md │ └── main.py ├── 12_Iterations_or_control_flow │ ├── Readme.md │ └── main.py ├── 13_string │ ├── Readme.md │ ├── function.md │ ├── mian.py │ └── string_methods.md ├── 14_list │ ├── Readme.md │ ├── list_comprehension.md │ ├── main.py │ └── unpacking_sequence_and_slicing.md ├── 15_tuple │ ├── main.py │ └── readme.md ├── 16_set │ ├── Readme.md │ └── main.py ├── 17_dictionary │ ├── Readme.md │ └── main.py ├── 18_functions │ ├── Readme.md │ ├── functions.md │ ├── functions_in_modules │ └── main.py ├── 19_Regular_expressions │ ├── 01_basic_regular_expressions │ │ └── Readme.md │ └── Readme.md ├── 20_Working_with_files │ ├── Readme.md │ ├── example.md │ ├── file.md │ ├── logs.txt │ ├── logs_backup.txt │ └── main.py ├── 21_Scope │ ├── Readme.md │ ├── example.txt │ └── main.py └── 22_Modules │ ├── 01_import_and_attributes │ ├── b.py │ ├── c.py │ ├── main.py │ └── readme.md │ ├── 02_standard_library_modules │ └── readme.md │ └── 03_byte_code │ ├── my_module.py │ └── readme.md ├── README.md └── images ├── Screenshot 2024-02-27 095542.png ├── Screenshot 2024-03-06 021617.png ├── and operator.png ├── arithmetic operators.png ├── bytecode.png ├── example.. of variables.png ├── interpreter and support library.png ├── interpreter, execution.png ├── logical operators.png ├── not, operator in python .png ├── or, operator.png ├── relational, comparison operator.png ├── reversed keywords.png ├── varables in python.png ├── variable as a tag.png └── variables in c and java.png /01_getting_started_python/01_intoduction_to_python/Readme.md: -------------------------------------------------------------------------------- 1 | # Python: The Friendly, Versatile Language 2 | 3 | ## Welcome to the World of Python! 4 | This section introduces you to the Python programming language in an engaging and informative way. Let’s explore why Python is a favorite among beginners, experts, and professionals across different fields. 5 | 6 | ## What is Python? 7 | Python is a high-level, interpreted programming language known for its readability, simplicity, and expressiveness. Instead of struggling with complex syntax, Python allows you to focus on solving problems and building great projects. It serves as a reliable companion for both learning and professional development. 8 | 9 | ## Is Python the Perfect Language? 10 | While no programming language is perfect, Python stands out due to its versatility and ease of use. 11 | - **Easy to Learn & Use**: A great choice for beginners. 12 | - **Large Community**: Millions of developers contribute to its growth and provide support. 13 | - **Extensive Libraries**: Offers numerous pre-built solutions, making development efficient. 14 | 15 | Although Python may not be the best tool for every scenario, it remains a powerful and flexible choice for various applications. 16 | 17 | ## Why Was the First Page of Google Written in Python? 18 | During Google's early days, rapid development and flexibility were key. Python provided the speed and adaptability required for quick prototyping and efficient changes. While Google now uses multiple languages, Python played a crucial role in shaping its initial development. 19 | 20 | ## Domains Where Python is Used 21 | Python is widely used across various domains: 22 | - **Web Development**: Frameworks like Django, FastAPI, and Flask enable efficient website creation. 23 | - **Data Science & Machine Learning**: Libraries such as NumPy, Pandas, Scikit-learn, and TensorFlow facilitate research and data analysis. 24 | - **Automation & Scripting**: Python simplifies repetitive tasks with automation scripts. 25 | - **Game Development**: Pygame provides tools to create interactive gaming experiences. 26 | - **IoT & Embedded Systems**: Python supports development on small computing devices. 27 | 28 | Its applications continue to expand, making it one of the most sought-after programming languages. 29 | 30 | ## Who Created Python? 31 | Python was developed by Guido van Rossum in the late 1980s. The language was named after the comedy group *Monty Python*, reflecting its user-friendly and engaging nature. Python’s core philosophy emphasizes readability, clarity, and simplicity. 32 | 33 | ## Is ChatGPT Built on Python Libraries? 34 | While ChatGPT is a complex AI model, many of the underlying tools and frameworks in AI research rely on Python. Libraries such as PyTorch and TensorFlow provide a strong foundation for training and fine-tuning models like ChatGPT. 35 | 36 | ## Who Can Learn Python? 37 | Python is accessible to everyone, regardless of background or experience. Whether you are a student, a professional, a data analyst, or a hobbyist, Python serves as an excellent programming language to explore and master. 38 | 39 | ## Community & Resources 40 | Python has a large and supportive community with numerous resources available: 41 | - **Official Documentation**: [Python.org](https://www.python.org/doc/) 42 | - **Stack Overflow**: A platform for asking and answering coding questions. 43 | - **Tutorials & Blogs**: Extensive guides ranging from beginner to advanced levels. 44 | - **Conferences & Meetups**: Opportunities to connect with fellow Python developers. 45 | 46 | ## A Final Word 47 | Python’s simplicity and versatility make it a standout programming language. Whether you are working on personal projects or large-scale applications, Python empowers you to build solutions efficiently and effectively. 48 | 49 | -------------------------------------------------------------------------------- /01_getting_started_python/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/01_getting_started_python/readme.md -------------------------------------------------------------------------------- /02_python_basics/01_line_and_indentation/Readme.md: -------------------------------------------------------------------------------- 1 | # Lines and Indentation in Python 2 | 3 | ## Logical and Physical Lines 4 | 5 | - A **Python program** consists of **logical lines**, each composed of one or more **physical lines**. 6 | - A **physical line** is a single line in your code editor, which may end with a **comment**. 7 | - **Comments** in Python start with a hash sign `#` and continue until the end of the line. 8 | - Python ignores everything after the `#`, making comments useful for adding explanations or notes to your code. 9 | 10 | ### Example: 11 | ```python 12 | x = 10 # This is a comment 13 | y = 20 # Python will ignore everything after the hash sign 14 | ``` 15 | 16 | ### Blank Lines 17 | 18 | - A **blank line** in Python contains only whitespace or a comment. 19 | - Python ignores blank lines, making them useful for improving code readability by separating logical sections. 20 | 21 | ### Statement Termination 22 | 23 | - In Python, most statements conclude at the end of a physical line. 24 | - Unlike some other programming languages, Python does not require a semicolon `;` to terminate statements. 25 | - If a statement is too long for one physical line, you can: 26 | - Use a backslash `\` to extend it across multiple physical lines. 27 | - Let Python automatically join lines if an open parenthesis `(`, bracket `[`, or brace `{` has not been closed. 28 | 29 | ### Example: 30 | ```python 31 | # Using a backslash to continue the statement 32 | total = 1 + 2 + 3 + \ 33 | 4 + 5 + 6 34 | 35 | # Using parentheses to continue the statement 36 | total = (1 + 2 + 3 + 37 | 4 + 5 + 6) 38 | ``` 39 | 40 | ## Triple-Quoted Strings 41 | 42 | - **Triple-quoted string literals** allow you to span multiple physical lines without using backslashes. 43 | 44 | ### Example: 45 | ```python 46 | text = """This is a long string 47 | that spans multiple lines.""" 48 | ``` 49 | 50 | ## Continuation Lines 51 | 52 | - Physical lines following the first one in a logical line are called **continuation lines**. 53 | - **Indentation** rules apply only to the first physical line of each logical line. 54 | 55 | ## Indentation and Block Structure 56 | 57 | - Python uses **indentation** to define the block structure of code. 58 | - Unlike other languages that use braces `{}`, Python relies solely on indentation. 59 | - **Blocks** are sequences of logical lines with the same indentation level. 60 | - A block ends when a logical line has less indentation. 61 | 62 | ### Example: 63 | ```python 64 | if x > 0: 65 | print("Positive number") 66 | y = x 67 | else: 68 | print("Non-positive number") 69 | y = 0 70 | ``` 71 | 72 | ### Important Rules 73 | 74 | - The first statement in a Python source file must not be indented. 75 | - Statements typed at the interactive prompt `>>>` must also have no indentation. 76 | 77 | ## Indentation Best Practices 78 | 79 | - **Standard Python style** recommends using **four spaces** per indentation level. 80 | - Avoid mixing spaces and tabs, as different tools handle them differently. 81 | - Use the `-t` and `-tt` options in Python to ensure consistent tab and space usage. 82 | - **Python 3** enforces no mixing of tabs and spaces for indentation. 83 | 84 | ### Pro Tip 85 | 86 | - Configure your code editor to replace tabs with four spaces. This ensures consistent indentation across all tools and Python itself. 87 | 88 | ### Example: 89 | ```python 90 | def greet(name): 91 | print(f"Hello, {name}!") # Correct: 4 spaces for indentation 92 | ``` 93 | 94 | -------------------------------------------------------------------------------- /02_python_basics/01_line_and_indentation/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/01_line_and_indentation/main.py -------------------------------------------------------------------------------- /02_python_basics/02_character_sets/Readme.md: -------------------------------------------------------------------------------- 1 | # Character Sets in Python 2 | 3 | ## Unicode and ASCII in Python 4 | 5 | ### Python 3 6 | 7 | - **Python 3** source files can use **any Unicode character**, encoded as **UTF-8**. 8 | - **UTF-8** is a variable-width character encoding that represents every character in the Unicode character set. 9 | - **ASCII characters** (with codes between 0 and 127) are encoded in UTF-8 as single bytes, ensuring that an ASCII text file is valid as a Python 3 source file. 10 | 11 | ### Python 2 12 | 13 | - **Python 2** source files typically consist of characters from the **ASCII set**. 14 | - ASCII characters have codes ranging between 0 and 127. 15 | 16 | ## Specifying a Different Encoding 17 | 18 | - In both Python 2 and 3, you can specify a different encoding for a source file. 19 | - Python uses this specified encoding to interpret the file correctly. 20 | 21 | ### Example: 22 | ```python 23 | # coding: utf-8 24 | ``` 25 | 26 | - This comment should be placed at the very beginning of the Python source file (immediately after the "shebang line" if present). 27 | - The `coding:` directive is also referred to as an **encoding declaration**. 28 | 29 | ## Using Non-ASCII Characters 30 | 31 | - In **Python 2**, non-ASCII characters can only be used in **comments** and **string literals**. 32 | - The **coding directive** allows you to use these characters by specifying the appropriate encoding. 33 | 34 | ### Example: 35 | ```python 36 | # coding: iso-8859-1 37 | # This is a comment with a non-ASCII character: ñ 38 | print("Hola, señor!") 39 | ``` 40 | 41 | ## Best Practices for Encoding 42 | 43 | - It is recommended to use **UTF-8** for all text files, including Python source files. 44 | - **UTF-8** ensures compatibility with a wide variety of characters from different languages. 45 | 46 | ### Example: 47 | ```python 48 | # coding: utf-8 49 | print("こんにちは, 世界!") # Prints "Hello, World!" in Japanese 50 | ``` 51 | 52 | --- 53 | This section covered how Python handles character sets and encodings. By understanding and applying the correct encoding, you can write Python code that is robust, flexible, and compatible across different systems. 54 | 55 | -------------------------------------------------------------------------------- /02_python_basics/02_character_sets/main.py: -------------------------------------------------------------------------------- 1 | # Python 3: Using UTF-8 encoding 2 | # UTF-8 allows the use of any Unicode character 3 | # ASCII characters (0-127) are encoded as single bytes 4 | 5 | # Example of a valid Python 3 source file with Unicode characters 6 | print("Hello, World!") # Standard ASCII characters 7 | print("こんにちは, 世界!") # Japanese characters (UTF-8 encoded) 8 | 9 | # Specifying a Different Encoding 10 | # The following comment should be placed at the top of the file 11 | # coding: utf-8 12 | 13 | # Using Non-ASCII Characters in Python 2 14 | # In Python 2, non-ASCII characters can be used in comments and string literals 15 | # Ensure the appropriate encoding is declared at the top 16 | 17 | # Example with ISO-8859-1 encoding 18 | # coding: iso-8859-1 19 | print("Hola, señor!") # Spanish text with a special character 20 | 21 | # Best Practices for Encoding 22 | # Always use UTF-8 encoding for Python files to ensure compatibility across different systems 23 | # UTF-8 supports a vast range of characters from different languages 24 | # Configure the editor to replace tabs with four spaces for consistency 25 | 26 | # Correct indentation using four spaces 27 | def greet(name): 28 | print(f"Hello, {name}!") # Properly formatted function with UTF-8 compatibility 29 | -------------------------------------------------------------------------------- /02_python_basics/03_tokens/Readme.md: -------------------------------------------------------------------------------- 1 | # Tokens in Python 2 | 3 | ## What Are Tokens? 4 | 5 | - Python divides each **logical line** into a sequence of basic lexical elements called **tokens**. 6 | - Each token represents a specific substring of the logical line. 7 | 8 | ### Types of Tokens 9 | 10 | The primary types of tokens in Python include: 11 | 12 | 1. **Identifiers**: Names assigned to variables, functions, classes, etc. 13 | 2. **Keywords**: Reserved words with special meanings in Python (e.g., `if`, `else`, `while`). 14 | 3. **Operators**: Symbols used for performing operations on variables and values (e.g., `+`, `-`, `*`, `/`). 15 | 4. **Delimiters**: Characters that separate tokens (e.g., `()`, `[]`, `{}`, `,`). 16 | 5. **Literals**: Fixed values such as numbers, strings, and booleans. 17 | 18 | ## The Role of Whitespace 19 | 20 | - **Whitespace** (spaces, tabs, and newlines) is used to separate tokens and improve readability. 21 | - Some whitespace is **mandatory** to distinguish adjacent identifiers or keywords. 22 | 23 | ### Examples: 24 | ```python 25 | # Incorrect: Python would interpret 'ifx' as a single identifier 26 | ifx = 10 27 | 28 | # Correct: Adding whitespace to separate 'if' and 'x' 29 | if x == 10: 30 | print("x is 10") 31 | ``` 32 | 33 | - In the above example, omitting the space between `if` and `x` would cause Python to interpret `ifx` as a single identifier instead of recognizing `if` as a keyword and `x` as a variable. 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /02_python_basics/03_tokens/main.py: -------------------------------------------------------------------------------- 1 | ### Examples of Tokens: 2 | 3 | # Identifiers 4 | variable_name = "Hello" # 'variable_name' is an identifier 5 | 6 | def my_function(): # 'my_function' is an identifier 7 | return "Python Tokens" 8 | 9 | # Keywords 10 | for i in range(5): # 'for' and 'in' are keywords 11 | print(i) 12 | 13 | # Operators 14 | a = 10 + 5 # '+' is an operator 15 | b = a * 2 # '*' is an operator 16 | 17 | # Delimiters 18 | my_list = [1, 2, 3, 4] # Square brackets '[]' are delimiters 19 | my_dict = {"key": "value"} # Curly braces '{}' are delimiters 20 | 21 | # Literals 22 | string_literal = "Hello, World!" # String literal 23 | integer_literal = 42 # Integer literal 24 | float_literal = 3.14 # Float literal 25 | boolean_literal = True # Boolean literal 26 | -------------------------------------------------------------------------------- /02_python_basics/04_Identifiers/Readme.md: -------------------------------------------------------------------------------- 1 | # Identifiers in Python 2 | 3 | In this section, we'll explore what **identifiers** are in Python and how to use them correctly. Identifiers are fundamental in Python as they represent variables, functions, classes, and other objects. 4 | 5 | ## What is an Identifier? 6 | 7 | - An **identifier** is a name used to specify a variable, function, class, module, or any other object in Python. 8 | - **Identifiers** help in naming various entities in your Python code, making it easier to reference them later. 9 | - They provide structure and readability to code, enabling maintainability and consistency. 10 | 11 | ## Rules for Creating Identifiers 12 | 13 | - An identifier must start with: 14 | - A letter (A-Z or a-z in Python 2). 15 | - An underscore `_`. 16 | - In Python 3, any character classified as a letter by Unicode can also be used to start an identifier. 17 | 18 | - After the first character, an identifier can include: 19 | - Letters (A-Z, a-z). 20 | - Digits (0-9). 21 | - Underscores `_`. 22 | - In Python 3, Unicode characters classified as digits or combining marks are also allowed. 23 | 24 | - **Case Sensitivity**: Identifiers are case-sensitive, meaning `studentName`, `StudentName`, and `STUDENTNAME` are all distinct. 25 | 26 | - **Punctuation**: Characters like `@`, `$`, and `!` are **not allowed** in identifiers. 27 | 28 | ### Examples: 29 | ```python 30 | student_age = 18 # Valid identifier 31 | Student_Age = 21 # Another valid identifier (case-sensitive distinction) 32 | # 1stRank = 5 # Invalid identifier (cannot start with a digit) 33 | अंक = 10 # Valid Unicode identifier 34 | رقم = 15 # Another valid Unicode identifier 35 | sum_result = अंक + رقم 36 | print(sum_result) # Unicode identifiers are allowed in Python 3 37 | ``` 38 | 39 | ## Naming Conventions 40 | 41 | - **Class Names**: Typically start with an uppercase letter. 42 | - **Other Identifiers**: Typically start with a lowercase letter. 43 | - **Constants**: Conventionally written in all uppercase letters (e.g., `PI = 3.1416`). 44 | 45 | ### Example: 46 | ```python 47 | class StudentProfile: # Class name starts with an uppercase letter 48 | pass 49 | 50 | def calculate_score(): # Function name starts with a lowercase letter 51 | pass 52 | 53 | MAX_LIMIT = 100 # Constant identifier using uppercase letters 54 | ``` 55 | 56 | ### Private Identifiers 57 | 58 | - Starting an identifier with a single leading underscore `_` indicates that the identifier is intended to be **private**. 59 | - Starting with two leading underscores `__` indicates a **strongly private** identifier. 60 | - If an identifier starts and ends with double underscores `__name__`, it is a **language-defined special name**. 61 | 62 | ### Example: 63 | ```python 64 | _internal_value = 50 # Indicates a private variable 65 | __secure_data = "Secret" # Indicates a strongly private variable 66 | __str__ = "Special method in Python" # Special language-defined name 67 | ``` 68 | 69 | ## Special Use of Underscore in Interactive Sessions 70 | 71 | - In the interactive Python interpreter, the identifier `_` (a single underscore) is special. 72 | - It is automatically bound to the result of the last evaluated expression. 73 | 74 | ### Example: 75 | ```python 76 | >>> 10 + 5 77 | 15 78 | >>> _ * 2 79 | 30 # _ refers to the last result, which was 15 80 | ``` 81 | 82 | --- 83 | 84 | This section provided an in-depth overview of **identifiers** in Python, including the rules for creating them, best practices, and naming conventions. Proper use of identifiers ensures that your Python code remains structured, readable, and maintainable. 85 | 86 | -------------------------------------------------------------------------------- /02_python_basics/04_Identifiers/main.py: -------------------------------------------------------------------------------- 1 | # Valid Identifiers 2 | 3 | student_name = "John Doe" # Variable with lowercase and underscore 4 | StudentName = "Alice" # Variable with PascalCase 5 | studentAge = 20 # CamelCase variable 6 | _studentID = 1001 # Private variable with a leading underscore 7 | PI = 3.14159 # Constant variable (conventionally in uppercase) 8 | 9 | 10 | 11 | # Invalid Identifiers 12 | 13 | # 1student = "Invalid" # Cannot start with a digit 14 | # student-name = "Invalid" # Cannot contain hyphens 15 | # student@id = 101 # Cannot contain special characters 16 | 17 | 18 | 19 | # Using Unicode Identifiers (Python 3+) 20 | 21 | नाम = "राम" # Hindi Unicode variable 22 | رقم = 500 # Arabic Unicode variable 23 | 結果 = 98 # Chinese Unicode variable 24 | 25 | print(नाम, رقم, 結果) 26 | 27 | 28 | 29 | # Private and Strongly Private Identifiers 30 | 31 | class User: 32 | def __init__(self, username): 33 | self._internal_value = 42 # Private variable (single underscore) 34 | self.__secure_data = "Hidden" # Strongly private variable (double underscores) 35 | 36 | user1 = User("admin") 37 | # print(user1.__secure_data) # This will raise an AttributeError due to name mangling 38 | 39 | 40 | 41 | # Special Use of Underscore in Interactive Mode 42 | 43 | # >>> 100 + 25 44 | # 125 45 | # >>> _ * 2 46 | # 250 # The underscore holds the last evaluated expression 47 | -------------------------------------------------------------------------------- /02_python_basics/05_Keywords_in_python/Readme.md: -------------------------------------------------------------------------------- 1 | # Keywords in Python 2 | 3 | ## What are Keywords? 4 | 5 | - **Keywords** are reserved words in Python that have special meanings and cannot be used as regular identifiers (like variable names or function names). 6 | - Python's keywords consist only of **lowercase letters**, except for `True`, `False`, and `None`. 7 | 8 | ### Python v2 vs. Python v3 9 | 10 | - **Python v2** has **31 keywords**. 11 | - **Python v3** has **35 keywords**, including `False`, `True`, `None`, `async`, and `await`. 12 | 13 | ### Example of Invalid Identifiers: 14 | ```python 15 | # Keywords cannot be used as identifiers 16 | # if = 10 # ❌ Invalid: 'if' is a keyword 17 | # def = 20 # ❌ Invalid: 'def' is a keyword 18 | ``` 19 | 20 | ## Categories of Keywords 21 | 22 | ### 1. **Control Flow Keywords** 23 | - `if`, `elif`, `else` – Conditional branching 24 | - `for`, `while` – Looping constructs 25 | - `break`, `continue`, `pass` – Loop control 26 | 27 | ### 2. **Function and Class Definition Keywords** 28 | - `def` – Function definition 29 | - `class` – Class definition 30 | - `return` – Returns a value from a function 31 | 32 | ### 3. **Logical and Boolean Keywords** 33 | - `and`, `or`, `not` – Logical operators 34 | - `True`, `False`, `None` – Boolean values and null representation 35 | 36 | ### 4. **Exception Handling Keywords** 37 | - `try`, `except`, `finally`, `raise`, `assert` – Error handling 38 | 39 | ### 5. **Asynchronous Programming Keywords** 40 | - `async`, `await` – Asynchronous execution (Python 3.5+) 41 | 42 | ## Python v3 Keywords 43 | ```plaintext 44 | and as assert async await break 45 | class continue def del elif else 46 | except False finally for from global 47 | if import in is lambda None 48 | nonlocal not or pass raise return 49 | True try while with yield 50 | ``` 51 | 52 | ## Reserved Nature of Keywords 53 | Python reserves certain words for specific functionalities. Trying to use them as identifiers will result in a **SyntaxError**. 54 | 55 | ### Example 1: Attempting to Use a Keyword as a Variable Name 56 | ```python 57 | # Invalid example: 'for' is a reserved keyword 58 | # for = 10 # ❌ SyntaxError: invalid syntax 59 | ``` 60 | 61 | ### Example 2: Using Keywords Correctly in a Program 62 | ```python 63 | # Using 'def' correctly to define a function 64 | def my_function(): 65 | return "This is a valid function definition." 66 | 67 | # Using 'class' to define a class 68 | class MyClass: 69 | pass 70 | 71 | # Using 'if', 'else' in conditional statements 72 | x = 10 73 | if x > 5: 74 | print("x is greater than 5") 75 | else: 76 | print("x is 5 or less") 77 | ``` 78 | 79 | ### Example 3: Keywords vs Identifiers 80 | ```python 81 | # Valid identifier 82 | my_var = 20 # 'my_var' is allowed 83 | 84 | # Invalid identifier 85 | # return = 50 # ❌ SyntaxError: invalid syntax (reserved keyword) 86 | ``` -------------------------------------------------------------------------------- /02_python_basics/05_Keywords_in_python/main.py: -------------------------------------------------------------------------------- 1 | # Using 'def' correctly to define a function 2 | 3 | def my_function(): 4 | return "This is a valid function definition." 5 | 6 | # Using 'class' to define a class 7 | class MyClass: 8 | pass 9 | 10 | 11 | # Using 'if', 'else' in conditional statements 12 | 13 | x = 10 14 | if x > 5: 15 | print("x is greater than 5") 16 | else: 17 | print("x is 5 or less") 18 | 19 | 20 | 21 | ### Keywords vs Identifiers 22 | 23 | # Valid identifier 24 | my_var = 20 # 'my_var' is allowed 25 | 26 | # Invalid identifier 27 | # return = 50 # ❌ SyntaxError: invalid syntax (reserved keyword) 28 | -------------------------------------------------------------------------------- /02_python_basics/06_Operators_in_python/Readme.md: -------------------------------------------------------------------------------- 1 | # Operators in Python 2 | 3 | Operators in Python, which are symbols or combinations of symbols that perform operations on variables and values. Understanding operators is crucial for working with expressions and performing calculations in Python. 4 | 5 | ## What are Operators? 6 | 7 | - **Operators** are special symbols that instruct Python to perform computations or logical manipulations on values or variables. 8 | - Python provides various types of operators, each serving a distinct purpose in programming logic. 9 | 10 | ## List of Common Operators in Python 11 | 12 | ### 1. **Arithmetic Operators** 13 | 14 | Arithmetic operators are used to perform mathematical operations such as addition, subtraction, multiplication, and division. 15 | 16 | | Operator | Description | Example | 17 | |----------|-------------|---------| 18 | | `+` | Adds two values | `10 + 5` → `15` | 19 | | `-` | Subtracts the second value from the first | `10 - 5` → `5` | 20 | | `*` | Multiplies two values | `10 * 5` → `50` | 21 | | `/` | Divides the first value by the second | `10 / 3` → `3.3333...` | 22 | | `%` | Returns the remainder after division | `10 % 3` → `1` | 23 | | `**` | Raises the first value to the power of the second | `2 ** 3` → `8` | 24 | | `//` | Performs floor division (rounds down) | `10 // 3` → `3` | 25 | 26 | #### Example: 27 | ```python 28 | a = 10 29 | b = 3 30 | 31 | print(a + b) # Output: 13 32 | print(a - b) # Output: 7 33 | print(a * b) # Output: 30 34 | print(a / b) # Output: 3.3333... 35 | print(a % b) # Output: 1 36 | print(a ** b) # Output: 1000 37 | print(a // b) # Output: 3 38 | ``` 39 | 40 | ### 2. **Comparison Operators** 41 | 42 | Comparison operators compare two values and return a boolean (`True` or `False`). 43 | 44 | | Operator | Description | Example | 45 | |----------|-------------|---------| 46 | | `<` | Checks if the first value is less than the second | `5 < 3` → `False` | 47 | | `<=` | Checks if the first value is less than or equal to the second | `5 <= 5` → `True` | 48 | | `>` | Checks if the first value is greater than the second | `5 > 3` → `True` | 49 | | `>=` | Checks if the first value is greater than or equal to the second | `5 >= 5` → `True` | 50 | | `==` | Checks if two values are equal | `5 == 5` → `True` | 51 | | `!=` | Checks if two values are not equal | `5 != 3` → `True` | 52 | 53 | #### Example: 54 | ```python 55 | a = 5 56 | b = 3 57 | 58 | print(a < b) # Output: False 59 | print(a <= b) # Output: False 60 | print(a > b) # Output: True 61 | print(a >= b) # Output: True 62 | print(a == b) # Output: False 63 | print(a != b) # Output: True 64 | ``` 65 | 66 | ### 3. **Logical Operators** 67 | 68 | Logical operators are used to perform logical operations on boolean values. 69 | 70 | | Operator | Description | Example | 71 | |----------|-------------|---------| 72 | | `and` | Returns `True` if both conditions are true | `True and False` → `False` | 73 | | `or` | Returns `True` if at least one condition is true | `True or False` → `True` | 74 | | `not` | Reverses the logical state | `not True` → `False` | 75 | 76 | #### Example: 77 | ```python 78 | x = True 79 | y = False 80 | 81 | print(x and y) # Output: False 82 | print(x or y) # Output: True 83 | print(not x) # Output: False 84 | ``` 85 | 86 | ### 4. **Bitwise Operators** 87 | 88 | Bitwise operators perform operations at the binary level. 89 | 90 | | Operator | Description | Example | 91 | |----------|-------------|---------| 92 | | `&` | Performs bitwise AND | `5 & 3` → `1` | 93 | | `|` | Performs bitwise OR | `5 | 3` → `7` | 94 | | `^` | Performs bitwise XOR | `5 ^ 3` → `6` | 95 | | `~` | Performs bitwise NOT | `~5` → `-6` | 96 | | `<<` | Performs bitwise left shift | `5 << 1` → `10` | 97 | | `>>` | Performs bitwise right shift | `5 >> 1` → `2` | 98 | 99 | #### Example: 100 | ```python 101 | a = 5 # 101 in binary 102 | b = 3 # 011 in binary 103 | 104 | print(a & b) # Output: 1 (001 in binary) 105 | print(a | b) # Output: 7 (111 in binary) 106 | print(a ^ b) # Output: 6 (110 in binary) 107 | print(~a) # Output: -6 (bitwise NOT of 5) 108 | print(a << 1) # Output: 10 (Left shift: 1010 in binary) 109 | print(a >> 1) # Output: 2 (Right shift: 010 in binary) 110 | ``` 111 | 112 | ### 5. **Assignment Operators** 113 | 114 | Assignment operators are used to assign values to variables. 115 | 116 | | Operator | Description | Example | 117 | |----------|-------------|---------| 118 | | `=` | Assigns a value | `x = 10` | 119 | | `+=` | Adds and assigns | `x += 5` (equivalent to `x = x + 5`) | 120 | | `-=` | Subtracts and assigns | `x -= 5` (equivalent to `x = x - 5`) | 121 | | `*=` | Multiplies and assigns | `x *= 5` | 122 | | `/=` | Divides and assigns | `x /= 5` | 123 | | `//=` | Floor divides and assigns | `x //= 5` | 124 | 125 | #### Example: 126 | ```python 127 | x = 10 128 | x += 5 129 | print(x) # Output: 15 130 | 131 | x *= 2 132 | print(x) # Output: 30 133 | ``` 134 | 135 | ## Summary 136 | 137 | Python provides a wide range of operators that allow for mathematical calculations, logical operations, comparisons, and more. Mastering these operators is essential for writing efficient and powerful Python code. The `@` operator, introduced in Python 3, is used for matrix multiplication, further expanding Python’s capabilities in handling complex mathematical computations. 138 | 139 | -------------------------------------------------------------------------------- /02_python_basics/06_Operators_in_python/main.py: -------------------------------------------------------------------------------- 1 | # Arithmetic Operators 2 | a = 10 3 | b = 3 4 | 5 | print(a + b) # Addition: 10 + 3 = 13 6 | print(a - b) # Subtraction: 10 - 3 = 7 7 | print(a * b) # Multiplication: 10 * 3 = 30 8 | print(a / b) # Division: 10 / 3 = 3.3333... 9 | print(a % b) # Modulus: Remainder of 10 / 3 = 1 10 | print(a ** b) # Exponentiation: 10^3 = 1000 11 | print(a // b) # Floor division: 10 // 3 = 3 (removes decimal) 12 | 13 | # Comparison Operators 14 | x = 5 15 | y = 3 16 | 17 | print(x < y) # Less than: False 18 | print(x <= y) # Less than or equal to: False 19 | print(x > y) # Greater than: True 20 | print(x >= y) # Greater than or equal to: True 21 | print(x == y) # Equal to: False 22 | print(x != y) # Not equal to: True 23 | 24 | # Logical Operators 25 | p = True 26 | q = False 27 | 28 | print(p and q) # AND: False (both must be True) 29 | print(p or q) # OR: True (at least one True) 30 | print(not p) # NOT: False (reverses True) 31 | 32 | # Bitwise Operators 33 | m = 5 # 101 in binary 34 | n = 3 # 011 in binary 35 | 36 | print(m & n) # Bitwise AND: 101 & 011 = 001 (1) 37 | print(m | n) # Bitwise OR: 101 | 011 = 111 (7) 38 | print(m ^ n) # Bitwise XOR: 101 ^ 011 = 110 (6) 39 | print(~m) # Bitwise NOT: ~101 = -6 (inverts bits) 40 | print(m << 1) # Left shift: 101 << 1 = 1010 (10) 41 | print(m >> 1) # Right shift: 101 >> 1 = 10 (2) 42 | 43 | # Assignment Operators 44 | num = 10 45 | num += 5 # Equivalent to num = num + 5 46 | print(num) # Output: 15 47 | 48 | num *= 2 # Equivalent to num = num * 2 49 | print(num) # Output: 30 50 | 51 | # Identity Operators 52 | list1 = [1, 2, 3] 53 | list2 = list1 54 | list3 = [1, 2, 3] 55 | 56 | print(list1 is list2) # True (same object) 57 | print(list1 is list3) # False (different objects) 58 | print(list1 is not list3) # True 59 | 60 | # Membership Operators 61 | fruits = ["apple", "banana", "cherry"] 62 | 63 | print("banana" in fruits) # True (exists in the list) 64 | print("grape" not in fruits) # True (does not exist) 65 | 66 | # Using @ Operator (Matrix Multiplication) 67 | import numpy as np 68 | 69 | matrix1 = np.array([[1, 2], [3, 4]]) 70 | matrix2 = np.array([[5, 6], [7, 8]]) 71 | 72 | result = matrix1 @ matrix2 # Matrix multiplication 73 | print(result) # Output: [[19 22] 74 | # [43 50]] 75 | -------------------------------------------------------------------------------- /02_python_basics/07_Delimiters/Readme.md: -------------------------------------------------------------------------------- 1 | # Delimiters in Python 2 | 3 | ## Definition 4 | 5 | A **delimiter** in Python is a symbol or a combination of symbols used to separate elements within a program. These delimiters help define expressions, lists, dictionaries, sets, function calls, and statements, ensuring proper syntax and logical structure within the code. 6 | 7 | ## Common Delimiters in Python 8 | 9 | Python uses the following characters as delimiters: 10 | 11 | | **Delimiter** | **Purpose/Usage** | 12 | |---------------|-----------------------------------------------------------------------------------| 13 | | `()` | Used for grouping expressions, function calls, and tuples. | 14 | | `[]` | Used for indexing, slicing, and list literals. | 15 | | `{}` | Used for dictionary and set literals, as well as formatting strings. | 16 | | `,` | Used to separate items in lists, tuples, dictionaries, function arguments, etc. | 17 | | `:` | Used in dictionaries to separate keys and values, and in various statements like `for`, `if`, and function definitions. | 18 | | `.` | Used for accessing object attributes or methods, and for floating-point literals. | 19 | | `=` | Used for assignment. | 20 | | `;` | Used to separate multiple statements on a single line. | 21 | | `@` | Used for decorators. | 22 | 23 | ### Example Usage of Delimiters 24 | ```python 25 | # Using parentheses for function calls 26 | def greet(name): 27 | return f"Hello, {name}!" 28 | print(greet("Alice")) # Output: Hello, Alice! 29 | 30 | # Using square brackets for lists and indexing 31 | fruits = ["apple", "banana", "cherry"] 32 | print(fruits[1]) # Output: banana 33 | 34 | # Using curly braces for dictionaries 35 | data = {"name": "Alice", "age": 25} 36 | print(data["name"]) # Output: Alice 37 | ``` 38 | 39 | ## Augmented Assignment Operators 40 | 41 | Python also uses augmented assignment operators, which are a combination of a delimiter and an operation. These operators perform an operation and then assign the result to a variable. 42 | 43 | | **Operator** | **Description** | 44 | |--------------|-----------------------------------------------------| 45 | | `+=` | Adds and assigns (e.g., `x += 2` is equivalent to `x = x + 2`). | 46 | | `-=` | Subtracts and assigns (e.g., `x -= 2` is equivalent to `x = x - 2`). | 47 | | `*=` | Multiplies and assigns (e.g., `x *= 2` is equivalent to `x = x * 2`). | 48 | | `/=` | Divides and assigns (e.g., `x /= 2` is equivalent to `x = x / 2`). | 49 | | `//=` | Floor divides and assigns (e.g., `x //= 2` is equivalent to `x = x // 2`). | 50 | | `%=` | Takes modulus and assigns (e.g., `x %= 2` is equivalent to `x = x % 2`). | 51 | | `**=` | Exponentiates and assigns (e.g., `x **= 2` is equivalent to `x = x ** 2`). | 52 | 53 | ### Example Usage of Augmented Assignment Operators 54 | ```python 55 | x = 10 56 | x += 5 # Equivalent to x = x + 5 57 | print(x) # Output: 15 58 | 59 | x *= 2 # Equivalent to x = x * 2 60 | print(x) # Output: 30 61 | ``` 62 | 63 | ## Special Characters and Their Uses 64 | 65 | Certain characters have specific meanings as part of other tokens in Python: 66 | 67 | | **Character** | **Special Meaning** | 68 | |---------------|-------------------------------------------------------------------------------------| 69 | | `'` | Surrounds string literals. | 70 | | `"` | Surrounds string literals. | 71 | | `#` | Starts a comment outside of a string. | 72 | | `\` | Used at the end of a physical line to join the next line into a single logical line. Also acts as an escape character in strings. | 73 | 74 | ### Example: 75 | ```python 76 | # This is a comment 77 | 78 | text = "Hello, World!" # Double quotes for string 79 | path = 'C:\\Users\\Hashim\\Documents' # Escape character in string 80 | ``` 81 | 82 | ## Restrictions on Certain Characters 83 | 84 | Some characters are not allowed in the main text of a Python program (except in comments or string literals): 85 | 86 | - `$` and `?` are not valid in identifiers or expressions. 87 | - All control characters (except whitespace) are restricted. 88 | - In Python 2, all characters with ISO codes above 126 (non-ASCII characters, like accented letters) were not allowed in identifiers. 89 | 90 | 91 | -------------------------------------------------------------------------------- /02_python_basics/07_Delimiters/main.py: -------------------------------------------------------------------------------- 1 | # 1. Using parentheses () for grouping expressions 2 | 3 | result = (2 + 3) * 4 # Parentheses group the expression 4 | print(result) # Output: 20 5 | 6 | 7 | # 2. Using square brackets [] for lists and indexing 8 | 9 | numbers = [1, 2, 3, 4, 5] # Creating a list 10 | print(numbers[0]) # Accessing the first element, Output: 1 11 | 12 | 13 | # 3. Using curly braces {} for dictionaries and sets 14 | 15 | student = {"name": "Ali", "age": 18} # Creating a dictionary 16 | print(student["name"]) # Output: Ali 17 | 18 | unique_values = {1, 2, 2, 3, 4} # Creating a set (removes duplicates) 19 | print(unique_values) # Output: {1, 2, 3, 4} 20 | 21 | 22 | # 4. Using colons : in dictionaries and loops 23 | 24 | ages = {"Ahmed": 20, "Sara": 22} # Dictionary with key-value pairs 25 | for key, value in ages.items(): 26 | print(key, "is", value, "years old") 27 | # Output: 28 | # Ahmed is 20 years old 29 | # Sara is 22 years old 30 | 31 | 32 | # 5. Using commas , to separate items in lists and function arguments 33 | 34 | colors = ["red", "blue", "green"] # List with multiple items 35 | print(colors) # Output: ['red', 'blue', 'green'] 36 | 37 | 38 | # 6. Using the dot . for floating-point numbers 39 | 40 | pi = 3.14 # Floating-point value 41 | print(pi) # Output: 3.14 42 | 43 | 44 | # 7. Using the assignment operator = 45 | 46 | x = 10 # Assigning a value to x 47 | y = x + 5 # Performing arithmetic and assignment 48 | print(y) # Output: 15 49 | 50 | 51 | # 8. Using semicolon ; for multiple statements (not recommended) 52 | 53 | a = 5; b = 10; print(a + b) # Output: 15 54 | 55 | 56 | # 9. Using the backslash \ for line continuation 57 | 58 | long_text = "This is a very long sentence that we " \ 59 | "can split across multiple lines." 60 | print(long_text) 61 | # Output: This is a very long sentence that we can split across multiple lines. 62 | -------------------------------------------------------------------------------- /02_python_basics/08_Data_types_in_python/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/08_Data_types_in_python/Readme.md -------------------------------------------------------------------------------- /02_python_basics/08_Data_types_in_python/main.py: -------------------------------------------------------------------------------- 1 | # Object Creation and Type Checking 2 | 3 | # Creating an integer and a string object 4 | x = 42 # 'x' is an integer object 5 | y = "Hello" # 'y' is a string object 6 | 7 | print("x:", x, "Type:", type(x)) 8 | print("y:", y, "Type:", type(y)) 9 | 10 | # Demonstrating immutability with integers and strings 11 | 12 | # For integers 13 | x = 42 # Original integer 14 | original_x = x # Preserve the original value 15 | x = x + 1 # x now references a new integer (43) 16 | print("Modified x:", x) 17 | print("Original x:", original_x) 18 | 19 | # For strings 20 | y = "Hello" # Original string 21 | original_y = y # Preserve the original value 22 | y += " World" # y now references a new string ("Hello World") 23 | print("Modified y:", y) 24 | print("Original y:", original_y) 25 | 26 | # Using type() and isinstance() for type checking 27 | print("Is x an int?", isinstance(x, int)) 28 | print("Is y a str?", isinstance(y, str)) 29 | 30 | # Numeric Data Types Examples 31 | 32 | # Integer literals in different bases 33 | decimal_int = 23 34 | binary_int = 0b1010 # Binary literal 35 | octal_int = 0o27 # Octal literal 36 | hex_int = 0x1F # Hexadecimal literal 37 | 38 | print("Decimal integer:", decimal_int) 39 | print("Binary integer:", binary_int) 40 | print("Octal integer:", octal_int) 41 | print("Hexadecimal integer:", hex_int) 42 | 43 | # Floating-point numbers and scientific notation 44 | float_num = 3.14159 45 | sci_notation1 = 1e3 # 1e3 equals 1000 46 | sci_notation2 = 2.5e-2 # 2.5e-2 equals 0.025 47 | 48 | print("Floating-point number:", float_num) 49 | print("Scientific notation (1e3):", sci_notation1) 50 | print("Scientific notation (2.5e-2):", sci_notation2) 51 | 52 | # Complex numbers 53 | complex_num = 1 + 2j 54 | print("Complex number:", complex_num) 55 | 56 | # Using underscores in numeric literals for readability (Python 3.6+) 57 | large_number = 100_000 58 | readable_hex = 0x_FF_FF # Underscores can be used in hex literals too 59 | print("Large number with underscores:", large_number) 60 | print("Hexadecimal with underscores:", readable_hex) 61 | 62 | # String Examples 63 | 64 | # Different ways to define strings 65 | single_quoted = 'Hello' 66 | double_quoted = "World" 67 | triple_quoted = """This is a 68 | multi-line string example.""" 69 | 70 | print("Single-quoted string:", single_quoted) 71 | print("Double-quoted string:", double_quoted) 72 | print("Triple-quoted string:\n", triple_quoted) 73 | 74 | # Boolean Data Type Examples 75 | 76 | # Boolean values and logical operations 77 | is_python_fun = True 78 | print("Boolean value:", is_python_fun) 79 | print("Boolean with AND:", is_python_fun and False) 80 | print("Boolean with NOT:", not is_python_fun) 81 | Below is your modified README file with all emojis removed and a brief explanation provided immediately after each heading, without using the word "Definition": 82 | 83 | --- 84 | 85 | # Variables and Other References in Python 86 | 87 | This section explains how Python uses variables and references to access and manipulate data values within programs. 88 | 89 | In this section, we examine how Python programs access and manipulate data through **references**. Understanding how variables and references work is essential for effective Python programming. 90 | 91 | ## References in Python 92 | 93 | A reference in Python is a label or name that points to a specific object in memory, enabling dynamic and flexible data management. 94 | 95 | - A **reference** is essentially a label that points to a value (object) in Python. 96 | - **References** can appear as variables, attributes, or items. 97 | - In Python, a reference itself does not have an intrinsic type; the type is determined by the object to which it currently points. 98 | - Over the course of a program’s execution, a single reference may be associated with objects of different types. 99 | 100 | ### Example: 101 | ```python 102 | value = 42 # 'value' is a reference to an integer object 103 | value = "hello" # 'value' now references a string object 104 | ``` 105 | 106 | ## Variables in Python 107 | 108 | Variables in Python are names that refer to objects. They are created by assignment and can be rebound to different objects as needed. 109 | 110 | - In Python, variables are simply **references** to objects. Unlike some other programming languages, there are no explicit variable declarations. 111 | - A variable comes into existence when it is **bound** to an object. 112 | - Variables can be **rebound** to new objects, and they can also be **unbound**, meaning they no longer refer to any object. 113 | 114 | ### Binding and Rebinding 115 | 116 | - **Binding:** The process of associating a variable with an object. 117 | - **Rebinding:** Assigning a new object to a variable that already has a binding. 118 | 119 | ### Example: 120 | ```python 121 | num = 10 # Binding: 'num' refers to the integer 10 122 | num = 20 # Rebinding: 'num' now refers to the integer 20 123 | ``` 124 | 125 | Unbinding is the process of removing the association between a variable and an object, typically using the `del` statement. 126 | 127 | ### Example: 128 | ```python 129 | item = 10 # 'item' refers to the integer 10 130 | del item # 'item' is now unbound; the name no longer exists 131 | ``` 132 | 133 | When a reference is unbound, the object it pointed to may be reclaimed by Python's garbage collector if no other references exist. 134 | 135 | ### Example: 136 | ```python 137 | list_obj = [1, 2, 3] # 'list_obj' refers to a list object 138 | alias = list_obj # 'alias' also refers to the same list object 139 | del list_obj # 'list_obj' is unbound, but the list remains because 'alias' still references it 140 | ``` 141 | 142 | ## Naming Variables 143 | 144 | Variable names in Python must follow the rules for identifiers and cannot be reserved keywords. Variables are categorized by their scope: 145 | 146 | - **Global Variables:** Accessible throughout the entire module; they are attributes of the module. 147 | - **Local Variables:** Accessible only within the function in which they are defined. 148 | 149 | ### Example: 150 | ```python 151 | message = "Global Message" # Global variable 152 | 153 | def show_message(): 154 | note = "Local Note" # Local variable 155 | print("Inside function:", note) 156 | print("Inside function accessing global variable:", message) 157 | 158 | show_message() # Displays both local and global messages 159 | print("Outside function:", message) 160 | ``` 161 | 162 | --- 163 | 164 | This section has covered the concepts of **variables** and **references** in Python, detailing how they are bound, rebound, and unbound. A clear grasp of these topics is essential for managing data and memory efficiently in Python programs. -------------------------------------------------------------------------------- /02_python_basics/09__variables_as_references/Readme.md: -------------------------------------------------------------------------------- 1 | # Variables and Other References in Python 2 | 3 | This section explains how Python uses variables and references to access and manipulate data values within programs. 4 | 5 | In this section, we examine how Python programs access and manipulate data through **references**. Understanding how variables and references work is essential for effective Python programming. 6 | 7 | ## References in Python 8 | 9 | A reference in Python is a label or name that points to a specific object in memory, enabling dynamic and flexible data management. 10 | 11 | - A **reference** is essentially a label that points to a value (object) in Python. 12 | - **References** can appear as variables, attributes, or items. 13 | - In Python, a reference itself does not have an intrinsic type; the type is determined by the object to which it currently points. 14 | - Over the course of a program’s execution, a single reference may be associated with objects of different types. 15 | 16 | ### Example: 17 | ```python 18 | value = 42 # 'value' is a reference to an integer object 19 | value = "hello" # 'value' now references a string object 20 | ``` 21 | 22 | ## Variables in Python 23 | 24 | Variables in Python are names that refer to objects. They are created by assignment and can be rebound to different objects as needed. 25 | 26 | - In Python, variables are simply **references** to objects. Unlike some other programming languages, there are no explicit variable declarations. 27 | - A variable comes into existence when it is **bound** to an object. 28 | - Variables can be **rebound** to new objects, and they can also be **unbound**, meaning they no longer refer to any object. 29 | 30 | ### Binding and Rebinding 31 | 32 | - **Binding:** The process of associating a variable with an object. 33 | - **Rebinding:** Assigning a new object to a variable that already has a binding. 34 | 35 | ### Example: 36 | ```python 37 | num = 10 # Binding: 'num' refers to the integer 10 38 | num = 20 # Rebinding: 'num' now refers to the integer 20 39 | ``` 40 | 41 | Unbinding is the process of removing the association between a variable and an object, typically using the `del` statement. 42 | 43 | ### Example: 44 | ```python 45 | item = 10 # 'item' refers to the integer 10 46 | del item # 'item' is now unbound; the name no longer exists 47 | ``` 48 | 49 | When a reference is unbound, the object it pointed to may be reclaimed by Python's garbage collector if no other references exist. 50 | 51 | ### Example: 52 | ```python 53 | list_obj = [1, 2, 3] # 'list_obj' refers to a list object 54 | alias = list_obj # 'alias' also refers to the same list object 55 | del list_obj # 'list_obj' is unbound, but the list remains because 'alias' still references it 56 | ``` 57 | 58 | ## Naming Variables 59 | 60 | Variable names in Python must follow the rules for identifiers and cannot be reserved keywords. Variables are categorized by their scope: 61 | 62 | - **Global Variables:** Accessible throughout the entire module; they are attributes of the module. 63 | - **Local Variables:** Accessible only within the function in which they are defined. 64 | 65 | ### Example: 66 | ```python 67 | message = "Global Message" # Global variable 68 | 69 | def show_message(): 70 | note = "Local Note" # Local variable 71 | print("Inside function:", note) 72 | print("Inside function accessing global variable:", message) 73 | 74 | show_message() # Displays both local and global messages 75 | print("Outside function:", message) 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /02_python_basics/09__variables_as_references/main.py: -------------------------------------------------------------------------------- 1 | # Code Examples for Variables and References in Python 2 | 3 | # --- References in Python --- 4 | 5 | print("=== References in Python ===") 6 | a = 50 # 'a' initially refers to an integer object 7 | print("a initially:", a) 8 | a = [1, 2, 3] # 'a' now refers to a list object 9 | print("a now references a list:", a) 10 | 11 | 12 | # --- Variables, Binding, and Rebinding --- 13 | 14 | print("\n=== Variables, Binding, and Rebinding ===") 15 | b = 30 # Binding: 'b' refers to the integer 30 16 | print("Original value of b:", b) 17 | b = b + 5 # Rebinding: 'b' now refers to a new integer value 35 18 | print("Rebound value of b:", b) 19 | 20 | 21 | # --- Unbinding Variables --- 22 | 23 | print("\n=== Unbinding Variables ===") 24 | c = {"x": 1, "y": 2} # 'c' refers to a dictionary object 25 | d = c # 'd' is another reference to the same dictionary 26 | print("Before unbinding, d:", d) 27 | del c # Unbinding: 'c' is removed, but the dictionary persists via 'd' 28 | print("After unbinding c, d still holds the dictionary:", d) 29 | 30 | 31 | 32 | # --- Global and Local Variables --- 33 | 34 | print("\n=== Global and Local Variables ===") 35 | global_message = "I am a global variable" # Global variable 36 | 37 | def demonstrate_scope(): 38 | local_message = "I am a local variable" # Local variable 39 | print("Inside function, local_message:", local_message) 40 | print("Inside function, global_message:", global_message) 41 | 42 | demonstrate_scope() 43 | print("Outside function, global_message:", global_message) 44 | -------------------------------------------------------------------------------- /02_python_basics/10_Type_conversion/Readme.md: -------------------------------------------------------------------------------- 1 | # Type Conversion in Python 2 | 3 | This document explains how to convert values between different data types in Python. It covers both implicit and explicit conversion, including examples where user input is taken and converted. 4 | 5 | ## Overview 6 | 7 | Type conversion is the process of converting a value from one data type to another. In Python, this can occur in two ways: 8 | - **Implicit Conversion:** Python automatically converts data types during operations, such as converting an integer to a float during arithmetic. 9 | - **Explicit Conversion:** You manually convert values using built-in functions like `int()`, `float()`, `str()`, and others. 10 | 11 | ## Implicit Type Conversion 12 | 13 | Python performs implicit type conversion when it automatically changes one data type into another to avoid errors during operations. For example, when an integer and a float are used together in an arithmetic operation, the integer is automatically converted to a float. 14 | 15 | ### Example: 16 | ```python 17 | a = 5 # integer 18 | b = 2.5 # float 19 | result = a + b # 'a' is implicitly converted to float 20 | print("Result of implicit conversion:", result) # Output: 7.5 21 | ``` 22 | 23 | ## Explicit Type Conversion 24 | 25 | Explicit conversion is when you use a function to change the type of a value. This method provides full control over how the conversion is performed. Common functions include: 26 | 27 | - `int()` – converts a value to an integer. 28 | - `float()` – converts a value to a float. 29 | - `str()` – converts a value to a string. 30 | - `list()` and `tuple()` – convert iterables to a list or tuple. 31 | 32 | ### Examples: 33 | ```python 34 | # Converting a string to an integer 35 | num_str = "100" 36 | num_int = int(num_str) 37 | print("Converted string to integer:", num_int) # Output: 100 38 | 39 | # Converting a float to an integer (decimal part is truncated) 40 | flt = 3.14 41 | int_flt = int(flt) 42 | print("Converted float to integer:", int_flt) # Output: 3 43 | 44 | # Converting an integer to a float 45 | int_val = 10 46 | flt_val = float(int_val) 47 | print("Converted integer to float:", flt_val) # Output: 10.0 48 | 49 | # Converting a number to a string 50 | number = 2021 51 | str_number = str(number) 52 | print("Converted number to string:", str_number) # Output: "2021" 53 | 54 | # Converting a list to a tuple 55 | my_list = [1, 2, 3] 56 | my_tuple = tuple(my_list) 57 | print("Converted list to tuple:", my_tuple) # Output: (1, 2, 3) 58 | ``` 59 | 60 | ## Input Conversion Examples 61 | 62 | When taking input from users, the value returned by the `input()` function is always a string. You can convert this input to another type as needed. 63 | 64 | ### Examples: 65 | ```python 66 | # Converting user input to an integer 67 | user_input = input("Enter an integer: ") 68 | converted_int = int(user_input) 69 | print("User input converted to integer:", converted_int) 70 | 71 | # Converting user input to a float 72 | user_input = input("Enter a floating-point number: ") 73 | converted_float = float(user_input) 74 | print("User input converted to float:", converted_float) 75 | ``` 76 | 77 | 78 | -------------------------------------------------------------------------------- /02_python_basics/10_Type_conversion/main.py: -------------------------------------------------------------------------------- 1 | 2 | # Type Conversion Examples in Python 3 | 4 | # --- Implicit Type Conversion --- 5 | 6 | print("=== Implicit Type Conversion ===") 7 | a = 5 # integer 8 | b = 2.5 # float 9 | result = a + b # 'a' is implicitly converted to float 10 | print("Result of adding an integer and a float:", result, type(result)) 11 | 12 | 13 | # --- Explicit Type Conversion --- 14 | 15 | print("\n=== Explicit Type Conversion ===") 16 | 17 | # Converting a string to an integer 18 | num_str = "123" 19 | num_int = int(num_str) 20 | print("Converted string to integer:", num_int, type(num_int)) 21 | 22 | 23 | # Converting a float to an integer (truncation occurs) 24 | 25 | flt = 9.99 26 | int_flt = int(flt) 27 | print("Converted float to integer:", int_flt, type(int_flt)) 28 | 29 | 30 | 31 | # Converting an integer to a float 32 | 33 | int_val = 10 34 | flt_val = float(int_val) 35 | print("Converted integer to float:", flt_val, type(flt_val)) 36 | 37 | 38 | 39 | # Converting a number to a string 40 | 41 | num = 456 42 | str_num = str(num) 43 | print("Converted number to string:", str_num, type(str_num)) 44 | 45 | 46 | 47 | # Converting a list to a tuple 48 | 49 | my_list = [1, 2, 3, 4] 50 | my_tuple = tuple(my_list) 51 | print("Converted list to tuple:", my_tuple, type(my_tuple)) 52 | 53 | 54 | 55 | # --- Input Conversion Examples --- 56 | print("\n=== Input Conversion Examples ===") 57 | 58 | # Example: Converting user input to an integer 59 | 60 | user_input = input("Enter an integer: ") 61 | converted_int = int(user_input) 62 | print("User input converted to integer:", converted_int, type(converted_int)) 63 | 64 | 65 | # Example: Converting user input to a float 66 | 67 | user_input = input("Enter a floating-point number: ") 68 | converted_float = float(user_input) 69 | print("User input converted to float:", converted_float, type(converted_float)) 70 | -------------------------------------------------------------------------------- /02_python_basics/11_decision_making_statements/Readme.md: -------------------------------------------------------------------------------- 1 | # Understanding Decision Statements in Python 2 | 3 | This document explains how decision statements work in Python. Decision statements allow your program to execute different code blocks based on certain conditions. In this guide, we cover the fundamentals of conditional tests and the various types of decision statements available, including simple `if` statements, `if-else` statements, `if-elif-else` chains, and nested `if` statements. 4 | 5 | ## Understanding Conditional Tests 6 | 7 | Conditional tests evaluate expressions to either `True` or `False`. Python uses these Boolean results to determine which blocks of code to execute. 8 | 9 | ### What is a Conditional Test? 10 | 11 | A conditional test is an expression that returns either `True` or `False`. These tests are the foundation of decision making in Python programs. 12 | 13 | ### Types of Conditional Tests 14 | 15 | 1. **Equality Tests (`==`):** 16 | - Checks if two values are equal. 17 | - Example: `5 == 5` returns `True`; `5 == 4` returns `False`. 18 | 19 | 2. **Inequality Tests (`!=`):** 20 | - Checks if two values are not equal. 21 | - Example: `5 != 4` returns `True`; `5 != 5` returns `False`. 22 | 23 | 3. **Greater Than and Less Than Tests (`>`, `<`):** 24 | - Compares two values. 25 | - Example: `7 > 5` returns `True`; `3 < 2` returns `False`. 26 | 27 | 4. **Greater Than or Equal To and Less Than or Equal To Tests (`>=`, `<=`):** 28 | - Checks if one value is greater than or equal to, or less than or equal to another. 29 | - Example: `5 >= 5` returns `True`; `3 <= 4` returns `True`. 30 | 31 | 5. **Boolean Tests (`and`, `or`, `not`):** 32 | - Combines multiple conditions. 33 | - `and`: Both conditions must be true. 34 | - `or`: At least one condition must be true. 35 | - `not`: Inverts the Boolean value. 36 | - Example: `(5 > 3) and (2 < 4)` returns `True`; `(5 > 3) and (2 > 4)` returns `False`. 37 | 38 | ### Ignoring Case in Conditional Tests 39 | 40 | When comparing strings, conditional tests are case-sensitive. Use the `.lower()` method to ignore case differences. 41 | 42 | ```python 43 | name = 'Alice' 44 | print(name == 'alice') # Returns False (case-sensitive) 45 | print(name.lower() == 'alice') # Returns True (ignoring case) 46 | ``` 47 | 48 | ## Simple `if` Statements 49 | 50 | An `if` statement tests a condition. If the condition is true, the corresponding block of code is executed; if it is false, the block is skipped. 51 | 52 | ### Example: Checking Voting Eligibility 53 | 54 | ```python 55 | age = 19 56 | 57 | if age >= 18: 58 | print("You are old enough to vote!") 59 | ``` 60 | 61 | ## `if-else` Statements 62 | 63 | An `if-else` statement provides an alternative block of code that executes when the condition is false. 64 | 65 | ### Example: Voting Eligibility with Feedback 66 | 67 | ```python 68 | age = 17 69 | 70 | if age >= 18: 71 | print("You are old enough to vote!") 72 | else: 73 | print("Sorry, you are too young to vote.") 74 | ``` 75 | 76 | ## `if-elif-else` Chains 77 | 78 | When you have multiple conditions to check, use an `if-elif-else` chain. Python evaluates each condition in order and executes the first block where the condition is true. 79 | 80 | ### Example: Amusement Park Ticket Pricing 81 | 82 | ```python 83 | age = 12 84 | 85 | if age < 4: 86 | print("Your admission cost is $0.") 87 | elif age < 18: 88 | print("Your admission cost is $25.") 89 | else: 90 | print("Your admission cost is $40.") 91 | ``` 92 | 93 | ## Nested `if` Statements 94 | 95 | Nested `if` statements are `if` statements within another `if` block. This structure allows you to check for multiple related conditions. 96 | 97 | ### Example: Admission Eligibility and Special Ticket Offers 98 | 99 | ```python 100 | age = 21 101 | 102 | if age >= 18: 103 | if age > 20: 104 | print("You are eligible for a special adult ticket.") 105 | else: 106 | print("You are eligible to vote!") 107 | else: 108 | print("You are too young to vote.") 109 | ``` 110 | 111 | ## Additional Real-World Use Cases 112 | 113 | 1. **Login Systems:** Check if the username and password match stored values. 114 | 2. **E-commerce:** Determine if a user qualifies for free shipping (e.g., `cart_total > 50` and `location == 'domestic'`). 115 | 3. **Game Development:** Check a player's status (e.g., `health > 0` and `level >= 5`). 116 | 117 | -------------------------------------------------------------------------------- /02_python_basics/11_decision_making_statements/main.py: -------------------------------------------------------------------------------- 1 | # Decision Statements Examples in Python 2 | 3 | # --- Simple if Statement --- 4 | 5 | print("=== Simple if Statement ===") 6 | voter_age = 19 7 | if voter_age >= 18: 8 | print("You are old enough to vote!") 9 | 10 | 11 | # --- if-else Statement --- 12 | 13 | print("\n=== if-else Statement ===") 14 | voter_age = 17 15 | if voter_age >= 18: 16 | print("You are old enough to vote!") 17 | else: 18 | print("Sorry, you are too young to vote.") 19 | 20 | 21 | # --- if-elif-else Chain --- 22 | 23 | print("\n=== if-elif-else Chain ===") 24 | age = int(input("Enter your age for ticket pricing: ")) 25 | if age < 4: 26 | print("Your admission cost is $0.") 27 | elif age < 18: 28 | print("Your admission cost is $25.") 29 | else: 30 | print("Your admission cost is $40.") 31 | 32 | 33 | # --- Nested if Statements --- 34 | 35 | print("\n=== Nested if Statements ===") 36 | age = int(input("Enter your age for eligibility check: ")) 37 | if age >= 18: 38 | if age > 20: 39 | print("You are eligible for a special adult ticket.") 40 | else: 41 | print("You are eligible to vote!") 42 | else: 43 | print("You are too young to vote.") 44 | 45 | 46 | # --- Additional Example: Number Parity --- 47 | 48 | print("\n=== Number Parity Check ===") 49 | number = int(input("Enter a number to check if it is even or odd: ")) 50 | if number % 2 == 0: 51 | print("The number is even.") 52 | else: 53 | print("The number is odd.") 54 | 55 | 56 | our_age = 12 57 | 58 | if our_age < 4: 59 | print("Your admission cost is $0.") 60 | elif our_age < 18: 61 | print("Your admission cost is $25.") 62 | else: 63 | print("Your admission cost is $40.") 64 | 65 | 66 | marks = 85 67 | 68 | if marks >= 90: 69 | print("You got an A grade! 🎉") 70 | elif marks >= 75 and marks < 90: 71 | print("You got a B grade! 👍") 72 | elif marks >= 60 and marks < 75: 73 | print("You got a C grade! 👌") 74 | else: 75 | print("You need to improve. 📚") 76 | 77 | 78 | mood = "energetic" 79 | 80 | if mood == "happy": 81 | print("How about listening to some pop music? 🎤") 82 | elif mood == "sad": 83 | print("Try some blues to feel those emotions! 🎷") 84 | elif mood == "energetic": 85 | print("Rock music is your go-to! 🎸") 86 | elif mood == "relaxed": 87 | print("Smooth jazz will be perfect for you. 🎹") 88 | else: 89 | print("Discover some new indie tracks! 🎧") -------------------------------------------------------------------------------- /02_python_basics/12_Iterations_or_control_flow/Readme.md: -------------------------------------------------------------------------------- 1 | # Control Flows - Loops 2 | 3 | ## What are Iterations or Loops? 4 | 5 | Iterations, or loops, allow you to execute a block of code repeatedly. They are essential for reducing repetition, handling variable-sized input, automating tasks, and improving code efficiency. Instead of writing the same code many times, loops let you write it once and run it repeatedly. 6 | 7 | ## Why Do We Need Iterations with Loops? 8 | 9 | - **Reduce Repetition:** Instead of writing multiple print statements, a loop can perform the task in a single, concise block. 10 | - **Dynamic Behavior:** Loops can process items from a list or lines in a file regardless of how many items there are. 11 | - **Automation:** They automate repetitive tasks, such as calculating values or processing user input. 12 | - **Efficiency:** Loops make code easier to modify and maintain since changes need to be made in only one place. 13 | 14 | ## Types of Loops in Python 15 | 16 | Python offers different kinds of loops: 17 | 18 | | Sr.No. | Name of the Loop | Description | 19 | |--------|------------------|-------------| 20 | | 1 | While Loop | Repeats a block of code while a condition remains True. The condition is checked before every iteration. | 21 | | 2 | For Loop | Iterates over a sequence (like a list, string, or range) a fixed number of times. | 22 | | 3 | Nested Loops | A loop inside another loop, used to handle multi-dimensional data or more complex iterations. | 23 | 24 | ## Loop Control Statements 25 | 26 | Loop control statements change the flow of loops: 27 | 28 | | Sr.No. | Control Statement | Description | 29 | |--------|-------------------|-------------| 30 | | 1 | Break | Exits the loop immediately. | 31 | | 2 | Continue | Skips the rest of the code in the current iteration and moves to the next iteration. | 32 | | 3 | Pass | A placeholder that does nothing; useful when a statement is required syntactically. | 33 | 34 | ## The `range()` Function 35 | 36 | The `range()` function generates a sequence of numbers. It is commonly used with loops. 37 | 38 | - **Syntax:** `range(start, stop, step)` 39 | - **start:** Beginning of the sequence (default is 0). 40 | - **stop:** End of the sequence (not included in the output). 41 | - **step:** The increment between each number (default is 1). 42 | 43 | ### Example: 44 | ```python 45 | print(list(range(10))) # Generates numbers 0 to 9. 46 | print(list(range(4, 9))) # Generates numbers 4 to 8. 47 | print(list(range(5, 25, 4))) # Generates numbers starting at 5, increasing by 4 until less than 25. 48 | ``` 49 | 50 | **How It Works:** 51 | - The first example prints numbers from 0 up to 9. 52 | - The second example starts at 4 and prints up to 8. 53 | - The third example starts at 5 and adds 4 each time until the next number would be 25 or more. 54 | 55 | ## For Loops 56 | 57 | For loops iterate over sequences like lists, strings, or ranges. 58 | 59 | ### Example: Printing a Multiplication Table 60 | ```python 61 | # Multiplication table for 5 62 | for i in range(1, 11): 63 | print(f"5 x {i} = {5 * i}") 64 | ``` 65 | 66 | **Flow Explanation:** 67 | - The loop starts with `i = 1` and checks if `i` is less than 11. 68 | - For each value of `i`, it calculates the product of 5 and `i` and prints the result. 69 | - `i` is automatically incremented until it reaches 11, at which point the loop stops. 70 | 71 | ### Example: Iterating Over a List 72 | ```python 73 | fruits = ["apple", "banana", "cherry"] 74 | for fruit in fruits: 75 | print(f"I like {fruit}!") 76 | ``` 77 | 78 | **Flow Explanation:** 79 | - The loop iterates over each item in the list `fruits`. 80 | - In each iteration, the variable `fruit` takes the value of the next item in the list. 81 | - The print statement outputs a message including the current fruit. 82 | 83 | ### Example: Using `range()` to Loop Over Indices 84 | ```python 85 | # Print even numbers from 2 to 20 86 | for number in range(2, 21, 2): 87 | print(number) 88 | ``` 89 | 90 | **Flow Explanation:** 91 | - The `range()` function generates numbers starting at 2, ending before 21, in steps of 2. 92 | - The loop iterates over each generated number and prints it. 93 | - This produces all even numbers between 2 and 20. 94 | 95 | ## While Loops 96 | 97 | While loops run as long as a specified condition is True. 98 | 99 | ### Example: Printing a Multiplication Table Using a While Loop 100 | ```python 101 | number = 1 102 | while number <= 10: 103 | print(f"5 x {number} = {5 * number}") 104 | number += 1 105 | ``` 106 | 107 | **Flow Explanation:** 108 | - The loop begins with `number = 1`. 109 | - It checks if `number` is less than or equal to 10. 110 | - If the condition is True, it prints the multiplication line and increments `number` by 1. 111 | - This process repeats until `number` exceeds 10, then the loop stops. 112 | 113 | ### Example: User Input with a While Loop 114 | ```python 115 | prompt = "Enter a number to get its square (or 'quit' to stop): " 116 | 117 | while True: 118 | user_input = input(prompt) 119 | if user_input.lower() == 'quit': 120 | break 121 | number = int(user_input) 122 | print(f"The square of {number} is {number ** 2}") 123 | ``` 124 | 125 | **Flow Explanation:** 126 | - The loop continuously asks the user for input. 127 | - If the user types "quit" (in any case), the condition triggers a `break` to exit the loop. 128 | - Otherwise, the input is converted to an integer, and its square is computed and printed. 129 | - The loop then repeats, prompting the user again. 130 | 131 | ### Example: Using `continue` in a While Loop 132 | ```python 133 | current_number = 0 134 | while current_number < 10: 135 | current_number += 1 136 | if current_number % 2 == 0: 137 | continue # Skip printing even numbers 138 | print(current_number) 139 | ``` 140 | 141 | **Flow Explanation:** 142 | - The loop starts with `current_number = 0`. 143 | - In each iteration, it increments `current_number` by 1. 144 | - If `current_number` is even (i.e., divisible by 2), the `continue` statement skips the print function and moves to the next iteration. 145 | - Only odd numbers are printed until `current_number` reaches 10. 146 | 147 | ### Avoiding Infinite Loops 148 | ```python 149 | x = 1 150 | while x <= 5: 151 | print(x) 152 | x += 1 # Ensures the loop stops once x becomes greater than 5 153 | ``` 154 | 155 | **Flow Explanation:** 156 | - The loop prints the value of `x` as long as `x` is less than or equal to 5. 157 | - The increment `x += 1` is crucial; without it, the condition would remain True indefinitely, resulting in an infinite loop. 158 | 159 | ## Nested Loops 160 | 161 | Nested loops are loops within loops, useful for complex iterations like processing multi-dimensional data. 162 | 163 | ### Example: Multiplication Table Generator 164 | ```python 165 | print("Welcome to the Multiplication Table Generator!") 166 | 167 | while True: 168 | number = int(input("\nEnter a number for its multiplication table: ")) 169 | print(f"\nMultiplication Table for {number}") 170 | for i in range(1, 11): 171 | print(f"{number} x {i} = {number * i}") 172 | 173 | continue_choice = input("\nDo you want to print another table? (yes/no): ").strip().lower() 174 | if continue_choice != 'yes': 175 | print("Exiting the program. Thank you!") 176 | break 177 | else: 178 | print("Let's print another table!") 179 | ``` 180 | 181 | **Flow Explanation:** 182 | - The outer while loop continually asks the user for a number. 183 | - Once a number is provided, the inner for loop generates and prints the multiplication table for that number. 184 | - After printing, the program asks if the user wants to print another table. 185 | - If the user types anything other than "yes", the loop breaks; otherwise, the process repeats. 186 | 187 | ### Example: Pyramid Pattern Generator 188 | ```python 189 | print("Welcome to the Pyramid Pattern Generator!") 190 | 191 | while True: 192 | height = int(input("\nEnter the height of the pyramid: ")) 193 | print(f"\nPyramid of height {height}\n") 194 | for i in range(1, height + 1): 195 | # Print spaces for alignment 196 | print(" " * (height - i), end='') 197 | # Print stars to form the pyramid 198 | print("*" * (2 * i - 1)) 199 | 200 | continue_choice = input("\nDo you want to create another pyramid? (yes/no): ").strip().lower() 201 | if continue_choice != 'yes': 202 | print("Exiting the program. Thank you!") 203 | break 204 | else: 205 | print("Let's build another pyramid!") 206 | ``` 207 | 208 | **Flow Explanation:** 209 | - The outer while loop prompts the user for the desired pyramid height. 210 | - The inner for loop prints each row of the pyramid: 211 | - It first prints a number of spaces to right-align the stars. 212 | - Then it prints an increasing number of stars to form the pyramid shape. 213 | - After printing, the user is asked if they want to generate another pyramid. 214 | - The loop repeats or terminates based on the user's input. 215 | 216 | -------------------------------------------------------------------------------- /02_python_basics/12_Iterations_or_control_flow/main.py: -------------------------------------------------------------------------------- 1 | ## Combined Code Examples for main.py 2 | 3 | # Combined Loop Examples in Python 4 | 5 | # --- For Loop Examples --- 6 | print("=== For Loop Examples ===") 7 | # Multiplication table for 5 using a for loop 8 | for i in range(1, 11): 9 | print(f"5 x {i} = {5 * i}") 10 | 11 | print() # Blank line for separation 12 | 13 | # Iterating over a list 14 | fruits = ["apple", "banana", "cherry"] 15 | for fruit in fruits: 16 | print(f"I like {fruit}!") 17 | 18 | print() # Blank line for separation 19 | 20 | # Using range() to print even numbers from 2 to 20 21 | for number in range(2, 21, 2): 22 | print(number) 23 | 24 | # --- While Loop Examples --- 25 | print("\n=== While Loop Examples ===") 26 | # Multiplication table for 5 using a while loop 27 | number = 1 28 | while number <= 10: 29 | print(f"5 x {number} = {5 * number}") 30 | number += 1 31 | 32 | print() # Blank line for separation 33 | 34 | # User input to calculate the square of a number 35 | prompt = "Enter a number to get its square (or 'quit' to stop): " 36 | while True: 37 | user_input = input(prompt) 38 | if user_input.lower() == 'quit': 39 | break 40 | number = int(user_input) 41 | print(f"The square of {number} is {number ** 2}") 42 | 43 | print() # Blank line for separation 44 | 45 | # Using continue in a while loop to print odd numbers only 46 | current_number = 0 47 | while current_number < 10: 48 | current_number += 1 49 | if current_number % 2 == 0: 50 | continue 51 | print(current_number) 52 | 53 | # --- Nested Loop Examples --- 54 | print("\n=== Nested Loop Examples ===") 55 | # Multiplication Table Generator with user control 56 | print("Welcome to the Multiplication Table Generator!") 57 | while True: 58 | table_number = int(input("\nEnter a number for its multiplication table: ")) 59 | print(f"\nMultiplication Table for {table_number}") 60 | for i in range(1, 11): 61 | print(f"{table_number} x {i} = {table_number * i}") 62 | 63 | continue_choice = input("\nDo you want to print another table? (yes/no): ").strip().lower() 64 | if continue_choice != 'yes': 65 | print("Exiting the Multiplication Table Generator. Thank you!") 66 | break 67 | 68 | print() # Blank line for separation 69 | 70 | # Pyramid Pattern Generator with user control 71 | print("Welcome to the Pyramid Pattern Generator!") 72 | while True: 73 | height = int(input("\nEnter the height of the pyramid: ")) 74 | print(f"\nPyramid of height {height}\n") 75 | for i in range(1, height + 1): 76 | print(" " * (height - i), end='') 77 | print("*" * (2 * i - 1)) 78 | 79 | continue_choice = input("\nDo you want to create another pyramid? (yes/no): ").strip().lower() 80 | if continue_choice != 'yes': 81 | print("Exiting the Pyramid Pattern Generator. Thank you!") 82 | break 83 | -------------------------------------------------------------------------------- /02_python_basics/13_string/Readme.md: -------------------------------------------------------------------------------- 1 | # Using Python to Manipulate Strings 2 | 3 | Python provides powerful ways to manipulate strings, allowing you to perform a variety of operations. This document explains how strings work in Python—including their creation, indexing, methods, formatting, escape sequences, and raw strings—with detailed code examples and explanations for each section. 4 | 5 | --- 6 | 7 | ## Creating Strings in Python 8 | 9 | Strings can be created using single quotes (`'...'`), double quotes (`"..."`), or triple quotes (`'''...'''` or `"""..."""`). Triple quotes are especially useful for creating multiline strings or docstrings. 10 | 11 | ### Example: 12 | ```python 13 | # Using single quotes 14 | str1 = 'Hello Python' 15 | print(str1) # Output: Hello Python 16 | 17 | # Using double quotes 18 | str2 = "Hello Python" 19 | print(str2) # Output: Hello Python 20 | 21 | # Using triple quotes for multiline strings 22 | str3 = '''Triple quotes are generally used for 23 | multiline strings or docstrings.''' 24 | print(str3) 25 | ``` 26 | 27 | **Explanation:** 28 | - The first two examples show that both single and double quotes can be used to create strings that print identically. 29 | - The triple-quoted string spans multiple lines, which is useful for long texts or documentation. 30 | 31 | --- 32 | 33 | ## Strings Indexing and Splitting 34 | 35 | Python strings are sequences, and each character in the string can be accessed by its index. Indexing starts at `0` for the first character, and negative indices allow access from the end. 36 | 37 | ### Example: 38 | ```python 39 | text = "HELLO" 40 | 41 | # Positive indexing 42 | print(text[0]) # Output: H 43 | print(text[1]) # Output: E 44 | 45 | # Negative indexing 46 | print(text[-1]) # Output: O 47 | print(text[-2]) # Output: L 48 | ``` 49 | 50 | **Explanation:** 51 | - `text[0]` accesses the first character 'H'. 52 | - `text[-1]` accesses the last character 'O'. 53 | This demonstrates how both positive and negative indexing work for accessing string characters. 54 | 55 | --- 56 | 57 | ## String Methods 58 | 59 | Python provides many built-in methods for manipulating strings. These methods return new strings and do not modify the original string. 60 | 61 | ### Example: 62 | ```python 63 | s = "hello world" 64 | 65 | # Capitalize: Convert the first character to uppercase. 66 | print(s.capitalize()) # Output: Hello world 67 | 68 | # Uppercase: Convert the entire string to uppercase. 69 | print(s.upper()) # Output: HELLO WORLD 70 | 71 | # Find: Locate the substring "world". 72 | print(s.find("world")) # Output: 6 73 | 74 | # Replace: Substitute "world" with "Python". 75 | print(s.replace("world", "Python")) # Output: hello Python 76 | ``` 77 | 78 | **Explanation:** 79 | - `capitalize()` changes only the first letter of the string. 80 | - `upper()` transforms all characters to uppercase. 81 | - `find()` returns the starting index of the substring "world" (which is 6). 82 | - `replace()` creates a new string where "world" is replaced with "Python". 83 | 84 | --- 85 | 86 | ## String Indexing and Slicing 87 | 88 | You can access individual characters or subsets of a string using indexing and slicing. 89 | 90 | ### Example: 91 | ```python 92 | word = 'Didcoding' 93 | 94 | # Accessing individual characters 95 | print(word[0]) # Output: D 96 | print(word[5]) # Output: d 97 | 98 | # Slicing: Get a substring from index 0 to 2 (excluding index 2). 99 | print(word[0:2]) # Output: Di 100 | 101 | # Slicing: Get a substring from index 2 to 5 (excluding index 5). 102 | print(word[2:5]) # Output: dco 103 | 104 | # Slicing with step: Reverse the string. 105 | print(word[::-1]) # Output: gnidcoDiD 106 | ``` 107 | 108 | **Explanation:** 109 | - `word[0:2]` extracts the first two characters of the string. 110 | - `word[2:5]` extracts a section from the string. 111 | - The slice `[::-1]` reverses the string by stepping backwards. 112 | 113 | --- 114 | 115 | ## String Operators 116 | 117 | Python supports several operators for string manipulation, including concatenation, repetition, and membership testing. 118 | 119 | ### Example: 120 | ```python 121 | str1 = "Hello" 122 | str2 = " World" 123 | 124 | # Concatenation: Combine strings using + 125 | print(str1 + str2) # Output: Hello World 126 | 127 | # Repetition: Repeat string using * 128 | print(str1 * 3) # Output: HelloHelloHello 129 | 130 | # Membership: Check if a substring exists within a string. 131 | print('H' in str1) # Output: True 132 | ``` 133 | 134 | **Explanation:** 135 | - The `+` operator concatenates two strings together. 136 | - The `*` operator repeats a string a specified number of times. 137 | - The `in` operator tests whether a character or substring is present in a string. 138 | 139 | --- 140 | 141 | ## String Formatting 142 | 143 | Python offers several methods to format strings. Two common techniques are using the `format()` method and the `%` operator. 144 | 145 | ### Using the `format()` Method: 146 | ```python 147 | name1 = "Hamza" 148 | name2 = "Hashim" 149 | 150 | # Using positional arguments. 151 | print("{} and {} are best friends.".format(name1, name2)) 152 | # Output: Hamza and Hashim are best friends. 153 | 154 | # Using keyword arguments. 155 | print("{a} and {b} are best friends.".format(a="Hamza", b="Hashim")) 156 | # Output: Hamza and Hashim are best friends. 157 | ``` 158 | 159 | **Explanation:** 160 | - The `format()` method replaces placeholders `{}` with the provided values. 161 | - Positional arguments fill the placeholders in order; keyword arguments let you explicitly assign values. 162 | 163 | ### Using the `%` Operator: 164 | ```python 165 | integer = 10 166 | floating = 1.29 167 | string = "Hamza" 168 | 169 | print("Integer: %d, Float: %f, String: %s" % (integer, floating, string)) 170 | # Output: Integer: 10, Float: 1.290000, String: Hamza 171 | ``` 172 | 173 | **Explanation:** 174 | - The `%` operator formats the string by inserting values into the format specifiers `%d`, `%f`, and `%s`. 175 | 176 | --- 177 | 178 | ## Escape Sequences in Strings 179 | 180 | Escape sequences allow you to include special characters in strings by using a backslash (`\`) followed by a character. 181 | 182 | ### Common Escape Sequence Examples: 183 | 184 | 1. **Newline (`\n`)** 185 | ```python 186 | print("Hello\nWorld") 187 | # Output: 188 | # Hello 189 | # World 190 | ``` 191 | **Explanation:** 192 | Moves the text after `\n` to a new line. 193 | 194 | 2. **Tab (`\t`)** 195 | ```python 196 | print("Hello\tWorld") 197 | # Output: Hello World 198 | ``` 199 | **Explanation:** 200 | Inserts a horizontal tab space between words. 201 | 202 | 3. **Backslash (`\\`)** 203 | ```python 204 | print("This is a backslash: \\") 205 | # Output: This is a backslash: \ 206 | ``` 207 | **Explanation:** 208 | Displays a single backslash by escaping it with another backslash. 209 | 210 | 4. **Single Quote (`\'`)** 211 | ```python 212 | print('It\'s a sunny day!') 213 | # Output: It's a sunny day! 214 | ``` 215 | **Explanation:** 216 | Allows a single quote to be included in a string defined with single quotes. 217 | 218 | 5. **Double Quote (`\"`)** 219 | ```python 220 | print("She said, \"Hello!\"") 221 | # Output: She said, "Hello!" 222 | ``` 223 | **Explanation:** 224 | Allows double quotes within a double-quoted string. 225 | 226 | 6. **Carriage Return (`\r`)** 227 | ```python 228 | print("Hello\rWorld") 229 | # Output: World 230 | ``` 231 | **Explanation:** 232 | Moves the cursor to the beginning of the line, so subsequent text overwrites it. 233 | 234 | 7. **Backspace (`\b`)** 235 | ```python 236 | print("Hello\bWorld") 237 | # Output: HellWorld 238 | ``` 239 | **Explanation:** 240 | Deletes the character immediately before it. 241 | 242 | 8. **Unicode and Hexadecimal Escapes** 243 | ```python 244 | print("\u03A9") # Output: Ω (Greek Omega) 245 | print("\U0001F600") # Output: 😀 (Smiling Face Emoji) 246 | print("\x48\x65\x6c\x6c\x6f") # Output: Hello 247 | ``` 248 | **Explanation:** 249 | Inserts Unicode characters using their hexadecimal values. 250 | 251 | --- 252 | 253 | ## Raw Strings 254 | 255 | Raw strings treat backslashes as literal characters and are defined by placing an `r` or `R` before the string. This is especially useful for regular expressions and file paths. 256 | 257 | ### Example: 258 | ```python 259 | print(r"C:\Users\Hashim\Python") 260 | # Output: C:\Users\Hashim\Python 261 | ``` 262 | 263 | **Explanation:** 264 | - The `r` prefix tells Python not to interpret backslashes as escape characters, so the string prints exactly as written. 265 | 266 | --- -------------------------------------------------------------------------------- /02_python_basics/13_string/function.md: -------------------------------------------------------------------------------- 1 | ```python 2 | def to_uppercase(input_string): 3 | uppercase_string = "" # Initialize an empty string to store the result 4 | 5 | # Iterate through each character in the input string 6 | for char in input_string: 7 | # Check if the character is a lowercase letter 8 | if 'a' <= char <= 'z': 9 | # Convert the lowercase letter to uppercase by subtracting 32 from its ASCII value 10 | uppercase_char = chr(ord(char) - 32) 11 | # Append the converted character to the result string 12 | uppercase_string += uppercase_char 13 | else: 14 | # If the character is not a lowercase letter, add it as is 15 | uppercase_string += char 16 | 17 | return uppercase_string # Return the final uppercase string 18 | 19 | # Example usage 20 | example_str = "hello world!" 21 | result = to_uppercase(example_str) 22 | print(result) # Output: HELLO WORLD! 23 | ``` 24 | 25 | ### Explanation: 26 | 27 | 1. **Initialize an Empty String:** 28 | - An empty string `uppercase_string` is created to store the final result. 29 | 30 | 2. **Iterate Through Each Character:** 31 | - The function iterates through each character in `input_string` using a `for` loop. 32 | 33 | 3. **Check if Character is Lowercase:** 34 | - It checks if the character is a lowercase letter by comparing its ASCII value. 35 | 36 | 4. **Convert Lowercase to Uppercase:** 37 | - If the character is lowercase, it is converted to its uppercase equivalent by subtracting 32 from its ASCII value. 38 | 39 | 5. **Append to Result String:** 40 | - The converted uppercase character is appended to `uppercase_string`. 41 | 42 | 6. **Handle Non-Lowercase Characters:** 43 | - If the character is not lowercase, it is directly appended to `uppercase_string`. 44 | 45 | 7. **Return the Uppercase String:** 46 | - Finally, the function returns the `uppercase_string` containing all the uppercase characters. -------------------------------------------------------------------------------- /02_python_basics/13_string/mian.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/13_string/mian.py -------------------------------------------------------------------------------- /02_python_basics/13_string/string_methods.md: -------------------------------------------------------------------------------- 1 | # Methods of String and Bytes Objects (Essential for Real-World Applications) 2 | 3 | In Python, both `str` and `bytes` objects are immutable. Most operations create and return new objects rather than modifying the original. Below is a concise list of the most useful methods you'll use in development, along with examples and explanations. 4 | 5 | --- 6 | 7 | ### 1. `capitalize()` 8 | - **Usage:** `s.capitalize()` 9 | - **Purpose:** Converts the first character of the string to uppercase and the rest to lowercase. 10 | - **Example:** 11 | ```python 12 | text = "hello WORLD" 13 | print(text.capitalize()) # Output: "Hello world" 14 | ``` 15 | **Explanation:** 16 | Useful for standardizing user input or displaying titles. 17 | 18 | --- 19 | 20 | ### 2. `encode()` and `decode()` 21 | - **Usage (encode):** `s.encode(encoding='utf-8')` 22 | - **Usage (decode):** `b.decode(encoding='utf-8')` 23 | - **Purpose:** Convert between strings and bytes, which is essential for file I/O and network operations. 24 | - **Example (encode):** 25 | ```python 26 | message = "Secure Message" 27 | encoded = message.encode('utf-8') 28 | print(encoded) # Output: b'Secure Message' 29 | ``` 30 | - **Example (decode):** 31 | ```python 32 | data = b'Python Bytes' 33 | decoded = data.decode('utf-8') 34 | print(decoded) # Output: "Python Bytes" 35 | ``` 36 | **Explanation:** 37 | These methods are fundamental when handling data transmission or storage. 38 | 39 | --- 40 | 41 | ### 3. `endswith()` 42 | - **Usage:** `s.endswith(suffix)` 43 | - **Purpose:** Checks if a string ends with a given suffix, common in validating file extensions or URLs. 44 | - **Example:** 45 | ```python 46 | filename = "report.pdf" 47 | if filename.endswith(".pdf"): 48 | print("PDF file confirmed.") 49 | ``` 50 | **Explanation:** 51 | Ensures that files have the correct format before processing. 52 | 53 | --- 54 | 55 | ### 4. `find()` and `replace()` 56 | - **Usage (find):** `s.find(sub)` 57 | - **Usage (replace):** `s.replace(old, new, maxsplit=-1)` 58 | - **Purpose:** 59 | - `find()` locates substrings (returns the index or -1 if not found). 60 | - `replace()` substitutes parts of the string. 61 | - **Example (find):** 62 | ```python 63 | sentence = "Search in this sentence." 64 | index = sentence.find("this") 65 | print(index) # Output: 10 66 | ``` 67 | - **Example (replace):** 68 | ```python 69 | phrase = "I love Java, Java is great." 70 | new_phrase = phrase.replace("Java", "Python", 1) 71 | print(new_phrase) # Output: "I love Python, Java is great." 72 | ``` 73 | **Explanation:** 74 | These methods are key for text processing tasks like search-and-replace operations. 75 | 76 | --- 77 | 78 | ### 5. `split()` and `join()` 79 | - **Usage (split):** `s.split(sep=None)` 80 | - **Usage (join):** `separator.join(iterable)` 81 | - **Purpose:** 82 | - `split()` divides a string into a list (useful for parsing CSV or logs). 83 | - `join()` combines an iterable of strings into one. 84 | - **Example (split):** 85 | ```python 86 | data = "apple,orange,banana" 87 | fruits = data.split(",") 88 | print(fruits) # Output: ['apple', 'orange', 'banana'] 89 | ``` 90 | - **Example (join):** 91 | ```python 92 | words = ['Join', 'these', 'words'] 93 | sentence = " ".join(words) 94 | print(sentence) # Output: "Join these words" 95 | ``` 96 | **Explanation:** 97 | Essential for data transformation and formatting output. 98 | 99 | --- 100 | 101 | ### 6. `strip()` 102 | - **Usage:** `s.strip([chars])` 103 | - **Purpose:** Removes leading and trailing whitespace (or specified characters). 104 | - **Example:** 105 | ```python 106 | messy = " clean me " 107 | clean = messy.strip() 108 | print(clean) # Output: "clean me" 109 | ``` 110 | **Explanation:** 111 | Frequently used to sanitize user input or clean up data from files. 112 | 113 | --- 114 | 115 | ### 7. Case Conversion: `upper()`, `lower()`, and `title()` 116 | - **Usage:** `s.upper()`, `s.lower()`, `s.title()` 117 | - **Purpose:** Convert strings to a uniform case. 118 | - **Example (upper and lower):** 119 | ```python 120 | text = "Mixed Case" 121 | print(text.upper()) # Output: "MIXED CASE" 122 | print(text.lower()) # Output: "mixed case" 123 | ``` 124 | - **Example (title):** 125 | ```python 126 | sentence = "python programming language" 127 | print(sentence.title()) # Output: "Python Programming Language" 128 | ``` 129 | **Explanation:** 130 | Useful for standardizing text data for comparisons, searches, or display. 131 | 132 | --- 133 | 134 | ### 8. The `string` Module Constants 135 | Some constants from the `string` module are particularly useful: 136 | 137 | - **`string.ascii_letters`:** All ASCII letters. 138 | ```python 139 | import string 140 | print(string.ascii_letters) # Output: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 141 | ``` 142 | - **`string.digits`:** All digit characters. 143 | ```python 144 | import string 145 | print(string.digits) # Output: "0123456789" 146 | ``` 147 | - **`string.punctuation`:** All punctuation symbols. 148 | ```python 149 | import string 150 | print(string.punctuation) # e.g., "!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~" 151 | ``` 152 | **Explanation:** 153 | These constants help with tasks like data validation, filtering, or generating random strings. 154 | 155 | --- 156 | 157 | ### 9. `islower()` 158 | - **Usage:** `s.islower()` 159 | - **Purpose:** Returns `True` if all alphabetic characters in the string are lowercase. 160 | - **Example:** 161 | ```python 162 | word = "python" 163 | print(word.islower()) # Output: True 164 | ``` 165 | **Explanation:** 166 | Checks that every letter in the string is lowercase, often used for input validation or consistency checks. 167 | 168 | --- 169 | 170 | ### 10. `isnumeric()` 171 | - **Usage:** `s.isnumeric()` 172 | - **Purpose:** Returns `True` if all characters in the string are numeric. 173 | - **Example:** 174 | ```python 175 | number_str = "123456" 176 | print(number_str.isnumeric()) # Output: True 177 | ``` 178 | **Explanation:** 179 | Validates that the string consists solely of numeric characters, which is useful when processing numerical input. 180 | 181 | --- 182 | 183 | ### 11. `isupper()` 184 | - **Usage:** `s.isupper()` 185 | - **Purpose:** Returns `True` if all alphabetic characters in the string are uppercase. 186 | - **Example:** 187 | ```python 188 | shout = "WARNING!" 189 | print(shout.isupper()) # Output: True 190 | ``` 191 | **Explanation:** 192 | Ensures that the string is fully in uppercase, which can be used for emphasis or formatting. 193 | 194 | --- 195 | 196 | ### 12. `join()` 197 | - **Usage:** `separator.join(iterable)` 198 | - **Purpose:** Concatenates the strings in an iterable, inserting the separator between elements. 199 | - **Example:** 200 | ```python 201 | words = ["join", "these", "words"] 202 | result = " ".join(words) 203 | print(result) # Output: "join these words" 204 | ``` 205 | **Explanation:** 206 | This method is essential for building a single string from a list of substrings. 207 | 208 | --- 209 | 210 | ### 13. `replace()` 211 | - **Usage:** `s.replace(old, new, count=-1)` 212 | - **Purpose:** Returns a new string with all occurrences (or a limited number if specified by `count`) of `old` replaced by `new`. 213 | - **Example:** 214 | ```python 215 | phrase = "I love Java, Java is great." 216 | new_phrase = phrase.replace("Java", "Python", 1) 217 | print(new_phrase) # Output: "I love Python, Java is great." 218 | ``` 219 | **Explanation:** 220 | Only the first occurrence of `"Java"` is replaced, which is useful for controlled substitution. 221 | 222 | --- 223 | 224 | ### 14. `split()` 225 | - **Usage:** `s.split(sep=None, maxsplit=-1)` 226 | - **Purpose:** Splits the string into a list of substrings based on the specified delimiter. If no delimiter is provided, it splits on whitespace. 227 | - **Example:** 228 | ```python 229 | data = "apple,orange,banana" 230 | fruits = data.split(",") 231 | print(fruits) # Output: ['apple', 'orange', 'banana'] 232 | ``` 233 | **Explanation:** 234 | Used for parsing delimited data, `split()` divides a string into components. 235 | 236 | --- 237 | 238 | ### 15. `title()` 239 | - **Usage:** `s.title()` 240 | - **Purpose:** Converts the string to title case, where the first character of each word is uppercase and the rest are lowercase. 241 | - **Example:** 242 | ```python 243 | sentence = "python programming for developers" 244 | titled_sentence = sentence.title() 245 | print(titled_sentence) # Output: "Python Programming For Developers" 246 | ``` 247 | **Explanation:** 248 | Useful for formatting headings or titles, ensuring each word is appropriately capitalized. 249 | -------------------------------------------------------------------------------- /02_python_basics/14_list/Readme.md: -------------------------------------------------------------------------------- 1 | # Python Lists 2 | 3 | A list in Python is a versatile, mutable sequence used to store collections of data. Lists are widely used in development for tasks like data processing, aggregation, and dynamic manipulation. 4 | 5 | Below are some of the most useful list methods and operations, along with examples and explanations. 6 | 7 | ## Creating and Modifying Lists 8 | 9 | Lists are created by placing elements inside square brackets `[]`. 10 | 11 | ```python 12 | fruits = ["apple", "banana", "cherry"] 13 | numbers = [10, 20, 30, 40] 14 | print(fruits) # Output: ['apple', 'banana', 'cherry'] 15 | print(numbers) # Output: [10, 20, 30, 40] 16 | ``` 17 | 18 | **Explanation:** 19 | Lists can hold elements of various types and are defined by comma-separated values inside square brackets. 20 | 21 | ## Key Points: 22 | - **Ordered:** Lists maintain the order of elements. 23 | - **Mutable:** Items in a list can be changed. 24 | - **Flexible:** Lists can store elements of different types. 25 | 26 | --- 27 | 28 | ## 🛠️ Common List Methods 29 | 30 | Python lists come with a variety of methods that allow for a wide range of operations, such as adding, removing, and sorting elements. Let's dive into each method with detailed explanations and new examples. 31 | 32 | ### `append(x)` 33 | - **Purpose:** Adds a single element `x` to the end of the list. 34 | - **Example:** 35 | ```python 36 | items = [10, 20, 30] 37 | items.append(40) 38 | print(items) # Output: [10, 20, 30, 40] 39 | ``` 40 | **Explanation:** 41 | The `append()` method adds the element 40 to the end of the list, increasing its length by one. 42 | 43 | --- 44 | 45 | ### `clear()` 46 | - **Purpose:** Removes all items from the list, resulting in an empty list. 47 | - **Example:** 48 | ```python 49 | records = ["data1", "data2", "data3"] 50 | records.clear() 51 | print(records) # Output: [] 52 | ``` 53 | **Explanation:** 54 | The `clear()` method empties the list completely, which is useful when you need to reset a collection of items. 55 | 56 | --- 57 | 58 | ### `copy()` 59 | - **Purpose:** Returns a shallow copy of the list. 60 | - **Example:** 61 | ```python 62 | original = [1, 2, 3] 63 | duplicate = original.copy() 64 | duplicate.append(4) 65 | print(original) # Output: [1, 2, 3] 66 | print(duplicate) # Output: [1, 2, 3, 4] 67 | ``` 68 | **Explanation:** 69 | Using `copy()` creates a new list with the same elements, so modifications to the copy do not affect the original list. 70 | 71 | --- 72 | 73 | ### `count(x)` 74 | - **Purpose:** Returns the number of times the element `x` appears in the list. 75 | - **Example:** 76 | ```python 77 | numbers = [5, 3, 5, 7, 5, 9] 78 | occurrence = numbers.count(5) 79 | print(occurrence) # Output: 3 80 | ``` 81 | **Explanation:** 82 | The `count()` method helps determine the frequency of a particular element in the list. 83 | 84 | --- 85 | 86 | ### `extend(iterable)` 87 | - **Purpose:** Appends elements from an iterable (like another list or tuple) to the end of the list. 88 | - **Example:** 89 | ```python 90 | list_a = [1, 2] 91 | list_b = [3, 4, 5] 92 | list_a.extend(list_b) 93 | print(list_a) # Output: [1, 2, 3, 4, 5] 94 | ``` 95 | **Explanation:** 96 | `extend()` merges two sequences, allowing you to combine their elements into a single list. 97 | 98 | --- 99 | 100 | ### `insert(i, x)` 101 | - **Purpose:** Inserts an element `x` at the specified index `i`, shifting subsequent elements to the right. 102 | - **Example:** 103 | ```python 104 | data = ["red", "blue", "green"] 105 | data.insert(1, "yellow") 106 | print(data) # Output: ["red", "yellow", "blue", "green"] 107 | ``` 108 | **Explanation:** 109 | `insert()` is used when you need to add an element at a specific position rather than at the end. 110 | 111 | --- 112 | 113 | ### `pop(i=-1)` 114 | - **Purpose:** Removes and returns the element at index `i`. If no index is provided, it removes the last element. 115 | - **Example:** 116 | ```python 117 | queue = [100, 200, 300, 400] 118 | last_item = queue.pop() 119 | first_item = queue.pop(0) 120 | print(last_item) # Output: 400 121 | print(first_item) # Output: 100 122 | print(queue) # Output: [200, 300] 123 | ``` 124 | **Explanation:** 125 | `pop()` allows you to remove items from any position in the list while also retrieving the removed item. 126 | 127 | --- 128 | 129 | ### `remove(x)` 130 | - **Purpose:** Removes the first occurrence of element `x` from the list. 131 | - **Example:** 132 | ```python 133 | letters = ["a", "b", "c", "b", "d"] 134 | letters.remove("b") 135 | print(letters) # Output: ["a", "c", "b", "d"] 136 | ``` 137 | **Explanation:** 138 | `remove()` deletes the first matching element, which is useful when duplicate values exist and only one instance needs to be removed. 139 | 140 | --- 141 | 142 | ### `reverse()` 143 | - **Purpose:** Reverses the order of elements in the list in place. 144 | - **Example:** 145 | ```python 146 | sequence = [1, 2, 3, 4] 147 | sequence.reverse() 148 | print(sequence) # Output: [4, 3, 2, 1] 149 | ``` 150 | **Explanation:** 151 | The `reverse()` method modifies the list so that its elements are in reverse order. 152 | 153 | --- 154 | 155 | ### `sort(key=None, reverse=False)` 156 | - **Purpose:** Sorts the list in place. The optional `key` parameter specifies a function to extract a comparison key from each element, and `reverse` determines whether the sort is ascending or descending. 157 | - **Example:** 158 | ```python 159 | values = [5, 2, 9, 1, 5, 6] 160 | values.sort() 161 | print(values) # Output: [1, 2, 5, 5, 6, 9] 162 | 163 | values.sort(reverse=True) 164 | print(values) # Output: [9, 6, 5, 5, 2, 1] 165 | ``` 166 | **Explanation:** 167 | Sorting helps arrange the list elements in order. The `sort()` method modifies the list itself. 168 | 169 | --- 170 | 171 | ### Checking List Equality 172 | - **Purpose:** Two lists are considered equal if they have the same elements in the same order, even if they are not the same object. 173 | - **Example:** 174 | ```python 175 | list_one = [1, 2, 3] 176 | list_two = [1, 2, 3] 177 | print(list_one == list_two) # Output: True 178 | print(list_one is list_two) # Output: False 179 | ``` 180 | **Explanation:** 181 | Equality (`==`) compares the contents, whereas the identity operator (`is`) checks if both references point to the same object. 182 | 183 | --- 184 | 185 | ### Nested Lists 186 | - **Purpose:** Lists can contain other lists, which allows you to create complex data structures like matrices. 187 | - **Example:** 188 | ```python 189 | matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 190 | print(matrix[1][2]) # Output: 6 191 | ``` 192 | **Explanation:** 193 | Nested lists enable the representation of multi-dimensional data structures, useful in many applications like data analysis. 194 | 195 | --- 196 | 197 | ### Modifying List Values 198 | - **Purpose:** Since lists are mutable, you can change their contents by assigning new values to indices or slices. 199 | - **Example:** 200 | ```python 201 | numbers = [10, 20, 30, 40] 202 | numbers[2] = 35 203 | numbers[1:3] = [25, 30] 204 | print(numbers) # Output: [10, 25, 30, 40] 205 | ``` 206 | **Explanation:** 207 | You can update single elements or ranges of elements, which is useful for data correction and dynamic modifications. 208 | 209 | --- 210 | 211 | ### Python List Operations 212 | - **Purpose:** Lists support various operators such as concatenation (`+`) and repetition (`*`), which enable combining and duplicating lists. 213 | - **Example:** 214 | ```python 215 | part1 = [1, 2, 3] 216 | part2 = [4, 5, 6] 217 | combined = part1 + part2 218 | repeated = part1 * 3 219 | print(combined) # Output: [1, 2, 3, 4, 5, 6] 220 | print(repeated) # Output: [1, 2, 3, 1, 2, 3, 1, 2, 3] 221 | ``` 222 | **Explanation:** 223 | These operators provide a quick way to merge lists or create multiple copies of a list. 224 | 225 | --- 226 | 227 | ### Iterating Through a List 228 | - **Purpose:** Use a loop to process each element in a list. 229 | - **Example:** 230 | ```python 231 | items = ["alpha", "beta", "gamma"] 232 | for element in items: 233 | print(element) 234 | ``` 235 | **Explanation:** 236 | Iteration over a list allows you to perform operations on each element, which is crucial for data processing and manipulation. 237 | 238 | --- 239 | 240 | ### Modifying and Deleting List Items 241 | - **Purpose:** You can change list values via indexing/slicing and remove items using the `del` keyword. 242 | - **Example:** 243 | ```python 244 | data = [100, 200, 300, 400] 245 | data[1] = 250 # Modify an element 246 | del data[3] # Delete an element at index 3 247 | print(data) # Output: [100, 250, 300] 248 | ``` 249 | **Explanation:** 250 | This allows you to update or remove elements from a list as needed, which is useful for dynamic data manipulation. 251 | 252 | --- 253 | 254 | This file presents a curated collection of list methods and operations that are essential in everyday Python development. Use these examples as a reference to work effectively with lists in your projects. -------------------------------------------------------------------------------- /02_python_basics/14_list/list_comprehension.md: -------------------------------------------------------------------------------- 1 | # Python List Comprehension 2 | 3 | List comprehension is a concise way to create lists in Python. It allows you to generate a new list by applying an expression to each item in an existing iterable, optionally including a filtering condition. This approach simplifies code and enhances readability, making it especially useful for data processing and transformation tasks. 4 | 5 | ### List Comprehension Syntax 6 | ```python 7 | [expression for item in iterable if condition] 8 | ``` 9 | - **expression:** The operation or value to include in the new list. 10 | - **item:** Each element from the original iterable. 11 | - **iterable:** The source sequence (e.g., list, tuple, or string). 12 | - **condition:** (Optional) A filter to include only items that meet a condition. 13 | 14 | --- 15 | 16 | ### Examples 17 | 18 | #### 1. Creating a List of Cubes 19 | **Without List Comprehension:** 20 | ```python 21 | cubes = [] 22 | for num in range(10): 23 | cubes.append(num ** 3) 24 | print(cubes) # Output: [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] 25 | ``` 26 | 27 | **With List Comprehension:** 28 | ```python 29 | cubes = [num ** 3 for num in range(10)] 30 | print(cubes) # Output: [0, 1, 8, 27, 64, 125, 216, 343, 512, 729] 31 | ``` 32 | 33 | **Explanation:** 34 | This example computes the cube of numbers 0 through 9. List comprehension performs the operation in one concise line. 35 | 36 | --- 37 | 38 | #### 2. Filtering Odd Numbers 39 | **Without List Comprehension:** 40 | ```python 41 | odds = [] 42 | for num in range(15): 43 | if num % 2 != 0: 44 | odds.append(num) 45 | print(odds) # Output: [1, 3, 5, 7, 9, 11, 13] 46 | ``` 47 | 48 | **With List Comprehension:** 49 | ```python 50 | odds = [num for num in range(15) if num % 2 != 0] 51 | print(odds) # Output: [1, 3, 5, 7, 9, 11, 13] 52 | ``` 53 | 54 | **Explanation:** 55 | This filters out even numbers, leaving only odd ones in the resulting list. 56 | 57 | --- 58 | 59 | #### 3. Converting a List of Strings to Lowercase 60 | **Without List Comprehension:** 61 | ```python 62 | names = ["ALICE", "BOB", "CHARLIE"] 63 | lowercase_names = [] 64 | for name in names: 65 | lowercase_names.append(name.lower()) 66 | print(lowercase_names) # Output: ['alice', 'bob', 'charlie'] 67 | ``` 68 | 69 | **With List Comprehension:** 70 | ```python 71 | names = ["ALICE", "BOB", "CHARLIE"] 72 | lowercase_names = [name.lower() for name in names] 73 | print(lowercase_names) # Output: ['alice', 'bob', 'charlie'] 74 | ``` 75 | 76 | **Explanation:** 77 | Each string in the list is converted to lowercase using the `lower()` method within a list comprehension. 78 | 79 | --- 80 | 81 | #### 4. Flattening a Nested List 82 | **Without List Comprehension:** 83 | ```python 84 | matrix = [[1, 2], [3, 4], [5, 6]] 85 | flat = [] 86 | for sublist in matrix: 87 | for element in sublist: 88 | flat.append(element) 89 | print(flat) # Output: [1, 2, 3, 4, 5, 6] 90 | ``` 91 | 92 | **With List Comprehension:** 93 | ```python 94 | matrix = [[1, 2], [3, 4], [5, 6]] 95 | flat = [element for sublist in matrix for element in sublist] 96 | print(flat) # Output: [1, 2, 3, 4, 5, 6] 97 | ``` 98 | 99 | **Explanation:** 100 | This example demonstrates how to combine multiple lists (nested lists) into a single list in one line. 101 | 102 | --- 103 | 104 | #### 5. Creating a List of Coordinate Tuples 105 | **Without List Comprehension:** 106 | ```python 107 | coords = [] 108 | for x in range(3): 109 | for y in range(3): 110 | coords.append((x, y)) 111 | print(coords) 112 | # Output: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] 113 | ``` 114 | 115 | **With List Comprehension:** 116 | ```python 117 | coords = [(x, y) for x in range(3) for y in range(3)] 118 | print(coords) 119 | # Output: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] 120 | ``` 121 | 122 | **Explanation:** 123 | List comprehension efficiently generates a list of coordinate pairs using nested iterations. 124 | 125 | --- 126 | 127 | #### 6. Filtering Words Based on Length 128 | **Without List Comprehension:** 129 | ```python 130 | words = ["sun", "moon", "stars", "sky"] 131 | filtered = [] 132 | for word in words: 133 | if len(word) > 3: 134 | filtered.append(word) 135 | print(filtered) # Output: ['moon', 'stars'] 136 | ``` 137 | 138 | **With List Comprehension:** 139 | ```python 140 | words = ["sun", "moon", "stars", "sky"] 141 | filtered = [word for word in words if len(word) > 3] 142 | print(filtered) # Output: ['moon', 'stars'] 143 | ``` 144 | 145 | **Explanation:** 146 | This filters out words with 3 or fewer characters, leaving a list of longer words. 147 | 148 | --- 149 | 150 | #### 7. Replacing Specific Characters in a String 151 | **Without List Comprehension:** 152 | ```python 153 | text = "development" 154 | modified = "" 155 | for char in text: 156 | if char in "aeiou": 157 | modified += "#" 158 | else: 159 | modified += char 160 | print(modified) # Output: "d#v#l#pm#nt" 161 | ``` 162 | 163 | **With List Comprehension:** 164 | ```python 165 | text = "development" 166 | modified = "".join(["#" if char in "aeiou" else char for char in text]) 167 | print(modified) # Output: "d#v#l#pm#nt" 168 | ``` 169 | 170 | **Explanation:** 171 | Vowels in the word are replaced with `#`, demonstrating character-level processing within a comprehension. 172 | 173 | --- 174 | 175 | #### 8. Generating a List of Factorials 176 | **Without List Comprehension:** 177 | ```python 178 | import math 179 | factorials = [] 180 | for n in range(1, 7): 181 | factorials.append(math.factorial(n)) 182 | print(factorials) # Output: [1, 2, 6, 24, 120, 720] 183 | ``` 184 | 185 | **With List Comprehension:** 186 | ```python 187 | import math 188 | factorials = [math.factorial(n) for n in range(1, 7)] 189 | print(factorials) # Output: [1, 2, 6, 24, 120, 720] 190 | ``` 191 | 192 | **Explanation:** 193 | Calculates the factorial for numbers 1 through 6 in a concise manner. 194 | 195 | -------------------------------------------------------------------------------- /02_python_basics/14_list/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/14_list/main.py -------------------------------------------------------------------------------- /02_python_basics/14_list/unpacking_sequence_and_slicing.md: -------------------------------------------------------------------------------- 1 | # Python Unpacking Sequences and Slicing 2 | 3 | Python’s unpacking and slicing features allow for efficient data extraction and manipulation from sequences such as lists, tuples, and strings. Below are essential examples—both basic and advanced—that are highly useful in development. 4 | 5 | --- 6 | 7 | ## Unpacking Sequences 8 | 9 | Unpacking lets you assign elements from a sequence directly to variables, reducing the need for explicit indexing. 10 | 11 | ### Basic Unpacking 12 | 13 | Assign values from a list to variables in one line. 14 | 15 | ```python 16 | coords = [51.5074, -0.1278] # Coordinates for London 17 | lat, lon = coords 18 | print("Latitude:", lat) # Output: Latitude: 51.5074 19 | print("Longitude:", lon) # Output: Longitude: -0.1278 20 | ``` 21 | 22 | **Explanation:** 23 | The list elements are directly unpacked into `lat` and `lon`, making the code cleaner and less error-prone. 24 | 25 | --- 26 | 27 | ### Advanced Unpacking with the `*` Operator 28 | 29 | Use the `*` operator to capture multiple values into a list. 30 | 31 | ```python 32 | data = [100, 200, 300, 400, 500] 33 | first, *middle, last = data 34 | print("First:", first) # Output: First: 100 35 | print("Middle:", middle) # Output: Middle: [200, 300, 400] 36 | print("Last:", last) # Output: Last: 500 37 | ``` 38 | 39 | **Explanation:** 40 | `first` captures the first element, `last` the final one, and `*middle` collects all elements in between. This is particularly useful when you need to separate head and tail data from a sequence. 41 | 42 | --- 43 | 44 | ## Slicing Sequences 45 | 46 | Slicing enables you to extract parts of a sequence without modifying the original. It works with lists, tuples, and strings. 47 | 48 | ### Basic Slicing 49 | 50 | Extract a subset from a list. 51 | 52 | ```python 53 | values = [10, 20, 30, 40, 50, 60] 54 | subset = values[1:4] 55 | print(subset) # Output: [20, 30, 40] 56 | ``` 57 | 58 | **Explanation:** 59 | `values[1:4]` returns a new list containing the elements from index 1 up to, but not including, index 4. 60 | 61 | --- 62 | 63 | ### String Slicing 64 | 65 | Extract parts of a string for data processing. 66 | 67 | ```python 68 | text = "data-analysis" 69 | prefix = text[:4] 70 | suffix = text[-8:] 71 | middle = text[5:13] 72 | print("Prefix:", prefix) # Output: "data" 73 | print("Middle:", middle) # Output: "-analysi" 74 | print("Suffix:", suffix) # Output: "analysis" 75 | ``` 76 | 77 | **Explanation:** 78 | Slicing a string works the same way as lists. Here, different segments of the string are captured based on index ranges. 79 | 80 | --- 81 | 82 | ### Practical Slicing: Extracting Substrings 83 | 84 | Use slicing to extract specific parts of a sentence. 85 | 86 | ```python 87 | sentence = "Python slicing is efficient" 88 | # Extracting the first word, middle part, and the last word 89 | first_word = sentence.split()[0] 90 | last_word = sentence.split()[-1] 91 | middle_section = sentence[7:14] 92 | print("First word:", first_word) # Output: "Python" 93 | print("Middle section:", middle_section) # Output: " slicing" 94 | print("Last word:", last_word) # Output: "efficient" 95 | ``` 96 | 97 | **Explanation:** 98 | Splitting the sentence by whitespace helps extract words, while slicing can capture parts based on exact character positions. 99 | 100 | --- 101 | 102 | ### Real-World Example: Parsing Log Data 103 | 104 | Suppose you have a log entry with fixed-width fields, and you need to extract specific details. 105 | 106 | ```python 107 | log_entry = "2023-08-15INFO User login succeeded " 108 | # Define slices for date, level, and message 109 | date_slice = slice(0, 10) 110 | level_slice = slice(10, 20) 111 | message_slice = slice(20, None) 112 | 113 | date = log_entry[date_slice] 114 | level = log_entry[level_slice].strip() 115 | message = log_entry[message_slice].strip() 116 | 117 | print("Date:", date) # Output: "2023-08-15" 118 | print("Level:", level) # Output: "INFO" 119 | print("Message:", message) # Output: "User login succeeded" 120 | ``` 121 | 122 | **Explanation:** 123 | Using slices with predefined indices extracts fixed-width fields from a log entry. The `strip()` method removes extra whitespace, ensuring clean data extraction. 124 | 125 | -------------------------------------------------------------------------------- /02_python_basics/15_tuple/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/15_tuple/main.py -------------------------------------------------------------------------------- /02_python_basics/15_tuple/readme.md: -------------------------------------------------------------------------------- 1 | ## 📘 Understanding Tuples in Python 2 | 3 | ### 📍 What is a Tuple? 4 | 5 | A **tuple** is a built-in data type in Python used to store a sequence of **immutable** Python objects. Tuples are defined by enclosing the elements in parentheses `()` and separating them with commas. Unlike lists, which are mutable, tuples cannot be modified after they are created. 6 | 7 | ### 💡 Why Do We Need Tuples? 8 | 9 | Tuples are used in Python when you want to store a collection of items that should not change throughout the life of a program. This immutability can provide **data integrity** and ensure that the data is not accidentally modified, making tuples useful in scenarios where data should remain constant. 10 | 11 | ### 🔍 Where are Tuples Used? 12 | 13 | Tuples are commonly used: 14 | 15 | 1. **To return multiple values from a function**: When a function needs to return multiple values, they can be packed into a tuple. 16 | 2. **As dictionary keys**: Since tuples are immutable, they can be used as keys in a dictionary, unlike lists. 17 | 3. **To store related pieces of information**: Tuples can be used to group different types of data together. 18 | 4. **For fixed collections**: Storing fixed collections of items where immutability is required. 19 | 20 | ### ⚖️ Difference Between Lists and Tuples 21 | 22 | | Feature | List | Tuple | 23 | |------------------------|-------------------------------|------------------------------| 24 | | **Syntax** | Defined using square brackets `[]`. | Defined using parentheses `()`. | 25 | | **Mutability** | Mutable (can be modified). | Immutable (cannot be modified). | 26 | | **Methods Available** | Many built-in methods like `append()`, `remove()`, etc. | Limited methods: `count()`, `index()`. | 27 | | **Memory Consumption** | Larger size due to extra features. | Smaller size, more memory efficient. | 28 | | **Use Case** | Suitable for collections that may change. | Suitable for fixed collections. | 29 | 30 | ### 🎯 Use Cases of Tuples 31 | 32 | 1. **Immutable Data**: Data that should not be changed once assigned. 33 | 2. **Multiple Return Values**: Functions can return multiple values in a single tuple. 34 | 3. **Dictionary Keys**: Tuples can be used as keys in dictionaries due to their immutability. 35 | 4. **Efficient Data Handling**: Tuples have a smaller memory footprint compared to lists. 36 | 37 | ## 🔧 Manipulating Tuples in Python 38 | 39 | ### Basics - Tuple Packing and Unpacking 40 | 41 | - **Tuple Packing**: When we pack values into a tuple. 42 | - **Tuple Unpacking**: When we extract values back into variables. 43 | 44 | ```python 45 | # Tuple Packing 46 | t = 12345, 54321, 'hello!' 47 | print(t) # Output: (12345, 54321, 'hello!') 48 | 49 | # Tuple Unpacking 50 | a, b, c = t 51 | print(a, b, c) # Output: 12345 54321 hello! 52 | ``` 53 | 54 | ### 🔹 Creating Tuples 55 | 56 | - **Empty Tuple**: 57 | 58 | ```python 59 | empty_tuple = () 60 | print(type(empty_tuple)) # Output: 61 | ``` 62 | 63 | - **Single Element Tuple**: 64 | 65 | ```python 66 | single_tuple = ("Python",) # Note the comma 67 | print(type(single_tuple)) # Output: 68 | ``` 69 | 70 | - **Multiple Elements**: 71 | 72 | ```python 73 | multi_tuple = (1, 2, 3, "Python", True) 74 | print(multi_tuple) # Output: (1, 2, 3, 'Python', True) 75 | ``` 76 | 77 | ### 🔄 Looping Through Tuples 78 | 79 | You can loop through all the values in a tuple using a `for` loop: 80 | 81 | ```python 82 | dimensions = (200, 50) 83 | for dimension in dimensions: 84 | print(dimension) 85 | # Output: 86 | # 200 87 | # 50 88 | ``` 89 | 90 | ### 🚫 Modifying Tuples 91 | 92 | Tuples are immutable, meaning their elements cannot be modified after creation. Attempting to do so will raise an error: 93 | 94 | ```python 95 | dimensions = (200, 50) 96 | dimensions[0] = 250 # Raises TypeError: 'tuple' object does not support item assignment 97 | ``` 98 | 99 | ### 📝 Tuple Indexing and Slicing 100 | 101 | Tuples support indexing and slicing, just like lists: 102 | 103 | ```python 104 | tuple1 = (1, 2, 3, 4, 5, 6) 105 | 106 | # Indexing 107 | print(tuple1[0]) # Output: 1 108 | print(tuple1[-1]) # Output: 6 109 | 110 | # Slicing 111 | print(tuple1[1:4]) # Output: (2, 3, 4) 112 | print(tuple1[::2]) # Output: (1, 3, 5) 113 | ``` 114 | 115 | ### 🗑️ Deleting Tuples 116 | 117 | While you cannot delete an element from a tuple, you can delete an entire tuple using the `del` keyword: 118 | 119 | ```python 120 | tuple1 = (1, 2, 3, 4, 5) 121 | del tuple1 122 | # print(tuple1) # Raises NameError: name 'tuple1' is not defined 123 | ``` 124 | 125 | ## 📚 Built-in Tuple Methods 126 | 127 | | Method | Description | 128 | |----------|---------------------------------------------------------------------------------| 129 | | `count()` | Returns the number of times a specified value appears in the tuple. | 130 | | `index()` | Returns the index of the first occurrence of a specified value in the tuple. | 131 | 132 | ### Example: Using Tuple Methods 133 | 134 | ```python 135 | tup = (1, 2, 2, 3, 4, 4, 4, 5) 136 | 137 | # count() 138 | print(tup.count(4)) # Output: 3 139 | 140 | # index() 141 | print(tup.index(2)) # Output: 1 142 | ``` 143 | 144 | ## 📂 Use Cases of Tuples 145 | 146 | 1. **Constants**: Use tuples for creating constants in your code. 147 | 2. **Function Arguments**: Tuples can be used to represent fixed collections of items (like arguments) passed to functions. 148 | 3. **Returning Multiple Values from Functions**: Functions can return multiple values as a tuple. 149 | 150 | ### Example: Returning Multiple Values from a Function 151 | 152 | ```python 153 | def get_user_info(): 154 | name = "John" 155 | age = 30 156 | return name, age 157 | 158 | user_info = get_user_info() 159 | print(user_info) # Output: ('John', 30) 160 | ``` 161 | 162 | -------------------------------------------------------------------------------- /02_python_basics/16_set/Readme.md: -------------------------------------------------------------------------------- 1 | # Python Set Data Structure 2 | 3 | A **set** is an unordered collection of unique and immutable elements in Python. It is defined by placing elements within curly braces `{}` or by using the built-in `set()` function. 4 | 5 | ## Key Characteristics of a Set: 6 | - **Unordered:** The elements do not have a defined order. 7 | - **Unique:** No duplicate elements are allowed. 8 | - **Mutable:** You can add or remove elements from a set. 9 | 10 | ## Where Do We Use Sets in Python? 11 | 12 | Sets are used in Python for tasks that require handling unique items and performing operations such as: 13 | - Removing duplicates from a collection. 14 | - Checking membership quickly. 15 | - Executing mathematical operations like union, intersection, difference, and symmetric difference. 16 | 17 | ## Why Use Sets? 18 | 19 | 1. **Uniqueness:** Automatically eliminates duplicate entries. 20 | 2. **Efficient Membership Testing:** Provides an average-time complexity of O(1) for membership tests. 21 | 3. **Mathematical Operations:** Ideal for operations like union, intersection, and difference. 22 | 23 | ## Set Initialization Examples 24 | 25 | ### Creating a Set Using Curly Braces 26 | 27 | ```python 28 | names_set = {"Ali", "Sana", "Ahmed", "Zara"} 29 | print(names_set) # Output: {'Ali', 'Ahmed', 'Sana', 'Zara'} (order may vary) 30 | ``` 31 | 32 | ### Creating a Set Using the `set()` Constructor 33 | 34 | ```python 35 | names_list = ["Ali", "Sana", "Ahmed", "Ahmed", "Zara", "Zara"] 36 | names_set = set(names_list) 37 | print(names_set) # Output: {'Ali', 'Ahmed', 'Sana', 'Zara'} (duplicates removed) 38 | ``` 39 | 40 | ### Creating an Empty Set 41 | 42 | ```python 43 | empty_set = set() 44 | print(empty_set) # Output: set() 45 | ``` 46 | 47 | ## Common Set Methods 48 | 49 | Below is a detailed list of set methods with examples adapted to include Pakistani names. 50 | 51 | ### 1. `add()` 52 | - **Purpose:** Adds an element to the set. 53 | - **Example:** 54 | ```python 55 | students = {"Ali", "Sana", "Ahmed"} 56 | students.add("Hina") 57 | print(students) # Output: {'Ali', 'Sana', 'Ahmed', 'Hina'} 58 | ``` 59 | - **Explanation:** 60 | The `add()` method inserts "Hina" into the set. If the element already exists, it does nothing. 61 | 62 | --- 63 | 64 | ### 2. `clear()` 65 | - **Purpose:** Removes all elements from the set. 66 | - **Example:** 67 | ```python 68 | cities = {"Lahore", "Karachi", "Islamabad"} 69 | cities.clear() 70 | print(cities) # Output: set() 71 | ``` 72 | - **Explanation:** 73 | The `clear()` method empties the set, leaving it with no elements. 74 | 75 | --- 76 | 77 | ### 3. `copy()` 78 | - **Purpose:** Returns a shallow copy of the set. 79 | - **Example:** 80 | ```python 81 | original_names = {"Faisal", "Khadija", "Zainab"} 82 | copied_names = original_names.copy() 83 | copied_names.add("Omar") 84 | print(original_names) # Output: {'Faisal', 'Khadija', 'Zainab'} 85 | print(copied_names) # Output: {'Faisal', 'Khadija', 'Zainab', 'Omar'} 86 | ``` 87 | - **Explanation:** 88 | A shallow copy creates a new set with the same elements. Modifications to the copy do not affect the original. 89 | 90 | --- 91 | 92 | ### 4. `difference()` 93 | - **Purpose:** Returns a new set containing elements in the first set that are not in the second. 94 | - **Example:** 95 | ```python 96 | team_A = {"Ali", "Sana", "Ahmed", "Hina"} 97 | team_B = {"Ahmed", "Hina", "Sadia"} 98 | diff = team_A.difference(team_B) 99 | print(diff) # Output: {'Ali', 'Sana'} 100 | ``` 101 | - **Explanation:** 102 | The `difference()` method identifies elements unique to `team_A` that are not present in `team_B`. 103 | 104 | --- 105 | 106 | ### 5. `difference_update()` 107 | - **Purpose:** Removes elements from the set that are also in another set. 108 | - **Example:** 109 | ```python 110 | primary_team = {"Ali", "Sana", "Ahmed", "Hina"} 111 | secondary_team = {"Ahmed", "Hina", "Sadia"} 112 | primary_team.difference_update(secondary_team) 113 | print(primary_team) # Output: {'Ali', 'Sana'} 114 | ``` 115 | - **Explanation:** 116 | `difference_update()` modifies `primary_team` by removing elements that are found in `secondary_team`. 117 | 118 | --- 119 | 120 | ### 6. `discard()` 121 | - **Purpose:** Removes a specified element without raising an error if it is not found. 122 | - **Example:** 123 | ```python 124 | colors = {"red", "green", "blue"} 125 | colors.discard("green") 126 | colors.discard("yellow") # No error even though "yellow" is not in the set 127 | print(colors) # Output: {'red', 'blue'} 128 | ``` 129 | - **Explanation:** 130 | The `discard()` method removes the specified element safely. 131 | 132 | --- 133 | 134 | ### 7. `intersection()` 135 | - **Purpose:** Returns a new set containing only the common elements between sets. 136 | - **Example:** 137 | ```python 138 | group1 = {"Ali", "Sana", "Ahmed"} 139 | group2 = {"Ahmed", "Sadia", "Hassan"} 140 | common_members = group1.intersection(group2) 141 | print(common_members) # Output: {'Ahmed'} 142 | ``` 143 | - **Explanation:** 144 | `intersection()` extracts elements that appear in both groups. 145 | 146 | --- 147 | 148 | ### 8. `intersection_update()` 149 | - **Purpose:** Updates the set to contain only elements found in both sets. 150 | - **Example:** 151 | ```python 152 | club_members = {"Ali", "Sana", "Ahmed", "Hina"} 153 | new_members = {"Ahmed", "Hina", "Usman"} 154 | club_members.intersection_update(new_members) 155 | print(club_members) # Output: {'Ahmed', 'Hina'} 156 | ``` 157 | - **Explanation:** 158 | `intersection_update()` modifies `club_members` to keep only the members present in `new_members`. 159 | 160 | --- 161 | 162 | ### 9. `isdisjoint()` 163 | - **Purpose:** Returns `True` if two sets have no elements in common. 164 | - **Example:** 165 | ```python 166 | set_X = {"Kamran", "Shazia"} 167 | set_Y = {"Rashid", "Ayesha"} 168 | print(set_X.isdisjoint(set_Y)) # Output: True 169 | ``` 170 | - **Explanation:** 171 | `isdisjoint()` verifies that the two sets have no overlapping elements. 172 | 173 | --- 174 | 175 | ### 10. `issubset()` 176 | - **Purpose:** Returns `True` if every element of one set is present in another. 177 | - **Example:** 178 | ```python 179 | junior_team = {"Ali", "Sana"} 180 | senior_team = {"Ali", "Sana", "Ahmed", "Hina"} 181 | print(junior_team.issubset(senior_team)) # Output: True 182 | ``` 183 | - **Explanation:** 184 | The `issubset()` method confirms that all members of `junior_team` are included in `senior_team`. 185 | 186 | --- 187 | 188 | ### 11. `issuperset()` 189 | - **Purpose:** Returns `True` if a set contains all elements of another set. 190 | - **Example:** 191 | ```python 192 | full_team = {"Ali", "Sana", "Ahmed", "Hina", "Usman"} 193 | part_team = {"Ali", "Usman"} 194 | print(full_team.issuperset(part_team)) # Output: True 195 | ``` 196 | - **Explanation:** 197 | `issuperset()` checks if `full_team` includes every member of `part_team`. 198 | 199 | --- 200 | 201 | ### 12. `pop()` 202 | - **Purpose:** Removes and returns an arbitrary element from the set. 203 | - **Example:** 204 | ```python 205 | applicants = {"Zara", "Sadia", "Faisal"} 206 | removed_applicant = applicants.pop() 207 | print("Removed:", removed_applicant) 208 | print("Remaining:", applicants) 209 | ``` 210 | - **Explanation:** 211 | The `pop()` method removes a random element since sets are unordered. 212 | 213 | --- 214 | 215 | ### 13. `remove()` 216 | - **Purpose:** Removes a specified element from the set and raises a `KeyError` if the element is not found. 217 | - **Example:** 218 | ```python 219 | registration = {"Hassan", "Sana", "Ali"} 220 | registration.remove("Sana") 221 | print(registration) # Output: {"Hassan", "Ali"} 222 | # registration.remove("Zainab") # Would raise KeyError if uncommented. 223 | ``` 224 | - **Explanation:** 225 | `remove()` is used when you are certain the element exists; otherwise, `discard()` is safer. 226 | 227 | --- 228 | 229 | ### 14. `symmetric_difference()` 230 | - **Purpose:** Returns a new set with elements in either set, but not in both. 231 | - **Example:** 232 | ```python 233 | set_A = {"Ali", "Ahmed", "Sana"} 234 | set_B = {"Sana", "Hina", "Usman"} 235 | sym_diff = set_A.symmetric_difference(set_B) 236 | print(sym_diff) # Output: {'Ali', 'Ahmed', 'Hina', 'Usman'} 237 | ``` 238 | - **Explanation:** 239 | `symmetric_difference()` returns the elements that are unique to each set. 240 | 241 | --- 242 | 243 | ### 15. `symmetric_difference_update()` 244 | - **Purpose:** Updates the set with the symmetric difference of itself and another. 245 | - **Example:** 246 | ```python 247 | team_one = {"Ali", "Sana", "Ahmed"} 248 | team_two = {"Ahmed", "Hina", "Usman"} 249 | team_one.symmetric_difference_update(team_two) 250 | print(team_one) # Output: {'Ali', 'Sana', 'Hina', 'Usman'} 251 | ``` 252 | - **Explanation:** 253 | This method updates `team_one` to contain only the elements not common with `team_two`. 254 | 255 | --- 256 | 257 | ### 16. `union()` 258 | - **Purpose:** Returns a new set containing all elements from both sets. 259 | - **Example:** 260 | ```python 261 | group_A = {"Ali", "Ahmed"} 262 | group_B = {"Ahmed", "Sana"} 263 | combined_group = group_A.union(group_B) 264 | print(combined_group) # Output: {'Ali', 'Ahmed', 'Sana'} 265 | ``` 266 | - **Explanation:** 267 | `union()` combines both sets while removing duplicates. 268 | 269 | --- 270 | 271 | ### 17. `update()` 272 | - **Purpose:** Adds all elements from another iterable (e.g., list, set) to the set. 273 | - **Example:** 274 | ```python 275 | enrolled = {"Zara", "Ali"} 276 | new_enrollments = ["Ahmed", "Sana", "Ali"] 277 | enrolled.update(new_enrollments) 278 | print(enrolled) # Output: {'Zara', 'Ali', 'Ahmed', 'Sana'} 279 | ``` 280 | - **Explanation:** 281 | `update()` incorporates all new elements into the set, ignoring duplicates. 282 | 283 | 284 | -------------------------------------------------------------------------------- /02_python_basics/16_set/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/16_set/main.py -------------------------------------------------------------------------------- /02_python_basics/17_dictionary/Readme.md: -------------------------------------------------------------------------------- 1 | # Python Dictionaries 2 | 3 | A **dictionary** in Python is a collection of **key-value pairs**. Each key is associated with a value, and you can use a key to access its corresponding value. Dictionaries are defined using curly braces `{}` or with the `set()` function. 4 | 5 | ## What is a Dictionary? 6 | 7 | A dictionary is a collection of items where each item has a key and a value. Keys must be unique and of an immutable type (such as strings, numbers, or tuples), while values can be of any type. Think of a dictionary like a real-life dictionary where a word (key) maps to its meaning (value). 8 | 9 | ### Key Points: 10 | - A dictionary is defined using curly braces `{}`. 11 | - **Keys** must be unique and can be of any immutable type (e.g., strings, numbers, or tuples). 12 | - **Values** can be of any type, including other dictionaries. 13 | 14 | ## Working with Dictionaries 15 | 16 | ### Adding New Key-Value Pairs 17 | 18 | Dictionaries are dynamic, allowing you to add key-value pairs at any time. 19 | 20 | ```python 21 | student_0 = {'name': 'Ali', 'age': 18} 22 | student_0['city'] = 'Lahore' 23 | student_0['university'] = 'LUMS' 24 | print(student_0) 25 | ``` 26 | 27 | **Explanation:** 28 | We add new key-value pairs `'city': 'Lahore'` and `'university': 'LUMS'` to the `student_0` dictionary. 29 | 30 | ### Modifying Values in a Dictionary 31 | 32 | To change a value, simply assign a new value to an existing key. 33 | 34 | ```python 35 | student_0 = {'name': 'Sana', 'age': 20} 36 | print(f"Student's name is {student_0['name']}.") 37 | student_0['name'] = 'Sadia' 38 | print(f"Student's name is now {student_0['name']}.") 39 | ``` 40 | 41 | **Explanation:** 42 | The value for the key `'name'` is updated from `'Sana'` to `'Sadia'`. 43 | 44 | ### Removing Key-Value Pairs 45 | 46 | Remove a key-value pair using the `del` statement. 47 | 48 | ```python 49 | student_0 = {'name': 'Ahmed', 'age': 19, 'city': 'Karachi'} 50 | del student_0['age'] 51 | print(student_0) 52 | ``` 53 | 54 | **Explanation:** 55 | The key `'age'` and its associated value are removed from the dictionary. 56 | 57 | ### Using `get()` to Access Values 58 | 59 | The `get()` method safely accesses a value; it returns a default value if the key is not present. 60 | 61 | ```python 62 | student_0 = {'name': 'Hassan', 'grade': 'A'} 63 | print(student_0.get('grade', 'Grade not available')) 64 | print(student_0.get('age', 'Age not provided')) 65 | ``` 66 | 67 | **Explanation:** 68 | `get()` retrieves the value for `'grade'`. Since `'age'` is missing, it returns the default message. 69 | 70 | ## Looping Through a Dictionary 71 | 72 | ### Looping Through Key-Value Pairs 73 | 74 | ```python 75 | student_info = {'name': 'Faisal', 'age': 21, 'city': 'Islamabad'} 76 | for key, value in student_info.items(): 77 | print(f"{key}: {value}") 78 | ``` 79 | 80 | **Explanation:** 81 | The loop iterates through each key-value pair, printing the details of the student. 82 | 83 | ### Looping Through Keys 84 | 85 | ```python 86 | languages = {'Ali': 'Python', 'Sana': 'Java', 'Ahmed': 'C++'} 87 | for person in languages.keys(): 88 | print(person.title()) 89 | ``` 90 | 91 | **Explanation:** 92 | Iterates over all the keys in the `languages` dictionary and prints them in title case. 93 | 94 | ### Looping Through Values 95 | 96 | ```python 97 | print("Programming languages used:") 98 | for language in languages.values(): 99 | print(language) 100 | ``` 101 | 102 | **Explanation:** 103 | Loops through all values and prints the programming languages. 104 | 105 | ### Looping Through Sorted Keys 106 | 107 | ```python 108 | for person in sorted(languages.keys()): 109 | print(f"{person.title()}, thank you for your input.") 110 | ``` 111 | 112 | **Explanation:** 113 | The keys are sorted alphabetically before iteration, ensuring a consistent order. 114 | 115 | ## Dictionary Unpacking 116 | 117 | Dictionary unpacking allows you to pass key-value pairs as arguments in functions or to merge dictionaries. 118 | 119 | ### Function Call with Unpacked Dictionary 120 | 121 | ```python 122 | def display_student(name, city): 123 | print(f"{name} lives in {city}.") 124 | 125 | student = {'name': 'Zara', 'city': 'Multan'} 126 | display_student(**student) 127 | ``` 128 | 129 | **Explanation:** 130 | The `**` operator unpacks the `student` dictionary into keyword arguments. 131 | 132 | ### Merging Dictionaries Using `**` 133 | 134 | ```python 135 | dict1 = {'name': 'Sadia', 'age': 22} 136 | dict2 = {'city': 'Faisalabad', 'university': 'NUST'} 137 | merged = {**dict1, **dict2} 138 | print(merged) 139 | ``` 140 | 141 | **Explanation:** 142 | Dictionary unpacking merges `dict1` and `dict2` into a single dictionary. 143 | 144 | ## Dictionary Comprehensions 145 | 146 | Dictionary comprehensions provide a concise way to create dictionaries. 147 | 148 | ### Creating a Dictionary from a List 149 | 150 | ```python 151 | cities = ["Lahore", "Karachi", "Islamabad"] 152 | populations = [11_000_000, 14_000_000, 1_000_000] 153 | city_population = {city: pop for city, pop in zip(cities, populations)} 154 | print(city_population) 155 | ``` 156 | 157 | **Explanation:** 158 | The comprehension pairs each city with its corresponding population, creating a dictionary. 159 | 160 | ### Filtering with Dictionary Comprehensions 161 | 162 | ```python 163 | grades = {'Ali': 85, 'Sana': 92, 'Ahmed': 78, 'Hassan': 95} 164 | high_scores = {student: score for student, score in grades.items() if score >= 90} 165 | print(high_scores) 166 | ``` 167 | 168 | **Explanation:** 169 | Only students with scores 90 or above are included in `high_scores`. 170 | 171 | ### Inverting a Dictionary 172 | 173 | ```python 174 | student_ids = {'Ali': 101, 'Sana': 102, 'Ahmed': 103} 175 | id_students = {v: k for k, v in student_ids.items()} 176 | print(id_students) 177 | ``` 178 | 179 | **Explanation:** 180 | The comprehension swaps keys and values, which can be useful for reverse lookups. 181 | 182 | --- 183 | 184 | -------------------------------------------------------------------------------- /02_python_basics/17_dictionary/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/17_dictionary/main.py -------------------------------------------------------------------------------- /02_python_basics/18_functions/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/18_functions/Readme.md -------------------------------------------------------------------------------- /02_python_basics/18_functions/functions_in_modules: -------------------------------------------------------------------------------- 1 | 2 | # Storing Your Functions in Modules in Python 3 | 4 | ## Why Store Functions in Modules? 5 | 6 | Storing your functions in a separate file, known as a module, allows you to organize your code better and reuse functions across multiple programs. Modules also help hide the details of your code, allowing you to focus on the higher-level logic of your program. Once your functions are stored in a module, you can import them into your main program or share them with others easily. 7 | 8 | ## How to Create and Import a Module 9 | 10 | A module is simply a Python file that contains functions. You can create a module by writing your functions in a `.py` file, and then import that file into other Python programs. 11 | 12 | Let’s go through an example where we store a function for making pizzas in a module and then import it into another program. 13 | 14 | ### 1. Creating the Module 15 | 16 | First, create a file called `pizza.py` that contains the `make_pizza()` function: 17 | 18 | ```python 19 | # pizza.py 20 | def make_pizza(size, *toppings): 21 | """Summarize the pizza we are about to make.""" 22 | print(f"\nMaking a {size}-inch pizza with the following toppings:") 23 | for topping in toppings: 24 | print(f"- {topping}") 25 | ``` 26 | 27 | Now you have a module `pizza.py` that contains a function for making pizzas. You can import this module into other programs. 28 | 29 | ### 2. Importing the Module 30 | 31 | Next, create a file called `making_pizzas.py` where you import the `pizza` module and call the `make_pizza()` function. 32 | 33 | ```python 34 | # making_pizzas.py 35 | import pizza 36 | 37 | pizza.make_pizza(16, 'pepperoni') 38 | pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') 39 | ``` 40 | 41 | #### How It Works 42 | 43 | 1. **`import pizza`** tells Python to import the `pizza.py` file into the current program. 44 | 2. To use the `make_pizza()` function from the `pizza` module, you call it using `pizza.make_pizza()`. The syntax is `module_name.function_name()`. 45 | 46 | #### Output 47 | 48 | ``` 49 | Making a 16-inch pizza with the following toppings: 50 | - pepperoni 51 | 52 | Making a 12-inch pizza with the following toppings: 53 | - mushrooms 54 | - green peppers 55 | - extra cheese 56 | ``` 57 | 58 | By separating the pizza-making logic into the `pizza.py` module, your code becomes more modular and reusable. 59 | 60 | ## Advantages of Using Modules 61 | 62 | 1. **Organization**: By storing functions in separate files (modules), your main program remains clean and focused on higher-level logic. 63 | 2. **Reusability**: You can reuse functions across different programs by importing the module. 64 | 3. **Collaboration**: Sharing modules is easier. You can give others access to specific functions without sharing the entire program. 65 | 4. **Maintenance**: If the function needs to be updated, you update it in one place (the module), and every program that imports it will benefit from the update. 66 | 67 | ## Calling Functions from Modules 68 | 69 | Once you import a module, you can call any function within it using the following syntax: 70 | 71 | ```python 72 | module_name.function_name() 73 | ``` 74 | 75 | For example, in our case, we use: 76 | 77 | ```python 78 | pizza.make_pizza(16, 'pepperoni') 79 | ``` 80 | 81 | This tells Python to use the `make_pizza()` function from the `pizza` module. 82 | 83 | ## Try It Yourself! 84 | 85 | ### 1. Creating a Sandwich Module 86 | 87 | Create a module `sandwich.py` that contains a function for making sandwiches: 88 | 89 | ```python 90 | # sandwich.py 91 | def make_sandwich(*ingredients): 92 | """Summarize the sandwich being made.""" 93 | print("\nMaking a sandwich with the following ingredients:") 94 | for ingredient in ingredients: 95 | print(f"- {ingredient}") 96 | ``` 97 | 98 | Next, create a program called `making_sandwiches.py` that imports the `sandwich` module and calls the function: 99 | 100 | ```python 101 | # making_sandwiches.py 102 | import sandwich 103 | 104 | sandwich.make_sandwich('chicken', 'lettuce', 'tomato') 105 | sandwich.make_sandwich('beef', 'cheddar', 'onion') 106 | ``` 107 | 108 | ### 2. Creating a Car Module 109 | 110 | Create a module `car.py` that stores information about a car: 111 | 112 | ```python 113 | # car.py 114 | def describe_car(manufacturer, model, **options): 115 | """Build a dictionary containing car information.""" 116 | car_info = {'manufacturer': manufacturer, 'model': model} 117 | car_info.update(options) 118 | return car_info 119 | ``` 120 | 121 | In another file, import the module and describe a car using Pakistani context: 122 | 123 | ```python 124 | # describing_car.py 125 | import car 126 | 127 | car_info = car.describe_car('Suzuki', 'Cultus', color='silver', year=2020) 128 | print(car_info) 129 | ``` 130 | 131 | --- 132 | 133 | # Importing Specific Functions in Python 134 | 135 | ## Why Import Specific Functions? 136 | 137 | When working with modules, you can import specific functions instead of the entire module. This is useful when you only need a few functions from a module. By importing just what you need, you can write cleaner and more focused code. 138 | 139 | ## How to Import Specific Functions 140 | 141 | The general syntax for importing specific functions from a module looks like this: 142 | 143 | ```python 144 | from module_name import function_name 145 | ``` 146 | 147 | You can also import multiple specific functions by separating them with commas: 148 | 149 | ```python 150 | from module_name import function_0, function_1, function_2 151 | ``` 152 | 153 | ### Example: Importing `make_pizza()` Function 154 | 155 | Let’s take our pizza example. If you only want to use the `make_pizza()` function from the `pizza.py` module, you can import it like this: 156 | 157 | ```python 158 | # Importing only the make_pizza function from the pizza module 159 | from pizza import make_pizza 160 | 161 | # Now you can call make_pizza() directly 162 | make_pizza(16, 'pepperoni') 163 | make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') 164 | ``` 165 | 166 | #### Output 167 | 168 | ``` 169 | Making a 16-inch pizza with the following toppings: 170 | - pepperoni 171 | 172 | Making a 12-inch pizza with the following toppings: 173 | - mushrooms 174 | - green peppers 175 | - extra cheese 176 | ``` 177 | 178 | #### How It Works 179 | 180 | - **`from pizza import make_pizza`** imports only the `make_pizza()` function from the `pizza.py` module. 181 | - Because you explicitly imported the function, you can call `make_pizza()` directly without using the dot notation. 182 | 183 | ## Importing Multiple Specific Functions 184 | 185 | You can import multiple functions from a module by listing them in the import statement, separated by commas: 186 | 187 | ```python 188 | from pizza import make_pizza, add_toppings, bake_pizza 189 | ``` 190 | 191 | Now you can call each of these functions directly without the need for dot notation. 192 | 193 | ## Why Use This Approach? 194 | 195 | - **Clean Code**: You only import what you need, which makes your code more focused and easier to read. 196 | - **No Dot Notation**: You can call the function directly by name, making the code more concise. 197 | 198 | However, if you’re going to use several functions from a module, it might be better to import the entire module to keep the code more maintainable. 199 | 200 | ## Try It Yourself! 201 | 202 | ### 1. Importing Specific Functions from a Sandwich Module 203 | 204 | Let’s create a `sandwich.py` module with multiple functions: 205 | 206 | ```python 207 | # sandwich.py 208 | def make_sandwich(*ingredients): 209 | """Summarize the sandwich being made.""" 210 | print("\nMaking a sandwich with the following ingredients:") 211 | for ingredient in ingredients: 212 | print(f"- {ingredient}") 213 | 214 | def add_sauce(sauce): 215 | """Add a sauce to the sandwich.""" 216 | print(f"Adding {sauce} sauce to the sandwich.") 217 | ``` 218 | 219 | Now, in another file, import only the functions you need: 220 | 221 | ```python 222 | from sandwich import make_sandwich, add_sauce 223 | 224 | make_sandwich('chicken', 'lettuce', 'tomato') 225 | add_sauce('mayo') 226 | ``` 227 | 228 | #### Output 229 | 230 | ``` 231 | Making a sandwich with the following ingredients: 232 | - chicken 233 | - lettuce 234 | - tomato 235 | 236 | Adding mayo sauce to the sandwich. 237 | ``` 238 | 239 | --- 240 | 241 | # Using `as` to Give a Function or Module an Alias in Python 242 | 243 | ## Why Use Aliases in Python? 244 | 245 | In Python, you can use the `as` keyword to give a function or module an alias. This is especially useful when: 246 | - The function or module name is long. 247 | - You want to avoid conflicts with other names in your code. 248 | - You want to make your code shorter and more readable. 249 | 250 | By using an alias, you can call a function or module by a shorter name. 251 | 252 | ## Example: Giving a Function an Alias 253 | 254 | Let’s say you have the `make_pizza()` function, but it has a long name or might conflict with another function in your code. You can give it an alias using `as` to make it shorter: 255 | 256 | ```python 257 | from pizza import make_pizza as mp 258 | 259 | # Calling the function using its alias 260 | mp(16, 'pepperoni') 261 | mp(12, 'mushrooms', 'green peppers', 'extra cheese') 262 | ``` 263 | 264 | #### How It Works 265 | 266 | 1. The `make_pizza()` function is imported and given the alias `mp`. 267 | 2. Instead of calling `make_pizza()`, you call `mp()`. 268 | 3. The alias makes the code more concise and avoids conflicts with other function names. 269 | 270 | #### Output 271 | 272 | ``` 273 | Making a 16-inch pizza with the following toppings: 274 | - pepperoni 275 | 276 | Making a 12-inch pizza with the following toppings: 277 | - mushrooms 278 | - green peppers 279 | - extra cheese 280 | ``` 281 | 282 | ## Giving a Module an Alias 283 | 284 | You can also give an entire module an alias using the same approach. This is particularly useful when the module name is long or you want to make function calls from the module more concise. 285 | 286 | ```python 287 | import pizza as p 288 | 289 | # Calling the function from the module using its alias 290 | p.make_pizza(16, 'pepperoni') 291 | p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') 292 | ``` 293 | 294 | #### How It Works 295 | 296 | 1. The entire `pizza` module is given the alias `p`. 297 | 2. Now you can call any function from the `pizza` module using `p.function_name()`. 298 | 3. This reduces the need to type the full module name repeatedly. 299 | 300 | ## Importing All Functions from a Module 301 | 302 | If you want to import all functions from a module, you can use the asterisk (`*`), but be cautious as this can sometimes lead to naming conflicts. 303 | 304 | ```python 305 | from pizza import * 306 | 307 | make_pizza(16, 'pepperoni') 308 | make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese') 309 | ``` 310 | 311 | While this allows you to call functions without the module name or alias, it’s generally not recommended for large modules since it can overwrite existing function names in your program. 312 | 313 | --- 314 | 315 | # Styling Functions in Python 316 | 317 | ## Why Style Your Functions? 318 | 319 | Styling your functions properly is crucial for writing readable, maintainable, and understandable code. Python has a style guide called PEP 8 that outlines best practices for naming, commenting, and structuring functions. These conventions ensure that your code is clean, easy to follow, and collaborative-friendly. 320 | 321 | ## Best Practices for Function Styling 322 | 323 | Here are the key guidelines for styling your functions in Python: 324 | 325 | ### 1. Descriptive Function Names 326 | 327 | Functions should have descriptive names that clearly indicate what the function does. Use lowercase letters and underscores to separate words. 328 | 329 | ```python 330 | # Good function name 331 | def make_pizza(size, *toppings): 332 | """Summarize the pizza we are about to make.""" 333 | print(f"Making a {size}-inch pizza with the following toppings:") 334 | for topping in toppings: 335 | print(f"- {topping}") 336 | 337 | # Avoid function names that are too vague or unclear 338 | def mp(): 339 | # Not descriptive 340 | pass 341 | ``` 342 | 343 | ### 2. Docstrings for Documentation 344 | 345 | Every function should have a docstring immediately following the function definition. This docstring should be concise and explain what the function does, what parameters it takes, and what it returns (if applicable). 346 | 347 | ```python 348 | def build_profile(first, last, **user_info): 349 | """Build a dictionary containing everything we know about a user.""" 350 | user_info['first_name'] = first 351 | user_info['last_name'] = last 352 | return user_info 353 | ``` 354 | 355 | The docstring allows other developers to understand the purpose of the function without reading the code itself. This is especially useful for collaboration or when revisiting code after a long time. 356 | 357 | ### 3. Using Default Values 358 | 359 | When specifying default values for parameters, do not use spaces around the `=` sign: 360 | 361 | ```python 362 | # Correct way 363 | def make_sandwich(bread_type, fillings='cheese'): 364 | """Make a sandwich with a specific bread and fillings.""" 365 | print(f"Making a {bread_type} sandwich with {fillings}.") 366 | 367 | # Incorrect way 368 | def make_sandwich(bread_type, fillings = 'cheese'): 369 | pass 370 | ``` 371 | 372 | This convention also applies to keyword arguments in function calls: 373 | 374 | ```python 375 | make_sandwich('whole wheat', fillings='turkey') 376 | ``` 377 | 378 | ### 4. Line Length and Formatting 379 | 380 | PEP 8 recommends limiting each line of code to 79 characters for readability. If a function has too many parameters and exceeds this limit, break the line after the opening parenthesis and indent the next line. 381 | 382 | ```python 383 | def describe_car( 384 | manufacturer, model, year, color, engine_type): 385 | """Display car details.""" 386 | print(f"{manufacturer} {model}, {year}, {color}, {engine_type}") 387 | ``` 388 | 389 | ### 5. Separate Functions with Blank Lines 390 | 391 | When you have multiple functions in a module, separate them with two blank lines to improve readability. 392 | 393 | ```python 394 | def make_pizza(size, *toppings): 395 | """Summarize the pizza we are about to make.""" 396 | pass 397 | 398 | 399 | def make_sandwich(bread_type, fillings='cheese'): 400 | """Make a sandwich with a specific bread and fillings.""" 401 | pass 402 | ``` 403 | 404 | ### 6. Import Statements 405 | 406 | All import statements should be placed at the beginning of the file. The only exception is if the file starts with comments that describe the overall program. 407 | 408 | ```python 409 | # Correct placement of imports 410 | import os 411 | import sys 412 | 413 | # Program starts here 414 | def main(): 415 | pass 416 | ``` 417 | 418 | ## Try It Yourself! 419 | 420 | ### 1. Printing Models Example 421 | 422 | Move the `print_models()` and `show_completed_models()` functions from the `printing_models.py` example into a separate file called `printing_functions.py`. Then, try the following import styles in your main program: 423 | 424 | - `import printing_functions` 425 | - `from printing_functions import print_models` 426 | - `from printing_functions import print_models as pm` 427 | - `import printing_functions as pf` 428 | - `from printing_functions import *` 429 | 430 | Each style allows you to call the functions defined in `printing_functions.py` in different ways. 431 | 432 | --- 433 | 434 | ## Key Points 435 | 436 | - Use descriptive function names that use lowercase letters and underscores. 437 | - Add docstrings immediately after the function definition to describe what the function does. 438 | - Avoid spaces around the `=` sign when using default parameter values. 439 | - Keep line length under 79 characters, and use proper indentation for longer function definitions. 440 | - Separate functions with two blank lines for clarity. 441 | - Place all import statements at the beginning of your file. 442 | 443 | Following these guidelines ensures that your code remains clean, readable, and easy to maintain—especially when working in teams or revisiting your projects later. -------------------------------------------------------------------------------- /02_python_basics/18_functions/main.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/02_python_basics/18_functions/main.py -------------------------------------------------------------------------------- /02_python_basics/19_Regular_expressions/Readme.md: -------------------------------------------------------------------------------- 1 | # Regular Expressions 2 | 3 | Regular Expressions (often abbreviated as **regex** or **regexp**) are like magic wands for text! They are special patterns that help programmers and applications perform powerful text manipulations. You can use regex to: 4 | 5 | - **Validate Input**: Check if an input follows a specific pattern (e.g., confirming an email format). 6 | - **Find and Extract**: Search for text matching a pattern in a larger body of text. 7 | - **Replace Text**: Substitute text that matches a pattern with something new. 8 | - **Split Text**: Break down a block of text into smaller pieces based on a pattern. 9 | 10 | > **Beware**: Regex can be tricky! If not used carefully, they can make your code confusing and difficult to debug! 11 | 12 | --- 13 | 14 | ## History of "Regular Expressions" 15 | 16 | The term **"regular expression"** comes from the fields of **mathematics** and **computer science**. It originally referred to expressions with a specific property called **regularity**. Here’s a brief history: 17 | 18 | - **Old-School Regex**: The earliest versions of regex were implemented using something called a **Deterministic Finite Automaton (DFA)**. Think of DFA as a path with no backtracking—once you move forward, there's no going back! 19 | 20 | - **Modern-Day Regex**: Today's popular regex, especially **Perl-style regex**, don't follow the old mathematical definition strictly. Instead, they use a **Nondeterministic Finite Automaton (NFA)**, which involves **backtracking** (going back to recheck previous paths). This allows for more flexibility and power, but also more complexity! 21 | 22 | > **Note**: Some computer scientists get a bit upset when modern regex is called "regular" since it technically isn't by their standards. But for us practical programmers, what matters is knowing how to wield this tool effectively! 23 | 24 | --- 25 | 26 | ## Why Use Regular Expressions? 27 | 28 | When used wisely, regular expressions can make your life as a programmer a lot easier! Here’s why: 29 | 30 | - **Efficiency**: With regex, tasks that would normally take hundreds of lines of code can be accomplished in just a few! For example, extracting all email addresses from a document might need a lot of complex procedural code—but with regex, it’s a breeze! 31 | 32 | - **Simplicity**: Regex can simplify many text-processing tasks that would otherwise be tedious and hard to maintain. 33 | 34 | However, remember the saying: 35 | > **“Some people, when confronted with a problem, think ‘I know, I’ll use regular expressions.’ Now they have two problems.”** 36 | 37 | This joke highlights a truth: regex can sometimes complicate things if overused or applied in the wrong context. That’s why you need to **read this section carefully** to master regex and avoid these pitfalls! 38 | 39 | --- 40 | 41 | ## The Many Flavors of Regular Expressions 42 | 43 | So, what exactly are regular expressions? Surprise! There isn't a single answer. Unlike some concepts with strict definitions, regex lacks a universal standard, leading to various **flavors**. 44 | 45 | - **Perl-Style Regex**: The most common and popular flavor is inspired by the **Perl programming language**. These "Perl-style" regular expressions are the basis for most modern regex patterns. While they are mostly similar and compatible, small differences can exist between implementations. 46 | - **Shortcut Terms**: Instead of always saying "regular expression," developers often use the shorthand **regex** or **regexp** for singular and **regexes** for plural. 47 | 48 | --- 49 | 50 | ## How to Use the `re` Module 51 | 52 | 1. **Creating a Pattern** 53 | A regular expression (RE) is formed using a pattern string. Patterns define what kind of text you're looking for. For example, a pattern could look for any sequence of digits or specific characters in a text. 54 | 55 | 2. **The `compile()` Function** 56 | The `re` module provides a `compile()` function to create a regex object from a pattern. This object allows you to perform different regex operations efficiently. 57 | 58 | 3. **Regex Object Methods** 59 | Once you have a regex object, you can use its methods to interact with text: 60 | - **`search()`**: Finds the first occurrence of the pattern in the text. 61 | - **`match()`**: Checks if the pattern matches from the start of the text. 62 | - **`findall()`**: Returns all occurrences of the pattern in the text. 63 | - **`sub()`**: Replaces the matched pattern with a new string. 64 | 65 | 4. **Shortcut Functions** 66 | The `re` module also has shortcut functions like `re.search()`, `re.match()`, `re.findall()`, and `re.sub()` that can be used without creating a regex object. 67 | 68 | --- 69 | 70 | ## Regular Expression Pattern Syntax 71 | 72 | | **Element** | **Meaning** | 73 | |------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| 74 | | **`.`** | Matches any single character except a newline (`\n`). This is like a wildcard that can be any letter, number, or symbol. | 75 | | **`^`** | Matches the start of a string. If `MULTILINE` mode is enabled, it also matches the position right after a newline (`\n`). | 76 | | **`$`** | Matches the end of a string. In `MULTILINE` mode, it also matches the position right before a newline (`\n`). | 77 | | **`*`** | Matches zero or more occurrences of the preceding pattern; it's greedy (tries to match as much as possible). | 78 | | **`+`** | Matches one or more occurrences of the preceding pattern; greedy. | 79 | | **`?`** | Matches zero or one occurrence of the preceding pattern; greedy. It is useful for optional characters or patterns. | 80 | | **`*?`, `+?`, `??`** | These are nongreedy (or lazy) versions of `*`, `+`, and `?` respectively. They match as few characters as possible. | 81 | | **`{m,n}`** | Matches between `m` and `n` occurrences of the preceding pattern; greedy. You can use it to specify exact repetition. | 82 | | **`{m,n}?`** | Matches between `m` and `n` occurrences of the preceding pattern; nongreedy. | 83 | | **`[...]`** | Matches any one character from a set inside the brackets. For example, `[abc]` matches `a`, `b`, or `c`. | 84 | | **`[^...]`** | Matches any one character not in the set inside the brackets. For example, `[^abc]` matches any character except `a`, `b`, or `c`. | 85 | | **`|`** | Acts like a logical OR; matches either the pattern before or after it. For example, `cat|dog` matches "cat" or "dog". | 86 | | **`(...)`** | Matches the pattern inside the parentheses and creates a capturing group. Use it to group patterns for extraction or backreferences. | 87 | | **`(?:...)`** | Matches the pattern inside the parentheses but does not create a capturing group. Useful for grouping without capturing. | 88 | | **`(?P...)`** | Matches the pattern and names the group as `id`. Named groups make patterns more readable and easier to reference. | 89 | | **`(?P=id)`** | Matches the same text as previously matched by the named group `id`. Use it to refer back to the named group. | 90 | | **`(?#...)`** | A comment inside the regex pattern; helps improve readability without affecting the match. | 91 | | **`(?=...)`** | Positive lookahead: Matches if the pattern matches what comes next, but does not consume any characters. Used to assert that something follows. | 92 | | **`(?!...)`** | Negative lookahead: Matches if the pattern does not match what comes next, without consuming any characters. Useful for excluding patterns. | 93 | | **`(?<=...)`** | Positive lookbehind: Matches if the pattern precedes the current position; must match a fixed length. Ensures something comes before the match. | 94 | | **`(? 88 |
89 | 90 | 91 | # 3. The Interpreter. 92 | 93 | An Interpreter in nothing just a sofware which can run your python script. 94 | Interestingly, it can be implemented in any programming language! 95 | CPython is the default interpreter or an implementation for Python which is written in C programming language. 96 | 97 | ## Programmer’s view of interpreter. 98 | 99 | An interpreter is simply a software which takes our code and reads it line by line and execute it line by line to produce the output. 100 | 101 |


102 | 103 | 104 | ## Python's View of Interpreter, Inside the Interpreter. 105 | 106 | Now, let us scan through the python interpreter and try to understand how it works. 107 | 108 | Have a look at the diagram shown below: 109 | 110 |


111 | 112 | From the figure above, it can be inferred that interpreter is made up of two parts: 113 | 114 | * compiler 115 | * virtual machine 116 | 117 | # What does compiler do? 118 | 119 | inside the interpreter you have a Compiler and virtual Machine (VM) 120 | i hope you are not surprised by seeing a compiler inside the interpreter 121 | as you have heard that python is not compiled language, actually 122 | a compiled language is one in which the compiler converts the sourse code into the machine code 123 | or the binary code, which is directly executed by the Machine itself. 124 | but in the case of python the compiler is bit different, its bit differnt as compare to the 125 | traditional compiler, here we are using the compiler to convert the source code to something called "bytecode" 126 | 127 | # What is "Bytecode"? 128 | 129 | You must be hearing it for the first time. 130 | 131 | Byte code is a: 132 | 133 | * lower level, 134 | * platform independent, 135 | * efficient and 136 | * intermediate 137 | 138 | Representation of your source code. 139 | 140 | 141 | In Python, bytecode is an intermediate representation of your source code that the Python 142 | This bytecode is stored in .pyc files When you run a Python script or execute a Python statement, 143 | the Python interpreter first converts your high-level code into bytecode, which is a lower-level,platform-independent representation of your code. 144 | 145 | Here's a simple overview of the process: 146 | 147 | * Source Code: You write your Python code in a .py file. 148 | 149 | * Compilation: When you run the Python script, the Python interpreter first compiles your source code into bytecode. 150 | 151 | * Bytecode: Bytecode is a low-level representation of your Python code, consisting of instructions that the Python Virtual Machine can execute. 152 | 153 | * Execution: Finally, the Python Virtual Machine (PVM) executes the bytecode, resulting in the desired output or behavior of your program. 154 | 155 | 156 | # What does Virtual Machine do? 157 | 158 | Python Virtual Machine (PVM) is a program which provides programming environment. The role of PVM is to convert the byte code instructions into machine code so the computer can execute those machine code instructions and display the output. 159 | Interpreter converts the byte code into machine code and sends that machine code to the computer processor for execution. 160 | 161 | ## Let's take an Overview of Bytecode in Python. 162 | 163 | Suppose you have a simple Python function: 164 | 165 | ```python 166 | 167 | def add_numbers(a, b): 168 | return a + b 169 | 170 | ``` 171 | When you run this Python script, Python compiles it into bytecode. For example, the bytecode for the "add_numbers" function might look like this: 172 | 173 | ```pyhon 174 | 1 0 LOAD_FAST 0 (a) 175 | 2 LOAD_FAST 1 (b) 176 | 4 BINARY_ADD 177 | 6 RETURN_VALUE 178 | 179 | ``` 180 | 181 | This bytecode represents the instructions needed to execute the "add_numbers" function efficiently. Each line corresponds to an operation, such as loading values onto the stack ('LOAD_FAST'), performing an addition ('BINARY_ADD'), and returning a value ('RETURN_VALUE'). The Python interpreter then executes these bytecode instructions to perform the addition operation and return the result. 182 | 183 | # Types of other Python Compliers or Implementations, 184 | 185 | * Jpython/ Jython 186 | * PyPy 187 | * RubyPython 188 | * IronPython 189 | * StacklessPython 190 | * Pythonxy 191 | * AnacondaPython 192 | 193 | # Executing Python Program 194 | 195 | * Command Line Window 196 | * IDE 197 | * Notepad or Notepad++ 198 | * PyCharm 199 | * Visual Studio Code 200 | 201 | # IDE 202 | 203 | An IDE stands for Integrated Development Environment. It's a software application that provides comprehensive facilities to computer programmers for software development. IDEs typically include features like: 204 | 205 | * Code Editor: for writing and editing code with features like syntax highlighting, auto-completion, and code formatting. 206 | * Build Automation Tools: for compiling, building, and running programs. 207 | * Debugging Tools: for identifying and fixing errors in code. 208 | * Version Control Integration: for managing changes to code with systems like Git. 209 | * Project Management: for organizing files, resources, and dependencies within a project. 210 | * Collaboration Tools: for facilitating teamwork among developers working on the same project. 211 | 212 | # VS Code, Visiual Studio Code. 213 | 214 | Vs Code is very popular IDE, code editor with It's a free and open-source source code editor developed by Microsoft. VS Code is widely used for various programming languages, including Python, JavaScript, TypeScript, C++, and many others, So most of the developers choose to use VS Code. 215 | 216 | ALso my Favourite one. -------------------------------------------------------------------------------- /images/Screenshot 2024-02-27 095542.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/Screenshot 2024-02-27 095542.png -------------------------------------------------------------------------------- /images/Screenshot 2024-03-06 021617.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/Screenshot 2024-03-06 021617.png -------------------------------------------------------------------------------- /images/and operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/and operator.png -------------------------------------------------------------------------------- /images/arithmetic operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/arithmetic operators.png -------------------------------------------------------------------------------- /images/bytecode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/bytecode.png -------------------------------------------------------------------------------- /images/example.. of variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/example.. of variables.png -------------------------------------------------------------------------------- /images/interpreter and support library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/interpreter and support library.png -------------------------------------------------------------------------------- /images/interpreter, execution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/interpreter, execution.png -------------------------------------------------------------------------------- /images/logical operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/logical operators.png -------------------------------------------------------------------------------- /images/not, operator in python .png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/not, operator in python .png -------------------------------------------------------------------------------- /images/or, operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/or, operator.png -------------------------------------------------------------------------------- /images/relational, comparison operator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/relational, comparison operator.png -------------------------------------------------------------------------------- /images/reversed keywords.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/reversed keywords.png -------------------------------------------------------------------------------- /images/varables in python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/varables in python.png -------------------------------------------------------------------------------- /images/variable as a tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/variable as a tag.png -------------------------------------------------------------------------------- /images/variables in c and java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IshaqueThePassionate/Python-Fundamentals/8514f7ab4c38bc30acd561aa92969d8b77c21dce/images/variables in c and java.png --------------------------------------------------------------------------------