JOURNAL
ON
ADVANCED PYTHON PROGRAMMING AND JULIA
IN THE PROGRAMME
BACHELOR OF SCIENCE (ARTIFICIAL INTELLIGENCE)
SUBMITTED BY
AAGAM NITIN SHAH
BSC (A.I)
SDAI028A
SEMESTER III
UNDER THE GUIDANCE OF
Asst. Prof. HARSHAL JUIKAR, Mr. VIVEK WADHER
ACADEMIC YEAR
2025 – 2026
DECLARATION
I hereby declare that the journal of Advanced Python Programming and Julia
done at KES Shroff College, has not been in any case duplicated to
submit to any other university for the award of any degree. To the best of
my knowledge other than me, no one has submitted to any other
university.
The project is done in partial fulfillment of the requirements for the
award of degree of BACHELOR OF SCIENCE in ARTIFICIAL
INTELLIGENCE to be submitted SEM-III JOURNAL as part of our
curriculum.
Aagam Nitin Shah
JOURNAL
ON
ADVANCED PYTHON PROGRAMMING
IN THE PROGRAMME
BACHELOR OF SCIENCE (ARTIFICAL INTELLIGENCE)
SUBMITTED BY
AAGAM NITIN SHAH
BSC (A.I)
SDAI028A
SEMESTER III
UNDER THE GUIDANCE OF
Asst. Prof. HARSHAL JUIKAR
ACADEMIC YEAR
2025 – 2026
CERTIFICATE
This is to certify that Aagam Nitin shah of SECOND year of Bachelor of
Science in Artificial Intelligence, Roll No. SDAI028A of Semester III (2025
- 2026) has successfully completed the Journal of the subject Advanced
Python Programming as per the guidelines of KES’ Shroff College of Arts
and Commerce, Kandivali (W), Mumbai-400067.
Teacher In-charge Principal
Asst. Prof. Harshal Juikar Dr. Lily Bhushan
INDEX
Sr. Practical [Link] Sign
No.
1. Implement custom decorators for access control or 1-3
caching.
2. Build a generator for infinite data streams. 4
3. Create nested comprehensions for matrix 5
manipulation.
4. Read/write structured data in JSON and XML 6 - 10
formats.
5. Create a [Link] and parse using configparser. 11 - 14
6. Develop a multithreaded downloader using 15 - 18
threading.
7. Use multiprocessing to speed up file compression. 19 - 23
8. Perform asynchronous web scraping using aiohttp. 24 - 26
9. Create a RESTful API using FastAPI with GET 27 - 29
and POST routes.
PRACTICAL 1:
AIM: Implement custom decorators for access control or caching.
CODE:
from functools import wraps
import time
def memoize():
"""Decorator to store function results in cache."""
cache_dict = {}
def decorator(fn):
@wraps(fn)
def inner(*args, **kwargs):
# Create a key based on args and kwargs
key = (args, frozenset([Link]()))
if key in cache_dict:
print(f"[HIT] Using cache for '{fn.__name__}' with {key}")
return cache_dict[key]
else:
print(f"[MISS] Computing '{fn.__name__}' with {key}")
result = fn(*args, **kwargs)
cache_dict[key] = result
return result
return inner
return decorator
@memoize()
def fib(n):
"""Return nth Fibonacci number (slow intentionally)."""
if n <= 1:
return n
[Link](0.5)
return fib(n - 1) + fib(n - 2)
@memoize()
def slow_add(x, y):
"""Add two numbers slowly."""
[Link](1)
return x + y
print("--- Checking Memoization ---")
t1 = [Link]()
print(f"Sum1: {slow_add(15, 30)}")
t2 = [Link]()
print(f"Took: {t2 - t1:.4f}s\n")
t1 = [Link]()
print(f"Sum2: {slow_add(15, 30)}")
t2 = [Link]()
print(f"Took: {t2 - t1:.4f}s\n")
t1 = [Link]()
print(f"Sum3: {slow_add(10, 20)}")
t2 = [Link]()
print(f"Took: {t2 - t1:.4f}s\n")
print("\n--- Fibonacci with Cache ---")
print(f"fib(15) = {fib(15)}")
OUTPUT:
PRACTICAL 2:
AIM: Build a generator for infinite data streams.
CODE:
def square_numbers():
"""Generate infinite square numbers."""
n=0
while True:
yield n * n
n += 1
# Create generator
squares = square_numbers()
print("First 5 square numbers:")
for _ in range(5):
print(next(squares))
print("\nNext 5 square numbers:")
for _ in range(5):
print(next(squares))
OUTPUT:
PRACTICAL 3:
AIM: Create nested comprehensions for matrix manipulation.
CODE:
# Flatten a matrix
matrix = [[1, 3, 3], [4, 7, 6], [7, 4, 9]]
flat = [x for row in matrix for x in row]
print("Original matrix:", matrix)
print("Flattened list:", flat)
print("\n" + "="*30 + "\n")
# Transpose a matrix
mat = [[1, 3, 3], [4, 7, 6]]
transposed = [[row[i] for row in mat] for i in range(len(mat[0]))]
print("Original matrix:", mat)
print("Transposed matrix:", transposed)
print("\n" + "="*30 + "\n")
# Square each element
nums = [[1, 3, 3], [4, 5, 6]]
squared = [[n**2 for n in row] for row in nums]
print("Original matrix:", nums)
print("Squared matrix:", squared)
OUTPUT:
PRACTICAL 4:
AIM: Read/write structured data in JSON and XML formats.
CODE:
# Python code for handling JSON and XML data
import json
import [Link] as ET
from [Link] import minidom
# Sample data to work with
data = {
"name": "Ankush Yadav",
"age": 19,
"city": "mumbai",
"hobbies": ["reading", "gaming", "music"],
"contact": {
"email": "ankush@[Link]",
"phone": "123-456-7890"
}
}
# --- JSON Handling ---
# Writing to JSON file
def write_json(data, filename="[Link]"):
try:
with open(filename, 'w') as file:
[Link](data, file, indent=4)
print(f"Successfully wrote data to {filename}")
except Exception as e:
print(f"Error writing JSON: {e}")
# Reading from JSON file
def read_json(filename="[Link]"):
try:
with open(filename, 'r') as file:
data = [Link](file)
print("Successfully read JSON data:")
return data
except Exception as e:
print(f"Error reading JSON: {e}")
return None
# --- XML Handling ---
# Writing to XML file
def write_xml(data, filename="[Link]"):
try:
# Create root element
root = [Link]("person")
# Add simple elements
[Link](root, "name").text = data["name"]
[Link](root, "age").text = str(data["age"])
[Link](root, "city").text = data["city"]
# Add hobbies list
hobbies = [Link](root, "hobbies")
for hobby in data["hobbies"]:
[Link](hobbies, "hobby").text = hobby
# Add contact details
contact = [Link](root, "contact")
[Link](contact, "email").text = data["contact"]["email"]
[Link](contact, "phone").text = data["contact"]["phone"]
# Pretty print XML
rough_string = [Link](root, 'utf-8')
reparsed = [Link](rough_string)
pretty_xml = [Link](indent=" ")
with open(filename, 'w') as file:
[Link](pretty_xml)
print(f"Successfully wrote data to {filename}")
except Exception as e:
print(f"Error writing XML: {e}")
# Reading from XML file
def read_xml(filename="[Link]"):
try:
tree = [Link](filename)
root = [Link]()
# Convert XML to dictionary
data = {}
data["name"] = [Link]("name").text
data["age"] = int([Link]("age").text)
data["city"] = [Link]("city").text
# Get hobbies
data["hobbies"] = [[Link] for hobby in [Link]("hobbies")]
# Get contact details
data["contact"] = {
"email": [Link]("contact/email").text,
"phone": [Link]("contact/phone").text
}
print("Successfully read XML data:")
return data
except Exception as e:
print(f"Error reading XML: {e}")
return None
# Example usage
if __name__ == "__main__":
# JSON operations
print("=== JSON Operations ===")
write_json(data)
json_data = read_json()
print(json_data)
print("\n=== XML Operations ===")
write_xml(data)
xml_data = read_xml()
print(xml_data)
OUTPUT:
PRACTICAL 5:
AIM: Create a [Link] and parse using configparser.
CODE:
import configparser
import os
# Sample data
data = {
"person": {
"name": "Ankush Yadav",
"age": 19,
"city": "mumbai",
"hobbies": ["reading", "gaming", "music"],
"contact": {
"email": "ankush@[Link]",
"phone": "123-456-7890"
}
}
}
# Function to create and write to [Link]
def write_config(data, filename="[Link]"):
try:
config = [Link]()
# Create sections and add data
config['PERSON'] = {
'name': data['person']['name'],
'age': str(data['person']['age']), # Convert to string for INI
'city': data['person']['city'],
# Join list into a comma-separated string
'hobbies': ', '.join(data['person']['hobbies'])
}
config['CONTACT'] = {
'email': data['person']['contact']['email'],
'phone': data['person']['contact']['phone']
}
# Write to [Link]
with open(filename, 'w') as configfile:
[Link](configfile)
print(f"Successfully wrote data to {filename}")
except Exception as e:
print(f"Error writing config: {e}")
# Function to read and parse [Link]
def read_config(filename="[Link]"):
try:
config = [Link]()
[Link](filename)
# Reconstruct data structure
parsed_data = {
'person': {
'name': config['PERSON']['name'],
'age': int(config['PERSON']['age']), # Convert back to int
'city': config['PERSON']['city'],
'hobbies': [[Link]() for hobby in config['PERSON']['hobbies'].split(',')],
'contact': {
'email': config['CONTACT']['email'],
'phone': config['CONTACT']['phone']
}
}
}
print("Successfully read config data:")
return parsed_data
except Exception as e:
print(f"Error reading config: {e}")
return None
# Example usage
if __name__ == "__main__":
print("=== INI Operations ===")
write_config(data)
config_data = read_config()
print(config_data)
# Verify file exists
if [Link]("[Link]"):
print("\nContents of [Link]:")
with open("[Link]", 'r') as file:
print([Link]())
OUTPUT:
PRACTICAL 6:
AIM: Develop a multithreaded downloader using threading.
CODE:
import threading
import [Link]
import os
import time
def download_chunk(url, start_byte, end_byte, chunk_index, output_file, lock):
"""
Downloads a specific byte range of a file and writes it to the output file.
"""
try:
req = [Link](url)
req.add_header('Range', f'bytes={start_byte}-{end_byte}')
with [Link](req) as response:
data = [Link]()
with lock:
with open(output_file, 'r+b') as f:
[Link](start_byte)
[Link](data)
print(f"Chunk {chunk_index} downloaded successfully.")
except Exception as e:
print(f"Error downloading chunk {chunk_index}: {e}")
def multithreaded_downloader(url, output_file, num_threads=4):
"""
Downloads a file from the given URL using multiple threads.
:param url: URL of the file to download.
:param output_file: Path to save the downloaded file.
:param num_threads: Number of threads to use (defaults to 4).
"""
try:
# Get the file size by making a HEAD request
req = [Link](url, method='HEAD')
with [Link](req) as response:
total_size = int([Link]('Content-Length', 0))
if total_size == 0:
print("Error: Unable to determine file size.")
return
print(f"Downloading {url} ({total_size / (1024*1024):.2f} MB) using {num_threads}
threads..."
# Create the output file with the correct size
with open(output_file, 'wb') as f:
[Link](total_size)
# Calculate chunk sizes
chunk_size = total_size // num_threads
threads = []
lock = [Link]()
for i in range(num_threads):
start_byte = i * chunk_size
end_byte = start_byte + chunk_size - 1 if i < num_threads - 1 else total_size - 1
t = [Link](target=download_chunk, args=(url, start_byte, end_byte, i,
output_file, lock))
[Link](t)
[Link]()
# Wait for all threads to complete
for t in threads:
[Link]()
print(f"Download complete: {output_file} ({[Link](output_file) /
(1024*1024):.2f} MB)")
except Exception as e:
print(f"Error: {e}")
# Example usage
if __name__ == "__main__":
# Example: Download a large file (e.g., a sample ISO or zip from a public URL)
# Note: Replace with a real URL that supports range requests
sample_url = "[Link] # Placeholder; use a real URL like a
Linux ISO
output_file = "downloaded_file.zip"
multithreaded_downloader(sample_url, output_file, num_threads=4)
OUTPUT:
PRACTICAL 7:
AIM: Use multiprocessing to speed up file compression.
CODE:
import multiprocessing
import zlib
import os
import math
import time
def compress_chunk(chunk_data, chunk_index, output_queue):
"""
Compresses a chunk of data using zlib and puts the result in the output queue.
"""
try:
compressed_data = [Link](chunk_data, level=6) # Balanced compression
output_queue.put((chunk_index, compressed_data))
except Exception as e:
print(f"Error compressing chunk {chunk_index}: {e}")
output_queue.put((chunk_index, None))
def show_progress(total_size, processed_size, progress_event):
"""
Displays compression progress based on processed (original) data size.
"""
import sys
while not progress_event.is_set():
with processed_size.get_lock():
current_size = processed_size.value
percent = (current_size / total_size) * 100 if total_size > 0 else 0
[Link](f"\rProcessed: {current_size / (1024*1024):.2f} MB / {total_size /
(1024*1024):.2f} MB ({percent:.2f}%)")
[Link]()
[Link](1)
# Final update
[Link](f"\rProcessed: {total_size / (1024*1024):.2f} MB / {total_size /
(1024*1024):.2f} MB (100.00%)\n")
[Link]()
def multiprocessing_compressor(input_file, output_file=None, num_processes=4):
"""
Compresses a file using multiple processes for faster compression.
:param input_file: Path to the input file.
:param output_file: Path to the output file (defaults to input_file.zlib).
:param num_processes: Number of processes (defaults to 4).
"""
if not [Link](input_file):
print(f"Error: Input file '{input_file}' does not exist.")
return
if output_file is None:
output_file = input_file + '.zlib'
total_size = [Link](input_file)
if total_size == 0:
print("Error: Input file is empty.")
return
print(f"Compressing {input_file} ({total_size / (1024*1024):.2f} MB) using
{num_processes} processes...")
chunk_size = [Link](total_size / num_processes)
chunks = []
with open(input_file, 'rb') as f:
for i in range(num_processes):
start_byte = i * chunk_size
[Link](start_byte)
chunk_data = [Link](chunk_size)
if chunk_data:
[Link]((i, chunk_data))
output_queue = [Link]()
processed_size = [Link]('i', 0)
processes = []
for chunk_index, chunk_data in chunks:
p = [Link](target=compress_chunk, args=(chunk_data,
chunk_index, output_queue))
[Link](p)
[Link]()
progress_event = [Link]()
progress_process = [Link](target=show_progress, args=(total_size,
processed_size, progress_event))
progress_process.start()
compressed_chunks = [None] * len(chunks)
for _ in range(len(chunks)):
chunk_index, compressed_data = output_queue.get()
if compressed_data is not None:
compressed_chunks[chunk_index] = compressed_data
with processed_size.get_lock():
processed_size.value += len(chunk_data)
else:
print(f"Warning: Chunk {chunk_index} failed to compress.")
for p in processes:
[Link]()
progress_event.set()
progress_process.join()
with open(output_file, 'wb') as f:
for i in range(len(chunks)):
if compressed_chunks[i] is None:
print(f"Error: Missing compressed chunk {i}. Compression incomplete.")
return
[Link](compressed_chunks[i])
print(f"Compression complete: {output_file} ({[Link](output_file) /
(1024*1024):.2f} MB)")
# Example usage
if __name__ == "__main__":
# Create a sample large file for testing (optional)
sample_file = "sample_large_file.txt"
if not [Link](sample_file):
print("Creating a sample large file for demonstration...")
with open(sample_file, 'w') as f:
for i in range(100000): # ~1MB file
[Link](f"This is line {i}\n" * 10)
print(f"Sample file created: {sample_file} ({[Link](sample_file) /
(1024*1024):.2f} MB)")
multiprocessing_compressor(sample_file, num_processes=4)
OUTPUT:
PRACTICAL 8:
AIM: Perform asynchronous web scraping using aiohttp.
CODE:
import aiohttp
import asyncio
from bs4 import BeautifulSoup
import time
async def scrape_page(session, url):
"""
Asynchronously scrapes a single page and extracts titles or relevant data.
"""
try:
async with [Link](url) as response:
if [Link] == 200:
html = await [Link]()
soup = BeautifulSoup(html, '[Link]')
title = [Link] if [Link] else "No title found"
return f"URL: {url}\nTitle: {title}\n"
else:
return f"Error fetching {url}: Status {[Link]}\n"
except Exception as e:
return f"Error scraping {url}: {e}\n"
async def async_web_scraper(urls):
"""
Scrapes multiple URLs asynchronously using aiohttp.
:param urls: List of URLs to scrape.
"""
async with [Link]() as session:
tasks = [scrape_page(session, url) for url in urls]
results = await [Link](*tasks)
return results
# Example usage
if __name__ == "__main__":
urls = [
"[Link]
"[Link]
"[Link]
"[Link] # A test page with HTML
]
print("Starting asynchronous web scraping...")
start_time = [Link]()
results = [Link](async_web_scraper(urls))
end_time = [Link]()
print("Scraping complete in {:.2f} seconds.\n".format(end_time - start_time))
for result in results:
print(result)
OUTPUT:
PRACTICAL 9:
AIM: Create a RESTful API using FastAPI with GET and POST routes.
CODE:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List
# Initialize FastAPI app
app = FastAPI(title="Simple Task API", description="A basic RESTful API for
managing tasks.")
# In-memory storage for tasks (for simplicity; in production, use a database)
tasks = [
{"id": 1, "title": "Buy groceries", "completed": False},
{"id": 2, "title": "Walk the dog", "completed": True}
]
# Pydantic model for task input (used in POST)
class TaskCreate(BaseModel):
title: str
completed: bool = False
# Pydantic model for task response
class Task(BaseModel):
id: int
title: str
completed: bool
# GET route: Retrieve all tasks
@[Link]("/tasks", response_model=List[Task])
def get_tasks():
return tasks
# POST route: Add a new task
@[Link]("/tasks", response_model=Task)
def create_task(task: TaskCreate):
new_id = max([t["id"] for t in tasks], default=0) + 1
new_task = {"id": 3, "title": “write a letter”, "completed": false}
[Link](new_task)
return new_task
# Optional: GET a specific task by ID
@[Link]("/tasks/{task_id}", response_model=Task)
def get_task(task_id: int):
task = next((t for t in tasks if t["id"] == task_id), None)
if not task:
raise HTTPException(status_code=404, detail="Task not found")
return task
OUTPUT:
JOURNAL
ON
JULIA
IN THE PROGRAMME
BACHELOR OF SCIENCE (ARTIFICIAL INTELLIGENCE)
SUBMITTED BY
AAGAM NITIN SHAH
BSC (A.I)
SDAI028A
SEMESTER III
UNDER THE GUIDANCE OF
Mr. VIVEK WADHER
ACADEMIC YEAR
2025 – 2026
CERTIFICATE
This is to certify that Mr. Aagam Nitin Shah of SECOND year of Bachelor
of Science in Artificial Intelligence, Roll No. SDAI028A of Semester III
(2025 - 2026) has successfully completed the Journal of the subject Julia as per
the guidelines of KES’ Shroff College of Arts and Commerce, Kandivali (W),
Mumbai-400067.
Teacher In-charge Principal
Mr. Vivek Wadher Dr. Lily Bhushan
INDEX
Sr. Practical [Link] Sign
No.
1. Set up Julia and run basic scripts. 1-5
2. Write programs using control structures and 6-9
functions.
3. Manipulate data using [Link]. 10 - 17
4. Load and analyze CSV files. 18 - 23
5. Create basic and advanced visualizations using 24 - 28
[Link].
6. Apply statistical functions to datasets. 29 - 32
7. Clean and preprocess messy datasets. 33 - 38
8. Build a linear regression model using [Link]. 39 - 41
9. Implement a classification model using [Link]. 42 - 44
10. Call a Python library using [Link]. 45 - 47
PRACTICAL 01: -
AIM: Set up Julia and run basic scripts.
CODE:
Setup : Jupyter notebook, REPL,VS Code, Pluto notebook
basic scripts:
x = 10 # Integer
y = 3.5 # Float
name = "Alice" # String
# array, tuple, dict
a= [1,2,3,4,5] # array
t= (1,"hello", true) # tuple
d=Dict("name"=>"vivek","age"=>21) # dict
# Basic arithmetic operations
println("Addition (2 + 3) = ", 2 + 3)
println("Subtraction (10 - 4) = ", 10 - 4)
println("Multiplication (3 * 5) = ", 3 * 5)
println("Division (12 / 3) = ", 12 / 3)
# Comparison operators
println("3 == 3: ", 3 == 3) # equal to
println("4 != 5: ", 4 != 5) # not equal to
println("2 < 7: ", 2 < 7) # less than
println("8 >= 6: ", 8 >= 6) # greater than or equal to
# Logical operators
println("true && false: ", true && false) # AND
println("true || false: ", true || false) # OR
println("!true: ", !true) # NOT
# Bitwise operators
println("5 & 3: ", 5 & 3) # AND
println("5 | 2: ", 5 | 2) # OR
println("~5: ", ~5) # NOT
# Assignment operators
x=5
println("x = 5 → x = ", x)
x += 3
println("x += 3 → x = ", x)
x *= 2
println("x *= 2 → x = ", x)
x %= 4
println("x %= 4 → x = ", x)
OUTPUT:
"Alice"
5
5-element Vector{Int64}:
1
2
3
4
5
(1, "hello", true)
Dict{String, Any} with 2 entries:
"name" => "vivek"
"age" => 21
Addition (2 + 3) = 5
Subtraction (10 - 4) = 6
Multiplication (3 * 5) = 15
Division (12 / 3) = 4.0
3 == 3: true
4 != 5: true
2 < 7: true
8 >= 6: true
true && false: false
true || false: true
!true: false
(true || false) && !false: true
5 & 3: 1
5 | 2: 7
~5: -6
4 << 1: 8
x=5→x=5
x += 3 → x = 8
x *= 2 → x = 16
x %= 4 → x = 0
PRACTICAL 02:-
AIM: Write programs using control structures and functions.
CODE:
# Check if a number is positive, negative, or zero
num = -3
if num > 0
println("Number $num is positive")
elseif num < 0
println("Number $num is negative")
else
println("Number $num is zero")
end
#Check if a number is even or odd
n=7
if n % 2 == 0
println("$n is Even")
else
println("$n is Odd")
end
# For loop - Print first 5 natural numbers
sum_even = 0
for i in 1:10
even_num = 2 * i
println(even_num)
sum_even += even_num
end
println("Sum of first 10 even numbers: $sum_even")
# While loop - Calculate factorial
n=5
fact = 1
i=1
while i <= n
fact *= i
i += 1
end
println("Factorial of $n is $fact")
# Function to calculate square of a number
function square(x)
return x^2
end
println("Square of 4 is ", square(4))
# Function to calculate sum of two numbers
function add(a, b)
return a + b
end
println("Sum of 5 and 7 is ", add(5, 7))
# Function to check prime number
function is_prime(num)
if num <= 1
return false
end
for i in 2:sqrt(num)
if num % i == 0
return false
end
end
return true
endprintln("11 is prime? ", is_prime(11))
#Function to generate Fibonacci series of n terms
function fibonacci(n)
a, b = 0, 1
for i in 1:n
print(a, " ")
a, b = b, a + b
end
println()
endprintln("First 7 Fibonacci numbers:")
fibonacci(7)
OUTPUT:
Number -3 is negative
7 is Odd
2
4
6
8
10
12
14
16
18
20
Sum of first 10 even numbers: 110
Factorial of 5 is 120
Sum of 5 and 7 is 12
11 is prime? True
First 7 Fibonacci numbers:
0112358
PRACTICAL 03: -
AIM: Manipulate data using [Link].
CODE:
# import libarires
using CSV
using DataFrames
# syantx of dataset(Pakages,name of dataset
df= [Link]("[Link]",DataFrame)
# see the data type of dataframe
typeof(df)
# size of the data frame
size(df)
# check total number of rows
nrow(df)
# check total number of columns
ncol(df)
# return a numerical summary of the datasets
describe(df)
# syntax is - [Link]
[Link]
# access only rows - synatx dataframe[rows:columns]
df[1:10,:]
#access rowws and columns - syntax is dataframe[rows:columns]
df[1:10,:hp]
# access only columns - syntax is dataframe[rows:columns]
df[!, :mpg]
#single columns
describe(df[:,[:mpg]])
# mutiple columns
describe(df[:,[:mpg,:cyl]])
# renameing cyl into cylinder and wt into weight
rename!(df,:cyl=> :Cylinder,:wt => :Weight)
# Select specific columns
select(df, [:model, :mpg, :hp])
# not() function is use to drop columns
select!(df, Not(:carb))
# Filter where Cyl is 4, 6, or 8
filter(row -> [Link] in(4,6,8),df)
# filter - MPG greater than 25
filter(row -> [Link] > 25, df)
# rev=true means descending order ; rev=False means ascending order
sort(df,:mpg,rev=true)
# sort the cylinder columns in ascending and MPG columns in descending
sort(df, [:Cylinder, :mpg], rev = [false, true])
OUTPUT:
DataFrame
(15, 12)
15
12
PRACTICAL 04:-
AIM: Load and analyze CSV files.
CODE:
using CSV
using DataFrames
using Statistics
df = [Link]("[Link]", DataFrame)
df
first(df, 5) # View first 5 rows
last(df, 5) # View last 5 rows
describe(df) # Summary statistics
size(df) # (rows, columns)
names(df) # Column names
describe(df)
# 1) Fill missing value in 'Age' columns with mean of age
[Link] = coalesce.([Link], round(Int64, mean(skipmissing([Link]))))
describe(df)
# 2) Fill missing value in Salary with median of salary
using Statistics
[Link] = coalesce.([Link] , round(Int, median(skipmissing([Link])))
# Fill missing Years_Experience with 0
df.Years_Experience = coalesce.(df.Years_Experience, 0)
# 1) extract data which are the employees earning > 60k
high_salary = filter(x -> [Link] >60000, df)
# 2)Select Name and Salary
name_salary = select(df,[:Name,:Salary])
# 3) Sort by Salary descending
sorted_salary = sort(df, :Salary, rev=false)
# 4)Group by Department and calculate average salary & avg years of exp
depart_df = groupby(df,:Department)
depart_df
depart_summary = combine( depart_df , :Salary => mean =>:Avg_salary, :Years_
[Link]("employlee_clean.csv",df)
OUTPUT:
"employlee_clean.csv"
PRACTICAL 05:-
AIM: Create basic and advanced visualizations using [Link].
CODE:
using StatsPlots;
using DataFrames;
using CSV;
df = [Link]("[Link]",DataFrame)
# line plot : sales over date
# :right,:left,:top,:bottom,:topright,:topleft,:bottomright,:bottomleft
@df df plot(:Date,:Sales,title = "Sales Over Date",
xlabel="Date",ylabel="Sales",label="Sales", legend=:left,linewidth=10)
# Bar Plot: Sales by Region
sales_region = combine(groupby(df, :Region), :Sales => sum => :TotalSales)
@df sales_region bar(:Region, :TotalSales, title="Sales by Region", xlabel="Region",
ylabel="Sales")
#scatter plot
@df df scatter(:Sales, :Profit, title="Sales vs Profit", xlabel="Sales", ylabel="Profit",
label="Data Points")
# histogram plot
@df df histogram(:Sales,bins=5,title="Sales Distribution",
xlabel="Sales",ylabel="Count",label="Sales")
# groupedbar chart
@df df groupedbar(:Region, :Sales, group=[Link],
title="Sales by Region and Category", xlabel="Region",
ylabel="Sales", legend=:topright)
using PlotlyBase
@df df boxplot([Link], [Link], title="Profit by Category",
xlabel="Category", ylabel="Profit")
OUTPUT:
PRACTICAL 06:-
AIM: Apply statistical functions to datasets.
CODE:
using CSV ,DataFrames,Statistics,StatsBase
df = [Link]("[Link]",DataFrame)
study = [Link]
scores = [Link]
println("\n--- Study Hours Stats ---")
println("Mean: ", mean(study))
println("Median: ", median(study))
println("Mode: ", mode(study))
println("Variance: ", var(study))
println("Std Dev: ", std(study))
println("Quantiles: ", quantile(study, [0.25, 0.5, 0.75]))
println("\n--- Exam Scores Stats ---")
println("Mean: ", mean(scores))
println("Median: ", median(scores))
println("Mode: ", mode(scores))
println("Variance: ", var(scores))
println("Std Dev: ", std(scores))
println("Quantiles: ", quantile(scores, [0.25, 0.5, 0.75]))
println("Correlation: ", cor(study, scores))
println("Covariance: ", cov(study, scores))
using Distributions
# mean= 50 , std =10
d = Normal(50, 10)
# x=55
pdf(d,55)
# X ≤ 60 - 60 or below
cdf(d,60)
# X ≥ 60 - 60 or above
1-cdf(d,60)
# 45 ≤ X ≤ 55
cdf(d, 55) - cdf(d, 45)
# n=10, p=0.5
bino = Binomial(10, 0.5)
# P(x=7)
pdf(bino, 7)
# P(X≤4)
cdf(bino, 4)
#P(X≥6)
1 - cdf(bino, 5)
# P(4 ≤ X ≤ 7 )
cdf(bino,7) - cdf(bino,4)
OUTPUT:
Correlation: 0.9975627356515969
Covariance: 28.944444444444443
Normal{Float64}(μ=50.0, σ=10.0)
0.03520653267642995
0.841344746068543
0.15865525393145696
0.38292492254802624
Binomial{Float64}(n=10, p=0.5)
0.1171875000000004
0.3769531250000003
0.3769531250000002
0.5683593749999996
PRACTICAL 07:-
AIM: Clean and preprocess messy datasets.
CODE:
using CSV
using Statistics
using DataFrames
# dataset of messy data
df = [Link]("[Link]",DataFrame)
# Clean the 'name' column: make lowercase and remove leading/trailing spaces
[Link] = strip.(lowercase.([Link]))
# Compute the rounded mean age (ignoring missing values) as an integer
mean_age = Int.(round(mean(skipmissing([Link]))))
# Replace missing values in 'age' column with the computed mean age
[Link] = coalesce.([Link], mean_age)
# summary of dataset
describe(df)
# Compute the median income (ignoring missing values), round it, and conver
m_income = round(Int, median(skipmissing([Link])))
# Replace missing values in 'income' column with the computed median income
[Link] = coalesce.([Link], m_income)
# Replace missing values in 'city' column with the string "NAN"
[Link] = coalesce.([Link], "NAN")
# Get the distinct values from the 'city' column
unique([Link])
# converting 'city' columns to lowercase
[Link] = lowercase.([Link])
unique([Link])
# Replace abbreviations in 'city' column: "ny" → "new york", "sf" → "san fr
[Link] = replace.([Link],
"ny"=> "new york",
"sf" => "san fransico")
Df
[Link]("messy_clean.csv",df)
OUTPUT:
60000
"messy_clean.csv"
PRACTICAL 08: -
AIM: Build a linear regression model using [Link].
CODE:
using MLJ
using MLJLinearModels
using DataFrames
using Plots
# Independent variable
study_hours = Float64[1,2,3,4,5,6,7,8,9,10]
# Dependent variable
exams_scores = Float64[35,45,56,85,78,99,45,32,45,75]
# Put into a DataFrame
data =DataFrame(study=study_hours,exams= exams_scores)
# independent variable
X=select(data, :study)
# dependent variable
y=[Link]
# importing model
model=LinearRegressor()
mach=machine(model,X,y)
fit!(mach) #train model
# prediction on new data
new_data = DataFrame(study = [4.5])
y_pred = predict(mach,new_data)
println(y_pred)
OUTPUT:
LinearRegressor(
fit_intercept = true,
solver = nothing)
[58.64545454545455]
PRACTICAL 09:-
AIM: Implement a classification model using [Link].
CODE:
using MLJ
using MLJLinearModels
using DataFrames
using CategoricalArrays
using StatisticalMeasures
# Feature: study hours
study_hours = Float64[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Target: pass/fail (categorical)
pass_exam = categorical([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])
data = DataFrame(hours=study_hours, pass=pass_exam)
X = select(data, :hours)
y = [Link]
model =LogisticClassifier()
mach = machine(model, X, y)
fit!(mach)
new_data = DataFrame(hours=[3.1, 7.0])
y_prob = predict(mach, new_data) # probabilities between 0 and 1
y_class = mode.(y_prob)
OUTPUT:
PRACTICAL 10:-
AIM: Call a Python library using [Link].
CODE:
using PyCall
py"""
def check_number(x):
if x > 0:
return "Positive"
elif x < 0:
return "Negative"
else:
return "Zero"
"""
println("Check 5: ", py"check_number"(5))
println("Check -3: ", py"check_number"(-3))
println("Check 0: ", py"check_number"(0))
py"""
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n-1)
"""
println("Factorial of 5: ", py"factorial"(5))
println("Factorial of 7: ", py"factorial"(7))
# for numpy and pandas we have to install first
np = pyimport("numpy")
pd = pyimport("pandas")
#Creates a NumPy array
a = [Link]([1, 2, 3, 4])
println("NumPy Array: ", a)
#print the array
println("Mean of Array: ", [Link](a)) #mean of the array
# Creates a Julia Dict
data = Dict(
"Name" => ["Alice", "Bob", "Charlie"],
"Age" => [25, 30, 35],
"Salary" => [50000, 60000, 70000]
)
# Converts the Julia dictionary into a Pandas DataFrame
df = [Link](data)
# Prints the DataFrame
println("DataFrame:\n",df)
OUTPUT:
Check 5: Positive
Check -3: Negative
Check 0: Zero
Factorial of 5: 120
Factorial of 7: 5040
NumPy Array: [1, 2, 3, 4]
Mean of Array: 2.5