First commit
This commit is contained in:
52
BokehChart.html
Normal file
52
BokehChart.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bokeh Plot</title>
|
||||
<script type="text/javascript" src="https://cdn.bokeh.org/bokeh/release/bokeh-3.0.2.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
Bokeh.set_log_level("info");
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a3ed5b52-0df3-4007-938f-5c6012e956c8" data-root-id="p1004" style="display: contents;"></div>
|
||||
|
||||
<script type="application/json" id="p1215">
|
||||
{"14ecb273-a373-45b0-a890-2c9208400025":{"version":"3.0.2","title":"Bokeh Application","defs":[],"roots":[{"type":"object","name":"Figure","id":"p1004","attributes":{"width":700,"height":300,"sizing_mode":"scale_width","x_range":{"type":"object","name":"FactorRange","id":"p1014","attributes":{"factors":["Durian","Surstr\u00f6mming","Liquorice","Vodka","Balut","Civet coffee","Maggot Cheese","Blood sausage","Escargots snail","Tarantula","Frog","Chicken feet"]}},"y_range":{"type":"object","name":"Range1d","id":"p1016","attributes":{"end":9}},"x_scale":{"type":"object","name":"CategoricalScale","id":"p1018"},"y_scale":{"type":"object","name":"LinearScale","id":"p1020"},"title":{"type":"object","name":"Title","id":"p1007","attributes":{"text":"Counts"}},"renderers":[{"type":"object","name":"GlyphRenderer","id":"p1042","attributes":{"data_source":{"type":"object","name":"ColumnDataSource","id":"p1001","attributes":{"selected":{"type":"object","name":"Selection","id":"p1003","attributes":{"indices":[],"line_indices":[]}},"selection_policy":{"type":"object","name":"UnionRenderers","id":"p1002"},"data":{"type":"map","entries":[["x",["Liquorice","Maggot Cheese","Vodka","Blood sausage","Escargots snail","Balut","Tarantula","Frog","Civet coffee","Durian","Surstr\u00f6mming","Chicken feet"]],["y",[2,1,2,1,1,2,1,1,2,3,3,1]]]}}},"view":{"type":"object","name":"CDSView","id":"p1043","attributes":{"filter":{"type":"object","name":"AllIndices","id":"p1044"}}},"glyph":{"type":"object","name":"VBar","id":"p1039","attributes":{"x":{"type":"field","field":"x"},"width":{"type":"value","value":0.9},"top":{"type":"field","field":"y"},"line_color":{"type":"value","value":"#1f77b4"},"fill_color":{"type":"value","value":"#1f77b4"}}},"nonselection_glyph":{"type":"object","name":"VBar","id":"p1040","attributes":{"x":{"type":"field","field":"x"},"width":{"type":"value","value":0.9},"top":{"type":"field","field":"y"},"line_color":{"type":"value","value":"#1f77b4"},"line_alpha":{"type":"value","value":0.1},"fill_color":{"type":"value","value":"#1f77b4"},"fill_alpha":{"type":"value","value":0.1},"hatch_alpha":{"type":"value","value":0.1}}},"muted_glyph":{"type":"object","name":"VBar","id":"p1041","attributes":{"x":{"type":"field","field":"x"},"width":{"type":"value","value":0.9},"top":{"type":"field","field":"y"},"line_color":{"type":"value","value":"#1f77b4"},"line_alpha":{"type":"value","value":0.2},"fill_color":{"type":"value","value":"#1f77b4"},"fill_alpha":{"type":"value","value":0.2},"hatch_alpha":{"type":"value","value":0.2}}}}}],"toolbar":{"type":"object","name":"Toolbar","id":"p1011"},"toolbar_location":null,"left":[{"type":"object","name":"LinearAxis","id":"p1028","attributes":{"ticker":{"type":"object","name":"BasicTicker","id":"p1029","attributes":{"mantissas":[1,2,5]}},"formatter":{"type":"object","name":"BasicTickFormatter","id":"p1030"},"major_label_policy":{"type":"object","name":"AllLabels","id":"p1031"}}}],"below":[{"type":"object","name":"CategoricalAxis","id":"p1022","attributes":{"ticker":{"type":"object","name":"CategoricalTicker","id":"p1023"},"formatter":{"type":"object","name":"CategoricalTickFormatter","id":"p1024"},"major_label_policy":{"type":"object","name":"AllLabels","id":"p1025"}}}],"center":[{"type":"object","name":"Grid","id":"p1027","attributes":{"axis":{"id":"p1022"},"grid_line_color":null}},{"type":"object","name":"Grid","id":"p1034","attributes":{"dimension":1,"axis":{"id":"p1028"}}},{"type":"object","name":"Legend","id":"p1057","attributes":{"visible":false,"items":[{"type":"object","name":"LegendItem","id":"p1058","attributes":{"label":{"type":"field","field":"x"},"renderers":[{"id":"p1042"}]}}]}}]}}]}}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
const fn = function() {
|
||||
Bokeh.safely(function() {
|
||||
(function(root) {
|
||||
function embed_document(root) {
|
||||
const docs_json = document.getElementById('p1215').textContent;
|
||||
const render_items = [{"docid":"14ecb273-a373-45b0-a890-2c9208400025","roots":{"p1004":"a3ed5b52-0df3-4007-938f-5c6012e956c8"},"root_ids":["p1004"]}];
|
||||
root.Bokeh.embed.embed_items(docs_json, render_items);
|
||||
}
|
||||
if (root.Bokeh !== undefined) {
|
||||
embed_document(root);
|
||||
} else {
|
||||
let attempts = 0;
|
||||
const timer = setInterval(function(root) {
|
||||
if (root.Bokeh !== undefined) {
|
||||
clearInterval(timer);
|
||||
embed_document(root);
|
||||
} else {
|
||||
attempts++;
|
||||
if (attempts > 100) {
|
||||
clearInterval(timer);
|
||||
console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
|
||||
}
|
||||
}
|
||||
}, 10, root)
|
||||
}
|
||||
})(window);
|
||||
});
|
||||
};
|
||||
if (document.readyState != "loading") fn();
|
||||
else document.addEventListener("DOMContentLoaded", fn);
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
120
CreateTestDatabase.sql
Normal file
120
CreateTestDatabase.sql
Normal file
@@ -0,0 +1,120 @@
|
||||
CREATE DATABASE Project;
|
||||
CREATE TABLE "Customer" (
|
||||
"CustomerID" INTEGER NOT NULL,
|
||||
"Name" TEXT,
|
||||
"Age" INTEGER,
|
||||
PRIMARY KEY("CustomerID")
|
||||
);
|
||||
CREATE TABLE "Address" (
|
||||
"AddressID" INTEGER NOT NULL,
|
||||
"CustomerID" INTEGER NOT NULL,
|
||||
"Street" TEXT,
|
||||
"Number" INTEGER,
|
||||
"PostalCode" INTEGER,
|
||||
"Region" TEXT,
|
||||
"CountryID" INTEGER NOT NULL,
|
||||
CONSTRAINT FK_CustomerID
|
||||
FOREIGN KEY("CustomerID") REFERENCES "Customer"("CustomerID")
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT FK_CountryID
|
||||
FOREIGN KEY("CountryID") REFERENCES "Country"("CountryID")
|
||||
ON DELETE CASCADE,
|
||||
PRIMARY KEY("AddressID")
|
||||
);
|
||||
CREATE TABLE "Country" (
|
||||
"CountryID" INTEGER NOT NULL,
|
||||
"Country" TEXT,
|
||||
PRIMARY KEY("CountryID")
|
||||
);
|
||||
CREATE TABLE "Contact" (
|
||||
"ContactID" INTEGER NOT NULL,
|
||||
"CustomerID" INTEGER NOT NULL,
|
||||
"Phone" TEXT,
|
||||
"Mail" TEXT,
|
||||
PRIMARY KEY("ContactID"),
|
||||
CONSTRAINT FK_CustomerID
|
||||
FOREIGN KEY("CustomerID") REFERENCES "Customer"("CustomerID")
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE "Shipment" (
|
||||
"CustomerID" INTEGER NOT NULL,
|
||||
"ItemID" INTEGER NOT NULL,
|
||||
"Date" TEXT,
|
||||
CONSTRAINT FK_ItemID
|
||||
FOREIGN KEY("ItemID") REFERENCES "Item"("ItemID")
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT FK_CustomerID
|
||||
FOREIGN KEY("CustomerID") REFERENCES "Customer"("CustomerID")
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE "Item" (
|
||||
"ItemID" INTEGER NOT NULL,
|
||||
"Name" TEXT,
|
||||
PRIMARY KEY("ItemID")
|
||||
);
|
||||
INSERT INTO Customer VALUES
|
||||
(10001,"Tomasz Gorczyca",23),
|
||||
(10002,"Leon Kulikowski",36),
|
||||
(10003,"Artur Nowak",32),
|
||||
(10004,"Iwa Cegielska",28),
|
||||
(10005,"Adriana Polkowska",31),
|
||||
(10006,"Patrycja Ptaszynska",29);
|
||||
INSERT INTO Country VALUES
|
||||
(1,"Czechia"),
|
||||
(2,"Slovakia");
|
||||
INSERT INTO Address VALUES
|
||||
(100,10003,"Bílokostelecká",77,46331,"Liberec",1),
|
||||
(102,10005,"Kyselská",167,41801,"Teplice",1),
|
||||
(103,10001,"Strmá",184,33701,"Rokycany",1),
|
||||
(104,10004,"Mjr. Archipova",1,26012,"Dolný Kubín",2),
|
||||
(105,10002,"Rybka",84,34092,"Ružomberok",2),
|
||||
(106,10006,"Kurtaserskou",136,93201," Veľký Meder",2);
|
||||
INSERT INTO Contact VALUES
|
||||
(1, 10001, "+420778756417","sveta4521@badutstore.com"),
|
||||
(2, 10002, "+421903443108","kimkjersteen@texasaol.com"),
|
||||
(3, 10003, "+420776121001","shiknikolai@eloltsf.com"),
|
||||
(4, 10004, "+421066229393","pebkac59@supermantutivie.com"),
|
||||
(5, 10005, "+420771019248","thodoan@lohpcn.com"),
|
||||
(6, 10006, "+421907353718","kotimur@playfuny.com");
|
||||
INSERT INTO Item VALUES
|
||||
(1000001,"Liquorice"),
|
||||
(1000002,"Surströmming"),
|
||||
(1000003,"Durian"),
|
||||
(1000004,"Frog"),
|
||||
(1000005,"Maggot Cheese"),
|
||||
(1000006,"Balut"),
|
||||
(1000007,"Blood sausage"),
|
||||
(1000008,"Vodka"),
|
||||
(1000009,"Coconut"),
|
||||
(1000010,"Escargots snail"),
|
||||
(1000011,"Tarantula"),
|
||||
(1000012,"Brain curry"),
|
||||
(1000013,"Chicken feet"),
|
||||
(1000014,"Hakarl"),
|
||||
(1000015,"Basashi"),
|
||||
(1000016,"Molokhia"),
|
||||
(1000017,"Civet coffee"),
|
||||
(1000018,"Stinky tofu");
|
||||
INSERT INTO Shipment VALUES
|
||||
(10001,1000001,"15/12/2021"),
|
||||
(10001,1000005,"11/12/2021"),
|
||||
(10002,1000008,"01/01/2022"),
|
||||
(10002,1000007,"11/01/2021"),
|
||||
(10002,1000010,"11/12/2021"),
|
||||
(10002,1000006,"02/01/2022"),
|
||||
(10003,1000011,"05/02/2022"),
|
||||
(10003,1000004,"07/08/2021"),
|
||||
(10003,1000017,"04/11/2021"),
|
||||
(10004,1000006,"12/01/2022"),
|
||||
(10004,1000003,"17/01/2022"),
|
||||
(10005,1000003,"25/12/2021"),
|
||||
(10006,1000002,"09/02/2022"),
|
||||
(10006,1000001,"11/08/2021"),
|
||||
(10007,1000003,"15/11/2021"),
|
||||
(10007,1000002,"18/01/2022"),
|
||||
(10007,1000008,"19/01/2022"),
|
||||
(10008,1000017,"21/12/2021"),
|
||||
(10004,1000013,"10/01/2022"),
|
||||
(10008,1000002,"25/12/2021");
|
||||
|
||||
|
||||
BIN
Project.db
Normal file
BIN
Project.db
Normal file
Binary file not shown.
263
Python Script.py
Normal file
263
Python Script.py
Normal file
@@ -0,0 +1,263 @@
|
||||
try:
|
||||
from prettytable import PrettyTable
|
||||
except ImportError:
|
||||
auth = input(
|
||||
'This Python script requires PrettyTable library. Please press ENTER.')
|
||||
import os
|
||||
os.system('pip install prettytable')
|
||||
from prettytable import PrettyTable
|
||||
try:
|
||||
from bokeh.io import output_file, show
|
||||
from bokeh.plotting import figure
|
||||
from bokeh.models import ColumnDataSource
|
||||
except ImportError:
|
||||
import os
|
||||
os.system('pip install bokeh')
|
||||
from bokeh.io import output_file, show
|
||||
from bokeh.plotting import figure
|
||||
from bokeh.models import ColumnDataSource
|
||||
import sys
|
||||
import sqlite3
|
||||
try:
|
||||
sql = sqlite3.connect(
|
||||
r"Project.db")
|
||||
except:
|
||||
print("\nDatabase not found!")
|
||||
cursor = sql.cursor()
|
||||
|
||||
|
||||
def back():
|
||||
input('\nPress ENTER to return to main menu...')
|
||||
main()
|
||||
|
||||
|
||||
def header():
|
||||
num_fields = len(cursor.description)
|
||||
field_names = [i[0] for i in cursor.description]
|
||||
return field_names
|
||||
|
||||
|
||||
def showTables():
|
||||
tablelist = []
|
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
|
||||
maintable = PrettyTable(["Option", "Number"])
|
||||
tablenames = cursor.fetchall()
|
||||
for i in range(len(tablenames)):
|
||||
a = [x.replace('(', "").replace(')', "").replace("'", "")
|
||||
for x in tablenames[i]]
|
||||
tablelist.append(str(a[0]))
|
||||
maintable.add_row([a[0], i+1])
|
||||
print(maintable)
|
||||
return tablelist
|
||||
|
||||
|
||||
# First query - View table
|
||||
|
||||
|
||||
def viewTable():
|
||||
try:
|
||||
tablelist = showTables()
|
||||
choiceTable = int(input("Select table to view: "))
|
||||
cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1]))
|
||||
table = PrettyTable(header())
|
||||
values = cursor.fetchall()
|
||||
for i in values:
|
||||
a = [x.replace('(', "").replace(')', "").replace("'", "")
|
||||
for x in str(i).split(',')]
|
||||
table.add_row(a)
|
||||
print(table)
|
||||
except Exception as e:
|
||||
print('\n'+str(e).capitalize())
|
||||
back()
|
||||
|
||||
|
||||
# Second query - Insert row
|
||||
|
||||
|
||||
def insertRow():
|
||||
try:
|
||||
insert = []
|
||||
tablelist = showTables()
|
||||
choiceTable = int(input("Select table to insert values: "))
|
||||
cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1]))
|
||||
scriptmain = "INSERT INTO %s VALUES " % tablelist[choiceTable-1]
|
||||
multi = len(header())-1
|
||||
scriptmain = scriptmain + '('+'%s'+',%s'*multi+')'
|
||||
for i in header():
|
||||
inp = input(i + " = ")
|
||||
if inp.isnumeric() == True:
|
||||
inp = int(inp)
|
||||
else:
|
||||
inp = "'"+inp+"'"
|
||||
insert.append(inp)
|
||||
insert = tuple(insert)
|
||||
cursor.execute(scriptmain % (insert))
|
||||
sql.commit()
|
||||
except Exception as e:
|
||||
print('\n'+str(e).capitalize())
|
||||
sql.rollback()
|
||||
back()
|
||||
|
||||
|
||||
# Third query - Delete row
|
||||
|
||||
|
||||
def deleteRow():
|
||||
try:
|
||||
tablelist = showTables()
|
||||
choiceTable = int(input("Select table to delete values: "))
|
||||
cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1]))
|
||||
scriptmain = "DELETE FROM %s WHERE" % (tablelist[choiceTable-1])
|
||||
table = PrettyTable(["Option", "Number"])
|
||||
count = 1
|
||||
for i in header():
|
||||
table.add_row([i, count])
|
||||
count += 1
|
||||
print(table)
|
||||
choiceColumn = int(input("Select column to delete values: "))
|
||||
column = header()[choiceColumn-1]
|
||||
choiceField = input(column + " = ")
|
||||
if choiceField.isnumeric() == True:
|
||||
choiceField = int(choiceField)
|
||||
else:
|
||||
choiceField = "'"+choiceField+"'"
|
||||
scriptmain = scriptmain + ' %s = %s'
|
||||
cursor.execute(scriptmain % (column, choiceField))
|
||||
sql.commit()
|
||||
except Exception as e:
|
||||
print('\n'+str(e).capitalize())
|
||||
sql.rollback()
|
||||
back()
|
||||
|
||||
|
||||
# Fourth query - Update row
|
||||
|
||||
|
||||
def updateRow():
|
||||
try:
|
||||
tablelist = showTables()
|
||||
choiceTable = int(input("Select table to update values: "))
|
||||
cursor.execute("SELECT * FROM %s" % (tablelist[choiceTable-1]))
|
||||
scriptmain = "UPDATE " + (tablelist[choiceTable-1]) + " SET %s WHERE "
|
||||
table = PrettyTable(["Option", "Number"])
|
||||
count = 1
|
||||
for i in header():
|
||||
table.add_row([i, count])
|
||||
count += 1
|
||||
print(table)
|
||||
choiceColumn = int(input("Select condition column: "))
|
||||
column = header()[choiceColumn-1]
|
||||
contentColumn = input(column + " = ")
|
||||
if contentColumn.isnumeric() == True:
|
||||
column = column + " = " + str(contentColumn)
|
||||
else:
|
||||
column = column + " = " + "'"+contentColumn + "'"
|
||||
scriptmain = scriptmain + column
|
||||
upd = ''
|
||||
while True:
|
||||
choiceField = int(input("Select column to be updated: "))
|
||||
field = header()[choiceField-1]
|
||||
contentField = input(field + " = ")
|
||||
if contentField.isnumeric() == True:
|
||||
field = field + " = " + str(contentField)
|
||||
else:
|
||||
field = field + " = " + "'"+contentField + "'"
|
||||
upd = upd+", "+field
|
||||
con = input(
|
||||
'Do you want to add another one to be updated? (y for yes, any other key for no) ')
|
||||
if con == 'y':
|
||||
continue
|
||||
else:
|
||||
break
|
||||
upd = upd[2:]
|
||||
cursor.execute(scriptmain % upd)
|
||||
sql.commit()
|
||||
except Exception as e:
|
||||
print('\n'+str(e).capitalize())
|
||||
sql.rollback()
|
||||
back()
|
||||
|
||||
|
||||
# Fifth query - Bokeh visualization
|
||||
|
||||
|
||||
def bokeh():
|
||||
try:
|
||||
lst = []
|
||||
cursor.execute(
|
||||
"SELECT Item.Name as Item from Shipment INNER JOIN Item on Shipment.ItemID=Item.ItemID ")
|
||||
items = cursor.fetchall()
|
||||
for i in items:
|
||||
i = str(i).replace('(', '').replace(')', '').replace(
|
||||
"'", "").replace(",", "")
|
||||
lst.append(i)
|
||||
order = [i for n, i in enumerate(lst) if i not in lst[:n]]
|
||||
dct = {}
|
||||
for i in order:
|
||||
dct[i] = lst.count(i)
|
||||
x = list(dct.keys())
|
||||
y = list(dct.values())
|
||||
sorted_x = sorted(x, key=lambda a: y[x.index(a)], reverse=True)
|
||||
source = ColumnDataSource(data=dict(x=x, y=y))
|
||||
p = figure(x_range=sorted_x, y_range=(0, 9), title="Counts",
|
||||
toolbar_location=None, tools="", width=700, height=300, sizing_mode='scale_width')
|
||||
p.vbar(x='x', top='y', width=0.9, legend_field='x', source=source)
|
||||
p.xgrid.grid_line_color = None
|
||||
p.legend.visible = False
|
||||
output_file('BokehChart.html')
|
||||
show(p)
|
||||
back()
|
||||
except Exception as e:
|
||||
print('\n'+str(e).capitalize())
|
||||
back()
|
||||
|
||||
# Sixth query - Many-to-many relation: 2 JOIN clauses
|
||||
|
||||
|
||||
def itemCustomer():
|
||||
try:
|
||||
cursor.execute('SELECT Customer.Name as Customer, group_concat(Item.Name, ", ") as Item from Shipment INNER JOIN Customer on Shipment.CustomerID=Customer.CustomerID INNER JOIN Item on Item.ItemID=Shipment.ItemID GROUP BY Customer;')
|
||||
table = PrettyTable(header())
|
||||
final = cursor.fetchall()
|
||||
for i in final:
|
||||
table.add_row(list(i))
|
||||
print(table)
|
||||
except Exception as e:
|
||||
print('\n'+str(e).capitalize())
|
||||
back()
|
||||
|
||||
|
||||
def main():
|
||||
table = PrettyTable(["Option", "Number"])
|
||||
table.add_row(['View Table', 1])
|
||||
table.add_row(['Insert Row', 2])
|
||||
table.add_row(['Delete Row', 3])
|
||||
table.add_row(['Update Row', 4])
|
||||
table.add_row(['Chart: Number of times each item was ordered', 5])
|
||||
table.add_row(['List items each customer has ordered', 6])
|
||||
table.add_row(['Quit', 7])
|
||||
print(table)
|
||||
option = input("Select option: ")
|
||||
if option == '1':
|
||||
viewTable()
|
||||
elif option == '2':
|
||||
insertRow()
|
||||
elif option == '3':
|
||||
deleteRow()
|
||||
elif option == '4':
|
||||
updateRow()
|
||||
elif option == '5':
|
||||
bokeh()
|
||||
elif option == '6':
|
||||
itemCustomer()
|
||||
elif option == '7':
|
||||
sql.close()
|
||||
print("Thank you for using!")
|
||||
sys.exit()
|
||||
else:
|
||||
print("\nUnknown option.")
|
||||
back()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user