def prac1():
    print("""
PRACTICAL 1: DDL, DML AND TCL QUERIES (MySQL)

-------------------- DDL --------------------

CREATE TABLE students (
    student_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    age INT,
    class VARCHAR(10)
);

ALTER TABLE students
ADD COLUMN address VARCHAR(100);

RENAME TABLE students TO student_details;

CREATE INDEX idx_class
ON student_details(class);

DROP TABLE students;

-------------------- DML --------------------

INSERT INTO student_details (name, age, class, address)
VALUES ('John Doe', 18, '12A', '123 Elm Street');

UPDATE student_details
SET age = 19
WHERE name = 'John Doe';

DELETE FROM student_details
WHERE age < 18;

SELECT *
FROM student_details
WHERE class = '12A';

INSERT INTO student_details (name, age, class, address)
VALUES
('Jane Smith', 17, '11B', '456 Oak Avenue'),
('Michael Brown', 18, '12A', '789 Pine Road');

-------------------- TCL --------------------

START TRANSACTION;

INSERT INTO student_details (name, age, class, address)
VALUES ('Temporary Student', 20, '12C', '999 Test Road');
ROLLBACK;

START TRANSACTION;
INSERT INTO student_details (name, age, class, address)
VALUES ('Final Student', 21, '12D', '888 Final Ave');
COMMIT;

START TRANSACTION;
INSERT INTO student_details (name, age, class, address)
VALUES ('Savepoint Test', 19, '11A', '101 Save St');
SAVEPOINT sp1;
INSERT INTO student_details (name, age, class, address)
VALUES ('Undo This', 20, '11B', '202 Undo Ave');
ROLLBACK TO sp1;
""")

def prac2():
    print("""
PRACTICAL 2: Hadoop Shell Commands Using Cloudera

1. hadoop fs -ls
Purpose: Lists files and directories present in HDFS.
Example:
hadoop fs -ls /user/hadoop/

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

2. hadoop fs -mkdir
Purpose: Creates a new directory in HDFS.
Example:
hadoop fs -mkdir /user/hadoop/data

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

3. hadoop fs -put
Purpose: Uploads files from local system to HDFS.
Example:
hadoop fs -put localfile.txt /user/hadoop/data/

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

4. hadoop fs -get
Purpose: Downloads files from HDFS to local system.
Example:
hadoop fs -get /user/hadoop/data/localfile.txt

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

5. hadoop fs -rm
Purpose: Deletes a file from HDFS.
Example:
hadoop fs -rm /user/hadoop/data/localfile.txt

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

6. hadoop fs -rmdir
Purpose: Deletes an empty directory in HDFS.
Example:
hadoop fs -rmdir /user/hadoop/emptydir

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

7. hadoop fs -cat
Purpose: Displays the contents of a file stored in HDFS.
Example:
hadoop fs -cat /user/hadoop/data/file.txt

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

8. hadoop fs -mv
Purpose: Moves or renames files/directories in HDFS.
Example:
hadoop fs -mv /user/hadoop/data/file1.txt /user/hadoop/data/renamed_file1.txt

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

9. hadoop fs -cp
Purpose: Copies files within HDFS.
Example:
hadoop fs -cp /user/hadoop/data/file1.txt /user/hadoop/data/file2.txt

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

10. hadoop fs -du
Purpose: Shows disk space used by files and directories.
Example:
hadoop fs -du /user/hadoop/data

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

11. hadoop fs -count
Purpose: Displays directory count, file count, and space used.
Example:
hadoop fs -count /user/hadoop/

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

12. hadoop fs -tail
Purpose: Displays the last part of a file in HDFS.
Example:
hadoop fs -tail /user/hadoop/logs/logs.txt
""")

