Wednesday, 27 November 2024

Data Structure and GUI: ADT, Comprehension, Time Complexity

 



Abstract Data Structures

Abstract data structures provide a logical way to organize and manipulate data. These include structures such as:

  • Stacks: Operate on a Last-In-First-Out (LIFO) principle.
  • Queues: Operate on a First-In-First-Out (FIFO) principle.
  • Trees: Hierarchical data structures with nodes connected by edges.
  • Graphs: Networks of nodes and edges.
  • Linked Lists: Sequences of nodes, where each node links to the next.

Primitive Data Structures

Primitive data structures are the most basic data types provided by programming languages:

  • Integer (int): Whole numbers.
  • Floating-point (float): Decimal numbers.
  • Character (char): Single characters.
  • Boolean (bool): True or False values.

Non-Primitive Data Structures

Non-primitive data structures are derived from primitive types and can store multiple values:

  • Arrays: Fixed-size collections of similar types.
  • Lists: Dynamic-size collections (e.g., Python list).
  • Dictionaries: Key-value pairs (e.g., Python dict).
  • Sets: Unordered collections of unique items.
  • Tuples: Immutable ordered collections.

List Comprehensions

A concise way to create lists using an expression inside square bracket:


# Example: Create a list of squares of numbers from 0 to 9 squares = [x**2 for x in range (10)]

Accessing Elements

  • Access by index: squares [2] give the 3rd element.
  • Slicing: squares [2:5] gives a sublist from index 2 to 4.

Performing Operations

  • Add elements: squares.append(100)
  • Modify elements: squares [1] = 10

Comprehension Using if

Filter elements with a condition:

# Example: Keep only even numbers evens = [x for x in range(10) if x % 2 == 0]


Comprehension Using if-else

Apply conditions to elements:

# Example: Label numbers as "Even" or "Odd" labels = ["Even" if x % 2 == 0 else "Odd" for x in range(10)]



Nested List Comprehensions

Used for working with multidimensional data:

# Example: Create a multiplication table table = [[i * j for j in range (1, 6)] for i in range (1, 6)]



Dictionary Comprehensions

Create dictionaries in a compact way:


# Example: Map numbers to their squares squares_dict = {x: x**2 for x in range (5)}

Accessing Elements

Access values by their key: squares_dict[2] gives the square of 2.

Performing Operations

  • Add a key-value pair: squares_dict[5] = 25
  • Update a value: squares_dict[2] = 10

Comprehension Using zip()

Combine two iterables into a dictionary:

keys = ['a', 'b', 'c'] values = [1, 2, 3] zipped_dict = {k: v for k, v in zip (keys, values)}


Comprehension for Lambda Functions

Use lambda functions in comprehensions:

# Example: Square numbers using lambda squared = [(lambda x: x**2)(x) for x in range (5)]


Nested Dictionary Comprehensions

Create dictionaries with complex structures:


# Example: Nested dictionary for students and their grades students = {f"Student {i}": {f"Subject {j}": j*10 for j in range(1, 4)} for i in range(1, 3)}


Processing Lists in Parallel

Using zip () to iterate over multiple lists simultaneously:


list1 = [1, 2, 3] list2 = [4, 5, 6] summed = [x + y for x, y in zip (list1, list2)]

This provides efficient and Pythonic ways to handle parallel list operations.


Time Functionality: Big O Notation

Case Scenarios

When evaluating an algorithm, we consider three scenarios:

  1. Best Case: Minimum time taken by an algorithm.
  2. Average Case: Average time over all inputs of a given size.
  3. Worst Case: Maximum time taken (used for Big O).

Example:

  • Searching in a list:
    • Best Case: The item is at the first position (O (1)).
    • Worst Case: The item is at the last position or not present (O(n)).

Time Complexity in Python Collections

Python collections like list, set, and dict have specific time complexities for various operations:

OperationListDictionarySet
IndexingO (1)N/AN/A
AppendingO (1)N/AN/A
InsertionO (n)O (1)O (1)
SearchingO (n)O (1)O (1)
DeletingO (n)O (1)O (1)
IterationO (n)O (n)O (n)


Tuesday, 26 November 2024

Regular Expression in Python.



Q. What is Regular Expression?

Ans: The word Regular comes from the concept of Regular Languages in automata theory.

Regular Languages can be represented using finite set of rules. These rules can be expressed using regular expression.

Example:

