Skip to content

Commit d6e0c30

Browse files
author
aryan
committed
content added
1 parent 3c02a95 commit d6e0c30

25 files changed

Lines changed: 1337 additions & 104 deletions

File tree

content/notes/iit-madras/data-science-and-application/foundational-level/python/week 1/lec1.1.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,41 @@ tags:
66
- IIT Madras
77
excludeSearch: false
88
weight: 1
9-
---
9+
---
10+
11+
The course is designed for beginners, including those who may have written some code before, but it is also useful for newcomers.
12+
13+
The material is often presented in a structured, **bottom-up** fashion, starting with foundational concepts and gradually building towards more complex ones.
14+
15+
Key areas covered in the introduction and foundational parts include:
16+
17+
* **Running Python Programs**: Learning how to execute Python code, whether by typing interactively or running code stored in files, potentially using tools like Replit. Replit provides features like a files panel for adding files and folders and built-in help for commands like `print`.
18+
* **Basic Syntax**: Understanding Python's general syntax model and fundamental statements, including the importance of indentation.
19+
* **Variables and Literals**: Introducing how to use variables to store values and understanding different types of literals.
20+
* **Data Types and Operations**: Studying Python's built-in object types in depth.
21+
* Each data element has a specific **data type** (e.g., integer, float, string) which indicates the category it belongs to.
22+
* You can check the type of a variable using the `type()` command.
23+
* Specific types covered include **numbers**, **strings**, **lists**, **dictionaries**, **tuples**, **sets**, and **booleans**.
24+
* String concepts like concatenation (`+`), replication (`*`), **indexing** (accessing individual characters like `s`), and **slicing** (accessing substrings like `s[1:3]`) are introduced. The use of different types of quotes (single and double) and **escape characters** are also covered.
25+
* Operators are categorised into arithmetic, relational, and logical.
26+
* **Keywords**: Understanding reserved words that have special meaning in Python, such as `and`, `or`, and `not`. Other keywords like `break`, `continue`, and `pass` are discussed in relation to control flow.
27+
* **Comments and Documentation**: Learning about using comments and **documentation strings (docstrings)** to explain your code. The PyDoc system can extract and display these docstrings.
28+
29+
Moving beyond the basics, the materials cover:
30+
31+
* **Statements and Control Flow**: Exploring Python's procedural statements, including loops (`for`, `while`) and conditional statements (`if`). The `range` function is used with `for` loops.
32+
* **Functions**: Learning how to define and use functions to package code for reuse and avoid redundancy. This includes exploring **scope rules** and argument passing.
33+
* **Modules**: Understanding how modules organize statements and functions into larger components, including how to create, use, and import them in different ways (`import calendar`, `from calendar import *`, `from calendar import month`, using `as`). Concepts like **module packages** and the `__name__` variable are also introduced. Module files live within a module, and classes live within a module.
34+
* **Classes and Object-Oriented Programming (OOP)**: Introducing the class as Python's main OOP tool. Classes are used to implement new kinds of objects and support **inheritance**.
35+
* A **class statement** creates a **class object**.
36+
* An **object** is a unique instance of a class. You create an **instance** by calling the class name like a function.
37+
* Functions defined within a class are called **methods**. The first argument in a class method is special; by convention, it's called `self` and receives the instance object the method is called on.
38+
* The `__init__` method is a special **constructor** method that is automatically called when a new instance is created. It's commonly used to initialise instance attributes.
39+
* **Operator overloading** allows defining how instances of your classes interact with standard Python operators (like `+` or `[]`) by implementing special methods (e.g., `__init__`, `__getitem__`).
40+
* **Inheritance** allows a new class (child) to be a modified version of an existing class (parent), inheriting its methods and attributes.
41+
* **Exceptions**: Covering Python's mechanism for handling errors and other conditions.
42+
* **File Handling**: Discussing how to work with files, including reading and writing.
43+
44+
The learning process is supported by end-of-chapter quizzes, answers to quizzes, and end-of-part exercises. The materials also highlight common coding mistakes or "gotchas" to help you avoid them.
45+
46+
Overall, while covering core concepts in depth, the focus is on teaching the Python language itself rather than specific application areas like web development or graphical user interfaces, although these may be briefly mentioned as possibilities after mastering the core language. Some advanced topics may be considered optional reading.