def prac3():
    print("""
==============================
Wordcount Implementation Using Pig
==============================

1. Create a Text File:

Create a file input.txt with some sample text.

Example:
Apache Pig is a high-level platform for big data.
Pig simplifies processing.
Data processing is efficient with Pig.

Commands:
touch input.txt
vim input.txt
cat input.txt

Output:
Apache Pig is a high-level platform for big data.
Pig simplifies processing.
Data processing is efficient with Pig.

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

2. Copy the File to HDFS:

Create a directory in HDFS and copy the file.

Commands:
hadoop fs -mkdir /user/cloudera/wordcount
hadoop fs -put input.txt /user/cloudera/wordcount

Verify:
hadoop fs -ls /user/cloudera/wordcount

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

3. Write the Pig Script:

Use a text editor to write the Pig Latin code.

Pig Script:
lines = LOAD '/user/cloudera/wordcount/input.txt' AS (line:chararray);
words = FOREACH lines GENERATE FLATTEN(TOKENIZE(line)) AS word;
grouped = GROUP words BY word;
word_count = FOREACH grouped GENERATE group AS word, COUNT(words) AS count;
STORE word_count INTO 'wordcount/output' USING PigStorage('\\t');

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

4. Save the File:

Save the script as pig1.pig

Command:
vim pig1.pig
ls -l pig1.pig

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

5. Execute the Pig Script:

Ensure Hadoop and YARN are running.

Command:
pig pig1.pig

Output:
Job execution completed successfully.

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

6. View the Output:

List output files:
hadoop fs -ls /user/cloudera/wordcount/output

View result:
hadoop fs -cat /user/cloudera/wordcount/output/part-r-00000

Sample Output:
a       1
is      2
Pig     2
processing 2
data    1

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

Conclusion:
This Pig program reads text from HDFS, tokenizes words, groups them,
counts occurrences, and stores the result back into HDFS.

==============================
""")

def prac4():
    print("""
========================================
Aim: Data Wrangling Using Apache Pig
========================================

Explanation:
Data wrangling (also called data munging) is the process of cleaning, transforming,
and organizing raw data into a usable format for analysis. It is an important step
in the data pipeline for tasks such as data integration, preprocessing, and enrichment.

Apache Pig is a high-level platform used for processing large datasets in Big Data
ecosystems. It uses Pig Latin, a scripting language that simplifies complex data
manipulation tasks such as filtering, grouping, joining, and aggregation.

----------------------------------------
Set Up Pig in Cloudera
----------------------------------------

1. Ensure Cloudera is installed and properly configured.
2. Start Hadoop services using Cloudera Manager or terminal.
3. Open the Pig Grunt shell using the command:
   pig

----------------------------------------
Create Employee Dataset (emp_data.csv)
----------------------------------------

id,name,age,city,salary
1,John Doe,28,New York,-50000
2,Jane Smith,34,Los Angeles,60000
3,Mike Johnson,25,Chicago,45000.45
4,Linda Green,40,New York,75000.55
5,James White,29,Los Angeles,55000
6,Patricia Brown,50,Chicago,-80000
7,Robert Black,,New York,48000
8,Emily Davis,27,Chicago,49000
9,William Harris,35,Los Angeles,62000
10,Elizabeth Clark,30,New York,52000

----------------------------------------
Create Department Dataset (dept_data.csv)
----------------------------------------

id,dept
1,Sales
2,Marketing
3,IT
4,HR
5,Finance
6,Operations
7,Sales
8,IT
9,Marketing
10,HR

----------------------------------------
1. Upload CSV Files to HDFS
----------------------------------------

hadoop fs -put emp_data.csv /user/cloudera/
hadoop fs -put dept_data.csv /user/cloudera/

----------------------------------------
2. Load Employee Data Using Pig
----------------------------------------

raw_data = LOAD 'emp_data.csv'
USING PigStorage(',')
AS (id:int, name:chararray, age:int, city:chararray, salary:float);

----------------------------------------
3. Inspect the Data
----------------------------------------

DESCRIBE raw_data;
DUMP raw_data;

----------------------------------------
4. Data Cleaning
----------------------------------------

Remove null or invalid records:
clean_data = FILTER raw_data BY (age IS NOT NULL AND salary > 0);

----------------------------------------
5. Data Formatting
----------------------------------------

formatted_data = FOREACH clean_data GENERATE
id,
name,
age,
city,
ROUND(salary) AS salary_rounded;

----------------------------------------
6. Data Transformation
----------------------------------------

Group data by city:
grouped_data = GROUP formatted_data BY city;

Aggregate data:
city_salary = FOREACH grouped_data GENERATE
group AS city,
AVG(formatted_data.salary_rounded) AS avg_salary;

----------------------------------------
7. Store Aggregated Results
----------------------------------------

STORE city_salary INTO 'emp_data' USING PigStorage(',');

----------------------------------------
8. Join Datasets
----------------------------------------

other_data = LOAD 'dept_data.csv'
USING PigStorage(',')
AS (id:int, dept:chararray);

joined_data = JOIN formatted_data BY id, other_data BY id;

----------------------------------------
9. Data Filtering and Sorting
----------------------------------------

Filter high salary employees:
high_earners = FILTER formatted_data BY salary_rounded > 50000;

Sort data in descending order:
sorted_data = ORDER high_earners BY salary_rounded DESC;

----------------------------------------
10. Store Final Results
----------------------------------------

STORE sorted_data INTO 'joint_data' USING PigStorage(',');

----------------------------------------
Conclusion:
----------------------------------------
This practical demonstrates data wrangling using Apache Pig by performing
data loading, cleaning, transformation, aggregation, joining, filtering,
sorting, and storing results in HDFS.

========================================
""")