Here, we want to create a string of two letters a and b but there is one condition that each string must end with 'a'. if string ends with 'a' then only that string is in Regular Language 'L'., otherwise it is not in the Regular Language 'L'.

So, let's define Regular Language L: 

L = (a | b) * a

it means the language contains strings made of letter a and b, but every string must end with letter 'a'.

Program in Python:


import re

# Define the regular expression

pattern = r"(a|b)*a"

"""A regular expression (regex) is a sequence of characters that defines a search pattern, primarily used for pattern matching and manipulation in strings."""

# Test some strings

strings = ["a", "bab", "bba", "b", "bb", "ba"]

for s in strings:

    if re.fullmatch(pattern, s):

        print(f'"{s}" is in the language.')

    else:

        print(f'"{s}" is NOT in the language.')


------ end of program ------


Regular Expression Methods:

The regular expression (regex) method is used for

  • Searching, 
  • Matching, 
  • and Manipulating strings based on patterns.
How to use Regular Expression:
1. Defining Pattern:
    A regex pattern is composed of:

  • Literal Characters: Match exactly as they appear (e.g., cat matches the word "cat").
  • Special Characters (Meta-characters):
    • .: Matches any character except a newline.
    • *: Matches zero or more of the preceding character.
    • +: Matches one or more of the preceding character.
    • ?:Matches zero or one of the preceding character.
    • ^: Matches the start of a string.
    • $: Matches the end of a string.
    • []: Denotes a set of characters (e.g., [a-z] matches any lowercase letter).
    • |: Acts as an OR (e.g., cat|dog matches "cat" or "dog").
    • (): Groups patterns and captures matches.

2. Using Regex Methods:

import re

# Matching a pattern
match = re.search(r'\d+', 'The year is 2024')  

# Finds first occurrence of digits
print(match.group()) # Output: 2024

# Checking for a pattern
if re.match(r'^[a-zA-Z] +$', 'Hello'):
    print ("It's a valid word")

# Finding all matches
matches = re.findall(r'\b\w{3}\b', 'The cat sat on the mat')  

# Finds all three-letter words
print(matches) # Output: ['cat', 'sat', 'mat']

# Replacing matches
result = re.sub(r'\d+', 'YEAR', 'The year is 2024')
print(result) # Output: 'The year is YEAR'


Implementation 

1. re.split():

The re.split() function in Python is part of the re module and is used to split a string into a list based on a specified regular expression pattern.

Syntax: re.split(pattern, string, maxsplit=0, flags=0)

pattern: The regular expression pattern to split on.

string: The input string to be split on.

maxsplit: default 0 means no limit, the maximum number of splits to perform. (optional)

flags: (optional) Flags to modify the behavior of regular expression

Example:

import re

text = "one,two;three four"

result = re.split(r'[,\s;]+', text)  # Split on commas, spaces, or semicolons

print(result)

# Output: ['one', 'two', 'three', 'four']

--------------------------------------------------

text = "abc123def456ghi"

result = re.split(r'\d+', text)  # Split on one or more digits

print(result)

# Output: ['abc', 'def', 'ghi']

-----------------------------------------------------

text = "one,two;three four"

result = re.split(r'[,\s;]+', text, maxsplit=2) # Limit to 2 splits

print(result)

# Output: ['one', 'two', 'three four']

-------------------------------------------------------
text = "HelloWorldHELLOworld"
result = re.split(r'world', text, flags=re.IGNORECASE) # Case-insensitive split
print(result)
# Output: ['HelloWorldHELLO', '']

--------------------------------------------------------

2. re.sub():
The re.sub() function in Python is used to replace parts of a string that match a regular expression pattern with a specified replacement. It’s part of the re module, which provides powerful tools for text processing.

Syntax: re.sub(pattern, repl, string, count=0, flags=0)

pattern: The regular expression pattern to search for.
repl: The replacement string or a function to generate the replacement dynamically.
string: The input string to perform the replacements on.
count (optional): The maximum number of replacements to make. Default is 0 (no limit).
flags (optional): Flags to modify the behavior of the pattern (e.g., re.IGNORECASE).

Example:

import re

text = "The rain in Spain falls mainly in the plain."
result = re.sub(r'in', 'out', text)
print(result)
# Output: 'The raout out Spaout falls maonly out the plaout.'
-------------------------------------------------
# Limiting replacement
text = "123 456 789"
result = re.sub(r'\d', 'X', text, count=4) # Replace only the first 4 digits
print(result)
# Output: 'XXX X56 789'
----------------------------------------------------
# case insensitive replacement
text = "Python is great. python is fun!"
result = re.sub(r'python', 'JavaScript', text, flags=re.IGNORECASE)
print(result)
# Output: 'JavaScript is great. JavaScript is fun!'

