Wednesday, 1 January 2025

Basics and need of Data Science and Big Data, Applications of Data Science

 




























Sunday, 1 December 2024

FPP Assignment No 14 and 15

Problem Statement:
Develop a program to create a DataFrame from a NumPy array with custom column names.


import numpy as np import pandas as pd # Create a NumPy array data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Define custom column names columns = ['Column A', 'Column B', 'Column C'] # Create a DataFrame df = pd.DataFrame(data, columns=columns) print("DataFrame created from NumPy array:") print(df)

2. Drawing a Bar Plot and Scatter Plot using Matplotlib


import matplotlib.pyplot as plt
# Data for plots categories = ['A', 'B', 'C', 'D'] values = [4, 7, 1, 8] x = [1, 2, 3, 4] y = [10, 20, 25, 30] # Bar Plot plt.figure(figsize=(8, 4)) plt.bar(categories, values, color='skyblue') plt.title("Bar Plot") plt.xlabel("Categories") plt.ylabel("Values") plt.show() # Scatter Plot plt.figure(figsize=(8, 4)) plt.scatter(x, y, color='red', label='Points') plt.title("Scatter Plot") plt.xlabel("X-axis") plt.ylabel("Y-axis") plt.legend() plt.show()

Explanation:

  1. DataFrame Creation:

    • The program uses np.array to create a data matrix.
    • Custom column names are passed to pd.DataFrame to create the DataFrame.
  2. Bar Plot:

    • A bar plot is drawn using plt.bar, with labels for categories and values.
  3. Scatter Plot:

    • A scatter plot is created using plt.scatter, with x and y as input points.

Let me know if you'd like to expand or modify these examples!

Friday, 29 November 2024

FPP Assignment No 13

 Problem Statement:  Create a basic CGI script in Python that allows students to submit their name and grade through a form and displays a personalized message based on their input?