def prac5():
    print("""
=============================================
Aim: Create Managed and External Table in Hive
     and View in Hadoop Web UI
=============================================

Explanation:
Apache Hive is a data warehousing tool built on top of Hadoop that allows users
to query and analyze large datasets stored in HDFS using a SQL-like language
called HiveQL. Hive converts queries into MapReduce, Tez, or Spark jobs, making
big data analysis easier without writing complex programs.

---------------------------------------------
Key Features of Hive
---------------------------------------------

1. SQL-like Language (HiveQL):
   - Queries are written similar to SQL.
   - Automatically converted into MapReduce, Tez, or Spark jobs.

2. Schema on Read:
   - Schema is applied when data is read, not when it is stored.
   - Suitable for unstructured and semi-structured data.

3. Support for Large Datasets:
   - Can handle petabytes of data stored in HDFS.

4. Integration with Hadoop:
   - Uses HDFS for storage.
   - Uses MapReduce, Tez, or Spark for processing.

5. Extensibility:
   - Supports User Defined Functions (UDFs).

6. Support for Various File Formats:
   - TextFile
   - SequenceFile
   - ORC
   - Parquet
   - AVRO

---------------------------------------------
Prerequisites
---------------------------------------------

1. Ensure Hadoop, YARN, ZooKeeper, and Hive services are running in Cloudera.
2. Open the Hive shell using the command:
   hive

---------------------------------------------
Create CSV Dataset
---------------------------------------------

Create a file named mydata.csv using a text editor.

Data:
1,John Doe,28
2,Jane Smith,34
3,Emily Davis,23
4,Michael Brown,45
5,Linda Johnson,30

---------------------------------------------
Create Managed Table in Hive
---------------------------------------------

Create managed table:
CREATE TABLE managed_table (
    id INT,
    name STRING,
    age INT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE;

Load data into managed table:
LOAD DATA LOCAL INPATH '/home/cloudera/mydata.csv'
INTO TABLE managed_table;

View data:
SELECT * FROM managed_table;

Note:
- In a managed table, Hive manages both data and metadata.
- Dropping the table deletes data from HDFS.

---------------------------------------------
Create External Table in Hive
---------------------------------------------

Create directory in HDFS:
hdfs dfs -mkdir /user/external
hdfs dfs -put mydata.csv /user/external

Create external table:
CREATE EXTERNAL TABLE external_table (
    id INT,
    name STRING,
    age INT
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION '/user/external/';

View data:
SELECT * FROM external_table;

Note:
- In an external table, Hive manages only metadata.
- Dropping the table does NOT delete data from HDFS.

---------------------------------------------
Conclusion
---------------------------------------------

This practical demonstrates the creation of managed and external tables in Hive.
Managed tables delete data when dropped, while external tables retain data in HDFS.
Hive simplifies big data querying using HiveQL and integrates seamlessly with Hadoop.

=============================================
""")