------------------------------------------------------
# dynamic replacement using function.
def multiply_by_two(match):
    return str(int(match.group()) * 2)

text = "I have 3 apples and 5 oranges."
result = re.sub(r'\d+', multiply_by_two, text) # Multiply numbers by 2
print(result)
# Output: 'I have 6 apples and 10 oranges.'
----------------------------------------------------------

3. re.sub():
The re.subn() function in Python is similar to re.sub(), but it provides additional information about the number of substitutions made. It performs a search-and-replace operation using a regular expression and returns a tuple containing: 
The modified string.
The number of replacements made.

Returns: A tuple of the form as follows:
(modified_string, number_of_replacements)

Example:
import re

text = "one fish, two fish, red fish, blue fish"
result = re.subn(r'fish', 'whale', text)
print(result)
# Output: ('one whale, two whale, red whale, blue whale', 4)
--------------------------------------------------------
# Limiting replacement.
text = "apple apple apple"
result = re.subn(r'apple', 'orange', text, count=2) # Replace only the first 2 occurrences
print(result)
# Output: ('orange orange apple', 2)
---------------------------------------------------------
# using Regex group replacement
text = "123-456-789"
result = re.subn(r'(\d+)', r'[\1]', text)
print(result)
# Output: ('[123]-[456]-[789]', 3)
----------------------------------------------------------

4. re.compile():
The re.compile() function in Python is used to compile a regular expression pattern into a regex object. This object can then be reused multiple times for pattern matching, making it more efficient when the same pattern is used repeatedly.

Syntax: re.compile(pattern, flags=0)
pattern: The regular expression pattern to compile.
flags (optional): Flags to modify the behavior of the pattern, such as:
                          re.IGNORECASE or re.I: Case-insensitive matching.
                          re.MULTILINE or re.M: Multi-line matching.
re.DOTALL or re.S: Make . match newline characters.
re.VERBOSE or re.X: Allow more readable regex patterns with comments.

Benefits of Using re.compile():
Efficiency: Compiling a regex once avoids recompiling the pattern every time it’s used.
Readability: You can create a reusable regex object, which improves code clarity.
Advanced Configuration: Predefine flags and patterns for later use.

Example:
import re

pattern = re.compile(r'\d+')  # Matches one or more digits
result = pattern.findall("There are 123 apples and 456 oranges.")
print(result)
# Output: ['123', '456']
------------------------------------------------------------
# Case-insensitive matching
pattern = re.compile(r'hello', re.IGNORECASE)  
result = pattern.search("Hello, how are you?")
print(result.group())
# Output: 'Hello'
-------------------------------------------------------------
# Matches words with exactly 3 characters
pattern = re.compile(r'\b\w{3}\b')  

text1 = "The cat sat on the mat."
text2 = "A bat flew by."

# Use the compiled pattern on multiple strings
print(pattern.findall(text1)) # Output: ['cat', 'sat', 'the', 'mat']
print(pattern.findall(text2)) # Output: ['bat']

----------------------------------------------------------------

Match Object:

A match object in Python is the result of using methods like re.match(), re.search(), or re.finditer() from the re module. It contains information about the part of the string that matched the regular expression, and it provides methods and attributes to extract useful details about the match.

Example:

import re

pattern = r'\d+'
text = "The number is 12345."

# Get a match object using re.search()
match = re.search(pattern, text)

if match:
    print ("Match found:", match.group()) # Access the matched text
else:
    print ("No match found.")

-------------------------------------------------------
# Extracting information with group
# Match a product code like ABC-1234

text = "The product code is ABC-1234 and costs $45."

pattern = r'(\w+)-(\d+)'  
match = re.search(pattern, text)

if match:
    print ("Full Match:", match.group(0)) # Output: 'ABC-1234'
    print ("Code:", match.group(1)) # Output: 'ABC'
    print ("Number:", match.group(2)) # Output: '1234'
-----------------------------------------------------------------------

Raw String with 'r' or 'R' Prefix:

In Python, the r or R prefix before a string denotes a raw string literal. This tells Python to interpret the string literally, without processing escape sequences like \n, \t, or \\.

Why Use Raw Strings in Regex?
Regular expressions often use backslashes (\) for special characters (e.g., \d for digits). Without raw strings, these backslashes would need to be escaped (\\d), making the code harder to read and prone to errors. Raw strings simplify this by treating backslashes as literal characters.

