From c7f165fa424bf1df4779566ae71abc4ac8889678 Mon Sep 17 00:00:00 2001 From: Drishan Gupta <66329991+drishangupta@users.noreply.github.com> Date: Sun, 12 May 2024 01:30:53 +0530 Subject: [PATCH 01/20] Create decorator-kwargs-args.md WIP --- .../advanced-python/decorator-kwargs-args.md | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 contrib/advanced-python/decorator-kwargs-args.md diff --git a/contrib/advanced-python/decorator-kwargs-args.md b/contrib/advanced-python/decorator-kwargs-args.md new file mode 100644 index 0000000..9a9ab93 --- /dev/null +++ b/contrib/advanced-python/decorator-kwargs-args.md @@ -0,0 +1,93 @@ +# Advanced Python +## Functions as First class objects +Functions in Python are so called first class objects, which means they can be treated as variables, viz. functions can be used as arguments or they can be returned using the return keyword. + +**Example** + +```python +def func1(): + def func2(): + print("Printing from the inner function, func2") + return func2 + +``` +Assigning func1 to function_call object +```python +function_call=func1() +``` +Calling the function +```python +>> function_call() +``` +**Output** +``` +Printing from the inner function, func2 +``` +Here we have seen the use of function as a first class object, func2 was returned as the result of the execution of the outer function, func1. + +## *args +\* is an iterating operator used to unpack datatypes such as lists, tuples etc. +**For example** +```python +tuple1=(1,2,4,5,6,7) +print(tuple1) +print(*tuple1) +``` +In the above we have defined a tuple called tuple1 with the items (1,2,4,5,6,7). +First we print normally and the output for that is: +``` +(1, 2, 4, 5, 6, 7) + +``` +Then we print with the \* operator, where we will get the output as: +``` +1 2 4 5 6 7 +``` + +Here the \* operator has unpacked the tuple, tuple1. + +Now that you have understood why \* is used, we can take a look at *args. *args is used in functions so that positional arguments are stored in the variable args. *args is just a naming convention, *anything can be used +*args makes python functions flexible to handle dynamic arguments. +```python +def test1(*args): + print(args) + print(f"The number of elements in args = {len(args)}") +a=list(range(0,10)) +test1(*a) +``` +In the above snippet, we are sending a list of numbers to the test function which returns the following output: +``` +(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) +The number of elements in args = 10 +``` +If in the test1 we do not use \* in the argument + +```python +def test1(*args): + print(args) + print(f"The number of elements in args = {len(args)}") +a=list(range(0,10)) +test1(a) +``` +we get the following result. This is a tuple containing a list. +``` +([0, 1, 2, 3, 4, 5, 6, 7, 8, 9],) +The number of elements in args = 1 +``` +## **kwargs +**kwargs stands for keyword arguments. This is used for key and value pairs and similar to *args, this makes functions flexible enough to handle dynamic key value pairs in arguments. +```python +def test2(**kwargs): + print(kwargs) + print(f"The number of elements in kwargs = {len(kwargs)}") +test2(a=1,b=2,c=3,d=4,e=5) +``` +The above snippet uses some key-value pairs and out test2 function gives the following output: +``` +{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} +The number of elements in kwargs = 5 +``` +A dictionary with keys and values is obtained. + +## Decorators (@decorators) +Now that we understand what first class object, *args, **kwargs is, we can move to decorators. From bd0adc17fcc30dd619b59df1ea7c042b65a47801 Mon Sep 17 00:00:00 2001 From: Drishan Gupta <66329991+drishangupta@users.noreply.github.com> Date: Sun, 12 May 2024 03:23:39 +0530 Subject: [PATCH 02/20] Update decorator-kwargs-args.md --- .../advanced-python/decorator-kwargs-args.md | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/contrib/advanced-python/decorator-kwargs-args.md b/contrib/advanced-python/decorator-kwargs-args.md index 9a9ab93..91f1eb4 100644 --- a/contrib/advanced-python/decorator-kwargs-args.md +++ b/contrib/advanced-python/decorator-kwargs-args.md @@ -90,4 +90,57 @@ The number of elements in kwargs = 5 A dictionary with keys and values is obtained. ## Decorators (@decorators) -Now that we understand what first class object, *args, **kwargs is, we can move to decorators. +Now that we understand what first class object, *args, **kwargs is, we can move to decorators. Decorators are used to perform a task that needs to be performed for existing functions. If some task has to be performed for each function, we can write a function which will perform the task without us having to make changes in each function. + +**Sample Code:** +``` +import time +def multiplication(a,b): + start=time.time() + c=a*b + total=time.time()-start + print("Time taken for execution of multiplication",total) + return c + +def addition(a,b): + start=time.time() + c=a+b + total=time.time()-start + print("Time taken for execution of addition ",total) + return c + +multiplication(4,5) +addition(4,5) +``` + +In the above code, we had to calculate time and print the execution time seperately for each function leading to repeatation of code. This is where decorators come in handy. +The same functionality can be achieved with the help of a decorator. + +**Here's how:** +``` +import time +def time_find(function): + def wrapper(*args, **kwargs): + starttime=time.time() + function(*args, **kwargs) + total=time.time()-starttime + print(f"Time Taken by {function.__name__} to run is ",total) + return wrapper + +@time_find #to use a decorator, simply use @ above a function. +def multiply(a, b): + print(a*b) + +@time_find +def addition(a,b): + print(a+b) + +multiply(4,5) +addition(4,5) +``` + +The above method eleminates redundant code and makes the code cleaner. You may have observed that we have used *args and **kwargs in the wrapper function. This is so that this decorator function is flexible for all types of functions and their parameters and this way it can find out the execution time of any function with as many parameters as needed, we just need to use our decorator @time_find. + + + + From 55f8871a9e3a21dace285a7ea12dcc786b2e00c9 Mon Sep 17 00:00:00 2001 From: Drishan Gupta <66329991+drishangupta@users.noreply.github.com> Date: Sun, 12 May 2024 03:24:56 +0530 Subject: [PATCH 03/20] 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 82596a2..dac9890 100644 --- a/contrib/advanced-python/index.md +++ b/contrib/advanced-python/index.md @@ -1,3 +1,3 @@ # List of sections -- [Section title](filename.md) +- [Decorators/\*args/**kwargs](decorator-kwargs-args) From 4c979af5410b8bff9e9d14e1f79580c0abf42023 Mon Sep 17 00:00:00 2001 From: Drishan Gupta <66329991+drishangupta@users.noreply.github.com> Date: Sun, 12 May 2024 03:26:49 +0530 Subject: [PATCH 04/20] Updated the index --- 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 dac9890..5ea5081 100644 --- a/contrib/advanced-python/index.md +++ b/contrib/advanced-python/index.md @@ -1,3 +1,3 @@ # List of sections -- [Decorators/\*args/**kwargs](decorator-kwargs-args) +- [Decorators/\*args/**kwargs](decorator-kwargs-args.md) From a324545579de03abf78245aea4e24c2baf3d0440 Mon Sep 17 00:00:00 2001 From: Drishan Gupta <66329991+drishangupta@users.noreply.github.com> Date: Sun, 12 May 2024 13:50:31 +0530 Subject: [PATCH 05/20] Update decorator-kwargs-args.md --- contrib/advanced-python/decorator-kwargs-args.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/advanced-python/decorator-kwargs-args.md b/contrib/advanced-python/decorator-kwargs-args.md index 91f1eb4..402dcc6 100644 --- a/contrib/advanced-python/decorator-kwargs-args.md +++ b/contrib/advanced-python/decorator-kwargs-args.md @@ -93,7 +93,7 @@ A dictionary with keys and values is obtained. Now that we understand what first class object, *args, **kwargs is, we can move to decorators. Decorators are used to perform a task that needs to be performed for existing functions. If some task has to be performed for each function, we can write a function which will perform the task without us having to make changes in each function. **Sample Code:** -``` +```python import time def multiplication(a,b): start=time.time() @@ -117,7 +117,7 @@ In the above code, we had to calculate time and print the execution time seperat The same functionality can be achieved with the help of a decorator. **Here's how:** -``` +```python import time def time_find(function): def wrapper(*args, **kwargs): From bb1cb39110356e18b542917759dcddde10540544 Mon Sep 17 00:00:00 2001 From: Yatharth Date: Mon, 13 May 2024 11:58:31 +0530 Subject: [PATCH 06/20] added about bubble selection quick and merge sort --- contrib/ds-algorithms/index.md | 1 + contrib/ds-algorithms/sorting-algorithms.md | 329 ++++++++++++++++++++ 2 files changed, 330 insertions(+) create mode 100644 contrib/ds-algorithms/sorting-algorithms.md diff --git a/contrib/ds-algorithms/index.md b/contrib/ds-algorithms/index.md index 82596a2..810313c 100644 --- a/contrib/ds-algorithms/index.md +++ b/contrib/ds-algorithms/index.md @@ -1,3 +1,4 @@ # List of sections - [Section title](filename.md) +- [Sorting Algorithms](soritng-algorithms.md) diff --git a/contrib/ds-algorithms/sorting-algorithms.md b/contrib/ds-algorithms/sorting-algorithms.md new file mode 100644 index 0000000..6423b4b --- /dev/null +++ b/contrib/ds-algorithms/sorting-algorithms.md @@ -0,0 +1,329 @@ +# Sorting Algorithms + +In computer science, a sorting algorithm takes a collection of items and arranges them in a specific order. This order is usually determined by comparing the items using a defined rule. + +## Real Life Example of Sorting +- Sorting a deck of cards +- Sorting names in alphabetical order +- Sorting a list of items, etc. + +# Some common sorting techniques + +# 1. Bubble Sort + +Bubble sort is a basic sorting technique that iteratively steps through a list, comparing neighboring elements. If elements are out of order, it swaps them. While easy to understand, bubble sort becomes inefficient for large datasets due to its slow execution time. + +**Algorithm Overview:** +- **Pass by Pass:** During each pass, the algorithm iterates through the list. +- **Comparing Neighbors:** In each iteration, it compares adjacent elements in the list. +- **Swapping for Order:** If the elements are in the wrong order (typically, the first being larger than the second), it swaps their positions. +- **Bubbling Up the Largest:** This swapping process effectively pushes the largest element encountered in a pass towards the end of the list, like a bubble rising in water. +- **Repeating Until Sorted:** The algorithm continues making passes through the list until no more swaps are needed. This indicates the entire list is sorted. + + +## Bubble Sort Code in Python + +```python +def bubble_sort(arr): + n = len(arr) + for i in range(n): + for j in range(0, n-i-1): + if arr[j] > arr[j+1]: + arr[j], arr[j+1] = arr[j+1], arr[j] + +arr = [5, 3, 8, 1, 2] +bubble_sort(arr) +print("Sorted array:", arr) # Output: [1, 2, 3, 5, 8] +``` +## Example with Visualization + +Let's sort the list `[5, 3, 8, 1, 2]` using bubble sort. + +1. **Pass 1:** + - Comparing neighbors: `[3, 5, 1, 2, 8]` + - Swapping: `[3, 5, 1, 2, 8]` → `[3, 1, 5, 2, 8]` → `[3, 1, 2, 5, 8]` + - Result: `[3, 1, 2, 5, 8]` + +2. **Pass 2:** + - Comparing neighbors: `[1, 3, 2, 5, 8]` + - Swapping: `[1, 3, 2, 5, 8]` → `[1, 2, 3, 5, 8]` + - Result: `[1, 2, 3, 5, 8]` + +3. **Pass 3:** + - Comparing neighbors: `[1, 2, 3, 5, 8]` + - No swapping needed, the list is already sorted. + +## Complexity Analysis + +- **Worst Case:** `O(n^2)` comparisons and swaps. This happens when the list is in reverse order, and we need to make maximum swaps. +- **Best Case:** `O(n)` comparisons. This occurs when the list is already sorted, but we still need O(n^2) swaps because of the nested loops. +- **Average Case:** `O(n^2)` comparisons and swaps. This is the expected number of comparisons and swaps over all possible input sequences. + +
+
+
+ +# 2. Selection Sort + +Selection sort is a simple sorting algorithm that divides the input list into two parts: a sorted sublist and an unsorted sublist. The algorithm repeatedly finds the smallest (or largest, depending on sorting order) element from the unsorted sublist and moves it to the sorted sublist. It's not efficient for large datasets but performs better than bubble sort due to fewer swaps. + +**Algorithm Overview:** +- **Initial State:** The entire list is considered unsorted initially. +- **Selecting the Minimum:** The algorithm repeatedly selects the smallest element from the unsorted sublist and moves it to the sorted sublist. +- **Expanding the Sorted Sublist:** As elements are moved to the sorted sublist, it expands until all elements are sorted. +- **Repeating Until Sorted:** The process continues until the entire list is sorted. + +## Example with Visualization + +Let's sort the list `[5, 3, 8, 1, 2]` using selection sort. + +1. **Pass 1:** + - Initial list: `[5, 3, 8, 1, 2]` + - Find the minimum: `1` + - Swap with the first element: `[1, 3, 8, 5, 2]` + +2. **Pass 2:** + - Initial list: `[1, 3, 8, 5, 2]` + - Find the minimum: `2` + - Swap with the second element: `[1, 2, 8, 5, 3]` + +3. **Pass 3:** + - Initial list: `[1, 2, 8, 5, 3]` + - Find the minimum: `3` + - Swap with the third element: `[1, 2, 3, 5, 8]` + +4. **Pass 4:** + - Initial list: `[1, 2, 3, 5, 8]` + - Find the minimum: `5` + - No swapping needed, the list is already sorted. + +## Selection Sort Code in Python + +```python +def selection_sort(arr): + n = len(arr) + for i in range(n): + min_index = i + for j in range(i+1, n): + if arr[j] < arr[min_index]: + min_index = j + arr[i], arr[min_index] = arr[min_index], arr[i] + +arr = [5, 3, 8, 1, 2] +selection_sort(arr) +print("Sorted array:", arr) # Output: [1, 2, 3, 5, 8] +``` + +## Complexity Analysis +- **Worst Case**: `O(n^2)` comparisons and O(n) swaps. This occurs when the list is in reverse order, and we need to make maximum comparisons and swaps. +- **Best Case**: `O(n^2)` comparisons and O(n) swaps. This happens when the list is in sorted order, but the algorithm still needs to iterate through all elements for comparisons. +- **Average Case**: `O(n^2)` comparisons and O(n) swaps. This is the expected number of comparisons and swaps over all possible input sequences. +
+
+
+ +# 3. Quick Sort +Quick sort is a popular divide-and-conquer sorting algorithm known for its efficiency on average. It works by selecting a 'pivot' element from the array and partitioning the other elements into two sub-arrays according to whether they are less than or greater than the pivot. The sub-arrays are then recursively sorted. + +**Algorithm Overview:** +- **Pivot Selection:** Choose a pivot element from the array. Common strategies include selecting the first, last, middle, or a randomly chosen element. +- **Partitioning:** Rearrange the array so that all elements less than the pivot are on its left, and all elements greater than the pivot are on its right. This step ensures that the pivot element is placed in its correct sorted position. +- **Recursion:** Apply the above steps recursively to the sub-arrays formed by partitioning until the base case is reached. The base case is usually when the size of the sub-array becomes 0 or 1, indicating it is already sorted. +- **Base Case:** If the sub-array size becomes 0 or 1, it is already sorted. + +## Example with Visualization + +Let's sort the list `[5, 3, 8, 1, 2]` using quick sort. + +1. **Initial Array:** `[5, 3, 8, 1, 2]` + +2. **Choose Pivot:** Let's choose the last element, `2`, as the pivot. + +3. **Partitioning:** + - We'll partition the array around the pivot `2`. All elements less than `2` will be placed to its left, and all elements greater than `2` will be placed to its right. + + - After partitioning, the array becomes `[1, 2, 5, 3, 8]`. The pivot element, `2`, is now in its correct sorted position. + +4. **Recursion:** + - Now, we recursively sort the sub-arrays `[1]` and `[5, 3, 8]`. + - For the sub-array `[5, 3, 8]`, we choose `8` as the pivot and partition it. + - After partitioning, the sub-array becomes `[3, 5, 8]`. The pivot element, `8`, is now in its correct sorted position. + + +5. **Concatenation:** + - Concatenating the sorted sub-arrays `[1]`, `[2]`, `[3, 5, 8]`, we get the final sorted array `[1, 2, 3, 5, 8]`. + +## Quick Sort Code in Python (Iterative) +```python +def partition(arr, low, high): + pivot = arr[high] + i = low - 1 + for j in range(low, high): + if arr[j] < pivot: + i += 1 + arr[i], arr[j] = arr[j], arr[i] + arr[i + 1], arr[high] = arr[high], arr[i + 1] + return i + 1 + +def quick_sort_iterative(arr): + stack = [(0, len(arr) - 1)] + while stack: + low, high = stack.pop() + if low < high: + pi = partition(arr, low, high) + stack.append((low, pi - 1)) + stack.append((pi + 1, high)) + +# Example usage: +arr = [38, 27, 43, 3, 9, 82, 10] +quick_sort_iterative(arr) +print("Sorted array:", arr) # Output: [3, 9, 10, 27, 38, 43, 82] + +``` +## Quick Sort Code in Python (Recursive) + +```python +def quick_sort(arr): + if len(arr) <= 1: + return arr + else: + pivot = arr[-1] + left = [x for x in arr[:-1] if x < pivot] + right = [x for x in arr[:-1] if x >= pivot] + return quick_sort(left) + [pivot] + quick_sort(right) + +arr = [5, 3, 8, 1, 2] +sorted_arr = quick_sort(arr) +print("Sorted array:", sorted_arr) # Output: [1, 2, 3, 5, 8] +``` +## Complexity Analysis + +- **Worst Case**: The worst-case time complexity of quick sort is `O(n^2)`. This occurs when the pivot selection consistently results in unbalanced partitioning, such as choosing the smallest or largest element as the pivot. +-**Best Case**: The best-case time complexity is `O(n log n)`. This happens when the pivot selection leads to well-balanced partitioning, halving the array size in each recursive call. +- **Average Case**: The average-case time complexity is `O(n log n)`. This is the expected time complexity when the pivot selection results in reasonably balanced partitioning across recursive calls. +- **Space Complexity**: Quick sort has an `O(log n)` space complexity for the recursion stack, as it recursively sorts sub-arrays. +
+
+
+ +# 4. Merge Sort + +Merge sort is a divide-and-conquer algorithm that recursively divides the input list into smaller sublists until each sublist contains only one element. Then, it repeatedly merges adjacent sublists while maintaining the sorted order until there is only one sublist remaining, which represents the sorted list. + +**Algorithm Overview:** +- **Divide:** Split the input list into smaller sublists recursively until each sublist contains only one element. +- **Merge:** Repeatedly merge adjacent sublists while maintaining the sorted order until there is only one sublist remaining, which represents the sorted list. + +## Example with Visualization + +Let's sort the list `[38, 27, 43, 3, 9, 82, 10]` using merge sort. + +1. **Initial Division:** + - Divide the list into sublists: `[38, 27, 43, 3, 9, 82, 10]` + - Visually it looks like + `[38], [27], [43], [3], [9], [82], [10]` + +2. **Merge Passes:** + - Merge adjacent sublists while maintaining sorted order: + - Pass 1: `[27, 38]`, `[3, 43]`, `[9, 82]`, `[10]` + - Pass 2: `[3, 27, 38, 43]`, `[9, 10, 82]` + - Pass 3: `[3, 9, 10, 27, 38, 43, 82]` + + +3. **Final Sorted List:** + - `[3, 9, 10, 27, 38, 43, 82]` + +## Merge Sort Code in Python (Iterative) + +```python +def merge_sort_iterative(arr): + n = len(arr) + curr_size = 1 + while curr_size < n: + left = 0 + while left < n - 1: + mid = min(left + curr_size - 1, n - 1) + right = min(left + 2 * curr_size - 1, n - 1) + merge(arr, left, mid, right) + left += 2 * curr_size + curr_size *= 2 + +def merge(arr, left, mid, right): + n1 = mid - left + 1 + n2 = right - mid + L = [0] * n1 + R = [0] * n2 + for i in range(n1): + L[i] = arr[left + i] + for j in range(n2): + R[j] = arr[mid + 1 + j] + i = j = 0 + k = left + while i < n1 and j < n2: + if L[i] <= R[j]: + arr[k] = L[i] + i += 1 + else: + arr[k] = R[j] + j += 1 + k += 1 + while i < n1: + arr[k] = L[i] + i += 1 + k += 1 + while j < n2: + arr[k] = R[j] + j += 1 + k += 1 + +arr = [38, 27, 43, 3, 9, 82, 10] +merge_sort_iterative(arr) +print("Sorted array:", arr) # Output: [3, 9, 10, 27, 38, 43, 82] +``` +## Merge Sort Code in Python (Recursive) +```python +def merge_sort(arr): + if len(arr) > 1: + mid = len(arr) // 2 + left_half = arr[:mid] + right_half = arr[mid:] + + merge_sort(left_half) + merge_sort(right_half) + + i = j = k = 0 + + # Merge the two sorted halves + while i < len(left_half) and j < len(right_half): + if left_half[i] < right_half[j]: + arr[k] = left_half[i] + i += 1 + else: + arr[k] = right_half[j] + j += 1 + k += 1 + + # Check if any elements are remaining in the left half + while i < len(left_half): + arr[k] = left_half[i] + i += 1 + k += 1 + + # Check if any elements are remaining in the right half + while j < len(right_half): + arr[k] = right_half[j] + j += 1 + k += 1 + +# Example usage: +arr = [38, 27, 43, 3, 9, 82, 10] +merge_sort(arr) +print("Sorted array:", arr) # Output: [3, 9, 10, 27, 38, 43, 82] +``` +## Complexity Analysis +- **Time Complexity**: `O(n log n)` for all cases. Merge sort always divides the list into halves until each sublist contains only one element, and then merges them back together, resulting in O(n log n) time complexity. +- **Space Complexity**: `O(n)` auxiliary space. In the iterative version, merge sort uses additional space for creating temporary sublists during merging operations. + +
+
+
From 0855a5ec6ea38dce5b9796097ed2b20e28b8b602 Mon Sep 17 00:00:00 2001 From: Yatharth Date: Mon, 13 May 2024 12:03:36 +0530 Subject: [PATCH 07/20] linked sorting-algorithms --- contrib/ds-algorithms/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ds-algorithms/index.md b/contrib/ds-algorithms/index.md index 810313c..5b52155 100644 --- a/contrib/ds-algorithms/index.md +++ b/contrib/ds-algorithms/index.md @@ -1,4 +1,4 @@ # List of sections - [Section title](filename.md) -- [Sorting Algorithms](soritng-algorithms.md) +- [Sorting Algorithms](sorting-algorithms.md) From ea62a209dce341eddb9c53a3b8865bd29f7c3843 Mon Sep 17 00:00:00 2001 From: Yatharth Date: Mon, 13 May 2024 12:25:42 +0530 Subject: [PATCH 08/20] added project Convert_JSON_to_CSV --- .../Convert_JSON_to_CSV/README.md | 20 +++++++++++++++++++ .../Convert_JSON_to_CSV/convert.py | 15 ++++++++++++++ .../Convert_JSON_to_CSV/input.json | 12 +++++++++++ .../Convert_JSON_to_CSV/output.csv | 3 +++ 4 files changed, 50 insertions(+) create mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/README.md create mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/convert.py create mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/input.json create mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/output.csv diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/README.md b/contrib/mini-projects/Convert_JSON_to_CSV/README.md new file mode 100644 index 0000000..a14aeb6 --- /dev/null +++ b/contrib/mini-projects/Convert_JSON_to_CSV/README.md @@ -0,0 +1,20 @@ +# Convert a JSON File into a CSV + +This script takes a JSON file as input and generates a CSV file as output. + +## Prerequisites modules +- `json`: This module is required for handling JSON files. +- Run `pip install json` to install the required external module. + +## How to Run the Script +1. Make sure you have the necessary prerequisites installed. +2. Download or clone the script `converter.py`. +3. Open a terminal or command prompt. +4. Navigate to the directory where `converter.py` is located. +5. Run the script by executing the command `py converter.py`. + +## Additional Information +- The script reads data from the input JSON file and converts it into CSV format. +- It handles nested JSON structures and converts them into flattened CSV rows. +- The output CSV file is created in the same directory as the input JSON file. +- You can customize the behavior of the script by modifying the source code according to your requirements. diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/convert.py b/contrib/mini-projects/Convert_JSON_to_CSV/convert.py new file mode 100644 index 0000000..0e52649 --- /dev/null +++ b/contrib/mini-projects/Convert_JSON_to_CSV/convert.py @@ -0,0 +1,15 @@ +import json + +if __name__ == '__main__': + try: + with open('input.json', 'r') as f: + data = json.loads(f.read()) + + output = ','.join([*data[0]]) + for obj in data: + output += f'\n{obj["Name"]},{obj["age"]},{obj["birthyear"]}' + + with open('output.csv', 'w') as f: + f.write(output) + except Exception as ex: + print(f'Error: {str(ex)}') \ No newline at end of file diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/input.json b/contrib/mini-projects/Convert_JSON_to_CSV/input.json new file mode 100644 index 0000000..f943006 --- /dev/null +++ b/contrib/mini-projects/Convert_JSON_to_CSV/input.json @@ -0,0 +1,12 @@ +[ + { + "Name": "Yatharth", + "age": 21, + "birthyear": "2003" + }, + { + "Name": "Sangita", + "age": 53, + "birthyear": "1971" + } + ] \ No newline at end of file diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/output.csv b/contrib/mini-projects/Convert_JSON_to_CSV/output.csv new file mode 100644 index 0000000..d841013 --- /dev/null +++ b/contrib/mini-projects/Convert_JSON_to_CSV/output.csv @@ -0,0 +1,3 @@ +Name,age,birthyear +Yatharth,21,2003 +Sangita,53,1971 \ No newline at end of file From ba5b874e2b90bad100370020a8629d6280e48584 Mon Sep 17 00:00:00 2001 From: Yatharth31 <118633431+Yatharth31@users.noreply.github.com> Date: Mon, 13 May 2024 12:31:10 +0530 Subject: [PATCH 09/20] Delete contrib/mini-projects/Convert_JSON_to_CSV directory --- .../Convert_JSON_to_CSV/README.md | 20 ------------------- .../Convert_JSON_to_CSV/convert.py | 15 -------------- .../Convert_JSON_to_CSV/input.json | 12 ----------- .../Convert_JSON_to_CSV/output.csv | 3 --- 4 files changed, 50 deletions(-) delete mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/README.md delete mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/convert.py delete mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/input.json delete mode 100644 contrib/mini-projects/Convert_JSON_to_CSV/output.csv diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/README.md b/contrib/mini-projects/Convert_JSON_to_CSV/README.md deleted file mode 100644 index a14aeb6..0000000 --- a/contrib/mini-projects/Convert_JSON_to_CSV/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Convert a JSON File into a CSV - -This script takes a JSON file as input and generates a CSV file as output. - -## Prerequisites modules -- `json`: This module is required for handling JSON files. -- Run `pip install json` to install the required external module. - -## How to Run the Script -1. Make sure you have the necessary prerequisites installed. -2. Download or clone the script `converter.py`. -3. Open a terminal or command prompt. -4. Navigate to the directory where `converter.py` is located. -5. Run the script by executing the command `py converter.py`. - -## Additional Information -- The script reads data from the input JSON file and converts it into CSV format. -- It handles nested JSON structures and converts them into flattened CSV rows. -- The output CSV file is created in the same directory as the input JSON file. -- You can customize the behavior of the script by modifying the source code according to your requirements. diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/convert.py b/contrib/mini-projects/Convert_JSON_to_CSV/convert.py deleted file mode 100644 index 0e52649..0000000 --- a/contrib/mini-projects/Convert_JSON_to_CSV/convert.py +++ /dev/null @@ -1,15 +0,0 @@ -import json - -if __name__ == '__main__': - try: - with open('input.json', 'r') as f: - data = json.loads(f.read()) - - output = ','.join([*data[0]]) - for obj in data: - output += f'\n{obj["Name"]},{obj["age"]},{obj["birthyear"]}' - - with open('output.csv', 'w') as f: - f.write(output) - except Exception as ex: - print(f'Error: {str(ex)}') \ No newline at end of file diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/input.json b/contrib/mini-projects/Convert_JSON_to_CSV/input.json deleted file mode 100644 index f943006..0000000 --- a/contrib/mini-projects/Convert_JSON_to_CSV/input.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "Name": "Yatharth", - "age": 21, - "birthyear": "2003" - }, - { - "Name": "Sangita", - "age": 53, - "birthyear": "1971" - } - ] \ No newline at end of file diff --git a/contrib/mini-projects/Convert_JSON_to_CSV/output.csv b/contrib/mini-projects/Convert_JSON_to_CSV/output.csv deleted file mode 100644 index d841013..0000000 --- a/contrib/mini-projects/Convert_JSON_to_CSV/output.csv +++ /dev/null @@ -1,3 +0,0 @@ -Name,age,birthyear -Yatharth,21,2003 -Sangita,53,1971 \ No newline at end of file From e58671c6a26a99ac03ced86ac7b70dc8b431e32e Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 14:18:50 +0530 Subject: [PATCH 10/20] Create Pandas_Series_Vs_NumPy_ndarray.md Created Pandas_Series_Vs_NumPy_ndarray.md file Added intro about Pandas series and NumPy ndarray Added Numpy ndarray section (Intro, key points, Used at) Added Pandas Series section (Intro, key points, Used at) --- .../pandas/Pandas_Series_Vs_NumPy_ndarray.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md diff --git a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md new file mode 100644 index 0000000..d60a058 --- /dev/null +++ b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md @@ -0,0 +1,53 @@ +# Pandas Series Vs NumPy ndarray + +NumPy ndarray and Pandas Series are two fundamental data structures in Python for handling and manipulating data. While they share some similarities, they also have distinct characteristics that make them suitable for different tasks. +## NumPy ndarray (n-dimensional array) + +NumPy is short form for Numerical Python, provides a powerful array object called `ndarray`, which is the backbone of many scientific and mathematical Python libraries. + +Here are key points about NumPy `ndarray`: + +- **Homogeneous Data**: All elements in a NumPy array are of the same data type, which allows for efficient storage and computation. +- **Efficient Computation**: NumPy arrays are designed for numerical operations and are highly efficient. They support vectorized operations, allowing you to perform operations on entire arrays rather than individual elements. +- **Multi-dimensional**: NumPy arrays can be multi-dimensional, making them suitable for representing complex numerical data structures like matrices and tensors. + +Example of creating a NumPy array: + +```python +import numpy as np + +narr = np.array(['A', 'B', 'C', 'D', 'E']) +print(narr) +``` +### Use NumPy ndarray: + +- When you need to perform mathematical operations on numerical data. +- When you’re working with multi-dimensional data. +- When computational efficiency is important. + +## Pandas Series + +Pandas, built on top of NumPy, introduces the `Series` data structure, which is designed for handling labeled one-dimensional data efficiently. + +Here are the key points about Pandas `Series`: + +- **Labeled Data**: Pandas Series associates a label (or index) with each element of the array, making it easier to work with heterogeneous or labeled data. + +- **Flexible Data Types**: Unlike NumPy arrays, Pandas Series can hold data of different types (integers, floats, strings, etc.) within the same object. + +- **Data Alignment**: One of the powerful features of Pandas Series is its ability to automatically align data based on label. This makes handling and manipulating data much more intuitive and less error-prone. + +Example of creating a Pandas Series: + +```python +import pandas as pd + +series = pd.Series([1, 3, 5, 7, 6, 8]) +print(series) +``` + +### Use Pandas Series: + +- When you need to manipulate and analyze labeled data. +- When you’re dealing with heterogeneous data or missing values. +- When you need more high-level, flexible data manipulation functions. From a269499c99f46be3d2ac087ff58c1e43888aa09a Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 14:20:18 +0530 Subject: [PATCH 11/20] Update Pandas_Series_Vs_NumPy_ndarray.md Extended Introduction --- contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md index d60a058..e71282b 100644 --- a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md +++ b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md @@ -1,6 +1,9 @@ # Pandas Series Vs NumPy ndarray NumPy ndarray and Pandas Series are two fundamental data structures in Python for handling and manipulating data. While they share some similarities, they also have distinct characteristics that make them suitable for different tasks. + +While both NumPy ndarray and Pandas Series are essential tools for data manipulation in Python, Choosing between them depends on the nature of your data and the specific tasks you need to perform. + ## NumPy ndarray (n-dimensional array) NumPy is short form for Numerical Python, provides a powerful array object called `ndarray`, which is the backbone of many scientific and mathematical Python libraries. From f61ceca303eeac22d84684a856a00fcffe18d926 Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 14:23:23 +0530 Subject: [PATCH 12/20] Update index.md Added Section title and Link to it --- contrib/pandas/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contrib/pandas/index.md b/contrib/pandas/index.md index 82596a2..cff8136 100644 --- a/contrib/pandas/index.md +++ b/contrib/pandas/index.md @@ -1,3 +1,5 @@ # List of sections +- Pandas Series Vs NumPy ndarray - [Section title](filename.md) +- [Pandas Series Vs NumPy ndarray)(Pandas_Series_Vs_NumPy_ndarray.md) From 33bae7b53f64715fccf0b2b2aa3aae481285eaf1 Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 14:24:24 +0530 Subject: [PATCH 13/20] Update index.md --- contrib/pandas/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contrib/pandas/index.md b/contrib/pandas/index.md index cff8136..c21ad57 100644 --- a/contrib/pandas/index.md +++ b/contrib/pandas/index.md @@ -1,5 +1,6 @@ # List of sections - Pandas Series Vs NumPy ndarray -- [Section title](filename.md) -- [Pandas Series Vs NumPy ndarray)(Pandas_Series_Vs_NumPy_ndarray.md) + + +- [Pandas Series Vs NumPy ndarray](Pandas_Series_Vs_NumPy_ndarray.md) From f87701802f2a48d476342096f64eb12e953cfdd7 Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 15:33:52 +0530 Subject: [PATCH 14/20] Update Pandas_Series_Vs_NumPy_ndarray.md Added Output for Code Snippets --- .../pandas/Pandas_Series_Vs_NumPy_ndarray.md | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md index e71282b..d493136 100644 --- a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md +++ b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md @@ -2,17 +2,17 @@ NumPy ndarray and Pandas Series are two fundamental data structures in Python for handling and manipulating data. While they share some similarities, they also have distinct characteristics that make them suitable for different tasks. -While both NumPy ndarray and Pandas Series are essential tools for data manipulation in Python, Choosing between them depends on the nature of your data and the specific tasks you need to perform. +Both NumPy ndarray and Pandas Series are essential tools for data manipulation in Python, Choosing between them depends on the nature of your data and the specific tasks you need to perform. -## NumPy ndarray (n-dimensional array) +## NumPy ndarray -NumPy is short form for Numerical Python, provides a powerful array object called `ndarray`, which is the backbone of many scientific and mathematical Python libraries. +NumPy is short form for Numerical Python, provides a powerful array object called `ndarray`, which is the backbone of many scientific and mathematical Python libraries. ndarray is also called n-dimensional array. Indexing in ndarray is integer based indexing. -Here are key points about NumPy `ndarray`: +Features of NumPy `ndarray`: - **Homogeneous Data**: All elements in a NumPy array are of the same data type, which allows for efficient storage and computation. -- **Efficient Computation**: NumPy arrays are designed for numerical operations and are highly efficient. They support vectorized operations, allowing you to perform operations on entire arrays rather than individual elements. -- **Multi-dimensional**: NumPy arrays can be multi-dimensional, making them suitable for representing complex numerical data structures like matrices and tensors. +- **Efficient Computation and Performance**: NumPy arrays are designed for numerical operations and are highly efficient. They support vectorized operations, allowing you to perform operations on entire arrays rather than individual elements. +- **Multi-dimensional**: NumPy arrays can be multi-dimensional, making them suitable for representing complex numerical data structures like matrices and n-dimensional arrays. Example of creating a NumPy array: @@ -22,21 +22,26 @@ import numpy as np narr = np.array(['A', 'B', 'C', 'D', 'E']) print(narr) ``` -### Use NumPy ndarray: +Output: +```python +['A' 'B' 'C' 'D' 'E'] +``` +### Usage of NumPy ndarray: - When you need to perform mathematical operations on numerical data. - When you’re working with multi-dimensional data. - When computational efficiency is important. +- When you need to store data of same data type. ` ## Pandas Series -Pandas, built on top of NumPy, introduces the `Series` data structure, which is designed for handling labeled one-dimensional data efficiently. +Pandas is a Python library used for data manipulation and analysis, introduces the `Series` data structure, which is designed for handling labeled one-dimensional data efficiently. -Here are the key points about Pandas `Series`: +Features of Pandas `Series`: - **Labeled Data**: Pandas Series associates a label (or index) with each element of the array, making it easier to work with heterogeneous or labeled data. -- **Flexible Data Types**: Unlike NumPy arrays, Pandas Series can hold data of different types (integers, floats, strings, etc.) within the same object. +- **Heterogeneous Data**: Unlike NumPy arrays, Pandas Series can hold data of different types (integers, floats, strings, etc.) within the same object. - **Data Alignment**: One of the powerful features of Pandas Series is its ability to automatically align data based on label. This makes handling and manipulating data much more intuitive and less error-prone. @@ -45,12 +50,23 @@ Example of creating a Pandas Series: ```python import pandas as pd -series = pd.Series([1, 3, 5, 7, 6, 8]) +series = pd.Series([1,'B', 5, 7, 6, 8], index = ['a','b','c','d','e','f']) print(series) ``` +Output: +```python +a 1 +b B +c 5 +d 7 +e 6 +f 8 +dtype: object +``` -### Use Pandas Series: +### Usage of Pandas Series: - When you need to manipulate and analyze labeled data. - When you’re dealing with heterogeneous data or missing values. - When you need more high-level, flexible data manipulation functions. +- When you are dealing with One-dimensional data. From 7cd0ec140e3a036a02b65a366d8336c02a8c016d Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 15:58:31 +0530 Subject: [PATCH 15/20] Update Pandas_Series_Vs_NumPy_ndarray.md --- contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md index d493136..e739766 100644 --- a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md +++ b/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md @@ -6,7 +6,7 @@ Both NumPy ndarray and Pandas Series are essential tools for data manipulation i ## NumPy ndarray -NumPy is short form for Numerical Python, provides a powerful array object called `ndarray`, which is the backbone of many scientific and mathematical Python libraries. ndarray is also called n-dimensional array. Indexing in ndarray is integer based indexing. +NumPy is short form for Numerical Python, provides a powerful array object called `ndarray`, It is very important for many scientific and mathematical Python libraries. ndarray is also called n-dimensional array. Indexing in ndarray is integer based indexing (like arr[0], arr[3], etc.). Features of NumPy `ndarray`: @@ -31,11 +31,11 @@ Output: - When you need to perform mathematical operations on numerical data. - When you’re working with multi-dimensional data. - When computational efficiency is important. -- When you need to store data of same data type. ` +- When you need to store data of same data type. ## Pandas Series -Pandas is a Python library used for data manipulation and analysis, introduces the `Series` data structure, which is designed for handling labeled one-dimensional data efficiently. +Pandas is a Python library used for data manipulation and analysis, introduces the `Series` data structure, which is designed for handling labeled one-dimensional data efficiently. Indexing in Pandas Series is Label-based. It effectively handles heterogeneous data. Features of Pandas `Series`: @@ -43,7 +43,7 @@ Features of Pandas `Series`: - **Heterogeneous Data**: Unlike NumPy arrays, Pandas Series can hold data of different types (integers, floats, strings, etc.) within the same object. -- **Data Alignment**: One of the powerful features of Pandas Series is its ability to automatically align data based on label. This makes handling and manipulating data much more intuitive and less error-prone. +- **Data Alignment**: One of the powerful features of Pandas Series is its ability to automatically align data based on label. Example of creating a Pandas Series: From d6184b240ea244d8804f450c91bbcca79fa521fe Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 16:04:53 +0530 Subject: [PATCH 16/20] Update index.md --- contrib/pandas/index.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/contrib/pandas/index.md b/contrib/pandas/index.md index c21ad57..8c7fa42 100644 --- a/contrib/pandas/index.md +++ b/contrib/pandas/index.md @@ -1,6 +1,3 @@ # List of sections -- Pandas Series Vs NumPy ndarray - - - [Pandas Series Vs NumPy ndarray](Pandas_Series_Vs_NumPy_ndarray.md) From 13bc6d8f3b5af50d9cb6676939e466d7c5e6a1e1 Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 17:07:48 +0530 Subject: [PATCH 17/20] Rename Pandas_Series_Vs_NumPy_ndarray.md to pandas_series_Vs_numpy_ndarray.md Renamed file name into lowercase --- ...ries_Vs_NumPy_ndarray.md => pandas_series_Vs_numpy_ndarray.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/pandas/{Pandas_Series_Vs_NumPy_ndarray.md => pandas_series_Vs_numpy_ndarray.md} (100%) diff --git a/contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md b/contrib/pandas/pandas_series_Vs_numpy_ndarray.md similarity index 100% rename from contrib/pandas/Pandas_Series_Vs_NumPy_ndarray.md rename to contrib/pandas/pandas_series_Vs_numpy_ndarray.md From 45f494f9c017ecadbae17e979d16e52fe46d8f07 Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 17:08:49 +0530 Subject: [PATCH 18/20] Update index.md Linked properly --- contrib/pandas/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/pandas/index.md b/contrib/pandas/index.md index 8c7fa42..5c0f2b4 100644 --- a/contrib/pandas/index.md +++ b/contrib/pandas/index.md @@ -1,3 +1,3 @@ # List of sections -- [Pandas Series Vs NumPy ndarray](Pandas_Series_Vs_NumPy_ndarray.md) +- [Pandas Series Vs NumPy ndarray](pandas_series_vs_numpy_ndarray.md) From 950a3136a0ef4b083b06d36bbef9453186c2add0 Mon Sep 17 00:00:00 2001 From: Lingamuneni Santhosh Siddhardha <103999924+Santhosh-Siddhardha@users.noreply.github.com> Date: Mon, 13 May 2024 17:10:35 +0530 Subject: [PATCH 19/20] Rename pandas_series_Vs_numpy_ndarray.md to pandas_series_vs_numpy_ndarray.md renamed file --- ...ries_Vs_numpy_ndarray.md => pandas_series_vs_numpy_ndarray.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename contrib/pandas/{pandas_series_Vs_numpy_ndarray.md => pandas_series_vs_numpy_ndarray.md} (100%) diff --git a/contrib/pandas/pandas_series_Vs_numpy_ndarray.md b/contrib/pandas/pandas_series_vs_numpy_ndarray.md similarity index 100% rename from contrib/pandas/pandas_series_Vs_numpy_ndarray.md rename to contrib/pandas/pandas_series_vs_numpy_ndarray.md From 378dbddc67a91ecebc6ccfb1fb38a8d45feaa0e2 Mon Sep 17 00:00:00 2001 From: Drishan Gupta <66329991+drishangupta@users.noreply.github.com> Date: Tue, 14 May 2024 08:44:20 +0530 Subject: [PATCH 20/20] Removed Formatting errors --- .../advanced-python/decorator-kwargs-args.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/contrib/advanced-python/decorator-kwargs-args.md b/contrib/advanced-python/decorator-kwargs-args.md index 402dcc6..63a41b3 100644 --- a/contrib/advanced-python/decorator-kwargs-args.md +++ b/contrib/advanced-python/decorator-kwargs-args.md @@ -6,9 +6,9 @@ Functions in Python are so called first class objects, which means they can be t ```python def func1(): - def func2(): - print("Printing from the inner function, func2") - return func2 + def func2(): + print("Printing from the inner function, func2") + return func2 ``` Assigning func1 to function_call object @@ -17,7 +17,7 @@ function_call=func1() ``` Calling the function ```python ->> function_call() +>>> function_call() ``` **Output** ``` @@ -50,8 +50,8 @@ Now that you have understood why \* is used, we can take a look at *args. *args *args makes python functions flexible to handle dynamic arguments. ```python def test1(*args): - print(args) - print(f"The number of elements in args = {len(args)}") + print(args) + print(f"The number of elements in args = {len(args)}") a=list(range(0,10)) test1(*a) ``` @@ -64,8 +64,8 @@ If in the test1 we do not use \* in the argument ```python def test1(*args): - print(args) - print(f"The number of elements in args = {len(args)}") + print(args) + print(f"The number of elements in args = {len(args)}") a=list(range(0,10)) test1(a) ``` @@ -78,8 +78,8 @@ The number of elements in args = 1 **kwargs stands for keyword arguments. This is used for key and value pairs and similar to *args, this makes functions flexible enough to handle dynamic key value pairs in arguments. ```python def test2(**kwargs): - print(kwargs) - print(f"The number of elements in kwargs = {len(kwargs)}") + print(kwargs) + print(f"The number of elements in kwargs = {len(kwargs)}") test2(a=1,b=2,c=3,d=4,e=5) ``` The above snippet uses some key-value pairs and out test2 function gives the following output: @@ -96,18 +96,18 @@ Now that we understand what first class object, *args, **kwargs is, we can move ```python import time def multiplication(a,b): - start=time.time() - c=a*b - total=time.time()-start - print("Time taken for execution of multiplication",total) - return c + start=time.time() + c=a*b + total=time.time()-start + print("Time taken for execution of multiplication",total) + return c def addition(a,b): - start=time.time() - c=a+b - total=time.time()-start - print("Time taken for execution of addition ",total) - return c + start=time.time() + c=a+b + total=time.time()-start + print("Time taken for execution of addition ",total) + return c multiplication(4,5) addition(4,5)