content/notes/iit-madras/data-science-and-application/foundational-level/python/week 1/lec1.10.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,75 @@ tags:
66
- IIT Madras
77
excludeSearch: false
88
weight: 10
9-
---
9+
---
10+
11+
Okay, let's continue our discussion on **Operators and Expressions**, building upon the foundational concepts we covered previously. The sources provide further details and examples across various operator types and how they form expressions.
12+
13+
As established, in Python, expressions are combinations of values, variables, and **operators** that are evaluated by the interpreter to produce a value. Operators are special symbols or keywords that perform computations or actions on operands.
14+
15+
The sources categorize operators into several types:
16+
17+
1. **Arithmetic Operators**: These perform mathematical operations.
18+
* `+`: Addition. For numbers, it adds. For sequences like strings or lists, it performs concatenation.
19+
* `-`: Subtraction. For numbers, it subtracts.
20+
* `*`: Multiplication. For numbers, it multiplies. For sequences, it performs repetition.
21+
* `/`: Division. In Python 3.0, this performs **true division**, keeping fractional remainders. In Python 2.6, it performed classic division, truncating for integers.
22+
* `//`: **Floor Division**. This divides and truncates fractional remainders, resulting in the integer quotient.
23+
* `%`: **Modulus**. This divides the left operand by the right and returns the remainder.
24+
* `**`: **Exponentiation** (power). `x ** y` calculates x raised to the power of y. Note that `^` is a bitwise operator in Python, not exponentiation.
25+
* There are also unary `+` and `-` for identity and negation.
26+
27+
2. **Comparison (Relational) Operators**: These compare values and return a Boolean result (`True` or `False`).
28+
* `==`: Equal value.
29+
* `!=`: Not equal value. Python 2.6 also used `<>` for not equal, but this was removed in Python 3.0.
30+
* `>`: Greater than.
31+
* `<`: Less than.
32+
* `>=`: Greater than or equal to.
33+
* `<=`: Less than or equal to.
34+
* Comparison operators can be **chained**. For example, `X < Y < Z` is evaluated similarly to `X < Y and Y < Z`. If all relational operators give a true result, the chain is true.
35+
* In Python 3.0, nonnumeric mixed-type magnitude comparisons are generally not allowed and raise exceptions, unlike in Python 2.x. Magnitude comparisons for dictionaries are also no longer supported in Python 3.0, though equality tests still are.
36+
37+
3. **Assignment Operators**: Used to assign values.
38+
* `=`: Basic assignment.
39+
* **Augmented assignment operators** (`+=`, `-=`, `*=`, `/=`, `%=`, `**=`, `//=`, etc.) provide a shorthand. For instance, `x += 1` is equivalent to `x = x + 1`. These work on any type that supports the implied binary expression.
40+
41+
4. **Logical Operators**: These combine Boolean expressions using the keywords `and`, `or`, and `not`.
42+
* `and`: True if both operands are true.
43+
* `or`: True if either operand is true.
44+
* `not`: Reverses the logical state of the operand.
45+
* While comparison operators return `True` or `False` (which are essentially custom versions of integers 1 and 0), the `and` and `or` operators can return an object (either the left or right operand), not necessarily just `True` or `False`. In a Boolean context (like an `if` statement), a nonzero number or a nonempty collection object is considered true.
46+
47+
5. **Membership Operators**: `in` and `not in`. These test if a value is present in a sequence (like strings, lists, or tuples) or a set.
48+
49+
6. **Identity Operators**: `is` and `is not`. These test if two variables point to the same object in memory, which is a stricter test than `==`. For example, `True is 1` is `False`, but `True == 1` is `True`.
50+
51+
7. **Bitwise Operators**: These operate on the individual bits of integers (`&`, `|`, `^`, `~`, `<<`, `>>`).
52+
53+
8. **Other Operators/Operations**:
54+
* Indexing (`[]`). Used for accessing elements in sequences or mappings.
55+
* Slicing (`[:]`). Used for extracting subsequences from sequences. Python 3.0 allows extended slicing with three parts: `X[I:J:K]`.
56+
* Call (`()`). Used to invoke functions, methods, or classes.
57+
* Attribute reference (`.`). Used to access attributes or methods of objects.
58+
59+
**Operator Precedence**:
60+
When an expression includes multiple operators, Python follows **operator precedence** rules to determine the order of evaluation.
61+
* **Parentheses (`()`)** have the highest precedence and can override the default order. Expressions within parentheses are evaluated first.
62+
* **Exponentiation (`**`)** is next.
63+
* **Multiplication (`*`), Division (`/`, `//`), and Modulus (`%`)** have higher precedence than Addition (`+`) and Subtraction (`-`).
64+
* Operators at the same precedence level are generally evaluated from **left to right**, except for exponentiation.
65+
* It is often good practice to use parentheses for clarity even when not strictly required by precedence. For example, `2 * 3 + 4` evaluates to 10 because multiplication happens first, while `2 * (3 + 4)` evaluates to 14 because parentheses force the addition first.
66+
67+
**Expressions and Statements**:
68+
Expressions can appear as **statements**. Common forms of expression statements include calling functions and methods. In Python 3.0, the `print()` function is typically used as an expression statement. Expressions typed directly into the interactive interpreter are also expression statements.
69+
70+
**Operators and Data Types**:
71+
The behaviour of an operator depends on the type of object it is applied to. For instance, `+` performs addition on numbers but concatenation on strings, and `*` performs multiplication on numbers but repetition on strings. Some operations like indexing (`[]`) and slicing (`[:]`) are specifically defined for sequence types like strings, lists, and tuples.
72+
73+
**Operator Overloading**:
74+
Classes in Python can intercept and respond to operators by defining special methods (often starting and ending with double underscores). This is known as **operator overloading**.
75+
* For example, defining `__add__(self, other)` in a class allows instances of that class to be used with the `+` operator.
76+
* The `__init__` method, called when an object is created (e.g., `X = Class(args)`), is the most commonly used operator overloading method.
77+
* Methods like `__getitem__` and `__setitem__` can be defined to support indexing and slicing (`[]`) for custom objects.
78+
* `__str__` and `__repr__` handle how objects are displayed when printed or represented.
79+
* Methods like `__bool__` or `__len__` (in Python 2.6, `__nonzero__`) determine how an object evaluates in a Boolean context.
80+
* Operator overloading is useful when a custom object needs to behave like a built-in type (emulating its interface) or when the operations naturally map to the object's purpose, such as adding vector objects. Python often tries a specific overloading method first and falls back to a more general one if needed; for instance, iteration might try `__iter__` before `__getitem__`, and in-place addition (`+=`) tries `__iadd__` before `__add__`.