Example:
import re

# Without raw string
pattern = "\\d+"
result = re.findall(pattern, "123 abc 456")
print(result) # Output: ['123', '456']

# With raw string
pattern = r"\d+"
result = re.findall(pattern, "123 abc 456")
print(result) # Output: ['123', '456']

Example:
import re

# *: 0 or more
print (re.findall(r"a*", "aaabbb")) # Output: ['aaa', '', '', '', '', '']

# +: 1 or more
print (re.findall(r"a+", "aaabbb")) # Output: ['aaa']

# ?: 0 or 1
print (re.findall(r"a?", "aaabbb")) # Output: ['a', 'a', 'a', '', '', '', '', '']

# {n}: exact number
print(re.findall(r"a{2}", "aaabbb")) # Output: ['aa']

# {n,}: n or more
print(re.findall(r"a{2,}", "aaabbb")) # Output: ['aaa']

# {n,m}: between n and m
print(re.findall(r"a{1,2}", "aaabbb")) # Output: ['aa', 'a']

-----------------------------------------------------------------------

3. Greedy vs Non-Greedy Quantifiers

Greedy Quantifiers:
By default, regex quantifiers are greedy, meaning they match as much text as possible.
Examples: *, +, {n,}

Non-Greedy Quantifiers:
Non-greedy quantifiers match as little text as possible. Add? to make a quantifier non-greedy.
Examples: *?, +?, {n,m}?

Example:

import re

text = "<tag>content</tag>"

# Greedy quantifier
result = re.findall(r"<.*>", text)
print(result)  
# Output: ['<tag>content</tag>'] (matches the entire string)

# Non-greedy quantifier
result = re.findall(r"<.*?>", text)
print(result)  
# Output: ['<tag>', '</tag>'] (matches the smallest possible matches)

---------------------------------------------------------------------------------

RegEx Flags:

Regex flags in Python modify the behavior of regular expression patterns. Flags are optional parameters you can pass to regex functions (re.compile(), re.search(), re.match(), etc.) to enable specific functionalities like case-insensitive matching, multi-line handling, and more.


Flags: 

re.IGNORECASE re.I Makes the pattern matching case-insensitive.

re.MULTILINE re.M Changes ^ and $ to match at the beginning and end of each line.

re.DOTALL re.S Makes the . match newline characters as well.

re.VERBOSE re.X Allows whitespace and comments in the regex pattern for readability.

re.ASCII re.A Makes \w, \d, \s match only ASCII characters (ignores Unicode).

re.LOCALE re.L Makes \w, \d, \s, etc., match based on the current locale settings.

re.UNICODE re.U Makes \w, \d, \s match Unicode characters (default in Python 3).


Monday, 25 November 2024

Python Built in Modules: datetime and random


 datetime Module:

Q. Why do we require datetime module?

Ans: The datetime module is very important module in python for any type of application that deals with date and time related functionality.

This library provides classes for manipulating dates and times. We can perform various operations such as date arithmetic, Formatting and parsing.


Q. What are the applications where i can use datetime module functionality?

Ans: Scheduling and Reminders application, Formatting dates for reports and user interface, Logging and Timestamps, Data analysis with time-based data.


Q. List the important classes in datetime module?

Ans: Following are the important key classes in datetime module.

  1. datetime: Represents date and time (year, month, day, hours, minutes, seconds, microseconds)
  2. date: Represents only the date (year, month, day)
  3. time: Represents only time (hours, minutes, seconds, microseconds)
  4. timedelta: Represents a duration, used for date and time arithmetic.
  5. tzinfo: An abstract base class for dealing with time zone.

Q. How do i display current date and time using datetime module?
Ans: first import the module in your program to use its inbuilt functionality.

from datetime import datetime

current_date_time = datetime. now ()

print ("Current date and Time", current_date_time)

Q. How to format date and time object?

# Format the datetime object
formatted = now.strftime("%Y-%m-%d %H:%M:%S")

print ("Formatted date and time:", formatted)


Q. What if you have given datetime in string format, can you parse it into date time object?
Ans:
# Parse a date string
date_string = "2024-11-25 14:30:00"

parsed_date = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")

print ("Parsed date and time:", parsed_date)


Q. Can we add 7 days in the current date, and can we subtract 30 minutes from current time in python using datetime module?
Ans: Yes, we can do this as follows.

from datetime import timedelta

