From cb5fcb4953a9b0a181479fc4b434c64123280497 Mon Sep 17 00:00:00 2001 From: somyasaxena01 <140182178+somyasaxena01@users.noreply.github.com> Date: Thu, 30 May 2024 10:56:55 +0530 Subject: [PATCH 01/45] Added stacks.md --- contrib/ds-algorithms/stacks.md | 131 ++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 contrib/ds-algorithms/stacks.md diff --git a/contrib/ds-algorithms/stacks.md b/contrib/ds-algorithms/stacks.md new file mode 100644 index 0000000..f9f662b --- /dev/null +++ b/contrib/ds-algorithms/stacks.md @@ -0,0 +1,131 @@ +# STACKS IN PYTHON +In Data Structures and Algorithms, a stack is a linear data structure that complies with the Last In, First Out (LIFO) rule. It works by use of two fundamental techniques: *PUSH* which inserts an element on top of the stack and *POP* which takes out the topmost element.This concept is similar to a stack of plates in a cafeteria. Stacks are usually used for handling function calls, expression evaluation, and parsing in programming. Indeed, they are efficient in managing memory as well as tracking program state. + +**POINTS TO BE REMEMBERED :-** +- A stack is a collection of data items that can be accessed at only one end, called *TOP*. +- Items can be inserted and deleted in a stack only at the *TOP*. +- The last item inserted in a stack is the first one to be deleted. +- Therefore, a stack is called a **Last-In-First-Out (LIFO)** data structure. + +## REAL LIFE EXAMPLES OF STACKS + +**PILE OF BOOKS** - Suppose a set of books are placed one over the other in a pile. When you remove books from the pile, the topmost book will be removed first. Similarly, when you have to add a book to the pile, the book will be placed at the top of the file. + +**PILE OF PLATES** - The first plate begins the pile. The second plate is placed on the top of the first plate and the third plate is placed on the top of the second plate, and so on. In general, if you want to add a plate to the pile, you can keep it on the top of the pile. Similarly, if you want to remove a plate, you can remove the plate from the top of the pile. + +**BANGLES IN A HAND** - When a person wears bangles, the last bangle worn is the first one to be removed. + +## APPLICATIONS OF STACKS + +Stacks are widely used in Computer Science: +- *Function call* management +- Maintaining the *UNDO* list for the application +- Web browser *history management* +- Evaluating expressions +- Checking the nesting of parentheses in an expression +- *Backtracking* algorithms (Recursion) + +Understanding these applications is essential for Software Development. + +## OPERATIONS ON A STACK + +Key operations on a stack include: +- **PUSH** - It is the process of inserting a new element on the top of a stack. +- **OVERFLOW** - A situation when we are pushing an item in a stack that is full. +- **POP** - It is the process of deleting an element from the top of a stack. +- **UNDERFLOW** - A situation when we are popping item from an empty stack. +- **PEEK** - It is the process of getting the most recent value of stack *(i.e. the value at the top of the stack)* +- **ISEMPTY** - It is the function which return true if stack is empty else false. +- **SHOW** -Displaying stack items. + +## IMPLEMENTING STACKS IN PYTHON + +```python +def isEmpty(S): + + if len(S) == 0: + return True + + else: + + return False + +def Push(S, item): + S.append(item) + +def Pop(S): + + if isEmpty(S): + return "Underflow" + + else: + val = S.pop() + return val + +def Peek(S): + + if isEmpty(S): + return "Underflow" + + else: + top = len(S) - 1 + return S[top] + +def Show(S): + + if isEmpty(S): + print("Sorry, No items in Stack") + + else: + print("(Top)", end=' ') + t = len(S) - 1 + while t >= 0: + print(S[t], "<", end=' ') + t -= 1 + print() +``` + +This code defines a stack data structure along with functions to manipulate it. To provide output, we would need to use these functions to interact with the stack. + +Here's an example: +```python +stack = [] + +Push(stack, 5) +Push(stack, 10) +Push(stack, 15) + +print("Stack after Push operations:") +Show(stack) + +print("Peek operation:", Peek(stack)) + +print("Pop operation:", Pop(stack)) + +print("Stack after Pop operation:") +Show(stack) +``` + +This would output: + +``` +Stack after Push operations: + +(Top) 15 < 10 < 5 < + +Peek operation: 15 + +Pop operation: 15 + +Stack after Pop operation: + +(Top) 10 < 5 < +``` + +## Complexity Analysis + +- **Worst case**: `O(n)` This occurs when the stack is full, it is dominated by the usage of Show operation. +- **Best case**: `O(1)` When the operations like isEmpty, Push, Pop and Peek are used, they have a constant time complexity of O(1). +- **Average case**: `O(n)` The average complexity is likely to be lower than O(n), as the stack is not always full. + + From 79017403f82fe8cd5e1737ff573eab8506a7fffa Mon Sep 17 00:00:00 2001 From: somyasaxena01 <140182178+somyasaxena01@users.noreply.github.com> Date: Thu, 30 May 2024 10:58:36 +0530 Subject: [PATCH 02/45] Update index.md --- contrib/ds-algorithms/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/ds-algorithms/index.md b/contrib/ds-algorithms/index.md index c61ca0b..783f982 100644 --- a/contrib/ds-algorithms/index.md +++ b/contrib/ds-algorithms/index.md @@ -9,3 +9,4 @@ - [Greedy Algorithms](greedy-algorithms.md) - [Dynamic Programming](dynamic-programming.md) - [Linked list](linked-list.md) +- [Stacks in Python](stacks.md) From 97f852c99616cab741e8c06469f239bd34b74dd6 Mon Sep 17 00:00:00 2001 From: rohit Date: Fri, 31 May 2024 10:26:09 +0530 Subject: [PATCH 03/45] Added sklearn.md file --- contrib/machine-learning/index.md | 1 + contrib/machine-learning/sklearn.md | 144 ++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+) create mode 100644 contrib/machine-learning/sklearn.md diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md index 46100df..68bd24d 100644 --- a/contrib/machine-learning/index.md +++ b/contrib/machine-learning/index.md @@ -10,3 +10,4 @@ - [PyTorch.md](pytorch.md) - [Types of optimizers](Types_of_optimizers.md) - [Logistic Regression](logistic-regression.md) +- [sklearn.md](sklearn.md) diff --git a/contrib/machine-learning/sklearn.md b/contrib/machine-learning/sklearn.md new file mode 100644 index 0000000..8174d93 --- /dev/null +++ b/contrib/machine-learning/sklearn.md @@ -0,0 +1,144 @@ +# scikit-learn (sklearn) Python Library + +## Overview + +scikit-learn, also known as sklearn, is a popular open-source Python library that provides simple and efficient tools for data mining and data analysis. It is built on NumPy, SciPy, and matplotlib. The library is designed to interoperate with the Python numerical and scientific libraries. + +## Key Features + +- **Classification**: Identifying which category an object belongs to. Example algorithms include SVM, nearest neighbors, random forest. +- **Regression**: Predicting a continuous-valued attribute associated with an object. Example algorithms include support vector regression (SVR), ridge regression, Lasso. +- **Clustering**: Automatic grouping of similar objects into sets. Example algorithms include k-means, spectral clustering, mean-shift. +- **Dimensionality Reduction**: Reducing the number of random variables to consider. Example algorithms include PCA, feature selection, non-negative matrix factorization. +- **Model Selection**: Comparing, validating, and choosing parameters and models. Example methods include grid search, cross-validation, metrics. +- **Preprocessing**: Feature extraction and normalization. + +## When to Use scikit-learn + +- **Use scikit-learn if**: + - You are working on machine learning tasks such as classification, regression, clustering, dimensionality reduction, model selection, and preprocessing. + - You need an easy-to-use, well-documented library. + - You require tools that are compatible with NumPy and SciPy. + +- **Do not use scikit-learn if**: + - You need to perform deep learning tasks. In such cases, consider using TensorFlow or PyTorch. + - You need out-of-the-box support for large-scale data. scikit-learn is designed to work with in-memory data, so for very large datasets, you might want to consider libraries like Dask-ML. + +## Installation + +You can install scikit-learn using pip: + +```bash +pip install scikit-learn +``` + +Or via conda: + +```bash +conda install scikit-learn +``` + +## Basic Usage with Code Snippets + +### Importing the Library + +```python +import numpy as np +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler +from sklearn.linear_model import LogisticRegression +from sklearn.metrics import accuracy_score +``` + +### Loading Data + +For illustration, let's create a simple synthetic dataset: + +```python +from sklearn.datasets import make_classification + +X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42) +``` + +### Splitting Data + +Split the dataset into training and testing sets: + +```python +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) +``` + +### Preprocessing + +Standardizing the features: + +```python +scaler = StandardScaler() +X_train = scaler.fit_transform(X_train) +X_test = scaler.transform(X_test) +``` + +### Training a Model + +Train a Logistic Regression model: + +```python +model = LogisticRegression() +model.fit(X_train, y_train) +``` + +### Making Predictions + +Make predictions on the test set: + +```python +y_pred = model.predict(X_test) +``` + +### Evaluating the Model + +Evaluate the accuracy of the model: + +```python +accuracy = accuracy_score(y_test, y_pred) +print(f"Accuracy: {accuracy * 100:.2f}%") +``` + +### Putting it All Together + +Here is a complete example from data loading to model evaluation: + +```python +import numpy as np +from sklearn.datasets import make_classification +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler +from sklearn.linear_model import LogisticRegression +from sklearn.metrics import accuracy_score + +# Load data +X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42) + +# Split data +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) + +# Preprocess data +scaler = StandardScaler() +X_train = scaler.fit_transform(X_train) +X_test = scaler.transform(X_test) + +# Train model +model = LogisticRegression() +model.fit(X_train, y_train) + +# Make predictions +y_pred = model.predict(X_test) + +# Evaluate model +accuracy = accuracy_score(y_test, y_pred) +print(f"Accuracy: {accuracy * 100:.2f}%") +``` + +## Conclusion + +scikit-learn is a powerful and versatile library that can be used for a wide range of machine learning tasks. It is particularly well-suited for beginners due to its easy-to-use interface and extensive documentation. Whether you are working on a simple classification task or a more complex clustering problem, scikit-learn provides the tools you need to build and evaluate your models effectively. \ No newline at end of file From 56e972133ff33ca0532c6d0637fb465425b41c09 Mon Sep 17 00:00:00 2001 From: manishh12 Date: Fri, 31 May 2024 12:02:09 +0530 Subject: [PATCH 04/45] added types of cost functions issue#625 --- .../Types_of_Cost_Functions.md | 227 ++++++++++++++++++ contrib/machine-learning/index.md | 1 + 2 files changed, 228 insertions(+) create mode 100644 contrib/machine-learning/Types_of_Cost_Functions.md diff --git a/contrib/machine-learning/Types_of_Cost_Functions.md b/contrib/machine-learning/Types_of_Cost_Functions.md new file mode 100644 index 0000000..547a05e --- /dev/null +++ b/contrib/machine-learning/Types_of_Cost_Functions.md @@ -0,0 +1,227 @@ + +# Cost Functions in Machine Learning + +Cost functions, also known as loss functions, play a crucial role in training machine learning models. They measure how well the model performs on the training data by quantifying the difference between predicted and actual values. Different types of cost functions are used depending on the problem domain and the nature of the data. + +## Types of Cost Functions + +### 1. Mean Squared Error (MSE) + +**Explanation:** +MSE is one of the most commonly used cost functions, particularly in regression problems. It calculates the average squared difference between the predicted and actual values. + +**Mathematical Formulation:** +The MSE is defined as: +$$ MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 $$ +Where: +- \( n \) is the number of samples. +- \( y_i \) is the actual value. +- \( y^i\) is the predicted value. + +**Advantages:** +- Sensitive to large errors due to squaring. +- Differentiable and convex, facilitating optimization. + +**Disadvantages:** +- Sensitive to outliers, as the squared term amplifies their impact. + +**Python Implementation:** +```python +import numpy as np + +def mean_squared_error(y_true, y_pred): + n = len(y_true) + return np.mean((y_true - y_pred) ** 2) +``` + +### 2. Mean Absolute Error (MAE) + +**Explanation:** +MAE is another commonly used cost function for regression tasks. It measures the average absolute difference between predicted and actual values. + +**Mathematical Formulation:** +The MAE is defined as: +$$ MAE = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i| $$ +Where: +- \( n \) is the number of samples. +- \( y_i \) is the actual value. +- \( y^i\) is the predicted value. + +**Advantages:** +- Less sensitive to outliers compared to MSE. +- Provides a linear error term, which can be easier to interpret. + + +**Disadvantages:** +- Not differentiable at zero, which can complicate optimization. + +**Python Implementation:** +```python +import numpy as np + +def mean_absolute_error(y_true, y_pred): + n = len(y_true) + return np.mean(np.abs(y_true - y_pred)) +``` + +### 3. Cross-Entropy Loss (Binary) + +**Explanation:** +Cross-entropy loss is commonly used in binary classification problems. It measures the dissimilarity between the true and predicted probability distributions. + +**Mathematical Formulation:** +For binary classification, the cross-entropy loss is defined as: +$$ \text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)] $$ +Where: +- \( n \) is the number of samples. +- \( y_i \) is the actual class label (0 or 1). +- \( y^i\) is the predicted probability of the positive class. + + +**Advantages:** +- Penalizes confident wrong predictions heavily. +- Suitable for probabilistic outputs. + +**Disadvantages:** +- Sensitive to class imbalance. + +**Python Implementation:** +```python +import numpy as np + +def binary_cross_entropy(y_true, y_pred): + n = len(y_true) + return -np.mean(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred)) +``` + +### 4. Cross-Entropy Loss (Multiclass) + +**Explanation:** +For multiclass classification problems, the cross-entropy loss is adapted to handle multiple classes. + +**Mathematical Formulation:** +The multiclass cross-entropy loss is defined as: +$$ \text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} \sum_{c=1}^{C} y_{i,c} \log(\hat{y}_{i,c}) $$ +Where: +- \( n \) is the number of samples. +- \( C \) is the number of classes. +- \( y_{i,c} \) is the indicator function for the true class of sample \( i \). + +- (y^i,c) is the predicted probability of sample \( i \) belonging to class \( c \). + +**Advantages:** +- Handles multiple classes effectively. +- Encourages the model to assign high probabilities to the correct classes. + +**Disadvantages:** +- Requires one-hot encoding for class labels, which can increase computational complexity. + +**Python Implementation:** +```python +import numpy as np + +def categorical_cross_entropy(y_true, y_pred): + n = len(y_true) + return -np.mean(np.sum(y_true * np.log(y_pred), axis=1)) +``` + +### 5. Hinge Loss (SVM) + +**Explanation:** +Hinge loss is commonly used in support vector machines (SVMs) for binary classification tasks. It penalizes misclassifications by a linear margin. + +**Mathematical Formulation:** +For binary classification, the hinge loss is defined as: +$$ \text{Hinge Loss} = \frac{1}{n} \sum_{i=1}^{n} \max(0, 1 - y_i \cdot \hat{y}_i) $$ +Where: +- \( n \) is the number of samples. +- \( y_i \) is the actual class label (-1 or 1). +- \( \hat{y}_i \) is the predicted score for sample \( i \). + +**Advantages:** +- Encourages margin maximization in SVMs. +- Robust to outliers due to the linear penalty. + +**Disadvantages:** +- Not differentiable at the margin, which can complicate optimization. + +**Python Implementation:** +```python +import numpy as np + +def hinge_loss(y_true, y_pred): + n = len(y_true) + loss = np.maximum(0, 1 - y_true * y_pred) + return np.mean(loss) +``` + +### 6. Huber Loss + +**Explanation:** +Huber loss is a combination of MSE and MAE, providing a compromise between the two. It is less sensitive to outliers than MSE and provides a smooth transition to MAE for large errors. + +**Mathematical Formulation:** + +The Huber loss is defined as: + + +$$ +\text{Huber Loss} = \frac{1}{n} \sum_{i=1}^{n} \left\{ +\begin{array}{ll} +\frac{1}{2} (y_i - \hat{y}_i)^2 & \text{if } |y_i - \hat{y}_i| \leq \delta \\ +\delta(|y_i - \hat{y}_i| - \frac{1}{2} \delta) & \text{otherwise} +\end{array} +\right. +$$ +Where: +- \( n \) is the number of samples. +- \( \delta \) is a threshold parameter. + +**Advantages:** +- Provides a smooth loss function. +- Less sensitive to outliers than MSE. + +**Disadvantages:** +- Requires tuning of the threshold parameter. + +**Python Implementation:** +```python +import numpy as np + +def huber_loss(y_true, y_pred, delta): + error = y_true - y_pred + loss = np.where(np.abs(error) <= delta, 0.5 * error ** 2, delta * (np.abs(error) - 0.5 * delta)) + return np.mean(loss) +``` + +### 7. Log-Cosh Loss + +**Explanation:** +Log-Cosh loss is a smooth approximation of the MAE and is less sensitive to outliers than MSE. It provides a smooth transition from quadratic for small errors to linear for large errors. + +**Mathematical Formulation:** +The Log-Cosh loss is defined as: +$$ \text{Log-Cosh Loss} = \frac{1}{n} \sum_{i=1}^{n} \log(\cosh(y_i - \hat{y}_i)) $$ +Where: +- \( n \) is the number of samples. + +**Advantages:** +- Smooth and differentiable everywhere. +- Less sensitive to outliers. + +**Disadvantages:** +- Computationally more expensive than simple losses like MSE. + +**Python Implementation:** +```python +import numpy as np + +def logcosh_loss(y_true, y_pred): + error = y_true - y_pred + loss = np.log(np.cosh(error)) + return np.mean(loss) +``` + +These implementations provide various options for cost functions suitable for different machine learning tasks. Each function has its advantages and disadvantages, making them suitable for different scenarios and problem domains. + +--- \ No newline at end of file diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md index 46100df..cfe9a67 100644 --- a/contrib/machine-learning/index.md +++ b/contrib/machine-learning/index.md @@ -10,3 +10,4 @@ - [PyTorch.md](pytorch.md) - [Types of optimizers](Types_of_optimizers.md) - [Logistic Regression](logistic-regression.md) +-[Types_of_Cost_Functions](Types_of_Cost_Functions.md) From d23389a8ea17ca0d16b96b14b710ac41606e8383 Mon Sep 17 00:00:00 2001 From: Manish kumar gupta <97523900+manishh12@users.noreply.github.com> Date: Fri, 31 May 2024 12:07:34 +0530 Subject: [PATCH 05/45] Updated maths formulas --- .../Types_of_Cost_Functions.md | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/contrib/machine-learning/Types_of_Cost_Functions.md b/contrib/machine-learning/Types_of_Cost_Functions.md index 547a05e..f650726 100644 --- a/contrib/machine-learning/Types_of_Cost_Functions.md +++ b/contrib/machine-learning/Types_of_Cost_Functions.md @@ -12,7 +12,7 @@ MSE is one of the most commonly used cost functions, particularly in regression **Mathematical Formulation:** The MSE is defined as: -$$ MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 $$ +$$MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2$$ Where: - \( n \) is the number of samples. - \( y_i \) is the actual value. @@ -41,7 +41,7 @@ MAE is another commonly used cost function for regression tasks. It measures the **Mathematical Formulation:** The MAE is defined as: -$$ MAE = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i| $$ +$$MAE = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|$$ Where: - \( n \) is the number of samples. - \( y_i \) is the actual value. @@ -70,8 +70,11 @@ def mean_absolute_error(y_true, y_pred): Cross-entropy loss is commonly used in binary classification problems. It measures the dissimilarity between the true and predicted probability distributions. **Mathematical Formulation:** + For binary classification, the cross-entropy loss is defined as: -$$ \text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)] $$ + +$$\text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)]$$ + Where: - \( n \) is the number of samples. - \( y_i \) is the actual class label (0 or 1). @@ -100,8 +103,11 @@ def binary_cross_entropy(y_true, y_pred): For multiclass classification problems, the cross-entropy loss is adapted to handle multiple classes. **Mathematical Formulation:** + The multiclass cross-entropy loss is defined as: -$$ \text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} \sum_{c=1}^{C} y_{i,c} \log(\hat{y}_{i,c}) $$ + +$$\text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} \sum_{c=1}^{C} y_{i,c} \log(\hat{y}_{i,c})$$ + Where: - \( n \) is the number of samples. - \( C \) is the number of classes. @@ -131,8 +137,11 @@ def categorical_cross_entropy(y_true, y_pred): Hinge loss is commonly used in support vector machines (SVMs) for binary classification tasks. It penalizes misclassifications by a linear margin. **Mathematical Formulation:** + For binary classification, the hinge loss is defined as: -$$ \text{Hinge Loss} = \frac{1}{n} \sum_{i=1}^{n} \max(0, 1 - y_i \cdot \hat{y}_i) $$ + +$$\text{Hinge Loss} = \frac{1}{n} \sum_{i=1}^{n} \max(0, 1 - y_i \cdot \hat{y}_i)$$ + Where: - \( n \) is the number of samples. - \( y_i \) is the actual class label (-1 or 1). @@ -165,17 +174,16 @@ Huber loss is a combination of MSE and MAE, providing a compromise between the t The Huber loss is defined as: -$$ -\text{Huber Loss} = \frac{1}{n} \sum_{i=1}^{n} \left\{ +$$\text{Huber Loss} = \frac{1}{n} \sum_{i=1}^{n} \left\{ \begin{array}{ll} \frac{1}{2} (y_i - \hat{y}_i)^2 & \text{if } |y_i - \hat{y}_i| \leq \delta \\ \delta(|y_i - \hat{y}_i| - \frac{1}{2} \delta) & \text{otherwise} \end{array} -\right. -$$ +\right.$$ + Where: - \( n \) is the number of samples. -- \( \delta \) is a threshold parameter. +- \(delta\) is a threshold parameter. **Advantages:** - Provides a smooth loss function. @@ -200,8 +208,11 @@ def huber_loss(y_true, y_pred, delta): Log-Cosh loss is a smooth approximation of the MAE and is less sensitive to outliers than MSE. It provides a smooth transition from quadratic for small errors to linear for large errors. **Mathematical Formulation:** + The Log-Cosh loss is defined as: -$$ \text{Log-Cosh Loss} = \frac{1}{n} \sum_{i=1}^{n} \log(\cosh(y_i - \hat{y}_i)) $$ + +$$\text{Log-Cosh Loss} = \frac{1}{n} \sum_{i=1}^{n} \log(\cosh(y_i - \hat{y}_i))$$ + Where: - \( n \) is the number of samples. @@ -224,4 +235,4 @@ def logcosh_loss(y_true, y_pred): These implementations provide various options for cost functions suitable for different machine learning tasks. Each function has its advantages and disadvantages, making them suitable for different scenarios and problem domains. ---- \ No newline at end of file +--- From 540163c863037f28afa4b9b7463198bf57e41866 Mon Sep 17 00:00:00 2001 From: Dishika Vaishkiyar <152963337+Dishika18@users.noreply.github.com> Date: Fri, 31 May 2024 14:09:16 +0530 Subject: [PATCH 06/45] Added Content: Line Charts in Matplotlib --- .../plotting-visualization/images/dot-line.png | Bin 0 -> 1180 bytes .../images/line-asymptote.png | Bin 0 -> 29209 bytes .../images/line-curve.png | Bin 0 -> 13975 bytes .../images/line-labels.png | Bin 0 -> 16851 bytes .../images/line-ticks.png | Bin 0 -> 22354 bytes .../images/line-with-text-scale.png | Bin 0 -> 19249 bytes .../images/simple_line.png | Bin 0 -> 14451 bytes .../plotting-visualization/images/two-lines.png | Bin 0 -> 18440 bytes 8 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 contrib/plotting-visualization/images/dot-line.png create mode 100644 contrib/plotting-visualization/images/line-asymptote.png create mode 100644 contrib/plotting-visualization/images/line-curve.png create mode 100644 contrib/plotting-visualization/images/line-labels.png create mode 100644 contrib/plotting-visualization/images/line-ticks.png create mode 100644 contrib/plotting-visualization/images/line-with-text-scale.png create mode 100644 contrib/plotting-visualization/images/simple_line.png create mode 100644 contrib/plotting-visualization/images/two-lines.png diff --git a/contrib/plotting-visualization/images/dot-line.png b/contrib/plotting-visualization/images/dot-line.png new file mode 100644 index 0000000000000000000000000000000000000000..ff9e67f536cc625fa97ed59095d5442f646ebcfb GIT binary patch literal 1180 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&B3=}#3|KN2X#a!&<8N$KAar>eF10a{P zz$3Dlfq_2}gc(=ZFV6%DT9mj(lmzFem6RtIr849umK5aVm*iw7DU_ua6=&w>8S5G9 z8R{rxl#~=$>FXop_413-^##(zC4pwB2l#}z0%`g3EehpZEZX*LIR9k(+!tCp-&KZT ziOI{1pupBLX%(#_j1w$40+g5DN={*pELt%~!D-XpO(u2sq|Ydy{&v4dygu|Q6Qe@| z10$CLkYp7Al1v;xl97c&U;zUY3r7G0BNK}TPyv$&sxlPC7TyQG|9-AmU6sM|W0%C1 zROJKPpU%+!@NtFUgZci+d4=+I<{;fb^FTH*Fq&o77jth|wpu2iVcPcDo2*zP?s-p| ztb5?my2(%Y5(>pVi#RWEz1ha@_wB&0;EJ~*W&9?cGg=Y);RaEkVH04#Kc6vdi}mU7 z2GPGB*Q6VczCAzbs(HiFzkZYS8M=Q@RhiEi)p+;Yf#T|frZANy-Pv+Jd4HeCINRo}u|dM@<+W^VIiEM2I?#|i@7qQuMzQye&%Yfw6i8F)+$;YiOidG=v||l;AR7qBta{;wKLwie}`!evg}x?+%kYA|=2{73MDcH@QD;Qu^I{8REs8x8<<> usIz~@RRc`$STlzp1HlXg$!9sY?5k$UY`w)e(GQsY89ZJ6T-G@yGywo1V^$&n literal 0 HcmV?d00001 diff --git a/contrib/plotting-visualization/images/line-asymptote.png b/contrib/plotting-visualization/images/line-asymptote.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d21da0627f3f44f301cfef247e3ca4018edb62 GIT binary patch literal 29209 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 literal 0 HcmV?d00001 diff --git a/contrib/plotting-visualization/images/line-labels.png b/contrib/plotting-visualization/images/line-labels.png new file mode 100644 index 0000000000000000000000000000000000000000..26505b1560a19627a47cc0156693f758adecfa67 GIT binary patch literal 16851 zcmbWfby!qu_dY&^fPn}I2uN6PXh{_i1XQG@kq!X?rKMvGloW$b0qGI}=}<~Z=?+P0 z>4xvxGvfQ6&-?r9cP{7ha%S)S#D3Pj?sc!Vj?Z0rN#bKP$51E~vDBTLN+=XA8im3c zA;N`kigRUh;V(QpaVZrdBBK7E3M25(qtNKz0ruCkxx_WmAhn9S#z@xdIoNd}b`s=Jb%d6Av{KL`6D5woXxHMC%fRl?W zG)q%UD>6KsPQaF zo1;tIch=SQ+*Qy1t|Ae=V@09BSnE%{^6f%kW2~s2Tli?0TBfF41Yc?wiZYp1-gdGv zd}nbYG$Jp`B=JII)nSFqFDj!X#3ERuJ%8ioC23GpZcz1 zVL51q&tX~Wv=nd8&&(|OkgZ~Wd)Admf3HiM$94T7Y09=v29f?!`FXCybm>GTVf9na z?CyS=!sndeBvjwlK3H&FpChf?+1l#d6@PJpT1hl}0C}Uq_JV_Bfufx5byu!l)fiV6 z7k^r~+bpzLda%DU`ZO{!vM^`nL=h*>?p$t*TAA_hkuRfoLlUT2pDCQ8q9S-(q=YZM zyr%Iq9-7O@$gI8e3HWq%WO<@tbh+Axobcq?Fs)l|ZlzAM^}%cw9_L0S))oe}&Q|K+ zGNPZjEN@gC=xo1Qg!f&&u2^h?>~d`N5n5VWQcWo-DNj~(T>!268YQV!HmvqKzO{-< zN556YV4TFuv|+RLrKMKS9^En*)$2p;?aF7Z=X$tpoGZ~d9Of$%p?Y1r;?;F?9jWh} z(!;}hzj_^C8*>CRW(<8i+a=Xs&!U{Xxi#nxoxV2NXPNVeyh%Ff!N z$%4IJ6z4zxoGMunao>J8SiCmZn@dkm-L{j|(07 z%~i2`UJoTCD5y5Lcx>2xLnj|q-azECySX&V);4YLxLxYF&HVw6tU=WapN)xfoKux( z{~&4O{?CtK^Y5)4k^cIvzd8W^S)y!NR9NVZcT=gJw9>RWiqvX(eZ4Do3eJ7{5$h%@ zgU9oIsxG8mU!D=xXl=l2SThO<4V}d+nW2h5ILGGW)ZCgVL$yE)(DrRMzgw65-lfl_ zs-Cjzv)L6Pt`pfCGH|4WJ9wr$%J_Sa@m>)O&@Yv9+$E)f=kl( z7yJ%7!UlY+XZj1Wy?>flc#kO@v6gF7xa~t%bZ6rwgNFwG{Ai6|V(5K!;*qopZwa@d zXdy?ny>EtW>^!PxFT`khvwQAuO@(sl>8hxxtQ@~rWIOTuXO+<7nTsObye-1H=AEp2 z+5Py39^+qLz9czXUS3{iW@d1B zMEba!T-WR-{fRm@H#aT1vp95$^Waq|Dk^rqT3T7*y?j}t!oyuw);~Bn_$m_*&s%Va zxM8SrD|*+toW+WR^1cA&B-!xG22b~Ayh$&Zw8Y4v@NOi$Z=WU_A)u?I37CWf^5Vsd z*4Ea}p$>3h99o}$W%u>;oS+vj>>`Q3`%l{5+6kBm{rlHJT1Ew%7pFqVDv1?u-mC`u zFxS`r0VhVYqN2a}@oa)*;7oR3f4?Ifl`axv3k$9JMM<(s)bIBK<-=PSskv-;wkHSX zs=nY`OMFmaB_|_$`s^782SJE< zLKYSlM%Sm?ll{`$xIH{PGBxx23T=!YKFr9>oZ!#fSZ`J5?UuNeR^hR z?afjBdv43$nQz~|4Lhk*;y`!ZB`>J_X;G1LXXeLe&m<1^_i7CA2v3ev*`RJn*j;0> z+GHgmE!zvd#&BGAYu3mVw~+J#8s|OzgS_JTsj(dmHA}bQfnOAn&Ijr`@HPohyYdb; zH9I?;GDcI`^3Q`=I&Ix3u|J3oKOdMlO0`oB4zE|&UcW5lNLtpSSrThp}U7KUL(M>OD<=EJ06ca4qnjphF{`*Cd-nzWB z-MK%hky8(*u&iX3$JTO7hE~sSKGbqNSmbp(BQnbex0O~JnC4f5+q&27gTynP@0yAu z&;Oxac-#2or^ghnZ2OKrjrR{Hqm;R~E*q4$6kXV^KKJZi%TawenB&23)z>%ZLO-nP zICE+~=bpWWBa6aAmqwkpjOc}ZdCBg$;@xcc=Nal=(nb?!SRT0@(<&?tbw24}wrn z+ZT_iE6HX?-P$fMY^xIG4umx%8Nf>+^Ku!=Ib}At`(*>C=+ZIdjlaM_m&Wt@4)u&& ziZ56sV|LBPe>6rdL|zGenNM0UdZDi2ifoALt7tt<_kC$w5oGhKP&agIDAHOyi&+Dr zMMbP9)KcFb4&j~mRdJTf`xn3N=xVfr(giwr6zm5LakRW+>FQh(5>?DGPKLm>&Ye5g6lZ{nxE7#R z(7UI(*l#p-&^t#Lt2!V&djoO5DWbi%D3mvJLu#9ccgb|KI{5mPFz$KArzJmXYHr}x zs))t>=$W@ejp<^@4X>jC-WF-t0-~|-CN4*$PeXuOF21KB;#^R{=b$@zMlr7KE;-ha zIIE3GbQYN69p4Ac_WnL`OdRu!Q0WAn`O_C3xp92fD}JLc{pT6dT>p614XI1(^|vb? z;|GXGY_V}5A(y~Y>zV`o{n;6^a49kDcuHyc4J|iiXor1-+?7`vQjTJc@Vq7SLgB^4 z#d^Ee^Zu!SzT|v!rRky0t<{tJT}>AR{hneLh{2;+-ynhVgPw^{-MjLKlW69ktC&Yn zEy_rh297YoSi+-EHk^5&43jXKTA&D(`!k8OyJqa30j~wh-)(G~QmP#;n(UKIt>qGF zYk&Xp!0m#ohbtM7fAN9%qXX&m&hD`dnWduB&#@T9ljssB5eC-2J~%OV{%}N{238M? zcLm-Zg38>N7G6z&;x zsV|#~od*Wa`WV9W(mpU@9n%fnH`88|fAB1?oB2%+FV=g!4wX+9`W5={Q=aYI?lMiw z2yH>i(LX<_8x)zZ|I`NzS(FevV*GdfMseliy7y*T;tPhAk{LL4sI&|)i-Z$@|KcZy z;hKwYN??&XQ`8}vH~!A-Sbfle;F*g6v>2`v|956zu2=?WyX)S}{;o7twg3I^Fr|5# zgO-cc!n5Ih~A|U^0eXma5FB63E%qNu@T^L^jEDJSy@@x*&l+rmAS03a&Tli zhsDOmLNu|xHfv;Pn30j8Szt*=O)Z7Odo4Axwo950^FW9Uv8=(IEb7V^R2D0QzCk^8 zb;*;Fz&v>jzT)q7l3uvo7;`-mMPNN_mS0R4v*gascBS0Pa@Du#KJhtpq!^0%;ze(= z?&AFU-rOmOIabvlJ$y(&La)7Y*-Kn;H8L-c5BE%EY(K$iHjzz{8#F>(S4lPN0fH<~ z;$(E1*U)bStLvt&WrFS@;Aw!qU=`H|k-Qkuh{@^7SoigNb+72k%F1{>m34JF%gjK< z2?+^lGZq!C0Da=oKq0q)Kv!2+2!jOfZ>m)OzO}5JwjSp>%Gl~CGIMd%m28xyV$~Bo z!Vg!%BO_bFxFtM4V7VtTF);-B-?&CmztsoW*<(w0DvYKQnJ=)a_(vZdnWO>_e&c${ zsmSa0z}$wO2xOUl<@tvQO9j5kB(`Qb_`VS+C;zM`+su)OIiSRNjM;fw##a41($f}p ztV(evbB)*#h{w*a{_O6fiJsoZuFh+tOh*v21s>qc(%Cm*8lM=jSWOoStPg8WRj6+= z)tN*(EbjBoxBV_B9X_0E$~)5JbJlqmLeJSr`siC?2qw@F+|Z?94OmOPV>Y()s?5qo z>>36Xkf&do3VAi`peQ}u+04yKY-Eb%KCgSHKl(or0M=#Tus}8XiRExn>EekwyZqvP zoAN{RvG+8@Fy@Fn|7hFFK9mL3oAQ=y>xwh65`Sl8 zEWIZF^0L{S@Z&`c;9+SRW3I)$8mmXk;EJ?_v&{bB9k?7G&B!+sC#lF7D6> zBq-!Nfi9J%nAxh6fWQL0?0CpOf47Kj(xjD^w(REWdX8|xiuluzzq67~Zr?lo+VE3` z?VPY-=T_zHR>yNJRU22;j*D>Ry9q{~CwjR;Me6So{~Pk^gaGn@pu)tKVPY?L-^qo5 zU)IwdqjnpkK_)_EUw=oQzl2;6uR^;+L_N6Y~<Ms4V)TA;#yg_(8?x2g{~;n8xlLYaV`Br-;n9;P*H>0{Hpc?B^35NE78LQax35oa zM~xfjgs_HrfWtEjZG<-EXt{w~PdQ37QhU0x)1QWa<{62IKH&*I>nq0_m>1VWYnwwV zZmXp5Arl@uIRff-IfxX%8*d~yoa1!;WqSo1D4uM1&&Y_56h~F8b!jb@uAGD!%CZJH zM~ ze}BBxd4(QS@s+6-^2!@{LArPM19d!Waj@=w+197j%w(1|-tl#2x|Rylk;CtmQuqau&jX(I zua}z@oDq5kPk~4>9FR!9#{)qkc?=RE#toWSE=0q4kKiOrgqAqhnkb(7^L_TQV3XN~LXO}{P9NTp zuAO>s*RGJy!NV%s(?Rjb-zE6AuVlaxc`D)LHn>Di}Bu{mjHg(?sr zIv4sB*$G&Kb1-Yiarx)cz^@0XUMpw3XF}rJqxv^=bHZaYB*&aD}7CItLQYwe@U)YO*4Y?9{Fp;m3f0rU2S256=8} zek+M8BD;bSiBFRUhkX2_zqkxB;yQhMeU5;Dz^Z&}QbBa@!`*-2(x6}V#lVG_WY~b> zsmGF(zfpj-4Bf@mAUb+c@_!>fO%1NQ|4eX!y40m@;zD z50n~fa9tn+1Fwl}x?1M#0GiHhy$VPZ_-Vn+3cWM-_S@DxWTJ0wmw)Qwy*NS14=3&h z-qovDotmSrfspAjlbQ^RiG2PXe;RHp0F^A@1x~;nvGC>Lmrphu4rvJqCO`VnBg-IV1{C-E5A^mb8}@B z6q3P0lR9VCotSC3QqKwnYI>eKpZOY&cxfCVaDSSTU8M=h9X#+cQL$N+>X)&HstOgZ zBh}21GvhYV;~c&MEE;(Uh@^Q#S2NRc%IkSK&>^dbzkQoWNO7>fm8XG2(e1Z88mPXf zaGnaVNUR9L$aPR%N~P`s8bQ9Th|Q(o9A1qUS__oAiV8jfLCkg6b$beUF=#%`LAAh5 zk&s~8;nv8~Y-0+=z%aBo8Jo@;@-qf(7+1)e!17yPjsi7od(!SAQ^#OW@cilx7QRA5dj9KaD6Q( zB|9NuEc)ci@-mIU!?3uxxSX6NpiGdPW6i%^(#nywF`u*2!yy7Z0Kq{*1S}{KK|yMw%QFVEiT;_;BA1@nkdnwYH~QeZRYvQF))Fi>gxO8CbrY% z<>g05mY0{!5r^@4^E&PsIn~=@TcQqIQqvX_XTJAP<6F0%7^$Ool`W?-7_0-S*5Bmo z1wo5%h$}D=$eQ|UrF05bDu9N#oy(z;QhTYVmxz*ZrPe|Lv&lQSQzwH{kGf< z)RhU;KA5YZ!`xN#juc1^a;C%&;Ue2%Vq&tL-ku~kc1z>I3q&1U0CmuDEBt{Ma518h zB>Kwi?#X~FLxo()s!B>^E|DpVlTDE|UO_>pZAuaoCm;`+X!Lt-K0T7@Xlcn<)Rxw!qj|N0g<_R@|ob4s)UnbF<6}M<>dv3Z?nSlU>_u>-CqfT56&>Y178qs^gM6L-LYV} z>8mXQ1=k3EzZZMvurR>FnP<_>$-*L)+};#*t-ZGP#S0wUJM}Eo1#9u%Lqj1`T}9Pt z80+|qvkR%si_FY^#{qU;d3&FtGBh-daa)$6AsBFcb#59jL+9qUi0RaV9mmV3s3t+Q z>*}v_6IngS7_PghX#d{WIH=O|601UsCjPfaQA0dRgeyt`63_60MxRDU>j2$3*jx0Z zrKVmw&psmZKaK{4yD7T0wFRek^r>39POeGQ@WK8D7|l#qrWW6cLasv(BwFzmLIlP$1=$^NzSdrqGgu;HCRZCrdho=s{V@gzqBTawq1mbhi zjZfdMfSy}!J6GDc1p@CGAv}asFmh$8nJxzZKt#y^V%=8ifh8mpb>{UwOCQ5+k|)3q zhH_q$c|}D0Nnttb$k)@B*Gt^YP7PjJVq@`-#$Z3{MJa&y=M`)WpK!&w&X`h}9LpWf zWzUWJZfxklKIsWz;2JYD&WZ3Xrg4#qc#u>4gB!TM07PRs#W$JER!dvIS$EetVUt`1 zaRDRKKTpbS{ObGNbvH35cOv^I1uHQ>4iW_7o>^Y@Z2;wpGk)WqMW}Mz^nacNk?Lcg zV1e?n&$_bpEOAVzS!eR2BVYqG)YSQA?IxSQe?EEggr5X-#v6XD)o<`G&qyAETuCE0 z#1UY~(I^p*-NLxIpZj||2?+_1qwNJoF*i3CfinO(?Z)Bz#>S+TDTGr-pI)##lDArz zjJa^`0x!e@b+?dd^V#W7YU%SsWjhi47Ul%jVDgb#RliXX0aKVJBnD*HtjkeaTE$nNhdA9Cid6Z$q9*}7$*+nOzPfuOA^8u2#*@OOO|p(kLLoE=pD zIXU69d2KTaXJ8!n>V*puL7l_HdY%pOxBRMO3i}L3(f=Rna^RsHvU@K}G5i@KB>EoI z7$3t0jYANfu9T_*Y+6lCZ4PbY=@XsRvnWlgmxD*Sqi+sZ0JsCDXH5<|4o3?AYql9G~+Q?fIn zZ7QOUSD2X~66B|Wc{f=~WcN%+D}i2FwI?+}@*AWklctEyRAuJrWd9_ESW7cA7P?%w zE!!(s3O;=J09u!CnHA*I;SC+t-+fHM+Qd_bkmwd259%X8qQTk8ppFYU%>C+24+W&{ zAtuDfzjGx5D~uEid+xhUqyMEVzt&Qc|6Z6$1p&YmS$Z2VBbX8;SmoN{f2V--8sZpH z7-@tt+cwc;spV%|tz$j?K}P&Bb6mvw_)aWKf8(Uj?UlS~Wz}F8Igp)7jkQ1GX9FH5 zG|UFDpwyI>lHH4T1A5)6-=+ zakg^lIFF1GvXB6ltn_`OlvHpTzLt595iQGjnBR+e7q173E*pc*?$y;G)sJq9u2`1oekZ*N;G^KJ0~< z35W_1G%>=X1W7Rg{V9n4h@Um?lG(=UDPD8%0ERj>!iN|f@;!p2OdA$uke04{xbD-! znuNG6@EzaS(o;su%Jv~}iPZbr5KMy@Am)zJ>4RhztPXD2sSnugBt)(R?DY?hN;Ia7=%AeBd zy8chqLr7-uq2gQ^XX9IV2vnGK3v4Sxn7{uCMM&Ry?s520a*(->n!khzZv)P4r?0QC zgCvo@)%qumH*f=F6t!1xfQZMI?D8C|Pd$plEu6-`EHv_B+Qo8u__Jdf2XpZLo$lr~GQ}{B`wkrG zo0)P$U}qXJ{SG3!37v}M*k3-hPs?jdK_p2zy)!CJa!@S{rxGyZMJZHXIM;~-^*Izv z5iS#k3Q@Pe4Pt32hTYv?41RAscLKSA32mI%KJ8KJR(1d0M9)@Y=T!E^DP`;^IPBS= zQ2>Pk0A^q)e2XNAP#ChIp-XD!1={1OR*TYVvuuU)e`busj*!lOC%ohT-UH@uNn2*f%R={OTKD90Mm;xyzdblr#NaqaRbV3@49@fP< zZ)rC;H#h6tTm<30?zKHY2*z71D_P{tY8!&|2JZTut@NL*dhvbM#9*tWWDm%Q3s1aw z&7Tday6}9KNisbiM;bsAgkAHpy1z9@Hd8nC&Be7wX;bBg82+ zU9zm5M`T1_h1qTzrhjEONTX{KsF0n|*75Mz2c=;c3KL(^33)(4(WOiI2TDYc5T{hd zWY4lxp?bxgRjF@t-zZcM@*gBRfZRCRel}yZ#MC?&85u{QTox*BAw=to#&v>1*6@l{ z8QKT~lwQlfGr>q@S)l+oH+OuJn3!0bDiu{IWZg{e--jXy5NRzeiFcIcUmBmt0~LuR z*RJAJXwwBs#5E1Kl8Em90AjYM3MiznZw-2gCSIXTC?}$nR6fCjg06;ob5F7CKb%#Q z_vpy6;M(PG;AcY41)e4bM@ZC>X}etkC1Pf{!n0Eg6rW-!Zi|py7%b`T?BqXxeiSh6 zy34B5RJ5b{9vV=I!z24Up|!ZfcTi`}ySQq_^#7tvHUZ-X)AjUnIr;qD+)a6?@dGKR z*lM^u;dX%eN#b+}?xPFenww9sw;_p!eII9G9w;Wo|6TU2rG+Z4KTD_NB%Pq!?o!>h zUiG<8YC-)C4KmvDa&i%lsQ5oiw1H7xFnw*}webuLwB# z{F*PRHkxFiX|$}Am9Gw zfn_2f-y##f42S=JQs_?jhcozU+X-qXMwESatRCW1?96h1fb`ns;`?j9pkw-_Om~f1 zSRFm`4w4Lb$nKSZ82e4gfrC&s(8x-jVEe10s@et1Sfm!xWUR9n2f&h)i&bH4_S*8#mkdxIJ*IQAecB!p>yUA~k5p_2($g_8=(P~bG_p{a)L_FnTJ5n8%rq=J za2^^N<$~^ts8|a)r4I9&HkF_de66a2wve7=g;-x-Ul)s>@2~T4pl;ATR_~_=x5!IE zq*6FQ1bqoI@r5!dzxnK*9l!^%VoeQ=o+PzZotVI_=bBG5NrJ;RJPOM6)s%(#ngq=JhNvPml9b3ecYDs=!aTc z*kh22L6FVK*C}^%E^(L_w_;;qc{6n1+}s7q!Kas@Mg^F^J>>tqy}hAQrE?|l91f7x zB+5#pdUw6dfQu{pAjZ;<($F+x7+*_E3(>6&7lm9_e}S9efB6Eg1_2D?uc2578EcX4j{_ z7g!zDUl5F9POf*hO^ad%ldy})_!`BWIVB9*m4@XpudiKQYP&7Y0_iIsKIFx`6{zZh z0wLJ`|J%!CosergQ4j4zh$;lUyR^YTFuJ*~Z~HrQ>_bR*LbNe9HnwI}-_qiFu(#1) zV8tc!l{wZ;NlEE^opaYjE(pNgyA+luPo6v|Bi|i@@}B#wW^~65EiHA|+@KCT(^FYm zx*no~Tgr(0wf-rduetZWS@|q4bVGpn-hL}u+t-)&+ZZ?V$^ zFy;DAG=vsdbj!!GjoO^2M{O6(v>ZH%O3U+ZjJl@mDYDH#d0NlQ`(4413mYF_M{jQt zkQ$i~cIUfOAYg9=dhU)v$m-+c6B84|#Kd&4J0+S<@KN^Cb?-A+_V6>p|URppQ?^r%&b}`d{rAEiD<+dwfk{iMoqiofAI~Zpf<&b9Ka;s;C4N(*DZL9Fk_GkA#Gv z5Ok>M;BG>7R-o{*w}wuQjy>p&qry5mItEbe${9PI{=!3&Q%|ZUMjx`AZN`~u{bjBj{1#m*LMBl6M9w7pLywNz z@HyYD!iK@MCsC&PQ{IsK6t(~LT7-j1E<%NbtCR#Y;% zP9e-O6hp9-mn~#x&$2h)d-yg@M83KVSQCRMbh*_Ko^J3x8=SF|>WiW*(XtU4J!fua zc27->Y0&b~BMyNi)!3VUyd+1DI*(kUKyrx9_ZHszn$nKmPvbNP)gZ3NNmVGrv?a!H zDO0e4TG;9L;9}N>I$cX{+UV#gl(|BZQ!SQq)CQ@;14HuMo=$dlcD5a0o^^^bBt7*K zGH$a_I813pA=Du1wt40G+lcURAG#0w=6gYTuW)wzEV5PI-*T*%jDBA&a}US2ULn>e zH5!$Nb{)Ar4uEpX9TFRZ&NS80SGsHZHr>N8&ffJh*G+aPBI`xt;H3>2nwn0{&a%CI zINz5)%CZZS8c(@DsPGv2^&m@0N=gcS5!0;+bD>R#T1H$B`cLK%=T2PfI7mtRn@*p=CTxca`qPrzii zw=#PqV?^9F2MDV**%z`#o&9^xi>9ocCiKoMBGQCH;p4}TlTx(BR;CxY3`t1g;o;RR zsa8DE6up#bgo+Fc%g`;;^z8ipUFxj1uC52k##!7##qG&RtA$lUCcpz)dDQTp@WGrZ zsiV!(#KVEYC3!+`og}9SE=j4yOh&NH(LvzXi$REnHSn-sOfPlbfu+b45VdzE_dqyzmZqF%FhK7}cgF-@lSKjEpx2d@OV`E9! z&(9Bb`5O4FlG4@5?4Z@5$=3lE_+*jNB4Q+@Lk`gyZKZGM+gaJtZeP<-YwqJcznPaH(yB)X^FYHyVtl%xn6+KWjpjHL{;j-4;FV8?Xq{AeH|*GmM8wh_M%d^ zgj9{C{=z^J#&Ds1M^o>)v4KHc1#8TC6?am#Ovmn>EP$d6tpa(zC1@CQ+`4OKW)^=0 zSdIsJDmA(FfvlVy6}!gWmbG2wWL7l}8z#ps&g_g!nKCFY-O`@MMp@6tpc1O;Jzq-} zgc?OT78aJ#qRdrtp}2x+PfJN*+%>Iu1k8!wtu_S%6;R#b{s3KcM+gXfPeXM2X0h(I z`5yc9^z^83x(E3`=gx@<&p=N=TKP^muPGQO6*V=>5E45|(mUUL7zQp*N1mUXyS2Gl zeq7Ji_EU;E#M3od;uY&Yg!5tCMqj^vh3p7izYP6u3^BaSKv(YAX+@1t9egWoP?%Mt|X zMq3`Fl9{o$wkK$}?I>?*L))aXaB9Z(!ui0LC+S#+_F5$w=y>jb0~|}EyW5f+5fQ;k zR$w>P93O*p^OCftdGf8+2GDx$^bga6iVD8gZEvl6dGGuyQDKE8&nByLet0u+AO56Y zyg75!p=bR^i$L{tHBbLP{ZQOc_>i&Xch$VCWXRFeDF&LSI*jZ9Rn9^x6P*E|nPA@FzuF=ire&A=IX`A*r zs7Y13E-Nfs-F-ghzWUCsv-uw3NOSmMWBC6xg%jyR4>}6dW1b?qb}-cr@hh-P=q&&7 z8uuy}mlbqOfXwW<`SWE{V`JL>pdJV^5NtO`UddKYmPZ;O7fKeTWn@IRe_b?AHuU6gzn`F@vHj!@@*<}I%M+n&43u158j=rM?o!!uI zn4?8Oid30ES35jrrA4%xp%?OOpvlXG-pcSrmA5nKw=_3XM(Qu&SPhj*P2k|3VMJSC zA$5Oq3^`aD8XC}>+*3M3LXIPBH6*h2u+ER!NHx- zXS%75y9rG}fg;-vpzYb7|MKOJ;L`HK<@0X(BKdD>tH?zd`pZ-6_pawkv literal 0 HcmV?d00001 diff --git a/contrib/plotting-visualization/images/line-ticks.png b/contrib/plotting-visualization/images/line-ticks.png new file mode 100644 index 0000000000000000000000000000000000000000..3a6ed78a9cf36240301a6af7480127eb39f0648d GIT binary patch literal 22354 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 WZ(;p)9Po=>m(HvHD^2mX_x}fm*rQ7T literal 0 HcmV?d00001 diff --git a/contrib/plotting-visualization/images/line-with-text-scale.png b/contrib/plotting-visualization/images/line-with-text-scale.png new file mode 100644 index 0000000000000000000000000000000000000000..e402a3e527ea9938cc4b8f9ea4ddd2f18d372a9e GIT binary patch literal 19249 zcmb7s1yojRw=M{X2!cq5unj^wq)P=vq@^3Aq&uV)0STo=X^?KEq!B@+MY@&lZusC% z%6;yC&b?!tJ@y{%Z@JdH-k9^5`7A$KX|XGpNiQQIAzcxFB=Q6a3FRLoB;<`t7vRd{ zn&oetaD_&;ifB&Az(#DASsv!{xye(K<6!|ucUt)8I zy;t_WJRX&!60R)1zL=r7gdGE=y|NEa82w{MKpZ(we zM8<>xPTqU+EON6f1qDScpQBP5jpX~EC6=Q$Y^e34#IR4ImsKn*EN+RtRY-H$TFB@& zX>PoV@1X~e`xgy~@MVxq9`#5L(yUaIM450}k30|SG}nHg^PgPnr|SA_hML+|j2 zium*A&wG!;KYaKQ92^`GVSgP7>EQZjm!_q>&e=@onzhx{5R6n9-`(Ba+S(cy7k6uG zOFm8djh|o0Y%=`Ma`jQw-jAfDn>^YVZ+-B0SRTFfQ zaIjpf(wVJcVq)S)xx>5B27BuGY&~YgEErz&xIzEa8!OqN0mzS0nJ?nT7 zyS1`1(~}d;D`3<{uB@zV@4Prr#I~ewWE82f5WrkT8<}0b`<=|P@c4B3H@oEZz6W-+ zNB)uY5whR2a2y_gGwg!dQ))ZiHTD|^7l}ZjFHuvhh*{&PqG$8_!w<|+yX_RjWcDw0 zzX~TTRWvm?nVOmcLE3XMcpGw~@%#6OBL-$>{EkZ+ zn|ElWV`wQVE@G3XOK&fa9(@cFe3FJkDQKpze_Ob_HJU3nCPpboO>wO?T_V8WpDxbd z2Zxg4`gKM)^ML8vV)Mbw=#0me^COlEBl>PXrkgza^RNBaGwvweH%n|gWc=P#6Z1qJIRqwZPK`+Ivm8S*qsc}yB#{#h=wnS4B4W^Zt>zuYko z>t0Am2!~16%KG~H>MAQM>mB!JuFdZl1q1}TXAN7Ua--j$c{9JAGrQ~zR>SW;5rS~?~}!lF|Xd_%a)+$?3pewpi`HB!3kn9N0=*4Z49 ztPCYlP04yZ>JqJGx}$wV{d+aeeaI4rhuvAqI2agmmP;d*>OK)qf}Vu(h#TgCByOfg zMn;kgekgNT=#x9BN!2WOXxs($4e8{v7z)P3!NlxjPIlYhqVzcUNFnp8`#}O_QJ?6_Ng4xvpY$ew=|3<5@X&~IRaRA1WgBr@YoxKMs;>6P zQp(vtR~}x>b*W(WN4b}R>oOMX?wcU3=ccPeugNIUk)L>Q6#Eq!c|HVO6R2#Wlg;!J5P`E+l-S>kCA){qmGK4+y`cm>+6&Wu_!& zagFMi=0a&Q0ti-!^?WLF3 z@X!z`mqkoS$bB%DDZ2A^Y1sQBt*%;cl+Z|{gS}DO>thwJMRt|f^$6mz?&J%1Gxw1bEup{2QuiP>$Z zSn46gp*Q>~FW3|90->kPXd33_w@07Zz9Pgq)Fw?9UcL)_#J9a4l8u2;`~BgrZoJNJ zSadXfSVN9_3Eg(y9gq9FrgPPFVl@|#G4DN(jE^L%FkdY-X6$}uFF$@Y|EZbtK&jBu zNdEnf8>duK4iE4(D3)(Y-C}ZNnz8k9vl^fYEQSsUL5s6 zk^Ebugl&p}e`Il5s8NkT$zcy87x|mJMj2A(g^Q-6$ibqV88)CqN5|=D1nH~?1 z_1RUIix?;Of^lA&d}<^4GZeSv?v_a*FISGiO8dI4Y5hw0j4{L7f z;KB=#td#xa?%%*1x_p<@q|iTh5}b_{LN8cO6yI$I0e~7B>(^huK7+a3-&(wN zI=iN#!QJPHRn6mRCHu>Y7E@IuE@MA6_yl_rM!gR#v!1oW}iV;(j71dIb3S-(Kf?7am@y*MKc1*3e&IlobT1qVnl!eTID6 zQ$0O{6*ev|8FBF&XD|Lprb_ZcNJ^rUQ}LtX+f)nK(G0(i6rsH}gVk29CK1EbFV&dc z9}g}vka!&qDX4ABU3_|ToBuI%RO;IQ=y15d5k47>uyWi~dpJ@A)KrNMJ;%&hOl z`1;;lkgkliCBZ`F@3uU2!n97mylSOf#=f$mok^mL`Jt%UVwC~;q5*_?6>Ck0i2ccO ze}Df_0Sh<>WMt&;-@mgPwp_Y$B?7~2Z)28CIwOdZ$40+1RjR~%&|z(&5q29a{NHzV%m363r}F21Yzit{z3EGw)s!QW~RAgne}*3*lTPG1{)jV?@f656d75{ zc}=MfJ1e@IQvj1)o*b4V{2!7wa9oZM+ndN);F7ReW_0%V_uB{}2f+9jR%j9K2@(6E z=IjXX55k04uY>rvs^gy@e0esap`zxGBcxA^p2l~CU0 z<>mSLHGY3XHarYhGXyF?FG5CnqNpX}fmR)+Pb0OT1%v{>Pi>RLwno%bzFY zv#fbK)@4U-xS)g$YeuZ+PwS8NuD8b%y&=6*j;5)}<422}b?qPul>uS^;@kUsMF~=I zcb0OxG*UWMeA}HTC%)z!jo-@}bKes$%}j6)=Cji*Ric*F z%G+k_m*;q(fZLm^fu+JnWj`>!SNQ_BK+B*1H-c;H;v5<}rkL1d@K!7ziOS!x31YAC zUH$w!mj6vGX%1V_l?#zURl!#`|7rd;8;;2t{rb$drSM9z==T0_O(+|iNW&+i)~LR{yV`mUWtyQzmCjEa z%*!HqT1`G#G;vp_+gRI96!=60Ghf+$!hO*!rrpV#QJQ&A505i#yHR+MVghN4FNWvV zT#w?fZuWL7^ZOTiKH8M5=W`kV(*INIokHUyB(o`filYauggg7xS)d#n(b-JKu_!&R z)>IrBW?DLfoVxnSuIfL(d38{qfDy!t5gKE&!8KINM#l45rJ1rk)3wci_Bru~m^$^^ z<>l+gg93iaUW_?8lNX+73Tiz4syEcD{Z?m^NA)98%?b1O)(dT|4R+bmWCHd!>kkoF z+{jr6sM$Ck%H3#A7xeFw7ku)_%PY_U0X<-UNoq zB#q9o9t?f424@%Im9RkhQMc__(){e~Y<>ZO_BerZr&WMqJs}|>x0+Bnv&p82H71fD z6PjziXON6PYdn3S*En=oGr)tD<+pF+tnnR#qo=#OWA#K4e zNwFvjr3UZcG81_oCf_M!20B>jy!i_~8#Hfrd2Xn5eWv5%=~84<2!`5lMoa$GEohZ+ z6r1FhrF_CsU6Jnkq-n5HU-Kj-m2MO-d^S^CXceatmF|8`Xd@p(_D1~1#^@3CBjr>@ zR#r#1eCMQrSE#sTF7e3omD?koqZ_B5Jp)5Ha`W)8rqEHeW!3YAPYoN$rU2)A?OGNIMHi9wOCWeWw4QrLM>|atoMBgd=!ZDM!qxe)$fCxdoLCy1Po{D_ z$^!hSHS?C6^JcKI84F=`BEE%XgunIWi6rq+4i6h&p(a5ywfSCLeCj4vKk`0gp`CuJ&1R3JF% z(arz_P2th*^HSJK^7vlm?{^T?^dtrPeS1dL1WsIng0($LD(Xk8-prn72Zq!;;ddFWx_QgX9`zgr>3nX+G6}A!{9fw- zCv#83UUcxbRlmp6Z#YC5z5)W*{QQ#i0Gl1SxK^i2^O4UVYbvs}rU4|9J9x?2TeSI- z2pizCWF;j2@OMFbxL0lzr=oNdq@PYLmTa4*J2{c1xq zkJCI*z_fWVf;GUlJrEHvIbTVLe~F!4?xRm%p&x-Sy2I+2D7gJ)_VgvcLaM`~awqb{ zai{=bJ;frj$_NiXWKGBvicQyCVb4vbjwmmQ4!Mz(6po=iDwLas$)66PF^8Vw(={Rn zy46;k3xtXz8Ggsx z%(}Y%_W2;kUapX=k)l@g7#tO9saGXj^SBAV*Yatxe|MAzTT!nxWUx}m%nK`eH!6;8 zhrKQ~%OGzTv`hcdW@vt4L-qn;Ju*L=D6i()hjC=ns@L%&(v+EYr1R|TaTo`U2ypxB zcQ}%gMCN;HyA(=o*pZxRkpsq%C@?g2b?s&jJqh&MrA$>1_%YL}mIw=tm7Gm%>UX8= zp6*!bKE0`-SwGvEt?EhfxF(6))0a_*c^iC*`vJb1J%Xw2io2wPm*8|pFq?;;6CS1& z-d*j}YqI!C$k@kt>8CJ;3O@RZ?C_5!?kZEMnS+u%)A?Cj#p3U)I~7%l)vh$lIl{%rx%y?K>^_QEXO9FY#|B^y+@=3jAXfEVDLyOLgba;&uln_9@x(lkM-c2G8eQaXyBc1Np zfv}D3=UWF{=!_KaQq7&GBawTh#d*lI#NFHTS#{jWs{LQRIm#qcN-|EHtoC zdu&EP`Zj{z`_rd%Elr;M>t}EAkQgZa5}Y$i9=~t+uK4geSr)i-g7$rBwei>+Ut8iB zO?nBDkrgi816`9NuW@T^Z1Z0kCI7N9+PIWkFWhZ!j>s>y{83>KDnf8Q>OFBsWx1@3 zx0-5DKl<5r(R-tzefr~z;{KkTqrh|(vll;88%2XdkoTG8*Tn-mfrq|0n0$N&CBF|5 z_*kd!xi{-?SB8lp2WRQix)_#WF6*k-EoxqnASztD_j`trwM5BD-8eSrt{6RT;nHl{QMfB?HtJ*Kocih#mH^;K7FQF z9QACD%}<*vNUJP`fB(X{HXP4Dk-5fEoMz;Jp|UOts+U=Xp07a0Njv@2%Id1bI~L-z z%^T}!C8NPH$J}vPPz`!p-+qD4*lM=15=JgdeKy&Y=5`|Hij@ZA++V+laZbfl z)_!tIKc07t?8{nbCwp9TZ`U1)%r+@gl0v7xRZUYiCT*RBL*ErEUA>RVSrh`{$!Fp% zJNckHCt6O-14D)5aHECE@l~dT+H^1)%7bENaXzAkd&7BG$im0_-vrjxdShKY-O2O^ z;DAeC-;yg{iKx+=#f;yVC=RaiM|J#Hyy?xIUYr!Ekh4XG>)H|v}&?{dbYG(I9S+|R@G&pLud zwrT7=1QO=TirpdByHI_^HrJOs6l3NyA0H9R$ZIFdsUfiX>c=3>9BKGv0)h>VAyd)xehX$8}_0QnTQ@KpgXfAUW=ZP}u zeg!63bzslYEVV4z9y@yfA!Mys6A!_E!Royg7K>=u%ES@8+SnL~etPn>+G{qp`f8Vl zSlI0j2dUbVgR?AB)i~MAwn>>}<+Wn??=Udb)x0OW@NVW2fWTemEF(QAM-z7b8u)vJ>8L-k57_2Q>Y(Ojuz2DG9~>( zyOAmR@*{=b!Yj87E6E|;`7!F=CMly=*ObvB*^wDx!@vLg>)7`z=OVzrAQIugv{W}@ zk39M&U}HgUjm!fwX4T6(`|YdRN;ZU>{x_%}^6w_IuwDD+v?}HN}-R#1HD{n<2 z@;<%UbfSBH5Jo@gLghY!qoh`N6&LqhPIu7py1ieq>z4PTy6%TaDkvAd zS$d=Zr?E3@?nQ)sdEoB6S>M-+A@Ykk4<5@9F)@K*?a7I-#J+GUuHlKbFJDf~ zaInCM`2j3<{G22H-NwTxz|j!*eKaNSi&&Dgl<&Ok~mUxenXvjIHq!4gv>K zixFMPaCF!jd{kf^QMYL%;zkN&^||@{@y%M-zA(at*c)q5D;EV#Q8lw9Qw%}_hHoxwEK7bbo>=Qt9k0Qx7okq zDgP{FgNtR8{KYLT-!cX(}<_JJShj95>7?C`qCrxk`oCO<*4O zsGSHU@(ou15&@C*?d={Ze^kfN8~d@2uReX6`FX$2n$i4Nbst3Bc`G#56}Nnx6mT6; z_e;4hn6k7S5VtD%b1dS#L8v7(!X2>q8==!^p1_ zE|myc#ZrSomuYuevWQMyX1v!_Z4En#bYgKb7no6146d)b8z}=Xlf@Z}#S+ ztEa09D7;rCk;rv~H-q=(g=ouHAtB&9Iyti)%Nc4m8|~YKjM&aXsbz=XrOpexA4uAL z7@TNyHm4!u|513$K%=TgP*8!6-SCpSIxa=qqm#XCO6R6l&A31J?z>>)Fo$ao{e6jt zsD~32aLlukGda;*#Iy=(xVTB`T#4?g5!ECo;i`cOIXWlPYwZ4p7t`rB2M4c;iar~y z%*b6tK|0O^S|j;1wh~xYLAZ6;M1S*+AMDtPzv`*Wq;Zu|jds>#{9c_CAqMnFyqK&OB8IR5F`WKI%wUWve zq=HLaRdpuki8j{Os#UH$@RyTK1RaGLHb0@tcaz5VRD>g#Xlc_WBAKAzZ$4NoU^f%2 zp_nEe8@fJO4e6cFpFi8!*^vvmySlqq9o}&)pWj&>hx&CyfJtv|tVVW7h@6g&PNQ;5 zb94D&+WK@mUcRg@xFq1ae*gY-u6(MbUr1yejubhRSbpuC*?qwf3W%OjOG z?pj)Lyh6~01U!BY`mmqTwI*DxA$J! z&|)rB7dg!OWZRZ|at4#d!Mo9b6DJ)jMRqR zDPv=M6&40w=ojmxKEF|<<0IQ6!@kZ770cM*;H%{13sX})U#!Qm`gLfr6{KFg01IH! zgO7t~#{xJ|%JeLPwxCq0XsG)&KI3>=_Zrkdjy&D}@@0|bk=h@R`1i9PNgMK?pdCKC z&iewR2vbhwENWgy!;*haon|DgV!I3*-LG@q^@YZ8MrY}ZmjMCkn(91vP|npkIGvW& zGL9`I}@Gg(|vdPj4PptRVfpxVB#Zp0%k2t=xg2o=Fn>41D;53-3aM z#G3h6@i383^ms^TID@0#%QUHhWj}vtJwtFl#%~+j`t^2tvRvnlt3hK5WoOWvuJJ(F zyQm0K%I>N>ntbPzyDB3yiIw#5VQq83*RwnCslMlw;+dhN_6hk5+ZRxvs%6J(poSni zgEJ>9K1Y9m;$}=AA22{CsO{y6_D$a?08HguBad~dkf95ZX0xAQsVdFJeLy!P9r-lA01pcG*_2(R}`5>fVoVV~ldSsHw-&;z8$*lT@_W;ocMa2GhTH*Fh$aok)Citnp=LGjq{< zNVkwdFJ;MTG3R?RB_t-l&}(Z0P+d|<;MRG+VfSY)liZF&|Fz8nIq1VYe$HmE(CNUM zO4IFt6~Y04Tv}}6g>N_!ZZC7x1A?!@v!@2jr_@#Tu6d@}m$?DOp^8SQvooq;85x1} zp}6ubG1#S3E6CE<@$qpX8y8Wz1MA;wk`KRA5>=A$DSfzjb~acxJNfBy!dR4GsZS5Q zMu#_6rC9R)2fw{d?|8~_{r(arz9J24T&UQ)8oDE{9U1xnM5 zxU2gqUFY-PaRT%_o4&ZD0(MEJk`(`T%#U^>{xgHC^IkCvoM~_~Tz9Fw&fn){U_?Kg zsl+&GmV|UF_MZ2j>eYW>Z>n1wKCv!mS9RZ#%SqoHNXLa;KTRKcfh%R)89w|{M)1yq z2VmY#tu^t~n!%sn39jl^ziv|*BcDy`B9D{o-Dm$~XV(RifP$TxN35`TX6FrA>AIhl z<&UHc{+;QMN4ln23xo?jZ-!s~-RT$}Q0CnaTtQ#YW_nN6%7M^+?zMaxF~<4JsTm~u z9jFZSp~QH8X`xr!yR?*rgGvqgeD6z3pVnQPblQs4+8bx%J{zvai_cM-o0o3ZWX~?K z6a0d+BW{7#o39I-^8u61B*%zzoRub~rV-=c4FCLRZnHN+c;N4rkPFZ;FoI@GMK2JZ z1>~MzQ>7Ji-SwW{?8(+;IXetl!c<8)rjeMKmcIhQa(FmaI^B2U(&_fTVEb$k05*fe z#A=i5{H+Y^@)avD0V_R`p-T1diSxK9-8D;3rhoJB#GyH#cnnXH5@Sb2X| z=4ugu+eVhVw}H!L!Se4a+hS{5B*m4#`L08P_-vJCZR95|jrkzxCg`PM^73qI?W7J10_cbbxq{hxI`>Sx>mXOt^)^;~9k-4Ep6zXxaZ!0E3V zUmUE~_EX|8z3k!f_nJ>fJomH>X7BsXZWoBJ7hB7-`D3G7e9+lzS zX%XB36S{tHGoE3=)qJeaPM=uVp5!ue>s>rk%}Xj5n_CoqMZ9@)2~+P>Y%ajSY0`f0 zi4AJoWhSQCPltWsY4F}{KfF_ehmZZ*iOjwjV^MLhde1G#GnT0*hD&mWU}*l|Sf<-C z)zv2lUv{Pi)IK0lW4vsI>Ej3DO0f>%)6$|g$ zO_N@wU)`p8ca*I!g0Y5C|LIHxXPk^Iz@Yi~=@Z8}+#9MmUS6-?7~DoWJ!jqbAI0ip zc%VOsx*Y9HVRTt2DRoWgT3SoZ*v~Wr>s>74h?_D`T&1IB$on7g-V;>&#sWQOZPMb( z>r;?&x{PwBoIa{0(mX`MA0Li2P~O2fdp9vPyL_SXN3$=^`{p4Lq5^-1aCfh*eITyv zb#WEY;dGwF3sAm$rg%~cV>>h6Vyf@&it_|LGoj-^I+OZu3j&*?YC0QiQ4I{t}8Olc07LrHQnQ`thD4T)dH3Av&UHgxl^U&+v9hcB6@U9RrP>dVk$Z3uaUG_qZ}nX z*wG7#Y~V#Z1!-U1mtLY?7n7Xr|NQwnfO>url*B2Yg%vlJFJR`G64m+P;ZZV^Ux(H> z%Sx)Xb=9Erfm{3uYWr0B8M*E0Os}3#Vz5-c-^##%>g7unxAPk%)dnc>#v1}+$a}7z zk2yXLm8dWI|D649dZ3&5o>f>}xvlNy-EhT==c}x%d(CSP3C2`OTr{+7pj({C;fbG- zMbpw!x6q$`=lmkIkha}&Zp`aMqxK_;LF}{3{0S$O0kAurVmwID%zxqrvi#`P1{W;w zIQ5?mZS1GRF02_)srC2!rPC^1IiD!###6lr3=a?RXwGKkwb++v_Ql3p*Zy1xb$EEj z#)BXW67M3-Gf8l+9Ko+pC!<=svjR$Oy`>w<&Lq)Sx7d=XxVTAmKsi?*;Nnab`umeK zp{k=ZS~WJnp@e+?e%qCVbX9qAWy@+te}7_+^Qlf9OSr+)o9;U=LeNjoPfXRy=85~0 zC&UitH+^rHY5DL`Qr~dxU)3-he`pY&kV4gQ`TWS5f5^Vo&r_0u8uk-;5|i_Xsd?2@ z)ahqUW}p0*mAmcde3r>KmjAQZdg-rxM>5m*n&m1^w&xepxnPti5Zi^?95l8{2&?NkewU_SS>$SD7Vq-&dD=LWZoeYZh z&0jbT503_FDp2L%b_(t|4FF(>&@j*iXngwfO;n3Q82#jwbyTdgRX>uqGj(S#`{Z%Zi*g=Z^CO5Trv-l(zG13iJsz?;a;0I_9$Ss{ElD-myDR+XK3_=Hy*n zT_;FG?>Du#%Zy}=Ec6#lLnq}#0V#*c?XaHtylM(kQo4eu*x2EhXqa6zgaiaqvAmnm z{NC8uSnjx-t6sA7*`T?rT)(!UxR`14`qbp4=22MGx7@+L*RL-L(j6a9lX1OP&2(FA)<}1?$5D{rUV4|KN)usrrULo#+UT@uoS`eL3bCb*XocoX zxvXwy7nfd$WYV;rPdP%;gP2YKHSZ$uU=HrAO*xLbrBxp@aD*&8b1iOs%DnGad22^C*_zWvgioSZ;0 zHWXkvOioT_u;bz384wQ?7zLF%LlP<1!{3?x?p=kWN2N88+1X5WeXk+CwH%2SzMBE8 zBvDb(IZfy)UJIGaZ6xEe_~HG^+gt8*J+3vpt~>dDe&QAuxz6$zZ}Du1i;J^4HL`3p z(!}4seS2qrzr>{5WaejLis0ni=)q$1Fqtmqqw?h{TWf2%G&c~ZTa(qFK7E1|8E{M- zZET*L&?qV-;-_iBj9gNIu4`aEW%w3m6U(#r}e{!zo`%_nE1wROwSLgc|4+H+LYVkUM0%DqXgFn3JK+_jH4ru0q^#W&$8O zKZ8FYlbxhv&+`uF4$Ik%z!*EtWgLToENsGQ;B{tokWb<6n5}ji(*4Jv$6U74nDXy1 zXUW_Dxbfd{|Iv9dhI9tk|My&usd=X%#D5#~e}4P_Jd8gq>1zHx>;Jy+<0Tx^_x^_^ zLK^$Ot>Anv|G9tvWhc;%Uv{>C=L}1P+X5!^TBV}K?qowe>ziHhQ@SMlVtJ<3b z>e&_5m(kIKKSFNZIS~)kY$0x5UWUWA7C?Ch)~zZsAZ z$G^XkPji8+tlf+(LKFCnjB16n_J7oJiU+iD;qd>_Q9ShIu=-u2`^{(8GLFagVQwu@ z9D$@1M8f{PySp3O>3{wD)z{~=G*r5VY*Xc0UDz>8OUvbniDW^l|AB#(#m~t2 z=KSPA3WmD7?V;I{O$hSq*ra!7U@~LdQmViZErirP9K4WwMWB4W%w`pkJ$62D@vMr}x?5=7)xcP6V5eRO~`qG#3X4v=^E_e%u6keRDH2Gjnt3 zaUM49&7GwLGUY&_v3!A{6gs*uG$0RGxv94)#7#7wEEvcLBAhhqjy+uK8 zuUr1Z$S5Uf09Nj}f`K#B_i4N_jAnV&CKFg>%?;7f(Iuw6P!9P433e8i;FDceWV-M! zC@6@Wjl>j0V{B~f=FOW6i;G~0N%8P*2}{ENjCdTmZH9n~*i^NMv)x`CsVs-R2IgVd zy5kwKG<9cV(6U;*fXq z90pC{J3CGw2;jC5R69vq*E4UqE)DVQK480`1$NKFw+xwzo<6|Sz8bXr%t07&-JOi& zAboSFMWP)O8!O>Lq_8+R8s++qH`@{owidgavwtr9TwF{ygnBcNH8`0RmM~T8OgoZ9Gc2EEbt{1o8{D{Y;|08QZ*!ieAb=Oho(#V2CyY_H zJ;0@z~K(mBd+I~C}P6A7-yU~`7$TAd$WeL zfq~Gf?h_v$Ujb3IA^1{Ck+QD5G&Bu$brU}mg#qNup{^yJM!$Kb@V~%Ci17jibD9=< z+0NG;Xx)cB(m!HFNA)DQtVFAlIC)d2F(eZ_+eeRHJKJtA4YM_bJF|oZO0l^R00Drj zvZ7+*UNf=X`1dQNub_>Ur(mZr^FR2WC~HN4#a&YJW80?uKmytVm$YoKxpDS7p98+o z7*yLd*K(n-BTMc&@bxkpto|pc$|YZRx$z8wvrnhq)yq&hr+Q|FE#gJ}d)VY7Qm> z!PYJVRANgXUYtzs>QaEFZdSeT$8OHv9_O>4_j1Uh5-Py-zShU+1> zouZYM6|5iB6J)p>*o#1b%2>DO9R@o#DG6%2I^NLi`Z3N$lPM8w(_YGKnj*bYHVX$w zgzBP&r4GQr+7+{r3e_nZ35n+WUKcf?1_?V4-SnCuBS1Ybx1Z;Pu6p2`?e7{GtbvPL zzfMVaSBdsm9`YYF8`tcmHD*(f2&R^~aw8OKh6fXZ z>n-fnhkIFvxqP`g4kehee-d~1=JOy(QUPu)ILlD;8rs4eRIJchK&xn)p5TB29PM;LNMUA^T&6tP&&;Nh#QT~>cfldE;NX8uY5Dmz zgwgH z(37V<+TXuB>^LeVF0OmKIq1t5?ozeQ=v4nOdTZcL?M0KmnS$^odng{-3%pRX!DnfF z`2~2~?rnTP0UIxkdCy~O2;N12(3ew-ruT@_4_)Otcy6D?W#af%g^a*S6a#0`daN#6 zwO}G%X>T6y_n${nQW2CT5X2#3+J%lP0976NB?Wb$61`SE>xGW9HQSlyus8s&PW5&g z0l`h3);NK|o*t!Yc_%;*^z`z4I=Xg-UUE@mY@rz!n6hCN(AhZU0bhxu6EED)I z3Du=`vrhn3nh+Q{Hpr%9b$;DTH+gxZJQW+2W=1uy0}C-Sb|0upkS>n4bLKQpJB_EfO6R7!p_ca5UN#VLI7_KB<08y52K!=Vuog0=;4`@0VuGx^*S;Jv|xOrm`0Odev8zS9czg?lD-JpY+ z3?p4)z)1Ib?}L^mB*r6BY)nkDyU&6bTA^{|Fg{+1-*wGHVY6C^B%hE$~PmfK?j5655 zlCE-pj|Y=`q4NqCGiGL< zyE{7M4y#82(%|2@$Y3b>mw#z7g3qeBFIR4Jcg%dWFX_H<v1{2V{AB{AZrRA; z8F(G8Whp5JkU3D!R!QufCGPfxZ#`sLkAH^`7eFHDmv+jAH<4B_rHcI?^kv9V{v#9t zG_SJ5Lh%c^-%?@Z|$hj;$vI z>F{7e5?VGmRS<}zgYkwBDZp1``txW~P)GPS($=b?l2kfWCNCl7U&I-7J z09Iz8`BagFkdlfla7Q?APJtN>&?X@TBaW0QQd4I2rxx75Z{NPb*ANJqwICEACnwLw zQGxIiK9&QSl{M|>%J5YK{gzNJKqPbcT1r@$yv+;f=_o2LmKGQ1@i?r=$yrPi4Ip-f zoCcC2z0PnVd^iG+TJk4)He?^QVwo5i3JVL#LBO2Z85zMnFnRIfg`@f-aK3slb<(@f61q)}*5i)~&HC41 zd@RA^H)ay#3xZX7_=Xh3exc<9`_bWc^|8CAQ{y}x>&OdVc#)O0TAz|4>GfaMKkhE` zq{BTPZ{h%U15!-z`5c43d|e;ZY>;R*H8rrlnOt68UeM4aH-`bGm%q|;@=2!u|Id?; iF8x2h{iGmxgd^N}N8Zri43YpyNaCW>BDoKAUj85VJN%mf literal 0 HcmV?d00001 diff --git a/contrib/plotting-visualization/images/simple_line.png b/contrib/plotting-visualization/images/simple_line.png new file mode 100644 index 0000000000000000000000000000000000000000..3097f469b35e6e8c82b4a6ce62ed07672e335280 GIT binary patch literal 14451 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 Ln;HLTJp2Cuehd}s literal 0 HcmV?d00001 diff --git a/contrib/plotting-visualization/images/two-lines.png b/contrib/plotting-visualization/images/two-lines.png new file mode 100644 index 0000000000000000000000000000000000000000..db2c88584d80d9fdd99c6bd55569abdb49e2449d GIT binary patch literal 18440 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 F{{R8nbqxRj literal 0 HcmV?d00001 From 0c7f4fa07608d91fcd2ef6a6bf47decd5269ebef Mon Sep 17 00:00:00 2001 From: Dishika Vaishkiyar <152963337+Dishika18@users.noreply.github.com> Date: Fri, 31 May 2024 14:26:51 +0530 Subject: [PATCH 07/45] Created matplotlib-line-plot.md --- .../matplotlib-line-plot.md | 268 ++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 contrib/plotting-visualization/matplotlib-line-plot.md diff --git a/contrib/plotting-visualization/matplotlib-line-plot.md b/contrib/plotting-visualization/matplotlib-line-plot.md new file mode 100644 index 0000000..00ddc90 --- /dev/null +++ b/contrib/plotting-visualization/matplotlib-line-plot.md @@ -0,0 +1,268 @@ +# Line Chart in Matplotlib + +A line chart is a simple way to visualize data where we connect individual data points. It helps us to see trends and patterns over time or across categories. +
This type of chart is particularly useful for:
+* Comparing Data: Comparing multiple datasets on the same axes. +* Highlighting Changes: Illustrating changes and patterns in data. +* Visualizing Trends: Showing trends over time or other continuous variables. + +## Prerequisites +Line plots can be created in Python with Matplotlib's ``pyplot`` library. To build a line plot, first import ``Matplotlib``. It is a standard convention to import Matplotlib's pyplot library as ``plt``. +``` +import matplotlib.pyplot as plt + +``` + +## Creating a simple Line Plot + +First import matplotlib and numpy, these are useful for charting. +
You can use the ``plot(x,y)`` method to create a line chart.
+ +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +print(x) +y = 2*x + 1 + +plt.plot(x, y) +plt.show() +``` +When executed, this will show the following line plot: + +![Basic line Chart](contrib/plotting-visualization/images/simple_line.png) + + +## Curved line + +The ``plot()`` method also works for other types of line charts. It doesn’t need to be a straight line, y can have any type of values. +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +y = 2**x + 1 + +plt.plot(x, y) +plt.show() +``` +When executed, this will show the following Curved line plot: + +![Curved line](contrib/plotting-visualization/images/line-curve.png) + + +## Line with Labels + +To know what you are looking at, you need meta data. Labels are a type of meta data. They show what the chart is about. The chart has an ``x label``, ``y label`` and ``title``. +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +y1 = 2*x + 1 +y2 = 2**x + 1 + +plt.figure() +plt.plot(x, y1) + +plt.xlabel("I am x") +plt.ylabel("I am y") +plt.title("With Labels") + +plt.show() +``` +When executed, this will show the following line with labels plot: + +![line with labels](contrib/plotting-visualization/images/line-labels.png) + +## Multiple lines + +More than one line can be in the plot. To add another line, just call the ``plot(x,y)`` function again. In the example below we have two different values for ``y(y1,y2)`` that are plotted onto the chart. + +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +y1 = 2*x + 1 +y2 = 2**x + 1 + +plt.figure(num = 3, figsize=(8, 5)) +plt.plot(x, y2) +plt.plot(x, y1, + color='red', + linewidth=1.0, + linestyle='--' + ) + +plt.show() +``` +When executed, this will show the following Multiple lines plot: + +![multiple lines](contrib/plotting-visualization/images/two-lines.png) + + +## Dotted line + +Lines can be in the form of dots like the image below. Instead of calling ``plot(x,y)`` call the ``scatter(x,y)`` method. The ``scatter(x,y)`` method can also be used to (randomly) plot points onto the chart. + +``` +import matplotlib.pyplot as plt +import numpy as np + +n = 1024 +X = np.random.normal(0, 1, n) +Y = np.random.normal(0, 1, n) +T = np.arctan2(X, Y) + +plt.scatter(np.arange(5), np.arange(5)) + +plt.xticks(()) +plt.yticks(()) + +plt.show() +``` + +When executed, this will show the following Dotted line plot: + +![dotted lines](contrib/plotting-visualization/images/dot-line.png) + +## Line ticks + +You can change the ticks on the plot. Set them on the ``x-axis``, ``y-axis`` or even change their color. The line can be more thick and have an alpha value. + +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +y = 2*x - 1 + +plt.figure(figsize=(12, 8)) +plt.plot(x, y, color='r', linewidth=10.0, alpha=0.5) + +ax = plt.gca() + +ax.spines['right'].set_color('none') +ax.spines['top'].set_color('none') + +ax.xaxis.set_ticks_position('bottom') +ax.yaxis.set_ticks_position('left') + +ax.spines['bottom'].set_position(('data', 0)) +ax.spines['left'].set_position(('data', 0)) + +for label in ax.get_xticklabels() + ax.get_yticklabels(): + label.set_fontsize(12) + label.set_bbox(dict(facecolor='y', edgecolor='None', alpha=0.7)) + +plt.show() +``` + +When executed, this will show the following line ticks plot: + +![line ticks](contrib/plotting-visualization/images/line-ticks.png) + +## Line with asymptote + +An asymptote can be added to the plot. To do that, use ``plt.annotate()``. There’s lso a dotted line in the plot below. You can play around with the code to see how it works. + +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +y1 = 2*x + 1 +y2 = 2**x + 1 + +plt.figure(figsize=(12, 8)) +plt.plot(x, y2) +plt.plot(x, y1, color='red', linewidth=1.0, linestyle='--') + +ax = plt.gca() + +ax.spines['right'].set_color('none') +ax.spines['top'].set_color('none') + +ax.xaxis.set_ticks_position('bottom') +ax.yaxis.set_ticks_position('left') + +ax.spines['bottom'].set_position(('data', 0)) +ax.spines['left'].set_position(('data', 0)) + + +x0 = 1 +y0 = 2*x0 + 1 + +plt.scatter(x0, y0, s = 66, color = 'b') +plt.plot([x0, x0], [y0, 0], 'k-.', lw= 2.5) + +plt.annotate(r'$2x+1=%s$' % + y0, + xy=(x0, y0), + xycoords='data', + + xytext=(+30, -30), + textcoords='offset points', + fontsize=16, + arrowprops=dict(arrowstyle='->',connectionstyle='arc3,rad=.2') + ) + +plt.text(0, 3, + r'$This\ is\ a\ good\ idea.\ \mu\ \sigma_i\ \alpha_t$', + fontdict={'size':16,'color':'r'}) + +plt.show() +``` + +When executed, this will show the following Line with asymptote plot: + +![Line with asymptote](contrib/plotting-visualization/images/line-asymptote.png) + +## Line with text scale + +It doesn’t have to be a numeric scale. The scale can also contain textual words like the example below. In ``plt.yticks()`` we just pass a list with text values. These values are then show against the ``y axis``. + +``` +import matplotlib.pyplot as plt +import numpy as np + +x = np.linspace(-1, 1, 50) +y1 = 2*x + 1 +y2 = 2**x + 1 + +plt.figure(num = 3, figsize=(8, 5)) +plt.plot(x, y2) + +plt.plot(x, y1, + color='red', + linewidth=1.0, + linestyle='--' + ) + +plt.xlim((-1, 2)) +plt.ylim((1, 3)) + +new_ticks = np.linspace(-1, 2, 5) +plt.xticks(new_ticks) +plt.yticks([-2, -1.8, -1, 1.22, 3], + [r'$really\ bad$', r'$bad$', r'$normal$', r'$good$', r'$readly\ good$']) + +ax = plt.gca() +ax.spines['right'].set_color('none') +ax.spines['top'].set_color('none') + +ax.xaxis.set_ticks_position('bottom') +ax.yaxis.set_ticks_position('left') + +ax.spines['bottom'].set_position(('data', 0)) +ax.spines['left'].set_position(('data', 0)) + +plt.show() +``` +When executed, this will show the following Line with text scale plot: + +![Line with text scale](contrib/plotting-visualization/images/line-with-text-scale.png) + + From 310ff8f340c15e0eef66b8b5acc383c586846662 Mon Sep 17 00:00:00 2001 From: Dishika Vaishkiyar <152963337+Dishika18@users.noreply.github.com> Date: Fri, 31 May 2024 14:29:39 +0530 Subject: [PATCH 08/45] Update index.md --- contrib/plotting-visualization/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/plotting-visualization/index.md b/contrib/plotting-visualization/index.md index 32261d6..61dd537 100644 --- a/contrib/plotting-visualization/index.md +++ b/contrib/plotting-visualization/index.md @@ -3,3 +3,4 @@ - [Installing Matplotlib](matplotlib-installation.md) - [Bar Plots in Matplotlib](matplotlib-bar-plots.md) - [Pie Charts in Matplotlib](matplotlib-pie-charts.md) +- [Line Charts in Matplotlib](matplotlib-line-plot.md) From 34d7bc39c9aa7ed30565cded96c14566ed7e9f80 Mon Sep 17 00:00:00 2001 From: Dishika Vaishkiyar <152963337+Dishika18@users.noreply.github.com> Date: Fri, 31 May 2024 14:32:11 +0530 Subject: [PATCH 09/45] Update matplotlib-line-plot.md --- .../matplotlib-line-plot.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contrib/plotting-visualization/matplotlib-line-plot.md b/contrib/plotting-visualization/matplotlib-line-plot.md index 00ddc90..566fdbb 100644 --- a/contrib/plotting-visualization/matplotlib-line-plot.md +++ b/contrib/plotting-visualization/matplotlib-line-plot.md @@ -31,7 +31,7 @@ plt.show() ``` When executed, this will show the following line plot: -![Basic line Chart](contrib/plotting-visualization/images/simple_line.png) +![Basic line Chart](images/simple_line.png) ## Curved line @@ -49,7 +49,7 @@ plt.show() ``` When executed, this will show the following Curved line plot: -![Curved line](contrib/plotting-visualization/images/line-curve.png) +![Curved line](images/line-curve.png) ## Line with Labels @@ -74,7 +74,7 @@ plt.show() ``` When executed, this will show the following line with labels plot: -![line with labels](contrib/plotting-visualization/images/line-labels.png) +![line with labels](images/line-labels.png) ## Multiple lines @@ -100,7 +100,7 @@ plt.show() ``` When executed, this will show the following Multiple lines plot: -![multiple lines](contrib/plotting-visualization/images/two-lines.png) +![multiple lines](images/two-lines.png) ## Dotted line @@ -126,7 +126,7 @@ plt.show() When executed, this will show the following Dotted line plot: -![dotted lines](contrib/plotting-visualization/images/dot-line.png) +![dotted lines](images/dot-line.png) ## Line ticks @@ -162,7 +162,7 @@ plt.show() When executed, this will show the following line ticks plot: -![line ticks](contrib/plotting-visualization/images/line-ticks.png) +![line ticks](images/line-ticks.png) ## Line with asymptote @@ -218,7 +218,7 @@ plt.show() When executed, this will show the following Line with asymptote plot: -![Line with asymptote](contrib/plotting-visualization/images/line-asymptote.png) +![Line with asymptote](images/line-asymptote.png) ## Line with text scale @@ -263,6 +263,6 @@ plt.show() ``` When executed, this will show the following Line with text scale plot: -![Line with text scale](contrib/plotting-visualization/images/line-with-text-scale.png) +![Line with text scale](images/line-with-text-scale.png) From 27dcfba508722dc35a96544e259cd49c9e3a7f9a Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:03:35 +0530 Subject: [PATCH 10/45] Update index.md --- contrib/plotting-visualization/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/plotting-visualization/index.md b/contrib/plotting-visualization/index.md index 32261d6..3f27246 100644 --- a/contrib/plotting-visualization/index.md +++ b/contrib/plotting-visualization/index.md @@ -3,3 +3,4 @@ - [Installing Matplotlib](matplotlib-installation.md) - [Bar Plots in Matplotlib](matplotlib-bar-plots.md) - [Pie Charts in Matplotlib](matplotlib-pie-charts.md) +- [Introduction to Seaborn and Installation](seaborn-intro.md) From 273515a8c22a17fc9af4eefcab30f42d6065a31c Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:04:45 +0530 Subject: [PATCH 11/45] Create seaborn-intro.md --- contrib/plotting-visualization/seaborn-intro.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 contrib/plotting-visualization/seaborn-intro.md diff --git a/contrib/plotting-visualization/seaborn-intro.md b/contrib/plotting-visualization/seaborn-intro.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/contrib/plotting-visualization/seaborn-intro.md @@ -0,0 +1 @@ + From 01552110695fc0d9b39797d983946483d2620a3c Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:12:32 +0530 Subject: [PATCH 12/45] Update seaborn-intro.md --- contrib/plotting-visualization/seaborn-intro.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/plotting-visualization/seaborn-intro.md b/contrib/plotting-visualization/seaborn-intro.md index 8b13789..4e28b6a 100644 --- a/contrib/plotting-visualization/seaborn-intro.md +++ b/contrib/plotting-visualization/seaborn-intro.md @@ -1 +1,4 @@ +Seaborn is a Python data visualization library based on Matplotlib. It provides a high-level interface for drawing attractive and informative statistical graphics. +# Seaborn Installation +Before installing Matplotlib, ensure you have Python installed on your system. You can download and install Python from the [official Python website](https://www.python.org/). From b81223f8e8e19c67078d835d7679e66036356fb4 Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:12:50 +0530 Subject: [PATCH 13/45] Update seaborn-intro.md --- contrib/plotting-visualization/seaborn-intro.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/plotting-visualization/seaborn-intro.md b/contrib/plotting-visualization/seaborn-intro.md index 4e28b6a..8b0d869 100644 --- a/contrib/plotting-visualization/seaborn-intro.md +++ b/contrib/plotting-visualization/seaborn-intro.md @@ -1,4 +1,4 @@ Seaborn is a Python data visualization library based on Matplotlib. It provides a high-level interface for drawing attractive and informative statistical graphics. -# Seaborn Installation +## Seaborn Installation Before installing Matplotlib, ensure you have Python installed on your system. You can download and install Python from the [official Python website](https://www.python.org/). From 32fcb9484e26f9ae38e5d6b82a338190b8e83358 Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:15:06 +0530 Subject: [PATCH 14/45] Update seaborn-intro.md --- contrib/plotting-visualization/seaborn-intro.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/plotting-visualization/seaborn-intro.md b/contrib/plotting-visualization/seaborn-intro.md index 8b0d869..bbbfec8 100644 --- a/contrib/plotting-visualization/seaborn-intro.md +++ b/contrib/plotting-visualization/seaborn-intro.md @@ -2,3 +2,10 @@ Seaborn is a Python data visualization library based on Matplotlib. It provides ## Seaborn Installation Before installing Matplotlib, ensure you have Python installed on your system. You can download and install Python from the [official Python website](https://www.python.org/). +Below are the steps to install and setup seaborn + +1. **Install Seaborn**: Open your terminal or command prompt and run the following command to install Seaborn using `pip`: + +```bash +pip install seaborn +``` From 56467e57bb3ac0b91bde6d504813e44e983a80ab Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:19:06 +0530 Subject: [PATCH 15/45] Update seaborn-intro.md --- .../plotting-visualization/seaborn-intro.md | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/contrib/plotting-visualization/seaborn-intro.md b/contrib/plotting-visualization/seaborn-intro.md index bbbfec8..0375db2 100644 --- a/contrib/plotting-visualization/seaborn-intro.md +++ b/contrib/plotting-visualization/seaborn-intro.md @@ -2,10 +2,26 @@ Seaborn is a Python data visualization library based on Matplotlib. It provides ## Seaborn Installation Before installing Matplotlib, ensure you have Python installed on your system. You can download and install Python from the [official Python website](https://www.python.org/). -Below are the steps to install and setup seaborn -1. **Install Seaborn**: Open your terminal or command prompt and run the following command to install Seaborn using `pip`: +Below are the steps to install and setup Seaborn: + +1. Open your terminal or command prompt and run the following command to install Seaborn using `pip`: ```bash pip install seaborn ``` + +2. The basic invocation of `pip` will install seaborn and, if necessary, its mandatory dependencies. It is possible to include optional dependencies that give access to a few advanced features: +```bash +pip install seaborn[stats] +``` + +3. The library is also included as part of the Anaconda distribution, and it can be installed with `conda`: +```bash +conda install seaborn +``` + +4. As the main Anaconda repository can be slow to add new releases, you may prefer using the conda-forge channel: +```bash +conda install seaborn -c conda-forge +``` From bdab7d9bb5154dc23e2b9b350900a5b148b6d3e1 Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 18:29:50 +0530 Subject: [PATCH 16/45] Update seaborn-intro.md --- contrib/plotting-visualization/seaborn-intro.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/contrib/plotting-visualization/seaborn-intro.md b/contrib/plotting-visualization/seaborn-intro.md index 0375db2..6e0a7d8 100644 --- a/contrib/plotting-visualization/seaborn-intro.md +++ b/contrib/plotting-visualization/seaborn-intro.md @@ -25,3 +25,17 @@ conda install seaborn ```bash conda install seaborn -c conda-forge ``` + +## Dependencies +### Supported Python versions +- Python 3.8+ + +### Mandatory Dependencies + - [numpy](https://numpy.org/) + - [pandas](https://pandas.pydata.org/) + - [matplotlib](https://matplotlib.org/) + +### Optional Dependencies + - [statsmodels](https://www.statsmodels.org/stable/index.html) for advanced regression plots + - [scipy](https://scipy.org/) for clustering matrices and some advanced options + - [fastcluster](https://pypi.org/project/fastcluster/) for faster clustering of large matrices From a8e60cf4b1121311363846e4ca06d0967e4652fb Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 20:29:42 +0530 Subject: [PATCH 17/45] Update index.md --- contrib/plotting-visualization/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/plotting-visualization/index.md b/contrib/plotting-visualization/index.md index 3f27246..96615db 100644 --- a/contrib/plotting-visualization/index.md +++ b/contrib/plotting-visualization/index.md @@ -4,3 +4,4 @@ - [Bar Plots in Matplotlib](matplotlib-bar-plots.md) - [Pie Charts in Matplotlib](matplotlib-pie-charts.md) - [Introduction to Seaborn and Installation](seaborn-intro.md) +- [Getting started with Seaborn](seaborn-basics.md) From 4446a85d1f81f8a18d75f5a29cc9a1733bd800ab Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 20:30:11 +0530 Subject: [PATCH 18/45] Create seaborn-basics.md --- contrib/plotting-visualization/seaborn-basics.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 contrib/plotting-visualization/seaborn-basics.md diff --git a/contrib/plotting-visualization/seaborn-basics.md b/contrib/plotting-visualization/seaborn-basics.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/contrib/plotting-visualization/seaborn-basics.md @@ -0,0 +1 @@ + From 6aecf49fd04b8777365b7173fa47d59c86e5e0aa Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 20:47:43 +0530 Subject: [PATCH 19/45] Update seaborn-basics.md --- .../plotting-visualization/seaborn-basics.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/contrib/plotting-visualization/seaborn-basics.md b/contrib/plotting-visualization/seaborn-basics.md index 8b13789..603f074 100644 --- a/contrib/plotting-visualization/seaborn-basics.md +++ b/contrib/plotting-visualization/seaborn-basics.md @@ -1 +1,19 @@ +Seaborn helps you explore and understand your data. Its plotting functions operate on dataframes and arrays containing whole datasets and internally perform the necessary semantic mapping and statistical aggregation to produce informative plots. Its dataset-oriented, declarative API lets you focus on what the different elements of your plots mean, rather than on the details of how to draw them. +Here’s an example of what seaborn can do: +```Python +# Import seaborn +import seaborn as sns + +# Apply the default theme +sns.set_theme() + +# Load an example dataset +tips = sns.load_dataset("tips") + +# Create a visualization +sns.relplot( + data=tips, + x="total_bill", y="tip", col="time", + hue="smoker", style="smoker", size="size", +) From 03920cd7501a05316e9a143f0dc7d0406e6117c1 Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 20:48:58 +0530 Subject: [PATCH 20/45] Add files via upload --- .../images/seaborn-basics1.png | Bin 0 -> 53821 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 contrib/plotting-visualization/images/seaborn-basics1.png diff --git a/contrib/plotting-visualization/images/seaborn-basics1.png b/contrib/plotting-visualization/images/seaborn-basics1.png new file mode 100644 index 0000000000000000000000000000000000000000..bedcee91b8855491cbc3c50ac7af23bf330dca99 GIT binary patch literal 53821 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
4;gz7aU{XPL0=T|cAUgk!XKT9QnA3dw>U}#EJ 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 z z9G*=FiJ5g?Sj$%cMD`}|TFK7-Xq{M;Xr)9j{8g<5gDYa6-CT6HvZv7b&}B}VrLD|8 zAtN~(KS(kNQ=0@8xOmx6N47S`7^dz99g(1c#SS(nsoD0ra)3p$dIPJ zfOPC~qd0g7_6vy+CF#cwf;bKG*JJl=vfr^nPKmN;=*1zub>=>C)bm1?XsnW_aPmqP# zjT3_HEDEKZ9Cp{iC+g9YHAnkqywJFvF1~%7^*!E~OlFkOp;#6|e^f1L584qcLbcCY z?9aZ$jOU2jLkF1yDvO8eLfNxk(xYm$ph{vqM&&T_Ji8;MfDV7mzBw0_T_J8oQwS=# zN&59l23Gf`3OlsMi1}@KF~y85^CrTJ;($41^Xvl5-;N@OS+r47)-g zmKRLxi4EXaMhuw&D4D`#nUTKsdk7^Yi+f*m>u6oEuecPS@7L^}%#p-RuotQ1{3PpO zELfvC6xH8L1lHU)jXG}MA3zs`#L3fYsZ1up9378O$QR+QH(gU8UR!5L*rT8Go)ftA)W)n2T?L;!N4cDz*HR`zMD49=$1JZsZ{D)+RIKxX zNUrrc&WixwqOAu%%4*X#O5KoTju&=z@1{N!%&+E0?D#K|)Cs!jQ(4E+7Z_dWFmijQ z341`yHO2qt6xb}H^ZBEuhiaa4QI)VHw7mvPgje^nFH>qFJ+xrVdZ{H4gWH|yy1?@l z82{i}?nAoQnq2VmK1-J}a@sYI%^!yX-5dIoa2`A-2%n~~#{l1>$Q!!)cgET%Y5pGN zid#ptziaS*q}~%FS>5w-JH9C3OI>If^NFW8+TT0IcO=X3B&|?9%gY2-sjMMRNJ)Ga z)+1I#p8C?mTfFqq?o`ETqxDo3?@{|4>EFHGK2o7S9)Fu6>R=fWM;;fH#cE#@Lg9?; z?xK0{E)~}Kk)#tMg-qwxgEnicAyv$X*HEKCPVmJuLV>z z&RX&nUhSluX?s6iCvYhMkb~?pEpzRV8C@n5Emz9P4O<34$3i9oO^6Z{X{5B4Gy3`* z6{XX=wV4weorwC54YMX8_B4!9DgGv9CVmP3AY)2t4^*?Pbo?mp?ELNN(OT8_&Rb~__o@pTnqtn3)U(W& zB2+s&zi!M;!@oTeX!FAM1cfKyM#jj1O)=VQ*U1{|GK=?1R!w-5CCD=n<%6t1J42!8 z8l5eLj!2OSRRZgeP%=oa#i_3)x@o8^nXnv8GqRNYH3Me7Lv_yp&ZX$!%#fAwM=Q(@Q^+e%W0{qQGSK{AP0WJ|`I zggJr(;D$i0jL#ZzgT?g43-(l>ojO#zKQRn_J76 zDsM_y(B7JBDt9K9l02+=9na|jmWPc#<`W8<3%AoK!DxCVsp(;^3Jkfpp;%KiIxUI& zRIfgRI&MN~;8(v1l*fcy{`=w07xdrCVrCfAw^VmskzHv0q+8o|*4P)l$+NIl*=fhO zkr?G)t@m&W$F!efh%qn#E}88cmGE1--&D0bp;Z)=tK{O*FlzGZ7xVQ>_nt_m@W*I5 z8SKUEf8u;Q7WOQ|6Tz`MW6<~!z!6Q(!xn&3->OfAWcVS7HdA8dBvJNpz$}-BO|M6w zd&Yymu@q4z@*CM+@#~N7{`OMT-!R$)@smG8UXuvj#*)=zh|g0Tl1lf?$_m?Wa>Fcn zh^_;e>bg4m@3K&r5bEaRMBSwBC4VX>5@GDsH?8>kB98y|IwwIO0cGt4M%-k0PM_>) z6H4xGd>iV`Uk4aKa0M}+WXjg@3@g4R_E9J$&L@9{bs+QMM`W&8F0JizI&Nga01^1{ zmw-<|%@nEje%fqN1Wuzy(k#eDf{9<+_$xKxJ}Ljxfg&gG@&uOuox~i(iEx}(Y>Mt{ zj$mls*7FMsJyS>&wa(ngqyF1GkwyEAY!Y-cKq4}iedy!m3jupZCW?9tTU@LGdLs-i z79yE8xhps#Dg8 zkV1`~>VSU2Z$;B;No=Qk)qW+oO<>1|Lk?Uj4Z6?41itFnPZvDgEfs*!IVqszB}u4t zdej5HqbM-avf?b(x$a)ib_*ejx#>tk5tWsDGyKam?p73@vlbktj)b{a0eZ(5*-|65 zv!A*PO~rok%q}A50pLG2#D}Z!2PyXDRcO%Ou*^2+S6oK?iB4*uExu3SuB&<27@c?j zy$Ws&IhFzpMVrstIZh?l2OCsQAk;ml;WbOQQ^w(opvA;yK_X$#@d`)y-qf24wl{X_ z()K*kYI~|dr6M=j4*HM-lhajO8GudB<}pDsJy(*+ox1?%PtOW@J4|r(h(VR|r^Sc4 z;vtCYgoDyP&rl_Yi#w5Ij;V~#K#p4!hV{X^0o1B=u{4{Ria>w@8dFg^-AQ~4Gd0y$VUE=M?Ew8iVityGa!*{;I`_TM zvcJhktqQKHY;(4@+Z7?B5e*p^sjx!P^Nr(&>xuVdLfD|H7i@K#DDsb~AC=H*m4tDA zF$b=jqui!wtEn@4slAMBY4oW!ggPeQ=`M(g{2j5d$&^N~pCr*Qbzdsv`~=5XWk8Ev z5T~zU5y!`K4G;WL@s5fdSLdL$_FaoITQKmY-xS=Z-Jlqw zYn(F*C$5N0O&)j?sNlcA4XIpm-}{?2hl?pT>q^o{<#GkKzW}~aK-QIs8i&)J9Z6(s zbDG8jXQTy7g~y7Hu!oOVb930=3(L;n+#Zj|`>+ME%AQLu1Esi!vn?DvY}xxeqF`Eg zv^u?mvy(;nPo^h*luYmpUu>5-GA+p2wv9|yx#^OaetXLtWioMJMY4ahA7K?IYKYhl zL9w}f7vcB{W!t8w!(b7&I^l(C5S?TUIG|D2i9_{uFDvrwqI_C45+>NarCA2CPyb`lsrsW_m4^kuf>~sdkUwL&=@t zPFG(fA5}`A4GOIg$(P7i6(Dwlk00|-0A59RDPnG2rGMF zsKhK`9Q0|69h1Rhfuj-mJ;v1qM;9K(TGuT$gQLkfFL?)yheT!nz54s5Vye%e7-=E= zC+6r~2By{nrER_^2G@-D1VIj$y=8mP#yC%kxm^-mAJKHE{mpN(U2zT7Xm#$u@a*kV zzG#nq;ccN8`+xa4T0w0Atjvy}{bwPX`214K)jm~%5JbV~Orr0NoXulw8e0DUWsW>q zB?MuOG_*@?j2X8W#&JGE>KGF0FPf1r3S!ITWr-xt)?(xnN{Wq!qx5?bKfW&yRaOEq zWFJ3A=r4#Y+zu;L(VLf&E`#TDtl3S?VSIhngPsRL%NN+1c#`tVYv*y(&2etS8k0 zFOn0W)w|AnIj;C{qR9Qm!`}ry8>roU2M8G(=Hin!g?dQxp|3U^5S3REWF1d8Bx$ew z6eymb&!Vc_hf@F|MC-pu4Sc{#gP1OepS=68<$n6tHq(DC4fyfvaYHe5aP7Z~vWKF` zRR3KKlv5(fzfJq}-5@%_e?s~1BCUXbkNfwPMnuT}UB;e$S)RWR1>CGdbV{j zr3)Z5hR*^w##RFUlf?yp9ktKKPwvc>jY*_kb8@t4Jk<*Q=YKgp!_Z#Mkfi<-(tl6Z zp9*_R6WL&DS3!8)xY4P8EjXvV^>2HY(Ta3b^>7`>Nb}O#t*8 z7kDDaexjEkbU)^=p2?M`KCFi#1AgLmIZ=Y1aJCgOS}e1p_1fY{-kTuP$$XoQXi>mO zvC-T3oTJQO6HQglX#x8VCV)H8UH?#s^|8Qn1O}?t`oTs*I(cH8?&4{UV-i{gLr^#SxTS<}*nB2^4}M%UfARQm+2#r+)D^TT=fp?e!?UdC z*KwFuI*=6@M-OInqhQQGC+pqE`}a|#T1edoMeY$0dDKHAxSnWWQq8>%8@AYQ_p9D9 z>c0Rb{ClNM5vQlNyw@ACjx?sX3zdcl3i*<2cV}aLpQLWi_xd1|>D}4Fq0ZoISBFk* z68!wn8X6ijz3$IJ!*~R;*ntZ=$0k6^3++PT+W-v}UwyBw#Tu&Y9~p^1`-;8dekP?{ zsyT3V0>!HvaG743$ddq17OFY`Glb7Q_jg>BZNAm%V&{fgBl!BobCVK|(|*#1 z-#!RQ40_L@eUXW0MK28v4WBCVmmFrblJem{3kv$Csp#a?7+r(TW7mID@d3TFWHOUK z-@{2HV1Ae>)mqFgJv}=c7#P@@*isTDVa#^`t3Uu!VwC?r25Ci;U7;!|D*EYtdUVMd zr_wH~8(=M)UEJ&o{cNN;0-h7twe}mdY1`l9)L_R2wWS++Lb0e{0U%aw>Ect2=8LuA5_AoI zjg6dyZu=Fzq3fd#HPGz2={-P>uy~NKQl@=(9LTo;xN)M-cFmsn#NWJm!wwj*Q_R7{ zH8eMKKinUA*#T);KXKlkEhFN)>OgUZhO=!n@A_@9nSsqW6N^*zw7@d@VRLUGK21sA zU|&@_9xU|E?%1b<sAWuv`v9^E>l)2Uwcs6Gc8J(Ic;poWf@9!_Q`}JU<#<@k? z^?Y|aBF};^)BP0QIKzb^!H~sLf+F^dvGI`0Im=T|&!e_SUO<|nH=M*coXMBj_IQ7E z2k4Fx!Ha_>8vDxU0GOMY&P*x-k#R>qlq+-KCyo@29{7{KZLA9 zYZypGA9$y+txPXzrsNIKFCyp1k07}mks7D*1z}TD>eYvfx`zGAq56Z`MQhIVa4*oP z6BmW|ig*l2N? z3+PO81@@8}AZQB3`l#RO2k*YcwYp~Ib(;zV5d#s<jX49i3LAH4;N`T8|6x7w|U>w({rF@UV#9HCH`+yJqf~p4J)Swff%_I5=(Ic z*v!*10UMN}vNDr?_v@zy%e|1djVT2gt|5RdjL>BR4g8MoJpimH8!K){t;hAf=fA7YU)kB()?clMHtZG^Gaw3%7AxPZp?FbkO-lm~@2kbt zhu&qU)e(=&<-paWtxg2`4M4#lLM^PNMesCJI3MeN{rVLKhufKuLj$k^@VU{A zfh$4{ECCbaSsgE)P;7e3X*a8;1J*yo$#&inQC& z$5&pWW*1MY6GdItvLp@(gN__c1UkT!X^mzFsb49GL^JeS*py6e@)hrX#og=cfsrWj9q6o<=^7SN&n zo>Gw61iO2_jEU!FJ4Z5!;ai14-)ZXVU4YR0XP=JpL1kh#H1_GaBcM!Nh|Bf&w^umq z*2GU;J1>`=h*UIfUhd77ZDj=#u7kz{ot3nu&8On)C+t8(5CCU8Z9%#t?ilYaEev>r zOPi);Za}8f{C7ekjF2Y#Z~x|NiO+s zDmk8}Qj~*(BPl<4Y|CIEh8$?rfXCamM`#dfgzomQtf#N|36N-eUK{#!5Yr_hMD{&# ze4IF^Jy{cbC3O>RUS7yt`wXS6H(#^IsZ!ajRtiq3^6GC7o8GaSVacvWaa3@xgLzk z1?YXXMtf>JR&!mTJ797rcRXkWpE{~QiNFRE%8{!zpRbg;#Q+AT&As~{@!l5*1Bc`8xT|3;0M8lRl^wiL z{Z@wC)p(?*P@UznDwuZO_&npWjIeji0pNX7mw=9v%;ZgfYGi}dRsxK9U#aylRDn-< z_HLyibpNsZfdf48zq+{uxQF8)`$rV-0)iwf(9>=;>S{e-hL5VEaI< zY=j>_eh_1Y9-JOo)}_Y8#Q3Vd2OdKpdN8v<(5TS=?lpw{^9G-u_y5r4cqCE{<~L*P Ss(20qenEt#g-Qi6$ literal 0 HcmV?d00001 From 5ffcbf21346cc0a56b873c5b11d97e349fa379fc Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 20:57:53 +0530 Subject: [PATCH 21/45] Update seaborn-basics.md --- .../plotting-visualization/seaborn-basics.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/contrib/plotting-visualization/seaborn-basics.md b/contrib/plotting-visualization/seaborn-basics.md index 603f074..41d76a4 100644 --- a/contrib/plotting-visualization/seaborn-basics.md +++ b/contrib/plotting-visualization/seaborn-basics.md @@ -17,3 +17,23 @@ sns.relplot( x="total_bill", y="tip", col="time", hue="smoker", style="smoker", size="size", ) +``` +Below is the output for the above code snippet: + +![Seaborn intro image](images/seaborn-basics.png) + +```Python +# Load an example dataset +tips = sns.load_dataset("tips") +``` +Most code in the docs will use the `load_dataset()` function to get quick access to an example dataset. There’s nothing special about these datasets: they are just pandas data frames, and we could have loaded them with `pandas.read_csv()` or build them by hand. Most of the examples in the documentation will specify data using pandas data frames, but Seaborn is very flexible about the data structures that it accepts. + +```Python +# Create a visualization +sns.relplot( + data=tips, + x="total_bill", y="tip", col="time", + hue="smoker", style="smoker", size="size", +) +``` +This plot shows the relationship between five variables in the tips dataset using a single call to the seaborn function `relplot()`. Notice how we provided only the names of the variables and their roles in the plot. Unlike when using matplotlib directly, it wasn’t necessary to specify attributes of the plot elements in terms of the color values or marker codes. Behind the scenes, seaborn handled the translation from values in the dataframe to arguments that Matplotlib understands. This declarative approach lets you stay focused on the questions that you want to answer, rather than on the details of how to control matplotlib. From 4a7e00b61aa225b133fc702d23d70b3a74b70adf Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 20:58:54 +0530 Subject: [PATCH 22/45] Update seaborn-basics.md --- contrib/plotting-visualization/seaborn-basics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/plotting-visualization/seaborn-basics.md b/contrib/plotting-visualization/seaborn-basics.md index 41d76a4..147083b 100644 --- a/contrib/plotting-visualization/seaborn-basics.md +++ b/contrib/plotting-visualization/seaborn-basics.md @@ -20,7 +20,7 @@ sns.relplot( ``` Below is the output for the above code snippet: -![Seaborn intro image](images/seaborn-basics.png) +![Seaborn intro image](images/seaborn-basics1.png) ```Python # Load an example dataset From ccaa3770e7b308fe25410124dedcdea772ebe504 Mon Sep 17 00:00:00 2001 From: Rishi Goswami <92781956+rishig2003@users.noreply.github.com> Date: Fri, 31 May 2024 21:04:10 +0530 Subject: [PATCH 23/45] Update seaborn-basics.md --- contrib/plotting-visualization/seaborn-basics.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/plotting-visualization/seaborn-basics.md b/contrib/plotting-visualization/seaborn-basics.md index 147083b..42df552 100644 --- a/contrib/plotting-visualization/seaborn-basics.md +++ b/contrib/plotting-visualization/seaborn-basics.md @@ -26,7 +26,7 @@ Below is the output for the above code snippet: # Load an example dataset tips = sns.load_dataset("tips") ``` -Most code in the docs will use the `load_dataset()` function to get quick access to an example dataset. There’s nothing special about these datasets: they are just pandas data frames, and we could have loaded them with `pandas.read_csv()` or build them by hand. Most of the examples in the documentation will specify data using pandas data frames, but Seaborn is very flexible about the data structures that it accepts. +Most code in the docs will use the `load_dataset()` function to get quick access to an example dataset. There’s nothing special about these datasets: they are just pandas data frames, and we could have loaded them with `pandas.read_csv()` or build them by hand. Many users specify data using pandas data frames, but Seaborn is very flexible about the data structures that it accepts. ```Python # Create a visualization @@ -36,4 +36,4 @@ sns.relplot( hue="smoker", style="smoker", size="size", ) ``` -This plot shows the relationship between five variables in the tips dataset using a single call to the seaborn function `relplot()`. Notice how we provided only the names of the variables and their roles in the plot. Unlike when using matplotlib directly, it wasn’t necessary to specify attributes of the plot elements in terms of the color values or marker codes. Behind the scenes, seaborn handled the translation from values in the dataframe to arguments that Matplotlib understands. This declarative approach lets you stay focused on the questions that you want to answer, rather than on the details of how to control matplotlib. +This plot shows the relationship between five variables in the tips dataset using a single call to the seaborn function `relplot()`. Notice how only the names of the variables and their roles in the plot are provided. Unlike when using matplotlib directly, it wasn’t necessary to specify attributes of the plot elements in terms of the color values or marker codes. Behind the scenes, seaborn handled the translation from values in the dataframe to arguments that Matplotlib understands. This declarative approach lets you stay focused on the questions that you want to answer, rather than on the details of how to control matplotlib. From d20b8efca6cb73ef7543c0db41c34aede656e88f Mon Sep 17 00:00:00 2001 From: Jaya-Prakash-17 Date: Sat, 1 Jun 2024 00:41:56 +0530 Subject: [PATCH 24/45] Content Added: Protocols --- contrib/advanced-python/index.md | 1 + contrib/advanced-python/protocols.md | 243 +++++++++++++++++++++++++++ 2 files changed, 244 insertions(+) create mode 100644 contrib/advanced-python/protocols.md diff --git a/contrib/advanced-python/index.md b/contrib/advanced-python/index.md index b95e4b9..3945721 100644 --- a/contrib/advanced-python/index.md +++ b/contrib/advanced-python/index.md @@ -7,3 +7,4 @@ - [Regular Expressions in Python](regular_expressions.md) - [JSON module](json-module.md) - [Map Function](map-function.md) +- [Protocols](protocols.md) diff --git a/contrib/advanced-python/protocols.md b/contrib/advanced-python/protocols.md new file mode 100644 index 0000000..9b5e74a --- /dev/null +++ b/contrib/advanced-python/protocols.md @@ -0,0 +1,243 @@ +# Protocols in Python +Python can establish informal interfaces using protocols In order to improve code structure, reusability, and type checking. Protocols allow for progressive adoption and are more flexible than standard interfaces in other programming languages like JAVA, which are tight contracts that specify the methods and attributes a class must implement. + +>Before going into depth of this topic let's understand another topic which is pre-requisite od this topic \#TypingModule + +## Typing Module +This is a module in python which provides +1. Provides classes, functions, and type aliases. +2. Allows adding type annotations to our code. +3. Enhances code readability. +4. Helps in catching errors early. + +### Type Hints in Python: +Type hints allow you to specify the expected data types of variables, function parameters, and return values. This can improve code readability and help with debugging. + +Here is a simple function that adds two numbers: +```python +def add(a,b): + return a + b +add(10,20) +``` +>Output: 30 + +While this works fine, adding type hints makes the code more understandable and serves as documentation: + +```python +def add(a:int, b:int)->int: + return a + b +print(add(1,10)) +``` +>Output: 11 + +In this version, `a` and `b` are expected to be integers, and the function is expected to return an integer. This makes the function's purpose and usage clearer. + +#### let's see another example + +The function given below takes an iterable (it can be any off list, tuple, dict, set, frozeset, String... etc) and print it's content in a single line along with it's type. + +```python +from typing import Iterable +# type alias + +def print_all(l: Iterable)->None: + print(type(l),end=' ') + for i in l: + print(i,end=' ') + print() + +l = [1,2,3,4,5] # type: List[int] +s = {1,2,3,4,5} # type: Set[int] +t = (1,2,3,4,5) # type: Tuple[int] + +for iter_obj in [l,s,t]: + print_all(iter_obj) + +``` +Output: +> 1 2 3 4 5 +> 1 2 3 4 5 +> 1 2 3 4 5 + +and now lets try calling the function `print_all` using a non-iterable object `int` as argument. + +```python +a = 10 +print_all(a) # This will raise an error +``` +Output: +>TypeError: 'int' object is not iterable + +This error occurs because `a` is an `integer`, and the `integer` class does not have any methods or attributes that make it work like an iterable. In other words, the integer class does not conform to the `Iterable` protocol. + +**Benefits of Type Hints** +Using type hints helps in several ways: + +1. **Error Detection**: Tools like mypy can catch type-related problems during development, decreasing runtime errors. +2. **Code Readability**: Type hints serve as documentation, making it easy to comprehend what data types are anticipated and returned. +3. **Improved Maintenance**: With unambiguous type expectations, maintaining and updating code becomes easier, especially in huge codebases. + +Now that we have understood about type hints and typing module let's dive deep into protocols. + +## Understanding Protocols + +In Python, protocols define interfaces similar to Java interfaces. They let you specify methods and attributes that an object must implement without requiring inheritance from a base class. Protocols are part of the `typing` module and provide a way to enforce certain structures in your classes, enhancing type safety and code clarity. + +### What is a Protocol? + +A protocol specifies one or more method signatures that a class must implement to be considered as conforming to the protocol. + This concept is often referred to as "structural subtyping" or "duck typing," meaning that if an object implements the required methods and attributes, it can be treated as an instance of the protocol. + +Let's write our own protocol: + +```python +from typing import Protocol + +# Define a Printable protocol +class Printable(Protocol): + def print(self) -> None: + """Print the object""" + pass + +# Book class implements the Printable protocol +class Book: + def __init__(self, title: str): + self.title = title + + def print(self) -> None: + print(f"Book Title: {self.title}") + +# print_object function takes a Printable object and calls its print method +def print_object(obj: Printable) -> None: + obj.print() + +book = Book("Python Programming") +print_object(book) +``` +Output: +> Book Title: Python Programming + +In this example: + +1. **Printable Protocol:** Defines an interface with a single method print. +2. **Book Class:** Implements the Printable protocol by providing a print method. +3. **print_object Function:** Accepts any object that conforms to the Printable protocol and calls its print method. + +we got our output because the class `Book` confirms to the protocols `printable`. +similarly When you pass an object to `print_object` that does not conform to the Printable protocol, an error will occur. This is because the object does not implement the required `print` method. +Let's see an example: +```python +class Team: + def huddle(self) -> None: + print("Team Huddle") + +c = Team() +print_object(c) # This will raise an error +``` +Output: +>AttributeError: 'Team' object has no attribute 'print' + +In this case: +- The `Team` class has a `huddle` method but does not have a `print` method. +- When `print_object` tries to call the `print` method on a `Team` instance, it raises an `AttributeError`. + +> This is an important aspect of using protocols: they ensure that objects provide the necessary methods, leading to more predictable and reliable code. + +**Ensuring Protocol Conformance** +To avoid such errors, you need to ensure that any object passed to `print_object` implements the `Printable` protocol. Here's how you can modify the `Team` class to conform to the protocol: +```python +class Team: + def __init__(self, name: str): + self.name = name + + def huddle(self) -> None: + print("Team Huddle") + + def print(self) -> None: + print(f"Team Name: {self.name}") + +c = Team("Dream Team") +print_object(c) +``` +Output: +>Team Name: Dream Team + +The `Team` class now implements the `print` method, conforming to the `Printable` protocol. and hence, no longer raises an error. + +### Protocols and Inheritance: +Protocols can also be used in combination with inheritance to create more complex interfaces. +we can do that by following these steps: +**Step 1 - Base protocol**: Define a base protocol that specifies a common set of methods and attributes. +**Step 2 - Derived Protocols**: Create derives protocols that extends the base protocol with addition requirements +**Step 3 - Polymorphism**: Objects can then conform to multiple protocols, allowing for Polymorphic behavior. + +Let's see an example on this as well: + +```python +from typing import Protocol + +# Base Protocols +class Printable(Protocol): + def print(self) -> None: + """Print the object""" + pass + +# Base Protocols-2 +class Serializable(Protocol): + def serialize(self) -> str: + pass + +# Derived Protocol +class PrintableAndSerializable(Printable, Serializable): + pass + +# class with implementation of both Printable and Serializable +class Book_serialize: + def __init__(self, title: str): + self.title = title + + def print(self) -> None: + print(f"Book Title: {self.title}") + + def serialize(self) -> None: + print(f"serialize: {self.title}") + +# function accepts the object which implements PrintableAndSerializable +def test(obj: PrintableAndSerializable): + obj.print() + obj.serialize() + +book = Book_serialize("lean-in") +test(book) +``` +Output: +> Book Title: lean-in +serialize: lean-in + +In this example: + +**Printable Protocol:** Specifies a `print` method. +**Serializable Protocol:** Specifies a `serialize` method. +**PrintableAndSerializable Protocol:** Combines both `Printable` and `Serializable`. +**Book Class**: Implements both `print` and `serialize` methods, conforming to `PrintableAndSerializable`. +**test Function:** Accepts any object that implements the `PrintableAndSerializable` protocol. + +If you try to pass an object that does not conform to the `PrintableAndSerializable` protocol to the test function, it will raise an `error`. Let's see an example: + +```python +class Team: + def huddle(self) -> None: + print("Team Huddle") + +c = Team() +test(c) # This will raise an error +``` +output: +> AttributeError: 'Team' object has no attribute 'print' + +In this case: +The `Team` class has a `huddle` method but does not implement `print` or `serialize` methods. +When test tries to call `print` and `serialize` on a `Team` instance, it raises an `AttributeError`. + +**In Conclusion:** +>Python protocols offer a versatile and powerful means of defining interfaces, encouraging the decoupling of code, improving readability, and facilitating static type checking. They are particularly handy for scenarios involving file-like objects, bespoke containers, and any case where you wish to enforce certain behaviors without requiring inheritance from a specific base class. Ensuring that classes conform to protocols reduces runtime problems and makes your code more robust and maintainable. \ No newline at end of file From 9a504138c2b4f1ccb412e4e05cd0d2f76f864448 Mon Sep 17 00:00:00 2001 From: somyasaxena01 <140182178+somyasaxena01@users.noreply.github.com> Date: Sat, 1 Jun 2024 10:12:12 +0530 Subject: [PATCH 25/45] Delete contrib/ds-algorithms/stacks.md --- contrib/ds-algorithms/stacks.md | 131 -------------------------------- 1 file changed, 131 deletions(-) delete mode 100644 contrib/ds-algorithms/stacks.md diff --git a/contrib/ds-algorithms/stacks.md b/contrib/ds-algorithms/stacks.md deleted file mode 100644 index f9f662b..0000000 --- a/contrib/ds-algorithms/stacks.md +++ /dev/null @@ -1,131 +0,0 @@ -# STACKS IN PYTHON -In Data Structures and Algorithms, a stack is a linear data structure that complies with the Last In, First Out (LIFO) rule. It works by use of two fundamental techniques: *PUSH* which inserts an element on top of the stack and *POP* which takes out the topmost element.This concept is similar to a stack of plates in a cafeteria. Stacks are usually used for handling function calls, expression evaluation, and parsing in programming. Indeed, they are efficient in managing memory as well as tracking program state. - -**POINTS TO BE REMEMBERED :-** -- A stack is a collection of data items that can be accessed at only one end, called *TOP*. -- Items can be inserted and deleted in a stack only at the *TOP*. -- The last item inserted in a stack is the first one to be deleted. -- Therefore, a stack is called a **Last-In-First-Out (LIFO)** data structure. - -## REAL LIFE EXAMPLES OF STACKS - -**PILE OF BOOKS** - Suppose a set of books are placed one over the other in a pile. When you remove books from the pile, the topmost book will be removed first. Similarly, when you have to add a book to the pile, the book will be placed at the top of the file. - -**PILE OF PLATES** - The first plate begins the pile. The second plate is placed on the top of the first plate and the third plate is placed on the top of the second plate, and so on. In general, if you want to add a plate to the pile, you can keep it on the top of the pile. Similarly, if you want to remove a plate, you can remove the plate from the top of the pile. - -**BANGLES IN A HAND** - When a person wears bangles, the last bangle worn is the first one to be removed. - -## APPLICATIONS OF STACKS - -Stacks are widely used in Computer Science: -- *Function call* management -- Maintaining the *UNDO* list for the application -- Web browser *history management* -- Evaluating expressions -- Checking the nesting of parentheses in an expression -- *Backtracking* algorithms (Recursion) - -Understanding these applications is essential for Software Development. - -## OPERATIONS ON A STACK - -Key operations on a stack include: -- **PUSH** - It is the process of inserting a new element on the top of a stack. -- **OVERFLOW** - A situation when we are pushing an item in a stack that is full. -- **POP** - It is the process of deleting an element from the top of a stack. -- **UNDERFLOW** - A situation when we are popping item from an empty stack. -- **PEEK** - It is the process of getting the most recent value of stack *(i.e. the value at the top of the stack)* -- **ISEMPTY** - It is the function which return true if stack is empty else false. -- **SHOW** -Displaying stack items. - -## IMPLEMENTING STACKS IN PYTHON - -```python -def isEmpty(S): - - if len(S) == 0: - return True - - else: - - return False - -def Push(S, item): - S.append(item) - -def Pop(S): - - if isEmpty(S): - return "Underflow" - - else: - val = S.pop() - return val - -def Peek(S): - - if isEmpty(S): - return "Underflow" - - else: - top = len(S) - 1 - return S[top] - -def Show(S): - - if isEmpty(S): - print("Sorry, No items in Stack") - - else: - print("(Top)", end=' ') - t = len(S) - 1 - while t >= 0: - print(S[t], "<", end=' ') - t -= 1 - print() -``` - -This code defines a stack data structure along with functions to manipulate it. To provide output, we would need to use these functions to interact with the stack. - -Here's an example: -```python -stack = [] - -Push(stack, 5) -Push(stack, 10) -Push(stack, 15) - -print("Stack after Push operations:") -Show(stack) - -print("Peek operation:", Peek(stack)) - -print("Pop operation:", Pop(stack)) - -print("Stack after Pop operation:") -Show(stack) -``` - -This would output: - -``` -Stack after Push operations: - -(Top) 15 < 10 < 5 < - -Peek operation: 15 - -Pop operation: 15 - -Stack after Pop operation: - -(Top) 10 < 5 < -``` - -## Complexity Analysis - -- **Worst case**: `O(n)` This occurs when the stack is full, it is dominated by the usage of Show operation. -- **Best case**: `O(1)` When the operations like isEmpty, Push, Pop and Peek are used, they have a constant time complexity of O(1). -- **Average case**: `O(n)` The average complexity is likely to be lower than O(n), as the stack is not always full. - - From 1f54c5a7ccb5ba49d5f49728837521796f2b4de7 Mon Sep 17 00:00:00 2001 From: somyasaxena01 <140182178+somyasaxena01@users.noreply.github.com> Date: Sat, 1 Jun 2024 10:12:55 +0530 Subject: [PATCH 26/45] Add files via upload --- contrib/ds-algorithms/stacks.md | 116 ++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 contrib/ds-algorithms/stacks.md diff --git a/contrib/ds-algorithms/stacks.md b/contrib/ds-algorithms/stacks.md new file mode 100644 index 0000000..428a193 --- /dev/null +++ b/contrib/ds-algorithms/stacks.md @@ -0,0 +1,116 @@ +# Stacks in Python + +In Data Structures and Algorithms, a stack is a linear data structure that complies with the Last In, First Out (LIFO) rule. It works by use of two fundamental techniques: **PUSH** which inserts an element on top of the stack and **POP** which takes out the topmost element.This concept is similar to a stack of plates in a cafeteria. Stacks are usually used for handling function calls, expression evaluation, and parsing in programming. Indeed, they are efficient in managing memory as well as tracking program state. + +## Points to be Remebered + +- A stack is a collection of data items that can be accessed at only one end, called **TOP**. +- Items can be inserted and deleted in a stack only at the TOP. +- The last item inserted in a stack is the first one to be deleted. +- Therefore, a stack is called a **Last-In-First-Out (LIFO)** data structure. + +## Real Life Examples of Stacks + +- **PILE OF BOOKS** - Suppose a set of books are placed one over the other in a pile. When you remove books from the pile, the topmost book will be removed first. Similarly, when you have to add a book to the pile, the book will be placed at the top of the file. + +- **PILE OF PLATES** - The first plate begins the pile. The second plate is placed on the top of the first plate and the third plate is placed on the top of the second plate, and so on. In general, if you want to add a plate to the pile, you can keep it on the top of the pile. Similarly, if you want to remove a plate, you can remove the plate from the top of the pile. + +- **BANGLES IN A HAND** - When a person wears bangles, the last bangle worn is the first one to be removed. + +## Applications of Stacks + +Stacks are widely used in Computer Science: + +- Function call management +- Maintaining the UNDO list for the application +- Web browser *history management* +- Evaluating expressions +- Checking the nesting of parentheses in an expression +- Backtracking algorithms (Recursion) + +Understanding these applications is essential for Software Development. + +## Operations on a Stack + +Key operations on a stack include: + +- **PUSH** - It is the process of inserting a new element on the top of a stack. +- **OVERFLOW** - A situation when we are pushing an item in a stack that is full. +- **POP** - It is the process of deleting an element from the top of a stack. +- **UNDERFLOW** - A situation when we are popping item from an empty stack. +- **PEEK** - It is the process of getting the most recent value of stack *(i.e. the value at the top of the stack)* +- **isEMPTY** - It is the function which return true if stack is empty else false. +- **SHOW** -Displaying stack items. + +## Implementing Stacks in Python + +```python +def isEmpty(S): + if len(S) == 0: + return True + else: + return False + +def Push(S, item): + S.append(item) + +def Pop(S): + if isEmpty(S): + return "Underflow" + else: + val = S.pop() + return val + +def Peek(S): + if isEmpty(S): + return "Underflow" + else: + top = len(S) - 1 + return S[top] + +def Show(S): + if isEmpty(S): + print("Sorry, No items in Stack") + else: + print("(Top)", end=' ') + t = len(S) - 1 + while t >= 0: + print(S[t], "<", end=' ') + t -= 1 + print() + +stack = [] # initially stack is empty + +Push(stack, 5) +Push(stack, 10) +Push(stack, 15) + +print("Stack after Push operations:") +Show(stack) +print("Peek operation:", Peek(stack)) +print("Pop operation:", Pop(stack)) +print("Stack after Pop operation:") +Show(stack) +``` + +## Output + +```markdown +Stack after Push operations: + +(Top) 15 < 10 < 5 < + +Peek operation: 15 + +Pop operation: 15 + +Stack after Pop operation: + +(Top) 10 < 5 < +``` + +## Complexity Analysis + +- **Worst case**: `O(n)` This occurs when the stack is full, it is dominated by the usage of Show operation. +- **Best case**: `O(1)` When the operations like isEmpty, Push, Pop and Peek are used, they have a constant time complexity of O(1). +- **Average case**: `O(n)` The average complexity is likely to be lower than O(n), as the stack is not always full. From 59773b20eed7cff5a85b5785f96edfe4e90a7139 Mon Sep 17 00:00:00 2001 From: "Kaza.Sunitha" <133480054+Kazasunitha@users.noreply.github.com> Date: Sun, 2 Jun 2024 03:49:19 +0530 Subject: [PATCH 27/45] Added viewing_data_in_pandas.md file (#660) * Add files via upload * Update classes.md * Update classes.md * Update classes.md * Update index.md * Update classes.md * Update index.md * Add files via upload * Update viewing_data_in_pandas.md * Delete contrib/advanced-python/classes.md * Delete contrib/advanced-python/index.md * Revert "Delete contrib/advanced-python/index.md" This reverts commit 55fe958c1c57daf431b3dce1d5d103bb8361612a. * Update index.md * Update viewing_data_in_pandas.md Updated the heading format * Update index.md * Update and rename viewing_data_in_pandas.md to viewing-data.md * Update viewing-data.md --------- Co-authored-by: Ankit Mahato --- contrib/pandas/index.md | 1 + contrib/pandas/viewing-data.md | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 contrib/pandas/viewing-data.md diff --git a/contrib/pandas/index.md b/contrib/pandas/index.md index 33c7347..e5a8353 100644 --- a/contrib/pandas/index.md +++ b/contrib/pandas/index.md @@ -1,6 +1,7 @@ # List of sections - [Pandas Introduction and Dataframes in Pandas](introduction.md) +- [Viewing data in pandas](viewing-data.md) - [Pandas Series Vs NumPy ndarray](pandas-series-vs-numpy-ndarray.md) - [Pandas Descriptive Statistics](descriptive-statistics.md) - [Group By Functions with Pandas](groupby-functions.md) diff --git a/contrib/pandas/viewing-data.md b/contrib/pandas/viewing-data.md new file mode 100644 index 0000000..8aaa4ae --- /dev/null +++ b/contrib/pandas/viewing-data.md @@ -0,0 +1,67 @@ +# Viewing rows of the frame + +## `head()` method + +The pandas library in Python provides a convenient method called `head()` that allows you to view the first few rows of a DataFrame. Let me explain how it works: +- The `head()` function returns the first n rows of a DataFrame or Series. +- By default, it displays the first 5 rows, but you can specify a different number of rows using the n parameter. + +### Syntax + +```python +dataframe.head(n) +``` + +`n` is the Optional value. The number of rows to return. Default value is `5`. + +### Example + +```python +import pandas as pd +df = pd.DataFrame({'animal': ['alligator', 'bee', 'falcon', 'lion','tiger','rabit','dog','fox','monkey','elephant']}) +df.head(n=5) +``` + +#### Output + +``` + animal +0 alligator +1 bee +2 falcon +3 lion +4 tiger +``` + +## `tail()` method + +The `tail()` function in Python displays the last five rows of the dataframe by default. It takes in a single parameter: the number of rows. We can use this parameter to display the number of rows of our choice. +- The `tail()` function returns the last n rows of a DataFrame or Series. +- By default, it displays the last 5 rows, but you can specify a different number of rows using the n parameter. + +### Syntax + +```python +dataframe.tail(n) +``` + +`n` is the Optional value. The number of rows to return. Default value is `5`. + +### Example + +```python +import pandas as pd +df = pd.DataFrame({'fruits': ['mongo', 'orange', 'apple', 'lemon','banana','water melon','papaya','grapes','cherry','coconut']}) +df.tail(n=5) +``` + +#### Output + +``` + fruits +5 water melon +6 papaya +7 grapes +8 cherry +9 coconut +``` From 839211767809e4c7d53f38dd21dafd90ccd9bd5a Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 03:56:26 +0530 Subject: [PATCH 28/45] Update matplotlib-line-plot.md --- .../matplotlib-line-plot.md | 56 +++++++++++-------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/contrib/plotting-visualization/matplotlib-line-plot.md b/contrib/plotting-visualization/matplotlib-line-plot.md index 566fdbb..b7488e6 100644 --- a/contrib/plotting-visualization/matplotlib-line-plot.md +++ b/contrib/plotting-visualization/matplotlib-line-plot.md @@ -1,24 +1,27 @@ # Line Chart in Matplotlib A line chart is a simple way to visualize data where we connect individual data points. It helps us to see trends and patterns over time or across categories. -
This type of chart is particularly useful for:
-* Comparing Data: Comparing multiple datasets on the same axes. -* Highlighting Changes: Illustrating changes and patterns in data. -* Visualizing Trends: Showing trends over time or other continuous variables. + +This type of chart is particularly useful for: +- Comparing Data: Comparing multiple datasets on the same axes. +- Highlighting Changes: Illustrating changes and patterns in data. +- Visualizing Trends: Showing trends over time or other continuous variables. ## Prerequisites -Line plots can be created in Python with Matplotlib's ``pyplot`` library. To build a line plot, first import ``Matplotlib``. It is a standard convention to import Matplotlib's pyplot library as ``plt``. -``` -import matplotlib.pyplot as plt +Line plots can be created in Python with Matplotlib's `pyplot` library. To build a line plot, first import `matplotlib`. It is a standard convention to import Matplotlib's pyplot library as `plt`. + +```python +import matplotlib.pyplot as plt ``` ## Creating a simple Line Plot First import matplotlib and numpy, these are useful for charting. -
You can use the ``plot(x,y)`` method to create a line chart.
-``` +You can use the `plot(x,y)` method to create a line chart. + +```python import matplotlib.pyplot as plt import numpy as np @@ -29,6 +32,7 @@ y = 2*x + 1 plt.plot(x, y) plt.show() ``` + When executed, this will show the following line plot: ![Basic line Chart](images/simple_line.png) @@ -36,8 +40,9 @@ When executed, this will show the following line plot: ## Curved line -The ``plot()`` method also works for other types of line charts. It doesn’t need to be a straight line, y can have any type of values. -``` +The `plot()` method also works for other types of line charts. It doesn’t need to be a straight line, y can have any type of values. + +```python import matplotlib.pyplot as plt import numpy as np @@ -47,6 +52,7 @@ y = 2**x + 1 plt.plot(x, y) plt.show() ``` + When executed, this will show the following Curved line plot: ![Curved line](images/line-curve.png) @@ -54,8 +60,9 @@ When executed, this will show the following Curved line plot: ## Line with Labels -To know what you are looking at, you need meta data. Labels are a type of meta data. They show what the chart is about. The chart has an ``x label``, ``y label`` and ``title``. -``` +To know what you are looking at, you need meta data. Labels are a type of meta data. They show what the chart is about. The chart has an `x label`, `y label` and `title`. + +```python import matplotlib.pyplot as plt import numpy as np @@ -72,15 +79,16 @@ plt.title("With Labels") plt.show() ``` + When executed, this will show the following line with labels plot: ![line with labels](images/line-labels.png) ## Multiple lines -More than one line can be in the plot. To add another line, just call the ``plot(x,y)`` function again. In the example below we have two different values for ``y(y1,y2)`` that are plotted onto the chart. +More than one line can be in the plot. To add another line, just call the `plot(x,y)` function again. In the example below we have two different values for `y(y1,y2)` that are plotted onto the chart. -``` +```python import matplotlib.pyplot as plt import numpy as np @@ -98,6 +106,7 @@ plt.plot(x, y1, plt.show() ``` + When executed, this will show the following Multiple lines plot: ![multiple lines](images/two-lines.png) @@ -105,9 +114,9 @@ When executed, this will show the following Multiple lines plot: ## Dotted line -Lines can be in the form of dots like the image below. Instead of calling ``plot(x,y)`` call the ``scatter(x,y)`` method. The ``scatter(x,y)`` method can also be used to (randomly) plot points onto the chart. +Lines can be in the form of dots like the image below. Instead of calling `plot(x,y)` call the `scatter(x,y)` method. The `scatter(x,y)` method can also be used to (randomly) plot points onto the chart. -``` +```python import matplotlib.pyplot as plt import numpy as np @@ -130,9 +139,9 @@ When executed, this will show the following Dotted line plot: ## Line ticks -You can change the ticks on the plot. Set them on the ``x-axis``, ``y-axis`` or even change their color. The line can be more thick and have an alpha value. +You can change the ticks on the plot. Set them on the `x-axis`, `y-axis` or even change their color. The line can be more thick and have an alpha value. -``` +```python import matplotlib.pyplot as plt import numpy as np @@ -166,9 +175,9 @@ When executed, this will show the following line ticks plot: ## Line with asymptote -An asymptote can be added to the plot. To do that, use ``plt.annotate()``. There’s lso a dotted line in the plot below. You can play around with the code to see how it works. +An asymptote can be added to the plot. To do that, use `plt.annotate()`. There’s lso a dotted line in the plot below. You can play around with the code to see how it works. -``` +```python import matplotlib.pyplot as plt import numpy as np @@ -222,9 +231,9 @@ When executed, this will show the following Line with asymptote plot: ## Line with text scale -It doesn’t have to be a numeric scale. The scale can also contain textual words like the example below. In ``plt.yticks()`` we just pass a list with text values. These values are then show against the ``y axis``. +It doesn’t have to be a numeric scale. The scale can also contain textual words like the example below. In `plt.yticks()` we just pass a list with text values. These values are then show against the `y axis`. -``` +```python import matplotlib.pyplot as plt import numpy as np @@ -261,6 +270,7 @@ ax.spines['left'].set_position(('data', 0)) plt.show() ``` + When executed, this will show the following Line with text scale plot: ![Line with text scale](images/line-with-text-scale.png) From aeb947bb1a0c3a44ff3b2ece398649bae6a9e5df Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 03:59:12 +0530 Subject: [PATCH 29/45] Rename ArtificialNeuralNetwork.md to ann.md --- contrib/machine-learning/{ArtificialNeuralNetwork.md => ann.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/machine-learning/{ArtificialNeuralNetwork.md => ann.md} (100%) diff --git a/contrib/machine-learning/ArtificialNeuralNetwork.md b/contrib/machine-learning/ann.md similarity index 100% rename from contrib/machine-learning/ArtificialNeuralNetwork.md rename to contrib/machine-learning/ann.md From e3c2799e6f8a4e58ba00778d7d0cedc76b1495b3 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 03:59:31 +0530 Subject: [PATCH 30/45] Rename Decision-Tree.md to decision-tree.md --- contrib/machine-learning/{Decision-Tree.md => decision-tree.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename contrib/machine-learning/{Decision-Tree.md => decision-tree.md} (99%) diff --git a/contrib/machine-learning/Decision-Tree.md b/contrib/machine-learning/decision-tree.md similarity index 99% rename from contrib/machine-learning/Decision-Tree.md rename to contrib/machine-learning/decision-tree.md index 6563a22..8159bcf 100644 --- a/contrib/machine-learning/Decision-Tree.md +++ b/contrib/machine-learning/decision-tree.md @@ -254,4 +254,4 @@ The final decision tree classifies instances based on the following rules: - If Outlook is Rain and Wind is Weak, PlayTennis is Yes - If Outlook is Rain and Wind is Strong, PlayTennis is No -> Note that the calculated entropies and information gains may vary slightly depending on the specific implementation and rounding methods used. \ No newline at end of file +> Note that the calculated entropies and information gains may vary slightly depending on the specific implementation and rounding methods used. From 038bc20a2805baf4165129ebdda4dc059cdcb223 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 03:59:44 +0530 Subject: [PATCH 31/45] Rename Regression.md to regression.md --- contrib/machine-learning/{Regression.md => regression.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/machine-learning/{Regression.md => regression.md} (100%) diff --git a/contrib/machine-learning/Regression.md b/contrib/machine-learning/regression.md similarity index 100% rename from contrib/machine-learning/Regression.md rename to contrib/machine-learning/regression.md From b19af0241afc2e239dfe31039d743ff888ec59ec Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:00:07 +0530 Subject: [PATCH 32/45] Rename tensorFlow.md to tensorflow.md --- contrib/machine-learning/{tensorFlow.md => tensorflow.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename contrib/machine-learning/{tensorFlow.md => tensorflow.md} (99%) diff --git a/contrib/machine-learning/tensorFlow.md b/contrib/machine-learning/tensorflow.md similarity index 99% rename from contrib/machine-learning/tensorFlow.md rename to contrib/machine-learning/tensorflow.md index 1d9357d..b2c847c 100644 --- a/contrib/machine-learning/tensorFlow.md +++ b/contrib/machine-learning/tensorflow.md @@ -61,4 +61,4 @@ TensorFlow is a great choice if you: ## Example Use Cases - Building and deploying complex neural networks for image recognition, natural language processing, or recommendation systems. -- Developing models that need to be run on mobile or embedded devices. \ No newline at end of file +- Developing models that need to be run on mobile or embedded devices. From f909c3a2b92d6e1379b9ee276edf78b06592c6a5 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:00:31 +0530 Subject: [PATCH 33/45] Rename binomial_distribution.md to binomial-distribution.md --- .../{binomial_distribution.md => binomial-distribution.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/machine-learning/{binomial_distribution.md => binomial-distribution.md} (100%) diff --git a/contrib/machine-learning/binomial_distribution.md b/contrib/machine-learning/binomial-distribution.md similarity index 100% rename from contrib/machine-learning/binomial_distribution.md rename to contrib/machine-learning/binomial-distribution.md From 3b161f57fabb3c1665ccec773578dfcd3377dbe5 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:00:53 +0530 Subject: [PATCH 34/45] Rename Types_of_optimizers.md to types-of-optimizers.md --- .../{Types_of_optimizers.md => types-of-optimizers.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/machine-learning/{Types_of_optimizers.md => types-of-optimizers.md} (100%) diff --git a/contrib/machine-learning/Types_of_optimizers.md b/contrib/machine-learning/types-of-optimizers.md similarity index 100% rename from contrib/machine-learning/Types_of_optimizers.md rename to contrib/machine-learning/types-of-optimizers.md From 87b2d056531182f69dea33798807b895214c731c Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:01:46 +0530 Subject: [PATCH 35/45] Update index.md --- contrib/machine-learning/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/machine-learning/index.md b/contrib/machine-learning/index.md index e56691d..a0dd999 100644 --- a/contrib/machine-learning/index.md +++ b/contrib/machine-learning/index.md @@ -1,16 +1,16 @@ # List of sections -- [Binomial Distribution](binomial_distribution.md) -- [Regression in Machine Learning](Regression.md) +- [Binomial Distribution](binomial-distribution.md) +- [Regression in Machine Learning](regression.md) - [Confusion Matrix](confusion-matrix.md) -- [Decision Tree Learning](Decision-Tree.md) +- [Decision Tree Learning](decision-tree.md) - [Random Forest](random-forest.md) - [Support Vector Machine Algorithm](support-vector-machine.md) -- [Artificial Neural Network from the Ground Up](ArtificialNeuralNetwork.md) +- [Artificial Neural Network from the Ground Up](ann.md) - [Introduction To Convolutional Neural Networks (CNNs)](intro-to-cnn.md) -- [TensorFlow.md](tensorFlow.md) +- [TensorFlow.md](tensorflow.md) - [PyTorch.md](pytorch.md) -- [Types of optimizers](Types_of_optimizers.md) +- [Types of optimizers](types-of-optimizers.md) - [Logistic Regression](logistic-regression.md) - [Clustering](clustering.md) - [Grid Search](grid-search.md) From d6e610d8cc3505c806687db1d4dfb9ad0f4f5e66 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:03:36 +0530 Subject: [PATCH 36/45] Rename sklearn.md to sklearn-introduction.md --- .../machine-learning/{sklearn.md => sklearn-introduction.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename contrib/machine-learning/{sklearn.md => sklearn-introduction.md} (99%) diff --git a/contrib/machine-learning/sklearn.md b/contrib/machine-learning/sklearn-introduction.md similarity index 99% rename from contrib/machine-learning/sklearn.md rename to contrib/machine-learning/sklearn-introduction.md index 8174d93..7bb5aa8 100644 --- a/contrib/machine-learning/sklearn.md +++ b/contrib/machine-learning/sklearn-introduction.md @@ -141,4 +141,4 @@ print(f"Accuracy: {accuracy * 100:.2f}%") ## Conclusion -scikit-learn is a powerful and versatile library that can be used for a wide range of machine learning tasks. It is particularly well-suited for beginners due to its easy-to-use interface and extensive documentation. Whether you are working on a simple classification task or a more complex clustering problem, scikit-learn provides the tools you need to build and evaluate your models effectively. \ No newline at end of file +scikit-learn is a powerful and versatile library that can be used for a wide range of machine learning tasks. It is particularly well-suited for beginners due to its easy-to-use interface and extensive documentation. Whether you are working on a simple classification task or a more complex clustering problem, scikit-learn provides the tools you need to build and evaluate your models effectively. From f671f4d3e9229ba6c622bad87a3972d4e74fea39 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:10:58 +0530 Subject: [PATCH 37/45] Rename matplotlib-line-plot.md to matplotlib-line-plots.md --- .../{matplotlib-line-plot.md => matplotlib-line-plots.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/plotting-visualization/{matplotlib-line-plot.md => matplotlib-line-plots.md} (100%) diff --git a/contrib/plotting-visualization/matplotlib-line-plot.md b/contrib/plotting-visualization/matplotlib-line-plots.md similarity index 100% rename from contrib/plotting-visualization/matplotlib-line-plot.md rename to contrib/plotting-visualization/matplotlib-line-plots.md From c7746086b91d44369aa6f8e7f3c4a863cd655da2 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:18:14 +0530 Subject: [PATCH 38/45] Rename Types_of_Cost_Functions.md to cost-functions.md --- .../{Types_of_Cost_Functions.md => cost-functions.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/machine-learning/{Types_of_Cost_Functions.md => cost-functions.md} (100%) diff --git a/contrib/machine-learning/Types_of_Cost_Functions.md b/contrib/machine-learning/cost-functions.md similarity index 100% rename from contrib/machine-learning/Types_of_Cost_Functions.md rename to contrib/machine-learning/cost-functions.md From f125cf4a33de46d7f8fee1066a347551f71ea13a Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:26:45 +0530 Subject: [PATCH 39/45] Update cost-functions.md --- contrib/machine-learning/cost-functions.md | 41 ++++++++++------------ 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/contrib/machine-learning/cost-functions.md b/contrib/machine-learning/cost-functions.md index f650726..c1fe217 100644 --- a/contrib/machine-learning/cost-functions.md +++ b/contrib/machine-learning/cost-functions.md @@ -14,9 +14,9 @@ MSE is one of the most commonly used cost functions, particularly in regression The MSE is defined as: $$MSE = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2$$ Where: -- \( n \) is the number of samples. -- \( y_i \) is the actual value. -- \( y^i\) is the predicted value. +- `n` is the number of samples. +- $y_i$ is the actual value. +- $\hat{y}_i$ is the predicted value. **Advantages:** - Sensitive to large errors due to squaring. @@ -43,9 +43,9 @@ MAE is another commonly used cost function for regression tasks. It measures the The MAE is defined as: $$MAE = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|$$ Where: -- \( n \) is the number of samples. -- \( y_i \) is the actual value. -- \( y^i\) is the predicted value. +- `n` is the number of samples. +- $y_i$ is the actual value. +- $\hat{y}_i$ is the predicted value. **Advantages:** - Less sensitive to outliers compared to MSE. @@ -76,9 +76,9 @@ For binary classification, the cross-entropy loss is defined as: $$\text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)]$$ Where: -- \( n \) is the number of samples. -- \( y_i \) is the actual class label (0 or 1). -- \( y^i\) is the predicted probability of the positive class. +- `n` is the number of samples. +- $y_i$ is the actual class label (0 or 1). +- $\hat{y}_i$ is the predicted probability of the positive class. **Advantages:** @@ -109,11 +109,10 @@ The multiclass cross-entropy loss is defined as: $$\text{Cross-Entropy} = -\frac{1}{n} \sum_{i=1}^{n} \sum_{c=1}^{C} y_{i,c} \log(\hat{y}_{i,c})$$ Where: -- \( n \) is the number of samples. -- \( C \) is the number of classes. -- \( y_{i,c} \) is the indicator function for the true class of sample \( i \). - -- (y^i,c) is the predicted probability of sample \( i \) belonging to class \( c \). +- `n` is the number of samples. +- `C` is the number of classes. +- $y_{i,c}$ is the indicator function for the true class of sample `i`. +- $\hat{y}_{i,c}$ is the predicted probability of sample `i` belonging to class `c`. **Advantages:** - Handles multiple classes effectively. @@ -143,9 +142,9 @@ For binary classification, the hinge loss is defined as: $$\text{Hinge Loss} = \frac{1}{n} \sum_{i=1}^{n} \max(0, 1 - y_i \cdot \hat{y}_i)$$ Where: -- \( n \) is the number of samples. -- \( y_i \) is the actual class label (-1 or 1). -- \( \hat{y}_i \) is the predicted score for sample \( i \). +- `n` is the number of samples. +- $y_i$ is the actual class label (-1 or 1). +- $\hat{y}_i$ is the predicted score for sample \( i \). **Advantages:** - Encourages margin maximization in SVMs. @@ -182,8 +181,8 @@ $$\text{Huber Loss} = \frac{1}{n} \sum_{i=1}^{n} \left\{ \right.$$ Where: -- \( n \) is the number of samples. -- \(delta\) is a threshold parameter. +- `n` is the number of samples. +- $\delta$ is a threshold parameter. **Advantages:** - Provides a smooth loss function. @@ -214,7 +213,7 @@ The Log-Cosh loss is defined as: $$\text{Log-Cosh Loss} = \frac{1}{n} \sum_{i=1}^{n} \log(\cosh(y_i - \hat{y}_i))$$ Where: -- \( n \) is the number of samples. +- `n` is the number of samples. **Advantages:** - Smooth and differentiable everywhere. @@ -234,5 +233,3 @@ def logcosh_loss(y_true, y_pred): ``` These implementations provide various options for cost functions suitable for different machine learning tasks. Each function has its advantages and disadvantages, making them suitable for different scenarios and problem domains. - ---- From 15fed7ee6e448637b27ecdc23ef5157ed2ef5ce4 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 04:31:21 +0530 Subject: [PATCH 40/45] Update index.md --- contrib/api-development/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/api-development/index.md b/contrib/api-development/index.md index 7278907..8d4dc59 100644 --- a/contrib/api-development/index.md +++ b/contrib/api-development/index.md @@ -1,4 +1,4 @@ # List of sections - [API Methods](api-methods.md) -- [FastAPI](fast-api.md) \ No newline at end of file +- [FastAPI](fast-api.md) From 643cadfa330d4fa5443ba1f4044ecc5942e2b7f3 Mon Sep 17 00:00:00 2001 From: manishh12 Date: Sun, 2 Jun 2024 11:54:06 +0530 Subject: [PATCH 41/45] Added Generators under Advance python --- contrib/advanced-python/Generators.md | 87 +++++++++++++++++++++++++++ contrib/advanced-python/index.md | 1 + 2 files changed, 88 insertions(+) create mode 100644 contrib/advanced-python/Generators.md diff --git a/contrib/advanced-python/Generators.md b/contrib/advanced-python/Generators.md new file mode 100644 index 0000000..ff5226e --- /dev/null +++ b/contrib/advanced-python/Generators.md @@ -0,0 +1,87 @@ +# Generators Under Advanced Python + +## Introduction + +Generators in Python are a sophisticated feature that enables the creation of iterators without the need to construct a full list in memory. They allow you to generate values on-the-fly, which is particularly beneficial for working with large datasets or infinite sequences. In this README, we'll explore generators in depth, covering their types, mathematical formulation, advantages, disadvantages, and implementation examples. + +## Function Generators + +Function generators are created using the `yield` keyword within a function. When invoked, a function generator returns a generator iterator, allowing you to iterate over the values generated by the function. + +### Mathematical Formulation + +Function generators can be represented mathematically using set-builder notation. The general form is: + +``` +{expression | variable in iterable, condition} +``` + +Where: +- `expression` is the expression to generate values. +- `variable` is the variable used in the expression. +- `iterable` is the sequence of values to iterate over. +- `condition` is an optional condition that filters the values. + +### Advantages of Function Generators + +1. **Memory Efficiency**: Function generators produce values lazily, meaning they generate values only when needed, saving memory compared to constructing an entire sequence upfront. + +2. **Lazy Evaluation**: Values are generated on-the-fly as they are consumed, leading to improved performance and reduced overhead, especially when dealing with large datasets. + +3. **Infinite Sequences**: Function generators can represent infinite sequences, such as the Fibonacci sequence, allowing you to work with data streams of arbitrary length without consuming excessive memory. + +### Disadvantages of Function Generators + +1. **Single Iteration**: Once a function generator is exhausted, it cannot be reused. If you need to iterate over the sequence again, you'll have to create a new generator. + +2. **Limited Random Access**: Function generators do not support random access like lists. They only allow sequential access, which might be a limitation depending on the use case. + +### Implementation Example + +```python +def fibonacci(): + a, b = 0, 1 + while True: + yield a + a, b = b, a + b + +# Usage +fib_gen = fibonacci() +for _ in range(10): + print(next(fib_gen)) +``` + +## Generator Expressions + +Generator expressions are similar to list comprehensions but return a generator object instead of a list. They offer a concise way to create generators without the need for a separate function. + +### Mathematical Formulation + +Generator expressions can also be represented mathematically using set-builder notation. The general form is the same as for function generators. + +### Advantages of Generator Expressions + +1. **Memory Efficiency**: Generator expressions produce values lazily, similar to function generators, resulting in memory savings. + +2. **Lazy Evaluation**: Values are generated on-the-fly as they are consumed, providing improved performance and reduced overhead. + +### Disadvantages of Generator Expressions + +1. **Single Iteration**: Like function generators, once a generator expression is exhausted, it cannot be reused. + +2. **Limited Random Access**: Generator expressions, similar to function generators, do not support random access. + +### Implementation Example + +```python +# Generate squares of numbers from 0 to 9 +square_gen = (x**2 for x in range(10)) + +# Usage +for num in square_gen: + print(num) +``` + +## Conclusion + +Generators offer a powerful mechanism for creating iterators efficiently in Python. By understanding the differences between function generators and generator expressions, along with their mathematical formulation, advantages, and disadvantages, you can leverage them effectively in various scenarios. Whether you're dealing with large datasets or need to work with infinite sequences, generators provide a memory-efficient solution with lazy evaluation capabilities, contributing to more elegant and scalable code. \ No newline at end of file diff --git a/contrib/advanced-python/index.md b/contrib/advanced-python/index.md index fa2fd7b..df4b545 100644 --- a/contrib/advanced-python/index.md +++ b/contrib/advanced-python/index.md @@ -9,3 +9,4 @@ - [Map Function](map-function.md) - [Protocols](protocols.md) - [Exception Handling in Python](exception-handling.md) +- [Generators](Generators.md) From f84da4252f1a80405a98451389d70c0ec2d1d3e0 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 21:39:17 +0530 Subject: [PATCH 42/45] Rename OOPs.md to oops.md --- contrib/advanced-python/{OOPs.md => oops.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/advanced-python/{OOPs.md => oops.md} (100%) diff --git a/contrib/advanced-python/OOPs.md b/contrib/advanced-python/oops.md similarity index 100% rename from contrib/advanced-python/OOPs.md rename to contrib/advanced-python/oops.md From 18003e05e2d9c9f019601c0bddd89e7eab456d90 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 21:39:35 +0530 Subject: [PATCH 43/45] Update index.md --- contrib/advanced-python/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/advanced-python/index.md b/contrib/advanced-python/index.md index fa2fd7b..16210c2 100644 --- a/contrib/advanced-python/index.md +++ b/contrib/advanced-python/index.md @@ -1,6 +1,6 @@ # List of sections -- [OOPs](OOPs.md) +- [OOPs](oops.md) - [Decorators/\*args/**kwargs](decorator-kwargs-args.md) - [Lambda Function](lambda-function.md) - [Working with Dates & Times in Python](dates_and_times.md) From 20494f222f48f91209a112475961cde7d1f01175 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 21:47:03 +0530 Subject: [PATCH 44/45] Update index.md --- contrib/advanced-python/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/advanced-python/index.md b/contrib/advanced-python/index.md index df4b545..0ce294f 100644 --- a/contrib/advanced-python/index.md +++ b/contrib/advanced-python/index.md @@ -9,4 +9,4 @@ - [Map Function](map-function.md) - [Protocols](protocols.md) - [Exception Handling in Python](exception-handling.md) -- [Generators](Generators.md) +- [Generators](generators.md) From bb245f09792e9853a7545503d56bcb027754ac19 Mon Sep 17 00:00:00 2001 From: Ankit Mahato Date: Sun, 2 Jun 2024 21:48:10 +0530 Subject: [PATCH 45/45] Update and rename Generators.md to generators.md --- contrib/advanced-python/{Generators.md => generators.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename contrib/advanced-python/{Generators.md => generators.md} (94%) diff --git a/contrib/advanced-python/Generators.md b/contrib/advanced-python/generators.md similarity index 94% rename from contrib/advanced-python/Generators.md rename to contrib/advanced-python/generators.md index ff5226e..96287ef 100644 --- a/contrib/advanced-python/Generators.md +++ b/contrib/advanced-python/generators.md @@ -1,8 +1,8 @@ -# Generators Under Advanced Python +# Generators ## Introduction -Generators in Python are a sophisticated feature that enables the creation of iterators without the need to construct a full list in memory. They allow you to generate values on-the-fly, which is particularly beneficial for working with large datasets or infinite sequences. In this README, we'll explore generators in depth, covering their types, mathematical formulation, advantages, disadvantages, and implementation examples. +Generators in Python are a sophisticated feature that enables the creation of iterators without the need to construct a full list in memory. They allow you to generate values on-the-fly, which is particularly beneficial for working with large datasets or infinite sequences. We will explore generators in depth, covering their types, mathematical formulation, advantages, disadvantages, and implementation examples. ## Function Generators @@ -84,4 +84,4 @@ for num in square_gen: ## Conclusion -Generators offer a powerful mechanism for creating iterators efficiently in Python. By understanding the differences between function generators and generator expressions, along with their mathematical formulation, advantages, and disadvantages, you can leverage them effectively in various scenarios. Whether you're dealing with large datasets or need to work with infinite sequences, generators provide a memory-efficient solution with lazy evaluation capabilities, contributing to more elegant and scalable code. \ No newline at end of file +Generators offer a powerful mechanism for creating iterators efficiently in Python. By understanding the differences between function generators and generator expressions, along with their mathematical formulation, advantages, and disadvantages, you can leverage them effectively in various scenarios. Whether you're dealing with large datasets or need to work with infinite sequences, generators provide a memory-efficient solution with lazy evaluation capabilities, contributing to more elegant and scalable code.