def prac6():
    print("""
=========================================================
Aim: Create a Namespace in HBase with Tables and
     Perform DML Queries
=========================================================

Explanation:
HBase is an open-source, non-relational, distributed database inspired by
Google's Bigtable. It is part of the Apache Hadoop ecosystem and runs on
top of HDFS, providing fault-tolerant storage for large volumes of sparse data.

HBase is designed for real-time read and write access to big data and is
well-suited for use cases where only a small fraction of columns are populated
in very large datasets.

---------------------------------------------------------
Prerequisites
---------------------------------------------------------

1. Start Hadoop services:
   - HADOOP
   - YARN
   - ZOOKEEPER
   - HBASE

2. Open HBase shell using:
   hbase shell

---------------------------------------------------------
Create Namespace
---------------------------------------------------------

create_namespace 'university'

---------------------------------------------------------
Create Tables Under Namespace
---------------------------------------------------------

Create students table:
create 'university:students', 'info', 'marks'

Create courses table:
create 'university:courses', 'details'

---------------------------------------------------------
Insert Data (Put Queries)
---------------------------------------------------------

Insert student 1 data:
put 'university:students', '1', 'info:name', 'John Doe'
put 'university:students', '1', 'info:age', '21'
put 'university:students', '1', 'marks:math', '85'
put 'university:students', '1', 'marks:science', '90'

Insert student 2 data:
put 'university:students', '2', 'info:name', 'Jane Smith'
put 'university:students', '2', 'info:age', '22'
put 'university:students', '2', 'marks:math', '78'
put 'university:students', '2', 'marks:science', '88'

Insert course data:
put 'university:courses', '101', 'details:name', 'Computer Science'
put 'university:courses', '101', 'details:credits', '4'

---------------------------------------------------------
Retrieve Data (Get Queries)
---------------------------------------------------------

Retrieve full row:
get 'university:students', '1'

Retrieve specific column:
get 'university:students', '2', 'info:name'

---------------------------------------------------------
Scan Data (Scan Queries)
---------------------------------------------------------

Scan students table:
scan 'university:students'

Scan courses table:
scan 'university:courses'

---------------------------------------------------------
Update Data
---------------------------------------------------------

Update math marks for student 1:
put 'university:students', '1', 'marks:math', '88'

---------------------------------------------------------
Delete Specific Column Data
---------------------------------------------------------

Delete science marks of student 1:
delete 'university:students', '1', 'marks:science'

---------------------------------------------------------
Delete Entire Row
---------------------------------------------------------

Delete student 2 record:
deleteall 'university:students', '2'

---------------------------------------------------------
Count Number of Rows
---------------------------------------------------------

count 'university:students'

---------------------------------------------------------
Drop a Table
---------------------------------------------------------

Disable table:
disable 'university:students'

Drop table:
drop 'university:students'

---------------------------------------------------------
Conclusion
---------------------------------------------------------

This practical demonstrates how to create namespaces and tables in HBase
and perform DML operations such as insert, retrieve, update, delete, scan,
count, and drop tables. HBase provides scalable and fault-tolerant storage
for large, sparse datasets in Hadoop environments.

=========================================================
""")