# Add 7 days to the current date

future_date = now + timedelta(days=7)

print ("Future date:", future_date)

# Subtract 30 minutes from the current time

past_time = now - timedelta(minutes=30)

print ("Past time:", past_time)


Q. Can we compare date and time using datetime module?
Ans: Yes, we can compare date and time as follows.

# Compare two dates or times
if parsed_date > now:
    print ("Parsed date is in the future")
else:
    print ("Parsed date is in the past")

-------------------------------------------------------------------------------

 random Module:

Q. Why do we require random Module?
Ans: If we want to generate random number and wants to perform randomization task then in that case, we can use this python module to do the same. Through this module we can generate random floating point, integer number also we generate random sampling.

Q. How i can generate random floating-point number between 0.0 to 1.0.
Ans:

import random
# Generate a random float
print(random.random())

Q. How i can generate random integer number between a and b.
Ans:

# Generate a random integer between 1 and 10
print (random.randint(1, 10))


Q. How i can generate random floating-point number between a and b.
Ans:

# Generate a random float between 5 and 10
print (random.uniform(5, 10))


Q. can i randomly choose elements from the non-empty sequence like list or tuple.
Ans: Yes, we can do this by using choice () inside random module.

# Random choice from a list
day_of_marriage = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]

print (random.choice(day_of_marriage))

Q. can we shuffle the elements inside list.
Ans: Yes, we can shuffle the elements inside the list as follows.

numbers = [11, 22, 33, 44, 55]
random.shuffle(numbers)
print(numbers)

Q. can we use random module for dice roll?
Ans: Yes, we can use randint () function of random module.

print ("Roll a dice:", random.randint(1, 6))

Q. can we use random module for random password generation?
Ans:

import string
characters = string.ascii_letters + string.digits + string.punctuation

password = ''. join (random.choices(characters, k=12))

print ("Generated password:", password)

Q. can we use random module Lottery unique number from specified range?
Ans: Yes, you can.

# Select 6 unique numbers from 1 to 99
print ("Lottery numbers:", random.sample(range (1, 100), 6))


Sunday, 24 November 2024

FPP Python assignment no 8 to 9. Theory, Flowchart and Algorithm.


 

Assignment No:08

Problem Statement:  Write a python program to accept a file name from the user and perform the following operations 
1.Display the first N line of the file.
2.Find the frequency of occurrence of the word accepted from the user in the file.

Learning Objectives:
  • To understand the basics about python file handling.
  • To learn how to create a file in various mode and how to perform various operation on it.
Learning Outcomes:
  • Upon completing this lab exercise, the learner will be able to
  • Able to create file, write content in it and close the file. 
  • Able to open file in read mode, move the file pointer in any location inside the file. 
  • Understand the difference between data streaming and data buffering.
  • Implementation of file program for user specific requirements.

Theory:

  1. What is data streaming?
  2. What is data buffering?
  3. What is serial data?
  4. What is Input Output Stream and what is buffer?
  5. Explain in detail different file access modes.
  6. Write a simple file handling program for explanation of seek () function.
  7. Write a simple file handling program for explanation of tell () function.
  8. What types of exceptions occurs in file handling program and how to handle those.
  9. How to write inside file and how to read one character at a time from file.
  10. Differentiate between readline () and readlines () function in file handling. 

Note:
To get above question answers click the following link. Click the below link:
Write a python program to accept a file name from the user and perform operations. - DATA STRUCTURES AND ALGORITHMS

Algorithm:

Step 1: Start
Step 2: Accept the file name from the user.
Step 3: We are assuming that file is already created on HDD, so we simply open it into read mode.
Step 4: We are asking user how many n lines you want to display from file.
Step 5: Displaying the first n lines from the file.
Step 6: We are asking user to enter which word occurance he/she wants to find from the file. 
Step 7: Counting the occurance of that word from the file.
Step 8: Showing the occurance of that word to the user.
Step 9: Stop


Conclusion: Hence, we learn how to create the file on secondary storage using python programming. also, we learn various operations on file to process the data as per user requirement.


----------------------------------------------------------------------------------------------------------------------

Assignment No:09

Problem Statement:  
Write Python program covers basic functionalities provided by the math module.

Learning Objectives:
  • To understand the basics about python modules in python.
  • To learn various built-in modules inside python.
  • To learn regular expression and its methods in python.
