Estimated time needed: 45 minutes
In this lab, you will focus on data visualization. The dataset will be provided through an RDBMS, and you will need to use SQL queries to extract the required data.
After completing this lab, you will be able to:
Visualize the distribution of data.
Visualize the relationship between two features.
Visualize composition and comparison of data.
Download the database file.
!wget https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/n01PQ9pSmiRX6520flujwQ/survey-data.csv
--2026-02-03 08:05:39-- https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/n01PQ9pSmiRX6520flujwQ/survey-data.csv
Resolving cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud (cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud)... 169.63.118.104
Connecting to cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud (cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud)|169.63.118.104|:443... connected.
200 OKequest sent, awaiting response...
Length: 159525875 (152M) [text/csv]
Saving to: ‘survey-data.csv’
survey-data.csv 100%[===================>] 152.13M 55.1MB/s in 2.8s
2026-02-03 08:05:44 (55.1 MB/s) - ‘survey-data.csv’ saved [159525875/159525875]
Install and Import Necessary Python Libraries
Ensure that you have the required libraries installed to work with SQLite and Pandas:
!pip install pandas
!pip install matplotlib
!pip install seaborn
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import textwrap
import numpy as np
Requirement already satisfied: pandas in /opt/conda/lib/python3.12/site-packages (3.0.0)
Requirement already satisfied: numpy>=1.26.0 in /opt/conda/lib/python3.12/site-packages (from pandas) (2.4.2)
Requirement already satisfied: python-dateutil>=2.8.2 in /opt/conda/lib/python3.12/site-packages (from pandas) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.12/site-packages (from python-dateutil>=2.8.2->pandas) (1.17.0)
Requirement already satisfied: matplotlib in /opt/conda/lib/python3.12/site-packages (3.10.8)
Requirement already satisfied: contourpy>=1.0.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (1.3.3)
Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (4.61.1)
Requirement already satisfied: kiwisolver>=1.3.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (1.4.9)
Requirement already satisfied: numpy>=1.23 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (2.4.2)
Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (24.2)
Requirement already satisfied: pillow>=8 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (12.1.0)
Requirement already satisfied: pyparsing>=3 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (3.3.2)
Requirement already satisfied: python-dateutil>=2.7 in /opt/conda/lib/python3.12/site-packages (from matplotlib) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.12/site-packages (from python-dateutil>=2.7->matplotlib) (1.17.0)
Requirement already satisfied: seaborn in /opt/conda/lib/python3.12/site-packages (0.13.2)
Requirement already satisfied: numpy!=1.24.0,>=1.20 in /opt/conda/lib/python3.12/site-packages (from seaborn) (2.4.2)
Requirement already satisfied: pandas>=1.2 in /opt/conda/lib/python3.12/site-packages (from seaborn) (3.0.0)
Requirement already satisfied: matplotlib!=3.6.1,>=3.4 in /opt/conda/lib/python3.12/site-packages (from seaborn) (3.10.8)
Requirement already satisfied: contourpy>=1.0.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (1.3.3)
Requirement already satisfied: cycler>=0.10 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (4.61.1)
Requirement already satisfied: kiwisolver>=1.3.1 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (1.4.9)
Requirement already satisfied: packaging>=20.0 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (24.2)
Requirement already satisfied: pillow>=8 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (12.1.0)
Requirement already satisfied: pyparsing>=3 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (3.3.2)
Requirement already satisfied: python-dateutil>=2.7 in /opt/conda/lib/python3.12/site-packages (from matplotlib!=3.6.1,>=3.4->seaborn) (2.9.0.post0)
Requirement already satisfied: six>=1.5 in /opt/conda/lib/python3.12/site-packages (from python-dateutil>=2.7->matplotlib!=3.6.1,>=3.4->seaborn) (1.17.0)
Read the CSV File into a Pandas DataFrame
Load the Stack Overflow survey data into a Pandas DataFrame:
# Read the CSV file
df = pd.read_csv('survey-data.csv')
# Display the first few rows of the data
print(df.head())
print('Initial dataframe:', df.shape)
ResponseId MainBranch Age \
0 1 I am a developer by profession Under 18 years old
1 2 I am a developer by profession 35-44 years old
2 3 I am a developer by profession 45-54 years old
3 4 I am learning to code 18-24 years old
4 5 I am a developer by profession 18-24 years old
Employment RemoteWork Check \
0 Employed, full-time Remote Apples
1 Employed, full-time Remote Apples
2 Employed, full-time Remote Apples
3 Student, full-time NaN Apples
4 Student, full-time NaN Apples
CodingActivities \
0 Hobby
1 Hobby;Contribute to open-source projects;Other...
2 Hobby;Contribute to open-source projects;Other...
3 NaN
4 NaN
EdLevel \
0 Primary/elementary school
1 Bachelor’s degree (B.A., B.S., B.Eng., etc.)
2 Master’s degree (M.A., M.S., M.Eng., MBA, etc.)
3 Some college/university study without earning ...
4 Secondary school (e.g. American high school, G...
LearnCode \
0 Books / Physical media
1 Books / Physical media;Colleague;On the job tr...
2 Books / Physical media;Colleague;On the job tr...
3 Other online resources (e.g., videos, blogs, f...
4 Other online resources (e.g., videos, blogs, f...
LearnCodeOnline ... JobSatPoints_6 \
0 NaN ... NaN
1 Technical documentation;Blogs;Books;Written Tu... ... 0.0
2 Technical documentation;Blogs;Books;Written Tu... ... NaN
3 Stack Overflow;How-to videos;Interactive tutorial ... NaN
4 Technical documentation;Blogs;Written Tutorial... ... NaN
JobSatPoints_7 JobSatPoints_8 JobSatPoints_9 JobSatPoints_10 \
0 NaN NaN NaN NaN
1 0.0 0.0 0.0 0.0
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
JobSatPoints_11 SurveyLength SurveyEase ConvertedCompYearly JobSat
0 NaN NaN NaN NaN NaN
1 0.0 NaN NaN NaN NaN
2 NaN Appropriate in length Easy NaN NaN
3 NaN Too long Easy NaN NaN
4 NaN Too short Easy NaN NaN
[5 rows x 114 columns]
Initial dataframe: (65437, 114)
Create a SQLite Database and Insert the Data
Now, let's create a new SQLite database (survey-data.sqlite) and insert the data from the DataFrame into a table using the sqlite3 library:
import sqlite3
# Create a connection to the SQLite database
conn = sqlite3.connect('survey-data.sqlite')
# Write the dataframe to the SQLite database
df.to_sql('main', conn, if_exists='replace', index=False)
# Close the connection
conn.close()
Verify the Data in the SQLite Database Verify that the data has been correctly inserted into the SQLite database by running a simple query:
# Reconnect to the SQLite database
conn = sqlite3.connect('survey-data.sqlite')
# Run a simple query to check the data
QUERY = "SELECT * FROM main LIMIT 5"
df_check = pd.read_sql_query(QUERY, conn)
# Display the results
print(df_check)
print('Initial dataframe:', df.shape)
ResponseId MainBranch Age \
0 1 I am a developer by profession Under 18 years old
1 2 I am a developer by profession 35-44 years old
2 3 I am a developer by profession 45-54 years old
3 4 I am learning to code 18-24 years old
4 5 I am a developer by profession 18-24 years old
Employment RemoteWork Check \
0 Employed, full-time Remote Apples
1 Employed, full-time Remote Apples
2 Employed, full-time Remote Apples
3 Student, full-time NaN Apples
4 Student, full-time NaN Apples
CodingActivities \
0 Hobby
1 Hobby;Contribute to open-source projects;Other...
2 Hobby;Contribute to open-source projects;Other...
3 NaN
4 NaN
EdLevel \
0 Primary/elementary school
1 Bachelor’s degree (B.A., B.S., B.Eng., etc.)
2 Master’s degree (M.A., M.S., M.Eng., MBA, etc.)
3 Some college/university study without earning ...
4 Secondary school (e.g. American high school, G...
LearnCode \
0 Books / Physical media
1 Books / Physical media;Colleague;On the job tr...
2 Books / Physical media;Colleague;On the job tr...
3 Other online resources (e.g., videos, blogs, f...
4 Other online resources (e.g., videos, blogs, f...
LearnCodeOnline ... JobSatPoints_6 \
0 NaN ... NaN
1 Technical documentation;Blogs;Books;Written Tu... ... 0.0
2 Technical documentation;Blogs;Books;Written Tu... ... NaN
3 Stack Overflow;How-to videos;Interactive tutorial ... NaN
4 Technical documentation;Blogs;Written Tutorial... ... NaN
JobSatPoints_7 JobSatPoints_8 JobSatPoints_9 JobSatPoints_10 \
0 NaN NaN NaN NaN
1 0.0 0.0 0.0 0.0
2 NaN NaN NaN NaN
3 NaN NaN NaN NaN
4 NaN NaN NaN NaN
JobSatPoints_11 SurveyLength SurveyEase ConvertedCompYearly JobSat
0 NaN NaN NaN None None
1 0.0 NaN NaN None None
2 NaN Appropriate in length Easy None None
3 NaN Too long Easy None None
4 NaN Too short Easy None None
[5 rows x 114 columns]
Initial dataframe: (5, 2)
Count the number of rows in the table named 'main'
QUERY = """
SELECT COUNT(*)
FROM main
"""
df = pd.read_sql_query(QUERY, conn)
df.head()
| COUNT(*) | |
|---|---|
| 0 | 65437 |
To view the names of all tables in the database:
QUERY = """
SELECT name as Table_Name FROM sqlite_master
WHERE type = 'table'
"""
pd.read_sql_query(QUERY, conn)
| Table_Name | |
|---|---|
| 0 | main |
For example, you can group data by a specific column, like Age, to get the count of respondents in each age group:
QUERY = """
SELECT Age, COUNT(*) as count
FROM main
GROUP BY Age
ORDER BY Age
"""
pd.read_sql_query(QUERY, conn)
| Age | count | |
|---|---|---|
| 0 | 18-24 years old | 14098 |
| 1 | 25-34 years old | 23911 |
| 2 | 35-44 years old | 14942 |
| 3 | 45-54 years old | 6249 |
| 4 | 55-64 years old | 2575 |
| 5 | 65 years or older | 772 |
| 6 | Prefer not to say | 322 |
| 7 | Under 18 years old | 2568 |
Use this query to get the schema of a specific table, main in this case:
table_name = 'main'
QUERY = """
SELECT sql FROM sqlite_master
WHERE name= '{}'
""".format(table_name)
df = pd.read_sql_query(QUERY, conn)
print(df.iat[0,0])
CREATE TABLE "main" (
"ResponseId" INTEGER,
"MainBranch" TEXT,
"Age" TEXT,
"Employment" TEXT,
"RemoteWork" TEXT,
"Check" TEXT,
"CodingActivities" TEXT,
"EdLevel" TEXT,
"LearnCode" TEXT,
"LearnCodeOnline" TEXT,
"TechDoc" TEXT,
"YearsCode" TEXT,
"YearsCodePro" TEXT,
"DevType" TEXT,
"OrgSize" TEXT,
"PurchaseInfluence" TEXT,
"BuyNewTool" TEXT,
"BuildvsBuy" TEXT,
"TechEndorse" TEXT,
"Country" TEXT,
"Currency" TEXT,
"CompTotal" REAL,
"LanguageHaveWorkedWith" TEXT,
"LanguageWantToWorkWith" TEXT,
"LanguageAdmired" TEXT,
"DatabaseHaveWorkedWith" TEXT,
"DatabaseWantToWorkWith" TEXT,
"DatabaseAdmired" TEXT,
"PlatformHaveWorkedWith" TEXT,
"PlatformWantToWorkWith" TEXT,
"PlatformAdmired" TEXT,
"WebframeHaveWorkedWith" TEXT,
"WebframeWantToWorkWith" TEXT,
"WebframeAdmired" TEXT,
"EmbeddedHaveWorkedWith" TEXT,
"EmbeddedWantToWorkWith" TEXT,
"EmbeddedAdmired" TEXT,
"MiscTechHaveWorkedWith" TEXT,
"MiscTechWantToWorkWith" TEXT,
"MiscTechAdmired" TEXT,
"ToolsTechHaveWorkedWith" TEXT,
"ToolsTechWantToWorkWith" TEXT,
"ToolsTechAdmired" TEXT,
"NEWCollabToolsHaveWorkedWith" TEXT,
"NEWCollabToolsWantToWorkWith" TEXT,
"NEWCollabToolsAdmired" TEXT,
"OpSysPersonal use" TEXT,
"OpSysProfessional use" TEXT,
"OfficeStackAsyncHaveWorkedWith" TEXT,
"OfficeStackAsyncWantToWorkWith" TEXT,
"OfficeStackAsyncAdmired" TEXT,
"OfficeStackSyncHaveWorkedWith" TEXT,
"OfficeStackSyncWantToWorkWith" TEXT,
"OfficeStackSyncAdmired" TEXT,
"AISearchDevHaveWorkedWith" TEXT,
"AISearchDevWantToWorkWith" TEXT,
"AISearchDevAdmired" TEXT,
"NEWSOSites" TEXT,
"SOVisitFreq" TEXT,
"SOAccount" TEXT,
"SOPartFreq" TEXT,
"SOHow" TEXT,
"SOComm" TEXT,
"AISelect" TEXT,
"AISent" TEXT,
"AIBen" TEXT,
"AIAcc" TEXT,
"AIComplex" TEXT,
"AIToolCurrently Using" TEXT,
"AIToolInterested in Using" TEXT,
"AIToolNot interested in Using" TEXT,
"AINextMuch more integrated" TEXT,
"AINextNo change" TEXT,
"AINextMore integrated" TEXT,
"AINextLess integrated" TEXT,
"AINextMuch less integrated" TEXT,
"AIThreat" TEXT,
"AIEthics" TEXT,
"AIChallenges" TEXT,
"TBranch" TEXT,
"ICorPM" TEXT,
"WorkExp" REAL,
"Knowledge_1" TEXT,
"Knowledge_2" TEXT,
"Knowledge_3" TEXT,
"Knowledge_4" TEXT,
"Knowledge_5" TEXT,
"Knowledge_6" TEXT,
"Knowledge_7" TEXT,
"Knowledge_8" TEXT,
"Knowledge_9" TEXT,
"Frequency_1" TEXT,
"Frequency_2" TEXT,
"Frequency_3" TEXT,
"TimeSearching" TEXT,
"TimeAnswering" TEXT,
"Frustration" TEXT,
"ProfessionalTech" TEXT,
"ProfessionalCloud" TEXT,
"ProfessionalQuestion" TEXT,
"Industry" TEXT,
"JobSatPoints_1" REAL,
"JobSatPoints_4" REAL,
"JobSatPoints_5" REAL,
"JobSatPoints_6" REAL,
"JobSatPoints_7" REAL,
"JobSatPoints_8" REAL,
"JobSatPoints_9" REAL,
"JobSatPoints_10" REAL,
"JobSatPoints_11" REAL,
"SurveyLength" TEXT,
"SurveyEase" TEXT,
"ConvertedCompYearly" REAL,
"JobSat" REAL
)
Histograms
Plot a histogram of CompTotal (Total Compensation).
## Write your code here
QUERY = """
SELECT CompTotal
FROM main
"""
df = pd.read_sql_query(QUERY, conn)
df.CompTotal.hist(log=True)
plt.xlabel('CompTotal')
plt.ylabel('Count')
plt.show()

Box Plots
Plot a box plot of Age.
## Write your code here
QUERY = """
SELECT Age, CompTotal
FROM main
"""
df = pd.read_sql_query(QUERY, conn)
df.plot(kind='box', by='Age', figsize=(5, 6))
plt.xticks(rotation=90)
plt.xlabel('Age')
plt.ylabel('CompTotal')
plt.title('Age')
plt.ylim(-10000, 700000)
plt.show()

QUERY = """
SELECT Age
FROM main
"""
df = pd.read_sql_query(QUERY, conn)
df.Age = df.Age.map({'Under 18 years old': 17, '18-24 years old': 21, 'Prefer not to say': float('nan'),
'25-34 years old': 30, '35-44 years old': 40, '45-54 years old': 50,
'55-64 years old': 60, '65 years or older': 66})
df.plot(kind='box', figsize=(3, 4))
plt.ylabel('Age')
plt.title('Age')
plt.show()

Scatter Plots
Create a scatter plot of Age and WorkExp.
## Write your code here
QUERY = """
SELECT Age, WorkExp
FROM main
"""
df = pd.read_sql_query(QUERY, conn)
df.Age = df.Age.map({'Under 18 years old': 17, '18-24 years old': 21, 'Prefer not to say': float('nan'),
'25-34 years old': 30, '35-44 years old': 40, '45-54 years old': 50,
'55-64 years old': 60, '65 years or older': 66})
df.plot(kind='scatter', x='Age', y='WorkExp', figsize=(10, 6), color='darkblue')
plt.title('Scatter plot of Age and WorkExp')
plt.xlabel('Age')
plt.ylabel('WorkExp')
plt.show()

Bubble Plots
Create a bubble plot of TimeSearching and Frustration using the Age column as the bubble size.
QUERY = """
SELECT Age, TimeSearching, Frustration
FROM main
"""
df = pd.read_sql_query(QUERY, conn).dropna()
df.Age = df.Age.map({'Under 18 years old': 17, '18-24 years old': 21, 'Prefer not to say': float('nan'),
'25-34 years old': 30, '35-44 years old': 40, '45-54 years old': 50,
'55-64 years old': 60, '65 years or older': 66})
norm_age = (df.Age - df.Age.min()) / (df.Age.max() - df.Age.min())
df.TimeSearching = df.TimeSearching.map({'30-60 minutes a day': 45, '60-120 minutes a day': 90,
'15-30 minutes a day': 23, 'Less than 15 minutes a day': 14, 'Over 120 minutes a day': 121})
df['NFrust'] = df['Frustration'].str.split(';').str.len() # Transform categorical variable to numerical
## Write your code here
ax = df.plot(kind='scatter',
x='TimeSearching',
y='NFrust',
alpha=0.5,
s=norm_age * 200 + 1
)
ax.set_ylabel('Frustration')
ax.set_xlabel('TimeSearching, min')
ax.legend(['Age'], loc='upper center', fontsize='x-large')
ax.set_title('Bubble plot')
Text(0.5, 1.0, 'Bubble plot')

Pie Charts
Create a pie chart of the top 5 databases(DatabaseWantToWorkWith) that respondents wish to learn next year.
## Write your code here
QUERY = """
SELECT DatabaseWantToWorkWith
FROM main
"""
df = pd.read_sql_query(QUERY, conn).dropna()
datab = df.copy()
dummiesdatab = datab['DatabaseWantToWorkWith'].str.get_dummies(sep=';')
datab = dummiesdatab.agg('sum').T.head()
datab.plot(kind='pie',
figsize=(9, 5),
autopct='%1.1f%%', # add in percentages
labels=None,
startangle=0,
pctdistance=1.12, # the ratio between the center of each pie slice and the start of the text
shadow=False,
colormap='Spectral'
)
plt.title('DatabaseWantToWorkWith')
plt.axis('equal') # Sets the pie chart to look like a circle
plt.legend(labels=datab.index, loc='upper left')
plt.show()

Stacked Charts
Create a stacked bar chart of median TimeSearching and TimeAnswering for the age group 30 to 35.
## Write your code here
QUERY = """
SELECT Age, TimeSearching, TimeAnswering
FROM main
"""
df = pd.read_sql_query(QUERY, conn)
df.TimeSearching = df.TimeSearching.map({'30-60 minutes a day': 45, '60-120 minutes a day': 90,
'15-30 minutes a day': 23, 'Less than 15 minutes a day': 14, 'Over 120 minutes a day': 121})
df.TimeAnswering = df.TimeAnswering.map({'30-60 minutes a day': 45, '60-120 minutes a day': 90,
'15-30 minutes a day': 23, 'Less than 15 minutes a day': 14, 'Over 120 minutes a day': 121})
df_time = df.groupby('Age', as_index=False).median()
order = [7, 0, 1, 2, 3, 4, 5]
df_time = df_time.reindex(order)
ax = df_time.plot(kind='bar', x='Age', figsize=(9, 5), stacked=True)
xlabels = [textwrap.fill(label.get_text(), width=10) for label in ax.get_xticklabels()]
ax.set(xlabel='Age group', ylabel='Time spent')
ax.set_xticklabels(xlabels)
plt.title('Median TimeSearching and TimeAnswering for different Age groups')
plt.xticks(rotation=0)
plt.grid(True, axis='y', linestyle='dashed')
plt.show()

Line Chart
Plot the median CompTotal for all ages from 45 to 60.
## Write your code here
QUERY = """
SELECT Age, CompTotal
FROM main
"""
df = pd.read_sql_query(QUERY, conn).dropna()
df = df.groupby('Age', as_index=False).median()
order = [7, 0, 1, 2, 3, 4, 5]
df_line = df.reindex(order)
plt.figsize=(10, 6)
ax = sns.lineplot(data=df_line, x='Age', y='CompTotal')
xlabels = [textwrap.fill(label.get_text(), width=10) for label in ax.get_xticklabels()]
ax.set_xticklabels(xlabels)
plt.title('Line plot of Age and Median CompTotal')
plt.xlabel('Age group')
plt.grid(True, linestyle='dashed')
plt.xticks(rotation=0)
plt.ylabel('Median CompTotal')
plt.show()
/tmp/ipykernel_300/3170935809.py:9: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
ax.set_xticklabels(xlabels)

Bar Chart
Create a horizontal bar chart using the MainBranch column.
## Write your code here
QUERY = """
SELECT MainBranch, COUNT(*) as Count
FROM main
GROUP BY MainBranch
ORDER BY Count DESC
"""
df = pd.read_sql_query(QUERY, conn)
plt.figure(figsize=(10, 8))
ax = sns.barplot(data=df, y='MainBranch', x='Count')
labels = [textwrap.fill(label.get_text(), width=20) for label in ax.get_yticklabels()]
ax.set(yticklabels=labels)
plt.xticks(rotation=0)
plt.xlabel("Type of MainBranch")
plt.ylabel("Number of Respondents")
plt.grid(True, axis='y', linestyle='dashed')
plt.title("Distribution of respondents by MainBranch")
plt.tight_layout()
plt.show()
/tmp/ipykernel_300/2340173538.py:4: UserWarning: set_ticklabels() should only be used with a fixed number of ticks, i.e. after set_ticks() or using a FixedLocator.
ax.set(yticklabels=labels)

In this lab, you focused on extracting and visualizing data from an RDBMS using SQL queries and SQLite. You applied various visualization techniques, including:
TimeSearching and TimeAnswering.Once the lab is complete, ensure to close the database connection:
conn.close()
Ayushi Jain
Copyright © IBM Corporation. All rights reserved.