def prac7():
    print("""
===============================================================
Aim: Create a Document and Collection in MongoDB and Perform
     Advanced Queries Using Conditional Operators and
     Aggregate Functions
===============================================================

Explanation:
MongoDB is a NoSQL, document-oriented database that stores data
in JSON-like documents. It is schema-less, flexible, and well
suited for handling large and complex datasets.

A document consists of key-value pairs and can contain nested
structures and arrays. A collection is a group of documents and
is automatically created when data is inserted.

MongoDB supports advanced querying using conditional operators,
logical operators, and an aggregation framework for data analysis.

---------------------------------------------------------------
Creating Documents and Collections
---------------------------------------------------------------

Example of a MongoDB document:
{
    "name": "Alice",
    "age": 28,
    "skills": ["JavaScript", "Python"],
    "isEmployed": true
}

Example of inserting a document:
db.users.insertOne({ name: "Alice", age: 28 });

---------------------------------------------------------------
Conditional Operators in MongoDB
---------------------------------------------------------------

Common operators:
- $eq  : Equal to
- $ne  : Not equal to
- $gt  : Greater than
- $lt  : Less than
- $in  : Matches values in an array

Example:
Retrieve users aged above 25 and below 40:
db.users.find({ age: { $gt: 25, $lt: 40 } });

---------------------------------------------------------------
Logical Operators
---------------------------------------------------------------

Common logical operators:
- $and
- $or
- $not

Example:
Find users aged above 30 OR employed:
db.users.find({
    $or: [
        { age: { $gt: 30 } },
        { isEmployed: true }
    ]
});

---------------------------------------------------------------
Aggregation Framework
---------------------------------------------------------------

Aggregation processes data through pipeline stages:
1. $match  : Filters documents
2. $group  : Groups documents and performs calculations
3. $sort   : Sorts the result

Example:
Calculate average age by employment status:
db.users.aggregate([
    { $group: { _id: "$isEmployed", avgAge: { $avg: "$age" } } }
]);

---------------------------------------------------------------
Step 1: Create Collection and Insert Documents
---------------------------------------------------------------

Create students collection and insert records:

db.students.insertMany([
{
    studentId: 1,
    name: "Alice Johnson",
    age: 21,
    subjects: ["Math", "Physics", "Computer Science"],
    scores: { math: 85, physics: 90, cs: 92 },
    city: "New York",
    enrollmentYear: 2021
},
{
    studentId: 2,
    name: "Bob Smith",
    age: 22,
    subjects: ["Math", "Biology", "Chemistry"],
    scores: { math: 75, biology: 80, chemistry: 78 },
    city: "San Francisco",
    enrollmentYear: 2020
},
{
    studentId: 3,
    name: "Charlie Brown",
    age: 23,
    subjects: ["Math", "Physics", "Economics"],
    scores: { math: 65, physics: 70, economics: 75 },
    city: "Los Angeles",
    enrollmentYear: 2019
},
{
    studentId: 4,
    name: "Diana Prince",
    age: 20,
    subjects: ["Math", "Physics", "Computer Science"],
    scores: { math: 95, physics: 89, cs: 99 },
    city: "New York",
    enrollmentYear: 2022
}
]);

---------------------------------------------------------------
Step 2: Performing Advanced Queries
---------------------------------------------------------------

1. Using Conditional Operators ($and):
Find students who scored above 80 in Math and enrolled after 2020:

db.students.find({
    $and: [
        { "scores.math": { $gt: 80 } },
        { enrollmentYear: { $gt: 2020 } }
    ]
});

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

2. Using $in Operator:
Find students from New York or San Francisco:

db.students.find({
    city: { $in: ["New York", "San Francisco"] }
});

---------------------------------------------------------------
Step 3: Aggregation Queries
---------------------------------------------------------------

a. Calculate Average Math Score:

db.students.aggregate([
    {
        $group: {
            _id: null,
            avgMathScore: { $avg: "$scores.math" }
        }
    }
]);

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

b. Count Students Per City:

db.students.aggregate([
    {
        $group: {
            _id: "$city",
            count: { $sum: 1 }
        }
    }
]);

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

c. Find Top Scorer in Computer Science:

db.students.aggregate([
    {
        $project: {
            name: 1,
            city: 1,
            csScore: "$scores.cs"
        }
    },
    { $sort: { csScore: -1 } },
    { $limit: 1 }
]);

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

d. Filter and Group Students Enrolled After 2020 by Age:

db.students.aggregate([
    { $match: { enrollmentYear: { $gt: 2020 } } },
    {
        $group: {
            _id: "$age",
            totalStudents: { $sum: 1 }
        }
    }
]);

---------------------------------------------------------------
Conclusion
---------------------------------------------------------------

This practical demonstrates document creation, collection usage,
advanced conditional queries, and aggregation functions in MongoDB.
MongoDB provides flexible and powerful data querying and analysis
capabilities suitable for modern data-driven applications.

===============================================================
""")

def prac8():
    print("""
===========================================================
Explanation: Map-Reduce in MongoDB
===========================================================

MongoDB Map-Reduce is a data processing technique used to perform
large-scale data aggregation. It processes data in two main phases:
Map and Reduce.

-----------------------------------------------------------
Map Function
-----------------------------------------------------------

- The map() function is applied to each document in the collection.
- It emits key-value pairs based on defined logic.
- Example:
  Key   -> category
  Value -> sales amount

-----------------------------------------------------------
Reduce Function
-----------------------------------------------------------

- The reduce() function aggregates values for each key.
- It combines multiple values into a single result.
- Example:
  Sum of all sales amounts for each category.

-----------------------------------------------------------
Steps in Map-Reduce
-----------------------------------------------------------

1. Mapping:
   - Each document is processed.
   - Key-value pairs are emitted.

2. Shuffling:
   - All emitted values are grouped by key.

3. Reducing:
   - Aggregated results are calculated for each key.

-----------------------------------------------------------
Insert Data into MongoDB Collection
-----------------------------------------------------------

db.sales.insertMany([
    { "_id": 1, "product": "Laptop", "category": "Electronics", "amount": 1500 },
    { "_id": 2, "product": "Headphones", "category": "Electronics", "amount": 200 },
    { "_id": 3, "product": "Shirt", "category": "Clothing", "amount": 50 },
    { "_id": 4, "product": "Pants", "category": "Clothing", "amount": 100 },
    { "_id": 5, "product": "Phone", "category": "Electronics", "amount": 800 },
    { "_id": 6, "product": "Shoes", "category": "Footwear", "amount": 120 }
]);

-----------------------------------------------------------
Map-Reduce Implementation
-----------------------------------------------------------

1. Map Function:
Emits category as key and amount as value.

var mapFunction = function() {
    emit(this.category, this.amount);
};

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

2. Reduce Function:
Aggregates sales amount for each category.

var reduceFunction = function(key, values) {
    return Array.sum(values);
};

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

3. Execute Map-Reduce:

db.sales.mapReduce(
    mapFunction,
    reduceFunction,
    {
        out: "category_totals"
    }
);

-----------------------------------------------------------
View Results
-----------------------------------------------------------

The output is stored in a new collection named category_totals.

View results:
db.category_totals.find().pretty();

-----------------------------------------------------------
Conclusion
-----------------------------------------------------------

This practical demonstrates the use of Map-Reduce in MongoDB to
aggregate large datasets. The map function emits category-wise
sales data, while the reduce function calculates total sales for
each category.

===========================================================
""")