Prerequisites

  1. Ensure you have a web server capable of running CGI scripts (e.g., Apache or Python's built-in HTTP server with CGI enabled).
  2. Save the script in a directory configured for CGI execution (e.g., cgi-bin).


Save this script as student_form.py in your CGI directory.

import cgi

import cgitb


# Enable debugging

cgitb.enable()


def main ():

    # Output HTTP headers

    print ("Content-Type: text/html\n")


    # Get form data

    form = cgi.FieldStorage()

    name = form.getvalue("name", ""). strip()

    grade = form.getvalue("grade", ""). strip ()


    # HTML Response

    print ("""

    <!DOCTYPE html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>Student Grade Submission</title>

    </head>

    <body>

    """)

    

    if not name or not grade:

        print ("""

        <h1>Student Grade Submission</h1>

        <form method="post" action="student_form.py">

            <label for="name">Name:</label><br>

            <input type="text" id="name" name="name" required><br><br>

            <label for="grade">Grade:</label><br>

            <input type="text" id="grade" name="grade" required><br><br>

            <button type="submit">Submit</button>

        </form>

        """)

    else:

        # Generate personalized message

        try:

            grade = float(grade)

            if grade >= 90:

                message = "Excellent work!"

            elif grade >= 75:

                message = "Good job, keep improving!"

            elif grade >= 50:

                message = "You passed, but there's room for improvement."

            else:

                message = "Unfortunately, you did not pass. Better luck next time!"

        except ValueError:

            message = "Invalid grade input. Please enter a numeric grade."

        

        print (f"""

        <h1>Hello, {name}! </h1>

        <p>Your grade is: {grade}</p>

        <p>{message}</p>

        <a href="student_form.py">Submit another grade</a>

        """)

    

    print ("""

    </body>

    </html>

    """)


if __name__ == "__main__":

    main ()


FPP Assignment No 12 Write Python code that creates a simple graphical user interface (GUI) application.

Problem Statement: Write Python code that creates a simple graphical user interface (GUI) application. 


Program Implementation and Explanation:


import tkinter as tk

from tkinter import messagebox


def display_greeting():

    """Displays a greeting message."""

    name = name_entry.get()

    if name.strip():

        messagebox.showinfo("Greeting", f"Hello, {name}!")

    else:

        messagebox.showwarning("Input Error", "Please enter your name.")


# Create the main window

root = tk.Tk()

root.title("Greeting App")

root.geometry("300x200")  # Set window size


# Create and place widgets

greeting_label = tk.Label(root, text="Enter your name:", font=("Arial", 12))

greeting_label.pack(pady=10)


name_entry = tk.Entry(root, width=30, font=("Arial", 12))

name_entry.pack(pady=5)


greet_button = tk.Button(root, text="Greet Me!", font=("Arial", 12), command=display_greeting)

greet_button.pack(pady=10)


quit_button = tk.Button(root, text="Quit", font=("Arial", 12), command=root.quit)

quit_button.pack(pady=10)


# Start the application

root.mainloop()


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

Explanation:

1. tkinter(Library): It is the python standard Library.

2. root (Main Window): It represents the main GUI window which appears on the screen when we run the code.
geometry is the method to set the window size.
title is the method which sets the title of window.

3. Widgets: It is nothing but graphical component through which user can interact with the application.
Label: On main window if you want to display the text then we have to use Label widget.
Entry: If you want to supply input to the application the use this widget. accepting input from user.
Button: if you want button to perform some operation then use this widget.

4. Event Handling: When we click on button some event occurs immediately. that event is going to handle by following event handler.
command: through this parameter we bind the function that we want must happen after button click.
messagebox: It is the module used to display popup message.

5. root.mainloop(): This is the event loop; it runs continuously until and unless user does not close it.

FPP Assignment no 11 Backing up a given file.

Problem Statement: Develop a program to backing Up a given Folder (Folder in a current working directory) into a ZIP File by using relevant modules and suitable methods.


Program Implementation:


import os

import zipfile

from datetime import datetime


def backup_to_zip(folder):

    # Ensure the folder path is absolute

"""

An absolute path is a full path that specifies the location of a file or directory from the root directory (‘/’). It provides a complete address that points directly to a file or directory, regardless of the current working directory.

"""

    folder = os.path.abspath(folder)

    

    # Generate a unique filename for the ZIP file

    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

    zip_filename = f"{os.path.basename(folder)}_backup_{timestamp}.zip"

    

    print (f"Creating backup ZIP file: {zip_filename}")

    

    # Create the ZIP file

    with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as backup_zip:

        # Walk through the folder and add files to the ZIP

        for foldername, subfolders, filenames in os.walk(folder):

            print (f"Adding folder: {foldername}")

            # Add the current folder to the ZIP

            backup_zip.write(foldername, os.path.relpath(foldername, folder))

 """

relative path specifies the location of a file or directory in relation to the current working directory (often abbreviated as pwd). It does not start with a slash (‘/’), and it utilizes navigational shortcuts to refer to the file or directory.

"""

            # Add all files in this folder to the ZIP

            for filename in filenames:

                file_path = os.path.join(foldername, filename)

                arcname = os.path.relpath(file_path, folder)

                print (f"Adding file: {file_path}")

                backup_zip.write(file_path, arcname)

    

    print (f"Backup completed successfully! Saved as {zip_filename}")


# Example Usage

if __name__ == "__main__":

    folder_to_backup = input ("Enter the folder name to back up: ")

    if os.path.exists(folder_to_backup) and os.path.isdir(folder_to_backup):

        backup_to_zip(folder_to_backup)

    else:

        print (f"The folder '{folder_to_backup}' does not exist or is not a directory.")

 

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

Explanation:

Q. What is zipFile( ) ?

zipfile.ZipFile() is a Python class provided by the zipfile module. It allows you to create, read, write, and extract ZIP files. The zipfile module is part of Python's standard library, so you don't need to install additional packages to use it.

With the zipfile class you can open an existing zip file, or you can create a new zip file.

Here, is the syntax of how zip file is created.


zipfile.ZipFile(file, mode='r', compression=ZIP_STORED, allowZip64=True)


Parameters

  • file: The name of the ZIP file (str or file-like object). If you're creating a new ZIP file, provide the name here.
  • mode:
    • 'r': Read (default).
    • 'w': Write, creating a new ZIP file (overwrites if it exists).
    • 'x': Write, creating a new ZIP file (raises an error if it exists).
    • 'a': Append to an existing ZIP file or create a new one.
  • compression: The compression type. Possible values:
    • zipfile.ZIP_STORED: No compression (default).
    • zipfile.ZIP_DEFLATED: Compressed (requires zlib).
    • zipfile.ZIP_BZIP2: BZIP2 compression (requires bz2).
    • zipfile.ZIP_LZMA: LZMA compression (requires lzma).
  • allowZip64: Whether to enable ZIP64 extensions for large files (enabled by default).


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).