Learning Outcomes:
  • Upon completing this lab exercise, the learner will be able to
  • Able to create modules inside python.
  • Able to create our own library by wrapping various function related with each other.
  • Understand the various built-in modules inside python like math module
  • Implementation of basic functionalities provided by the math module.

Theory:

  1. What is Module in python and how to create it?
  2. What is loading and reloading of module?
  3. Explain dir() function in python?
  4. How the module search path work in the python?
  5. List any nine methods of math modules.

Note:
To get above question answers click the following link. Click the below link:
Modules and Regular Expressions in Python. - DATA STRUCTURES AND ALGORITHMS

Algorithm:

Step 1: Start
Step 2: Display two constants of math module
Step 3: Call to basic functions in math modules.
Step 4: Call three Trigonometric functions from math modules.
Step 5: Call two Logarithmic functions from math module.
Step 6: Call two Exponential functions from math module. 
Step 7: Call two Rounding functions from math module.
Step 8: Call factorial and GCD functions from math module.
Step 9: Call Degree and Radians functions from math module.
Step 10: Stop


Conclusion: Hence, we learn all the functionalities inside math module.


Write a Python program that demonstrates the use of a recursive function, nested functions (FPP Assignment no 6)


Problem Statement:

Write a Python program that demonstrates the use of a recursive function, nested functions, and functional programming techniques such as map, filter, lambda functions and print the result, which is the sum of the squares of the even number.

Implementation / Python Code:

def sum_of_squares_of_evens(numbers):
    # Recursive function to calculate the sum of a list
    def recursive_sum(myLst):
        if not myLst:
            return 0
        return myLst[0] + recursive_sum(myLst[1:])

    # Nested function to calculate the square of a number
    def square(n):
        return n * n

    # Filter even numbers using a lambda function
    evens = filter (lambda x: x % 2 == 0, numbers)

    # Map to calculate the square of each number
    squares = map (square, evens)

    # Calculate and return the sum of squares
    return recursive_sum(list(squares))

# Example usage
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = sum_of_squares_of_evens(numbers)
print ("Sum of the squares of even numbers:", result)



Output:
Sum of the squares of even numbers: 220

Explanation:
1. First, we are accepting numbers inside numbers [] list which is 1 to 10.

2. We are calling the function sum_of_squares_of_evens (numbers) by passing numbers list as an argument for processing.

3. Control goes to the definition of sum_of_squares_of_evens (numbers): function. here we have written two functions definition inside it. 1. recursive_sum () function to find sum of the square of the even numbers. 2. square () function to find the square of the even numbers. now to call function definition we know function calling must be there so,

4. directly control goes to the line
evens = filter (lambda x: x % 2 == 0, numbers) for execution. here we just filtering the even numbers with the help of lambda function from whole numbers [] list and stored it inside evens [] list.

5. once we get the even number then we are calling map function to find square of all even numbers and stored it inside squares [] objects list who stores the map objects.
    squares = map (square, evens)
Here we use the concept of nested function. how so we first we call
sum_of_squares_of_evens (numbers) function
                     |
                     |
inside this function we call map () function from map () functions we call the square () function.

6. Now we have a square of all even numbers in squares which we are passing to the recursive function recursive_sum(list(squares)) to find out sum of all those squares.
here recursive means:

    def recursive_sum(myLst):
        if not myLst:
            return 0
        return myLst[0] + recursive_sum(myLst[1:])

assume myLst contains the squares of all even numbers from 1 to 10.
                0   1    2    3    4
myLst = [4, 16, 36, 64, 100]

so first it checks myLst [] elements are there or not if not return 0 but here myLst[] is having elements in it call once again the same function with different value. this time
myLst[0] = myLst[0] + recursive_sum(myLst[1]) # 16

again, it checks myLst[] elements are there or not if not return 0 else call once again the same function with different value. this time
myLst[0] = myLst[0] + recursive_sum(myLst[2]) # 36

again, it checks myLst[] elements are there or not if not return 0 else call once again the same function with different value. this time
myLst[0] = myLst[0] + recursive_sum(myLst[3]) #64

again, it checks myLst[] elements are there or not if not return 0 else call once again the same function with different value. this time
myLst[0] = myLst[0] + recursive_sum(myLst[4]) # 100

again, it checks myLst[] elements are there or not if not return 0 else call once again the same function with different value. this time
myLst[0] = myLst[0] + recursive_sum(myLst[5]) # 0

Now this time for recursive_sum(myLst[5]) elements are not there so it returns 0 now calling is done 5 times now for each function call (5 times) it returns the value as follows:

myLst[0] = myLst[0] + recursive_sum(myLst[5]) # return 0
myLst[0] = 4 + 0 => 4

myLst[0] = myLst[0] + recursive_sum(myLst[4]) # return 100
myLst[0] = 4 + 100 => 104

myLst[0] = myLst[0] + recursive_sum(myLst[3]) # return 64
myLst[0] = 104 + 64 => 168

myLst[0] = myLst[0] + recursive_sum(myLst[2]) # return 36
myLst[0] = 168 + 36 => 204

myLst[0] = myLst[0] + recursive_sum(myLst[1]) # return 16
myLst[0] = 204 + 16 => 220

Output: So, finally we get the output of sum is 220.
Sum of the squares of even numbers: 220
  
Hope you all get the clear idea of this program.


Saturday, 23 November 2024

Why do we require Map, Filter and Lambda Function?


The question comes to every developer mind is that what is function? and why do we need function? in any programming language.
Let's talk about what is function.
Ans: As we know in industry projects there are so many tasks inside one project. All those tasks are depending on each other or sometimes they work individually. There might be situation comes that same task we require more than one time in each module. so, in that case we have to write that specific task code in all those modules again and again. which ultimately increases the code size of project also readability of code also not there and in case any problem occurs then it is very tedious & time-consuming task to debug this code and rectify the bug.
How to overcome all those limitations simply the answer is using function.
Definition: To perform specific task repeatedly we write a block of code in programming that reusable block of code is called as function.

How to create function in python?
simple every function has its specific function name for eg: if i want to create addition function.

def addition ():
    a = 10
    b = 20
    c = a + b
    print ("addition of two number is:", c)

Here, def is the keyword you have to use compulsory while creating the function after that write function name that must be specific as per the logic of function. after that there is ( ): brackets that indicates either function is taking arguments/parameters as an input or not.
Every function process something and may or may not return the output to the caller function.

here is the example of function taking argument as an input. here we are passing two arguments or parameters that is a and b to addition function.

def addition (a, b):
    c = a + b
    print ("addition of two number is:", c)

When there is word function there are 3 things related with function that is:
1. Function Prototype Declaration: In this we are just deciding the prototype of function. Prototype means set of rules so, here we decide what is our function name, how many arguments it takes, after processing the data does this function return output to caller function or not. Example: addition (int, int): Here function name is addition, and it takes two arguments of type integer means we are setting the rule that this function must take data of type integer only.

2. Function Definition: Here in function definition, we write the logic of that specific task so that we can reuse this function again and again in various places inside the project. Example: if we want to add two integer number then function definition as follows:

def addition (a, b):
    c = a + b
    print ("addition of two number is:", c)

3. Function Calling: Function calling means we have to execute this function definition by calling it. so, when we call the function as per function prototype the body of function get execute and we will get the required output. Example: Now, we want to execute addition function then we must call this function like this:
a = 10
b = 20
addition (a, b) 

here in above code, we are accepting the two values from user and pass those values at the time of function calling for processing.

From the above discussion i hope there is no doubt that what is function and why do we require function. Now let's discuss why do we require map, filter and lambda function.

Why do we need Function?
Ans: We need function to overcome the limitation mentioned above as follows:
  1. To avoid repetition of code.
  2. To improve the code readability.
  3. To simplifies the code debugging.
  4. To enables reusability of code.
  5. To modularize the code.

1. What is the use of map function in python?
Ans: A map is built in function in python. We used map function to map specific functions into looping items.
For Example: I want to find out even numbers from the given numbers list and find out the square of all those even number so without using map function i have to write code as follows:

Without map function:

numbers = [11, 22, 33, 44, 55, 66]
evens = []
for n in numbers:
    if n % 2 == 0:
        evens. append(n)
print(evens) # Output: [22, 44, 66]

evens = [22, 44, 66]
square = []
for a in evens:
    a = a*a:
    square. append(a)
print(square)# Output: [484, 1936, 4356]


Total we have to write 12 lines of code. what we have done here, we first create one list of numbers [] where we take six numbers like 11 to 66 in it. Now among this number we want to find even numbers, so we create one more list of evens [] to store even numbers in it.
To find out the even numbers from numbers [] list we iterate or loop through each element of list by using for loop and check using decision making statement if that either this number is even or odd. if the number is even, we append it inside evens list and so on.
Finally processing all the elements from list will get all even numbers inside evens list and lastly, we display all those numbers to user.
Next, we want to find out the square of all those even numbers from the evens list. so once again we want to process each element from the evens [] list one by one so, we need for loop for the same so, accordingly we use for loop take one element from evens list then find out its square and append this square inside square list. finally, we display all the squared element to the user.