def prac9():
    print("""
===============================================================
Aim: Creating Nodes and Relationships in Graph Database Using
     Cypher and Performing Exploration Queries
===============================================================

Explanation:
A graph database stores data in the form of nodes and relationships.
Neo4j is a popular graph database that uses Cypher, a declarative
query language, to create, manage, and explore graph data efficiently.

Nodes represent entities, relationships represent connections between
entities, and properties store additional information.

---------------------------------------------------------------
1. Setting Up the Graph Database
---------------------------------------------------------------

Use Neo4j for this practical:
- Install Neo4j Desktop locally
OR
- Use Neo4j Aura Cloud (Free Tier)

Open Neo4j Browser and start the database.

---------------------------------------------------------------
2. Creating Nodes
---------------------------------------------------------------

Nodes are entities in the graph with labels and properties.

CREATE
(john:Person {name: 'John Doe', age: 30, city: 'New York'}),
(jane:Person {name: 'Jane Smith', age: 25, city: 'Los Angeles'}),
(neoCorp:Company {name: 'NeoCorp', industry: 'Technology'}),
(alphaInc:Company {name: 'Alpha Inc.', industry: 'Finance'});

---------------------------------------------------------------
3. Creating Relationships
---------------------------------------------------------------

Relationships connect nodes and can have properties.

MATCH
(john:Person {name: 'John Doe'}),
(jane:Person {name: 'Jane Smith'}),
(neoCorp:Company {name: 'NeoCorp'}),
(alphaInc:Company {name: 'Alpha Inc.'})
CREATE
(john)-[:WORKS_FOR {since: 2015}]->(neoCorp),
(jane)-[:WORKS_FOR {since: 2018}]->(alphaInc),
(john)-[:FRIENDS_WITH {since: 2020}]->(jane);

---------------------------------------------------------------
4. Performing Exploration Queries
---------------------------------------------------------------

4.1 Retrieve All Nodes:
MATCH (n) RETURN n;

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

4.2 Retrieve Specific Nodes:
MATCH (p:Person)
RETURN p.name, p.age, p.city;

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

4.3 Retrieve Relationships:
MATCH (a)-[r]->(b)
RETURN a.name AS From,
       TYPE(r) AS Relationship,
       b.name AS To;

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

4.4 Filter by Property:
MATCH (p:Person)-[:WORKS_FOR]->(c:Company {name: 'NeoCorp'})
RETURN p.name AS Employee, c.name AS Company;

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

4.5 Find Mutual Relationships:
MATCH
(p1:Person {name: 'John Doe'})-[:FRIENDS_WITH]-(mutual)-[:FRIENDS_WITH]-
(p2:Person {name: 'Jane Smith'})
RETURN mutual.name AS MutualFriend;

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

4.6 Find Employees of Companies:
MATCH (p:Person)-[:WORKS_FOR]->(c:Company)
RETURN c.name AS Company,
       COLLECT(p.name) AS Employees;

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

4.7 Suggest Connections:
MATCH
(p1:Person)-[:WORKS_FOR]->(c:Company)<-[:WORKS_FOR]-(p2:Person)
WHERE NOT (p1)-[:FRIENDS_WITH]-(p2)
  AND p1 <> p2
RETURN p1.name AS Person,
       p2.name AS SuggestedFriend,
       c.name AS CommonCompany;

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

4.8 Shortest Path:
MATCH path = shortestPath(
    (john:Person {name: 'John Doe'})-[:FRIENDS_WITH*..5]-
    (jane:Person {name: 'Jane Smith'})
)
RETURN path;

---------------------------------------------------------------
5. Advanced Exploration Queries
---------------------------------------------------------------

5.1 Analyze Connectivity:
MATCH (p:Person)-[:FRIENDS_WITH]-(friend)
RETURN p.name AS Person,
       COUNT(friend) AS NumberOfConnections;

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

5.2 Find Influential Companies:
MATCH (c:Company)<-[:WORKS_FOR]-(employee)
RETURN c.name AS Company,
       COUNT(employee) AS EmployeeCount
ORDER BY EmployeeCount DESC;

---------------------------------------------------------------
6. Cleaning Up the Database
---------------------------------------------------------------

Delete all nodes and relationships:
MATCH (n)
DETACH DELETE n;

---------------------------------------------------------------
Conclusion
---------------------------------------------------------------

This practical demonstrates how to create nodes and relationships
in Neo4j using Cypher and perform exploration queries such as
filtering, relationship traversal, path finding, and graph analysis.
Graph databases are highly efficient for handling connected data.

===============================================================
""")