content/notes/iit-madras/data-science-and-application/foundational-level/python/week 1/lec1.11.md

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,55 @@ tags:
66
- IIT Madras
77
excludeSearch: false
88
weight: 11
9-
---
9+
---
10+
11+
Okay, let's delve into strings, drawing from the provided sources and our previous conversation about operators and expressions.
12+
13+
**What are Strings?**
14+
15+
Strings are a fundamental data type in Python used to record textual information as well as arbitrary collections of bytes. They are essentially an ordered collection of characters used to store and represent text-based information. In Python, unlike some other languages, there isn't a separate type for individual characters; instead, you use one-character strings. Strings are a core object type provided by Python.
16+
17+
**Creating Strings (String Literals)**
18+
19+
Strings can be created using literal expressions. Common ways to code strings include using single quotes (`'...'`) or double quotes (`"..."`). Single and double-quoted strings are treated the same.
20+
21+
For special characters, you can use backslash escape sequences, such as `\n` for a newline or `\t` for a tab. Raw strings (`r'...'`) suppress the interpretation of escape sequences. Triple-quoted strings (`"""..."""` or `'''...'''`) can span multiple lines.
22+
23+
In Python 3.0, there's a distinction between text strings (Unicode, represented by the `str` type) and binary data (byte strings, represented by the `bytes` type), although byte strings can reflect encoded Unicode text. Python 2.6 handled strings and Unicode differently, with `str` and `unicode` types.
24+
25+
**Basic String Operations**
26+
27+
Strings support various operations. Some key basic operations include:
28+
29+
* **Concatenation** (`+`): This operator combines two strings by placing one next to the other. We saw this in our previous discussion on operators, noting that `+` means concatenation for strings. For example, combining the strings "coffee" and "bread" using `+` results in "coffee bread".
30+
* **Repetition/Replication** (`*`): This operator repeats a string a specified number of times. We also touched upon this in our last lecture on operators. For example, `'Spam!' * 8` results in `'Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!'`. Similarly, if a variable `s` is the string "good", `s * 5` would repeat "good" five times.
31+
* **Length** (`len()`): The built-in `len()` function returns the number of characters in a string. For a string with 36 characters, the length is 36.
32+
* **Membership** (`in`, `not in`): These operators check if a substring is present within a string.
33+
* **Comparison**: Strings can be compared using relational operators like `==`, `!=`, `<`, `>`, `<=`, and `>=`.
34+
35+
**Accessing String Elements: Indexing and Slicing**
36+
37+
Strings are **sequences**, which means their items have a left-to-right positional order and can be accessed by their relative position (offset).
38+
39+
* **Indexing** (`[]`): You can access individual characters in a string by using the bracket operator with an integer index. Indexing starts at 0 for the first character. For example, `alpha` accesses the first letter, and `alpha` accesses the 11th letter (if 'a' is at index 0, 'k' is at index 10). Similarly, for a string `s`, `s` gives the first letter, `s` the second, and so on. Negative indices can be used to count from the right; `T[-2]` fetches the second to last element.
40+
* **Slicing** (`[:]`): You can extract a portion (a substring) of a string using slicing. Slicing fetches sections from the string. For example, `s[1:3]` might extract characters from index 1 up to (but not including) index 3. Extended slicing with a third index allows specifying a "step size", determining how many characters to skip.
41+
42+
**Immutability**
43+
44+
A crucial property of Python strings is that they are **immutable**. This means that once a string object is created, its contents cannot be changed in-place. Operations like concatenation or slicing don't modify the original string; they create *new* string objects. If you need to change a string, you effectively create a new string and reassign it to the variable.
45+
46+
**String Methods**
47+
48+
In addition to basic operations, string objects have a rich set of built-in methods that perform common string-specific tasks. These methods are called using dot notation (e.g., `string_variable.method_name()`). Examples include methods for splitting and joining, case conversions, content tests (`isalnum()`, `isdigit()`, etc.), substring searches (`find()`, `index()`), and replacements.
49+
50+
You can discover the available methods and attributes for a string object using the built-in `dir()` function and get help on what they do using the `help()` function.
51+
52+
**String Formatting**
53+
54+
Python provides ways to format strings, such as using the string formatting operator (`%`) or the string formatting method (`.format()`).
55+
56+
**Strings as Sequences**
57+
58+
As mentioned, strings are a type of sequence. This is important because many operations that work on strings (like indexing, slicing, and iteration) also work on other sequence types such as lists and tuples. We've seen how lists also support concatenation and repetition, similar to strings.
59+
60+
In summary, strings are a fundamental, immutable sequence type in Python used for text, supporting various operations, indexing, slicing, and a wide array of methods for manipulation and processing.

0 commit comments

Comments
 (0)