With map function:

Now when we use map function then there is no need to use boiler plate of for loop means without using for loop, we can process all elements inside the list with the help of map and filter function.
How, let's see how we use map () in various way and then at last we do above task.

Syntax:
map (function, Iterable)

 1. using map () we can apply specific function to each element of list.

Without Map means using loop how we do this as follows:

numbers = [11, 22, 33, 44]
twice = []
for n in numbers:
    twice. append (n * 2)
print(twice) # Output: [22, 44, 66, 88]

With Map means without using loop how we do this as follows:

numbers = [11, 22, 33, 44]
twice = list (map (lambda x: x * 2, numbers))
print(twice) # Output: [22, 44, 66, 88]

Explanation:
Now question comes to your mind is how map () works and what is lambda and how it works?

First let's discuss what lambda is.
Using lambda, we can avoid the overhead (means defining the function body and writing that one line of code in it) of defining separate function for easy or simple task.

For example, if we want to do twice each element from numbers list without using lambda function then we have to write definition of twice () function then only it is possible like follows:

def Twice (a):
    return a*2

numbers = (1, 2, 3, 4, 5, 6)
result = map (Twice, numbers)
print (list (result) #Output: 2, 4, 6, 8, 10, 12


How lambda does the same task in one line of code instead of 2 lines of code, because inside function definition there is only one line of code which is very simple.

Twice = lambda x: x*2
print (Twice (5) #Output: 10

why use lambda?
Ans: Without using lambda, you would have to define or write a separate named function even for small or simple one line of tasks, making the code unnecessarily lengthy.

So, when to use lambda?
Ans: When we want to create small unnamed (anonymous) functions in a single line which is often used for short-term, simple operations. 

twice = list (map (lambda x: x * 2, numbers))

Now, we understand how lambda works in it and why to use it. so, in above line of code lambda takes x values from numbers [] with the help of map function find out its double and return that it in map object form. finally, we convert this map object into list type and stored it inside twice [] list.

2. Converting data types into strings.

strings = ["11", "22", "33", "44"]
integers = list (map (int, strings))
print (integers) # Output: [11, 22, 33, 44] 

3. Applying a function to multiple Iterables.

mylist1 = [10, 20, 30]
mylist2 = [44, 55, 66]
sum = list (map (lambda a, b: a + b, mylist1, mylist2))
print(sum) # Output: [54, 75, 96]

4. Applying a predefined function: you can pass predefined function to map.

def square_my_num(x):
    return x ** 2

numbers = [ 2, 3, 4]
squared_list = list (map (square_my_num, numbers))
print(squared_list) # Output: [4, 9, 16]

5. Processing of Strings: Capitalize each string from string list.


names = ["ramnath", "somnath", "tejas", "pallavi"]
capitalized = list (map (str.capitalize, names))
print(capitalized) # Output: ['Ramnath', 'Somnath', 'Tejas', 'Pallavi']

Now, Concepts related with map and lambda i think gets clear idea of it.

Now What is Filter?
Ans: Filters elements from a list (or other iterable) based on a condition, returning only those that meet the condition.

Why to use Filter and when to use it?
Ans: If we are not using inbuilt function Filter then we need to write loop statement and decision-making statement to filter the element from the list. which ultimately increases the code size.

Example: Suppose we want to filter even numbers from the given list.

Without using Filter:

numbers = [11, 22, 33, 44, 55, 66]
evens = []
for n in numbers:
    if n % 2 == 0:
        evens.append(n)
print(evens) # Output: [22, 44, 66]

Using Filter:

numbers = [1, 2, 3, 4, 5, 6]
evens = list (filter (lambda x: x % 2 == 0, numbers))
print(evens) # Output: [2, 4, 6]

Explanation: Based on the lambda functions condition the elements from the numbers [] list get filter and stored inside the evens [] list. here we observe that no need to write looping and condition statement the inbuilt function filter does it automatically for us.


Let's combine this 3 functions map, filter and lambda in one example.

numbers = [11, 22, 33, 44]

# Filter even numbers

evens = filter (lambda x: x % 2 == 0, numbers) # [22, 44]

# Square the even numbers

squared = map (lambda x: x ** 2, evens) # [ 484, 1936]

# Convert to list and print

result = list(squared)

print(result) # Output: [484, 1936]