def prac10():
    print("""
===============================================================
Aim: Access a Cloud Data Warehouse (BigQuery) and Perform
     ETL, Data Exploration, and Visualization
===============================================================

Explanation:
A cloud data warehouse is a scalable system used to store and analyze
large volumes of structured data. Google BigQuery is a fully managed,
serverless cloud data warehouse that allows fast SQL-based analytics
on large datasets.

In this practical, ETL (Extract, Transform, Load) operations are
performed using a public dataset, followed by data exploration
and visualization.

---------------------------------------------------------------
Step 1: Access Cloud Data Warehouse (BigQuery)
---------------------------------------------------------------

1. Open Google BigQuery Console:
   https://console.cloud.google.com/bigquery

2. Sign in using a Google account.

3. Use BigQuery Public Datasets (no data upload required).

Example Public Dataset:
bigquery-public-data.samples.natality

This dataset contains birth statistics such as year, state,
and baby weight.

---------------------------------------------------------------
Step 2: ETL Process
---------------------------------------------------------------

-------------------
E – Extract
-------------------

Extract required data using SQL:

SELECT
    year,
    state,
    weight_pounds
FROM
    `bigquery-public-data.samples.natality`
WHERE
    year >= 2000;

Extracted Fields:
- Year
- State
- Baby weight

-------------------
T – Transform
-------------------

Clean and transform data by calculating average birth weight:

SELECT
    year,
    state,
    AVG(weight_pounds) AS avg_birth_weight
FROM
    `bigquery-public-data.samples.natality`
WHERE
    weight_pounds IS NOT NULL
GROUP BY
    year, state
ORDER BY
    year;

Transformations Performed:
- Removed NULL values
- Aggregated data using AVG
- Grouped by year and state

-------------------
L – Load
-------------------

Save transformed data into a new table:

1. Click "Save Results"
2. Select "Save as Table"
3. Create a dataset named: etl_practical
4. Table name: birth_weight_summary

This completes the ETL process.

---------------------------------------------------------------
Step 3: Data Exploration
---------------------------------------------------------------

1. View Sample Records:

SELECT *
FROM `etl_practical.birth_weight_summary`
LIMIT 10;

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

2. Find Highest Average Birth Weight by State:

SELECT
    state,
    MAX(avg_birth_weight) AS max_weight
FROM
    `etl_practical.birth_weight_summary`
GROUP BY
    state
ORDER BY
    max_weight DESC;

---------------------------------------------------------------
Step 4: Data Visualization
---------------------------------------------------------------

Method: Built-in BigQuery Visualization Tool

Steps:
1. Run the SQL query
2. Click on the "Chart" option
3. Select appropriate chart types:

Visualization Types:
- Line Chart:
  X-axis → Year
  Y-axis → Average Birth Weight

- Bar Chart:
  X-axis → State
  Y-axis → Average Birth Weight

---------------------------------------------------------------
Conclusion
---------------------------------------------------------------

This practical demonstrates accessing a cloud data warehouse,
performing ETL operations using SQL, exploring transformed data,
and creating visualizations using BigQuery’s built-in tools.
BigQuery enables scalable, fast, and efficient analytics on
large datasets.

===============================================================
""")

