Commit 0c630b13 authored by Kumarasinghe C.A.W.'s avatar Kumarasinghe C.A.W.

Automated ER Diagram Generation and Query Generation

parent f55d0806
This source diff could not be displayed because it is too large. You can view the blob instead.
from flask import Flask, render_template, url_for, redirect, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin, login_user, LoginManager, login_required, logout_user, current_user
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import InputRequired, Length, ValidationError
from flask_bcrypt import Bcrypt
from similarity import perform_ocr_and_similarity
from flask import Flask, render_template,session
import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.neighbors import NearestNeighbors
import os
import cv2
import keras_ocr
app = Flask(__name__)
bcrypt = Bcrypt(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SECRET_KEY'] = 'thisisasecretkey'
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # Set max upload size to 16 MB
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False, unique=True)
password = db.Column(db.String(80), nullable=False)
class RegisterForm(FlaskForm):
username = StringField(validators=[
InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Username"})
password = PasswordField(validators=[
InputRequired(), Length(min=8, max=20)], render_kw={"placeholder": "Password"})
submit = SubmitField('Register')
def validate_username(self, username):
existing_user_username = User.query.filter_by(
username=username.data).first()
if existing_user_username:
raise ValidationError(
'That username already exists. Please choose a different one.')
class LoginForm(FlaskForm):
username = StringField(validators=[
InputRequired(), Length(min=4, max=20)], render_kw={"placeholder": "Username"})
password = PasswordField(validators=[
InputRequired(), Length(min=8, max=20)], render_kw={"placeholder": "Password"})
submit = SubmitField('Login')
@app.route('/')
def home():
return render_template('home.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user:
if bcrypt.check_password_hash(user.password, form.password.data):
login_user(user)
return redirect(url_for('dashboard'))
return render_template('login.html', form=form)
USER_ROLES = {
"student1": "student",
"teacher1": "teacher",
# Add more username-role mappings as needed
}
@app.route('/dashboard', methods=['GET', 'POST'])
@login_required
def dashboard():
username = current_user.username
user_role = USER_ROLES.get(username, "default_role") # Assign a default role if username not found in the mapping
print(username)
return render_template('dashboard.html', user_role=user_role)
# Import necessary libraries and functions (including your ER diagram generation logic)
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
class ERDiagramForm(FlaskForm):
user_input = StringField('User Input', validators=[DataRequired()])
submit = SubmitField('Generate ER Diagram')
import subprocess
import json
@app.route('/generate_er_diagram', methods=['GET', 'POST'])
@login_required
def generate_er_diagram():
form = ERDiagramForm(request.form)
sql_queries = ""
if form.validate_on_submit():
user_input = form.user_input.data
user_input = user_input.replace('"', '') # Process the input as needed
# Call the diagram.py script with the processed user input
try:
result = subprocess.run(["python", "diagram.py", user_input], capture_output=True, text=True, check=True)
sql_queries = result.stdout.strip() # Get the SQL queries from the subprocess output
except Exception as e:
sql_queries = f"Error: {e}"
# Load SQL queries from the JSON file
with open('data/sql_queries.json', 'r') as json_file:
saved_queries = json.load(json_file)
return render_template('er_diagram.html', form=form, er_diagram=True, sql_queries=saved_queries)
return render_template('er_diagram.html', form=form, er_diagram=False, sql_queries=sql_queries)
import cv2
from flask import send_from_directory
# Get the absolute path to the temp folder
temp_folder_path = os.path.abspath('temp/')
@app.route('/images/<filename>')
def get_image(filename):
return send_from_directory(temp_folder_path, filename)
# Route to handle image similarity functionality
@app.route('/similarity', methods=['GET', 'POST'])
@login_required
def similarity():
temp_folder = 'temp'
os.makedirs(temp_folder, exist_ok=True)
if request.method == 'POST':
# Handle uploaded images
image1 = request.files['image1']
image2 = request.files['image2']
# Save the uploaded images to temporary files
image1_path = os.path.join(temp_folder, 'image1.jpg')
image2_path = os.path.join(temp_folder, 'image2.jpg')
image1.save(image1_path)
image2.save(image2_path)
# Invert the images
#inverted_image1 = cv2.bitwise_not(cv2.imread(image1_path))
#inverted_image2 = cv2.bitwise_not(cv2.imread(image2_path))
img = cv2.imread(image1_path)
img2 = cv2.imread(image2_path)
# Load the images
inverted_image1 = cv2.bitwise_not(img)
inverted_image2 = cv2.bitwise_not(img2)
# Save the inverted images with correct names
inverted_image1_path = os.path.join(temp_folder, 'inverted_image1.jpg')
inverted_image2_path = os.path.join(temp_folder, 'inverted_image2.jpg')
cv2.imwrite(inverted_image1_path, inverted_image1)
cv2.imwrite(inverted_image2_path, inverted_image2)
# Perform OCR and similarity calculations (assuming these functions are defined)
word_list1, corrected_word_list1, word_list2, corrected_word_list2, pred, corr = perform_ocr_and_similarity(inverted_image1_path, inverted_image2_path)
# Call the similarity.py script with the processed image paths
try:
result = subprocess.run(["python", "similarity.py", inverted_image1_path, inverted_image2_path], capture_output=True, text=True, check=True)
similarity_result = result.stdout.strip()
except Exception as e:
similarity_result = f"Error: {e}"
similarity_result = "Similarity Result"
# Detailed results dictionary
detailed_results = {
"word_list1": word_list1,
"corrected_word_list1": corrected_word_list1,
"word_list2": word_list2,
"corrected_word_list2": corrected_word_list2,
"pred": pred,
"corr": corr
}
return render_template('similarity.html', similarity_result=similarity_result, detailed_results=detailed_results)
return render_template('similarity.html')
import numpy as np
from spellchecker import SpellChecker
from nltk.stem import SnowballStemmer
pipeline = keras_ocr.pipeline.Pipeline()
spell = SpellChecker()
stemmer = SnowballStemmer("english")
# Calculate marks, marks1, marks2, marks3, and final_marks here...
def calculate_marks(corrected_words):
with open('data/entity_list.json', 'r') as json_file:
entity_list = json.load(json_file)
with open('data/attributes.json', 'r') as json_file:
attributes_data = json.load(json_file)
with open('data/relations.json', 'r') as json_file:
relations_data = json.load(json_file)
entity_matches = sum(word.lower() in entity_list for word in corrected_words)
# Filter out None values from corrected_words list
corrected_words = [word for word in corrected_words if word is not None]
attribute_words = [attribute.split('_')[-1].lower() for attributes in attributes_data.values() for attribute in attributes]
attribute_matches = sum(word.lower() in attribute_words for word in corrected_words)
relation_words = [stemmer.stem(word.split()[0]) for word in relations_data.keys()]
relation_matches = sum(stemmer.stem(word) in relation_words for word in corrected_words)
total_entities = len(entity_list)
total_attributes = len(attribute_words)
total_relations = len(relation_words)
marks1 = entity_matches / total_entities
marks2 = attribute_matches / total_attributes
marks3 = relation_matches / total_relations
final_marks = (marks1 + marks2 + marks3) / 3 * 10
return marks1, marks2, marks3, final_marks
import traceback
@app.route('/extract', methods=['GET', 'POST'])
@login_required
def extract():
if request.method == 'POST':
try:
image_file = request.files['image']
if image_file.filename == '':
return "No selected file"
# Process the file
img = cv2.imdecode(np.fromstring(image_file.read(), np.uint8), cv2.IMREAD_COLOR)
inverted_image = cv2.bitwise_not(img)
cv2.imwrite("temp/extract/inverted_image1.jpg", inverted_image)
results = pipeline.recognize(["temp/extract/inverted_image1.jpg"])
word_list = [word_info[0] for word_info in results[0]]
corrected_word_list = [spell.correction(word) for word in word_list]
# Load JSON data
with open('data/entity_list.json', 'r') as json_file:
json_word_list = json.load(json_file)
json_word_list = [word.lower() for word in json_word_list]
# Filter out None values from corrected_word_list
corrected_word_list = [word.lower() for word in corrected_word_list if word is not None]
pred_list = [word.lower() for word in corrected_word_list]
matches = [word for word in json_word_list if word in pred_list]
marks1, marks2, marks3, final_marks = calculate_marks(corrected_word_list)
result = {
'words': word_list,
'corrected_words': corrected_word_list,
'matched_entities': matches,
'marks1': marks1, # Calculate marks1
'marks2': marks2, # Calculate marks2
'marks3': marks3, # Calculate marks3
'final_marks': final_marks # Calculate final_marks
}
return render_template('extract.html', result=result)
except Exception as e:
# Log the exception for debugging purposes
traceback.print_exc() # Print the traceback to console
return f"Error: {e}"
return render_template('extract.html')
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.neighbors import NearestNeighbors
import re
def preprocess_text(text):
return re.sub(r"[^a-zA-Z0-9]", " ", text).lower()
# Refactored initialization code from ai_quiz.py
def initialize_quiz_data():
dataset = pd.read_csv('data/que_ans.csv')
dataset = dataset[['Question', 'Answer']]
dataset['Answer'] = dataset['Answer'].apply(preprocess_text)
vectorizer = TfidfVectorizer()
answer_vectors = vectorizer.fit_transform(dataset['Answer'])
topics_df = pd.read_csv('data/topics.csv')
topic_vector = vectorizer.fit_transform(topics_df['topic'])
return dataset, vectorizer, answer_vectors, topic_vector, topics_df
data, vectorizer, answer_vectors, topic_vector, topics_df = initialize_quiz_data()
def evaluate_answers(user_answers, random_questions):
correct_count = 0
incorrect_questions = []
similarity_scores_list = [] # List to hold similarity scores for each answer
for question, user_answer in zip(random_questions, user_answers):
correct_answer = data[data['Question'] == question]['Answer'].iloc[0]
correct_answer_vector = vectorizer.transform([correct_answer])
user_answer_vector = vectorizer.transform([user_answer])
similarity_scores = cosine_similarity(correct_answer_vector, user_answer_vector)
similarity_scores_list.append(similarity_scores[0][0]) # Add the similarity score to the list
if similarity_scores >= 0.4:
correct_count += 1
else:
incorrect_questions.append(question)
# Recommend topics based on incorrect answers
neigh = NearestNeighbors(n_neighbors=3, metric='cosine')
neigh.fit(topic_vector)
ranked_topics = []
for question in incorrect_questions:
question_vector = vectorizer.transform([question])
_, indices = neigh.kneighbors(question_vector.reshape(1, -1))
ranked_topic = topics_df['topic'].iloc[indices[0]]
ranked_topics.extend(ranked_topic)
return correct_count, similarity_scores_list, ranked_topics
@app.route('/quiz', methods=['GET', 'POST'])
@login_required
def quiz():
if request.method == 'POST':
if 'user_answer' in request.form:
user_answers = request.form.getlist('user_answer')
random_questions = session['questions']
correct_count, similarity_scores_list, ranked_topics = evaluate_answers(user_answers, random_questions)
return render_template('quiz.html', step='results', user_answers=user_answers,
correct_count=correct_count, questions=random_questions,
similarity_scores_list=similarity_scores_list, recommended_topics=ranked_topics,
zip=zip)
else: # This is the GET request, which means the student is starting the quiz
num_questions = session.get('num_questions', 10) # default to 10 if not set
random_indices = np.random.randint(0, len(data), size=int(num_questions))
random_questions = data['Question'].iloc[random_indices].tolist()
session['questions'] = random_questions
return render_template('quiz.html', step='answer', questions=random_questions)
# This line will probably never be reached now, but let's keep it just in case
return render_template('quiz.html', step='select_num_questions')
@app.route('/quiz_count', methods=['GET', 'POST'])
def quiz_count():
if request.method == 'POST':
num_questions = request.form['num_questions']
topics = request.form.getlist('topics') # Assuming topics is a multi-select field
session['num_questions'] = num_questions
session['topics'] = topics
session['message'] = f"Topics {', '.join(topics)} were selected and the number of questions was set as {num_questions}."
return redirect(url_for('quiz_count'))
# Clear the message after it has been set
message = session.pop('message', None)
return render_template('quiz_count.html', message=message)
@app.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
@ app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(form.password.data)
new_user = User(username=form.username.data, password=hashed_password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
return render_template('register.html', form=form)
if __name__ == "__main__":
with app.app_context():
db.create_all() # Create the tables inside the application context
app.run(debug=True)
This source diff could not be displayed because it is too large. You can view the blob instead.
{"Event": ["e_id", "e_title", "e_date", "e_venue"], "Customer": ["c_id", "c_name", "c_contact_info", "c_ticket_history"], "Attendee": ["a_id", "a_event_id", "a_customer_id"], "Ticket": ["t_id", "t_price", "t_event_id", "t_capacity", "t_scanning"]}
\ No newline at end of file
["Event", "Customer", "Attendee", "Ticket"]
\ No newline at end of file
{"has": {"left": ["Event", "M"], "right": ["Attendee", "M"]}, "purchases": {"left": ["Customer", "M"], "right": ["Ticket", "M"]}, "attends": {"left": ["Attendee", "M"], "right": ["Event", "M"]}}
\ No newline at end of file
"CREATE TABLE Event (e_id VARCHAR(255), e_title VARCHAR(255), e_date VARCHAR(255), e_venue VARCHAR(255));\nCREATE TABLE Customer (c_id VARCHAR(255), c_name VARCHAR(255), c_contact_info VARCHAR(255), c_ticket_history VARCHAR(255));\nCREATE TABLE Attendee (a_id VARCHAR(255), a_event_id VARCHAR(255), a_customer_id VARCHAR(255));\nCREATE TABLE Ticket (t_id VARCHAR(255), t_price VARCHAR(255), t_event_id VARCHAR(255), t_capacity VARCHAR(255), t_scanning VARCHAR(255));\nALTER TABLE Event ADD CONSTRAINT FK_Event_Attendee FOREIGN KEY (event_id) REFERENCES Attendee(attendee_id);\nALTER TABLE Customer ADD CONSTRAINT FK_Customer_Ticket FOREIGN KEY (customer_id) REFERENCES Ticket(ticket_id);\nALTER TABLE Attendee ADD CONSTRAINT FK_Attendee_Event FOREIGN KEY (attendee_id) REFERENCES Event(event_id);"
\ No newline at end of file
File added
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix,accuracy_score
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.linear_model import LogisticRegression
from nltk.corpus import stopwords
import nltk
import re
from nltk.stem import PorterStemmer
from nltk.stem import WordNetLemmatizer
import os
import seaborn as sns
import matplotlib.pyplot as plt
# Get the absolute path to the CSV file
file_path = os.path.abspath('data/ER_Analysis_Edited.csv')
# Get the absolute path to the CSV file
file_path_next = os.path.abspath('data/ER_Analysis_Edited.csv')
# Read the CSV file into a DataFrame
df = pd.read_csv(file_path)
df1 = pd.read_csv(file_path_next)
df = df.applymap(lambda x: x.lower() if isinstance(x, str) else x)
def combine_words(entity):
return ', '.join(['_'.join(word.split()) for word in entity.split(', ')])
# Apply the combine_words function to the "entity" column
df["Entities"] = df["Entities"].apply(combine_words)
df
import re
# Take each word one by one and append it to the list
entity_list = []
for entity in df['Entities']:
words = re.findall(r'\b\w+\b', entity)
entity_list.extend(words)
# Print the words
for word in entity_list:
print(word)
# Take each word one by one and append it to the list
attribute_list = []
for entity in df['Attributes']:
words = re.findall(r'\b\w+\b', entity)
attribute_list.extend(words)
# Print the words
for word in attribute_list:
print(word)
import re
relations = []
for relation in df['Relationship']:
if isinstance(relation, str):
words = re.findall(r'\b\w+\b', relation)
relations.extend(words)
for word in relations:
print(word)
df_rel = pd.DataFrame(relations, columns=['Name'])
df_rel['Class']='relation'
df_rel
df_attribute = pd.DataFrame(attribute_list,columns=['Name'])
df_attribute['Class']='attribute'
df_attribute
df_entity = pd.DataFrame(entity_list,columns=['Name'])
df_entity['Class']='entity'
df_new = pd.concat([df_entity, df_rel], axis=0)
df=df_new
df
# Create a CountVectorizer to convert words into numerical features
vectorizer = CountVectorizer()
# Fit and transform the words in your dataset into numerical features
X = vectorizer.fit_transform(df['Name'])
# Encode labels
from sklearn.preprocessing import LabelEncoder
label_encoder = LabelEncoder()
y = label_encoder.fit_transform(df['Class'])
# Split the dataset into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Train a logistic regression classifier
classifier = LogisticRegression(max_iter=1000, random_state=42)
classifier.fit(X_train, y_train)
# Evaluate the classifier on the test set
y_pred = classifier.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy on test set: {accuracy * 100:.2f}%")
# Print classification report for detailed evaluation
report = classification_report(y_test, y_pred, target_names=label_encoder.classes_)
print(report)
input_word = "order"
preprocessed_word = vectorizer.transform([input_word])
predicted_class = label_encoder.inverse_transform(classifier.predict(preprocessed_word))[0]
# Print the predicted class
print(f"Input word: {input_word}")
print(f"Predicted class: {predicted_class}")
# Initialize NLTK Porter Stemmer and WordNet Lemmatizer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
# Define a function to preprocess an input sentence with stop word removal, stemming, and lemmatization
def preprocess_sentence(sentence):
words = re.findall(r'\b\w+\b', sentence.lower())
# Remove stop words
stop_words = set(stopwords.words('english'))
words = [word for word in words if word not in stop_words]
lemmatized_words = [lemmatizer.lemmatize(word) for word in words]
return ' '.join(lemmatized_words)
# Define a function to predict the class of each word in a sentence
def predict_word_classes(sentence):
words = sentence.split()
predicted_classes = []
for word in words:
preprocessed_word = vectorizer.transform([word])
predicted_class = label_encoder.inverse_transform(classifier.predict(preprocessed_word))[0]
predicted_classes.append((word, predicted_class))
return predicted_classes
input_sentence = "A company wants to develop a system to manage their inventory. They have products with attributes such as name, description, price, and quantity in stock. Each product belongs to a specific category. The company wants to track customer orders, including the products ordered, the quantity of each product, and the customer details like name, address, and contact information"
preprocessed_input = preprocess_sentence(input_sentence)
word_classes = predict_word_classes(preprocessed_input)
unique_entities = []
unique_relations = []
# Define a function to extract and store unique entities and relations
def extract_unique_entities_and_relations(sentence):
words = sentence.split() # Split the sentence into words
for word in words:
preprocessed_word = vectorizer.transform([word])
predicted_class = label_encoder.inverse_transform(classifier.predict(preprocessed_word))[0]
if predicted_class == 'entity' and word not in unique_entities:
unique_entities.append(word)
elif predicted_class == 'relation' and word not in unique_relations:
unique_relations.append(word)
#input_sentence = "Shipped items are the heart of the UPS product tracking information system. Shipped items can be characterized by item number (unique), weight, dimensions, insurance amount, destination, and final delivery date. Shipped items are received into the UPS system at a single retail center. Retail centers are characterized by their type, uniqueID, and address. Shipped items make their way to their destination via one or more standard UPS transportation events (i.e., flights, truck deliveries). These transportation events are characterized by a unique scheduleNumber, a type (e.g, flight, truck), and a deliveryRoute."
preprocessed_input = preprocess_sentence(input_sentence)
extract_unique_entities_and_relations(preprocessed_input)
unique_entities
import re
def extract_unique_entities_and_relation(user_input):
scenario = f"I need to extract entities and attribute for ER diagram from {user_input}\n Attribute standard should be same for each entity 'first letter_attribute name', example output: ' Entities: \n customer':'c_id, c_name'.\n dont show numbers and Relationships or anything other than the given example in ur output";import openai;openai.api_type = "azure";openai.api_base = "https://openitest.openai.azure.com/";openai.api_version = "2022-12-01";openai.api_key = "c461434794eb43f2ad9be371728f70c4";model_engine = "text-davinci-003";response = openai.Completion.create(engine=model_engine,prompt=scenario,temperature=0,max_tokens=3500,top_p=1,frequency_penalty=0,presence_penalty=0,best_of=1,stop=None);output_text = response.choices[0].text.strip();return output_text
att_list = df1['Attributes'].tolist()
att_list = list(set(att_list))
att_list=str(att_list)
import pandas as pd
def extract_cardinality_and_relationship(user_input):
scenario="please identify 'Entities for ER diagram and extract relationship(should be one single verb) between entities seperatly from "+user_input+" output should be seperate sentences. I dont need the entity list in your output. use entities in "+output_ent_attr+" Output format must be 'Entity---Relation---Entity---Cardinality(one-to-one/one-to-many/many-to-many)' between all entities";import openai;openai.api_type = "azure";openai.api_base = "https://openitest.openai.azure.com/";openai.api_version = "2022-12-01";openai.api_key = "c461434794eb43f2ad9be371728f70c4";prompt = scenario;model_engine="text-davinci-003";response = openai.Completion.create(engine=model_engine,prompt=prompt,temperature=0,max_tokens=3500,top_p=1,frequency_penalty=0,presence_penalty=0,best_of=1,stop=None);output_text = response.choices[0].text.strip();return output_text
att_list
allowed_characters = set('_,')
# Remove all punctuation except allowed characters
cleaned_string = ''.join(char for char in att_list if char.isalnum() or char in allowed_characters)
# Output the cleaned string
print(cleaned_string)
output_list = cleaned_string.split(',')
print(output_list)
output_list = list(set(output_list))
def generate_entitiy_attributes(sentence, variable_name, attributes):
sentence_words = re.findall(r'\b\w+\b', sentence.lower())
# Convert the variable_name and attributes to lowercase
variable_name = variable_name.lower()
attributes = [attr.lower() for attr in attributes]
if variable_name in sentence_words:
# Check which attributes are present
attributes_present = [attr for attr in attributes if attr in sentence_words]
return {"entity": variable_name, "attributes": attributes_present, "confirmed": True}
else:
return {"entity": variable_name, "attributes": [], "confirmed": False}
#att_list = ["prod_id", "prod_name", "prod_description", "prod_price", "prod_quantity", "cat_id", "cat_name", "order_id", "order_date", "cus_id", "cus_name", "cus_address", "cus_contact"]
attributes_list = output_list
entity_list = unique_entities
print()
sentences="A virtual supermarket has registered suppliers to supply the customer orders placed online. The supermarket always fulfils its customer orders through these suppliers. One supplier is responsible only for the customers who live in the supplier's area. A customer has only one supplier. Each supplier is characterized by a code (unique), address and contact numbers. A supplier can have several contact numbers. Each customer is characterized by an email address (unique), name and location. A customer can confirm orders. Each order has only one supplier and one customer. An order is characterized by an order number (unique), description and a value. A supplier can supply more than one order."
confirmed_entities = []
for entity in entity_list:
entity_result = [generate_entitiy_attributes(sentence, entity, attributes_list) for sentence in sentences]
confirmed_result = [result for result in entity_result if result["confirmed"]]
confirmed_entities.extend(confirmed_result)
import sys
if __name__ == "__main__":
user_input = sys.argv[1]
# user_input = input("Please enter your input: ")
user_input= user_input.replace('"', '')
output_ent_attr = extract_unique_entities_and_relation(user_input)
print(output_ent_attr)
lines = output_ent_attr.split('\n')
# dictionary to store attributes for each entity
attributes = {}
if lines[0].strip().lower() == "entities:":
lines = lines[1:]
for line in lines:
parts = line.split(':')
entity_name = parts[0].strip()
entity_attributes = [attr.strip() for attr in parts[1].split(',')]
# If the entity does not have a primary key, generate one
if not any(attr.endswith('ID') or attr.endswith('id') or attr.endswith('Id') for attr in entity_attributes):
primary_key = f"{entity_name.lower()[:1]}_id"
entity_attributes.insert(0, primary_key)
attributes[entity_name] = entity_attributes
entity_list = list(attributes.keys())
print("entity_list =", entity_list)
print("attributes =", attributes)
import re
def extract_cardinelity_and_relationship(sentence):
one_to_one_pattern = re.compile(r'(\bone\b|\b1\b) (\w+) has (\bone\b|\b1\b) (\w+)')
one_to_many_pattern = re.compile(r'(\b1\b) (\w+) has (\bmany\b|\bmultiple\b) (\w+)')
# Search for patterns in the sentence
match_one_to_one = one_to_one_pattern.search(sentence)
match_one_to_many = one_to_many_pattern.search(sentence)
if match_one_to_one:
entity1, relationship, entity2 = match_one_to_one.group(2, 3, 4)
return f" {entity1} ---{relationship} ---{entity2}"
elif match_one_to_many:
entity1, relationship, entity2 = match_one_to_many.group(2, 3, 4)
return f" {entity1} --- {relationship} --- {entity2}"
else:
return "No cardinality or relationship pattern found."
relation_cardinality=extract_cardinality_and_relationship(user_input)
print(relation_cardinality)
relations = {}
lines = relation_cardinality.strip().split('\n')
for line in lines:
left_entity, relationship, right_entity, cardinality = line.split('---')
left_cardinality, right_cardinality = cardinality.split('-to-')
left_cardinality = left_cardinality.replace("One", "1").replace("Many", "M")
right_cardinality = right_cardinality.replace("One", "1").replace("Many", "M")
relations[relationship] = {
"left": (left_entity, left_cardinality),
"right": (right_entity, right_cardinality)
}
print(relations)
import networkx as nx
import matplotlib.pyplot as plt
def draw_er_diagram(entity_list, attributes, relations):
G = nx.Graph()
# Add entities as nodes with square shape
for entity in entity_list:
G.add_node(entity, shape='s')
# Add attributes as nodes with circle shape
for entity, attrs in attributes.items():
for attr in attrs:
attr_with_entity = f"{attr}"
G.add_node(attr_with_entity, shape='o')
G.add_edge(entity, attr_with_entity)
# Add relations as nodes with diamond shape
for relation, sides in relations.items():
G.add_node(relation, shape='d')
left_entity, left_cardinality = sides["left"]
right_entity, right_cardinality = sides["right"]
G.add_edge(left_entity, relation)
G.add_edge(relation, right_entity)
pos = nx.spring_layout(G, seed=62, k=0.2)
entity_marker = 's'
attribute_marker = 'o'
relationship_marker = 'd'
entity_nodes = [node for node in G.nodes if node in entity_list]
attribute_nodes = [node for node in G.nodes if node not in entity_list]
plt.figure(figsize=(12, 8))
nx.draw_networkx_nodes(G, pos, nodelist=entity_nodes, node_shape=entity_marker, node_color='skyblue',
node_size=1000, alpha=0.9, linewidths=0.5)
nx.draw_networkx_nodes(G, pos, nodelist=attribute_nodes, node_shape=attribute_marker, node_color='lightgreen',
node_size=800, alpha=0.9, linewidths=0.5)
nx.draw_networkx_nodes(G, pos, nodelist=list(relations.keys()), node_shape=relationship_marker, node_color='gray',
node_size=1200, alpha=0.9, linewidths=0.5)
nx.draw_networkx_edges(G, pos, edge_color='gray', alpha=0.5, width=0.5)
nx.draw_networkx_labels(G, pos, font_color='black', font_size=8)
# Adding cardinality labels to the edges
cardinality_labels = {}
for relation, sides in relations.items():
left_entity, left_cardinality = sides["left"]
right_entity, right_cardinality = sides["right"]
cardinality_labels[(left_entity, relation)] = left_cardinality
cardinality_labels[(relation, right_entity)] = right_cardinality
pos_labels = {k: (v[0], v[1] + 0.03) for k, v in pos.items()}
nx.draw_networkx_edge_labels(G, pos_labels, edge_labels=cardinality_labels, font_size=8, font_color='red')
#plt.title("Entity-Relationship Diagram")
diagram_path = os.path.abspath('static/er_diagram.png')
plt.axis('off')
plt.savefig(diagram_path, format="png")
# plt.show()
draw_er_diagram(entity_list, attributes, relations)
print("entity_list =", entity_list)
print("attributes =", attributes)
print("relations=",relations)
# SQL statements to create tables for the relations
table_creation_statements = []
for entity in entity_list:
attributes_list = attributes[entity]
attribute_str = ', '.join([f'{attribute} VARCHAR(255)' for attribute in attributes_list])
table_creation_query = f"CREATE TABLE {entity} ({attribute_str});"
table_creation_statements.append(table_creation_query)
# SQL statements to create foreign keys for the relations
foreign_key_statements = []
for relation, details in relations.items():
left_entity, left_cardinality = details["left"]
right_entity, right_cardinality = details["right"]
foreign_key_query = f"ALTER TABLE {left_entity} " \
f"ADD CONSTRAINT FK_{left_entity}_{right_entity} " \
f"FOREIGN KEY ({left_entity.lower()}_id) " \
f"REFERENCES {right_entity}({right_entity.lower()}_id);"
foreign_key_statements.append(foreign_key_query)
import json
# Print only the SQL statements for Flask to use
if __name__ == "__main__":
sql_queries = "\n".join(table_creation_statements + foreign_key_statements)
# Split the SQL queries into lines
queries_lines = sql_queries.split('\n')
# Filter relevant lines starting with "CREATE TABLE" or "ALTER TABLE"
relevant_queries = [line for line in queries_lines if line.startswith(('CREATE TABLE', 'ALTER TABLE'))]
# Join the relevant queries into a string
formatted_queries = "\n".join(relevant_queries)
print(formatted_queries)
query_path = os.path.abspath('data/sql_queries.json')
# Save formatted_queries to a JSON file (optional)
with open(query_path, 'w') as sql_file:
json.dump(formatted_queries, sql_file)
entity_path = os.path.abspath('data/entity_list.json')
# Save entity_list to a JSON file
with open(entity_path, 'w') as entity_file:
json.dump(entity_list, entity_file)
attribute_path = os.path.abspath('data/attributes.json')
# Save attributes to a JSON file
with open(attribute_path, 'w') as attributes_file:
json.dump(attributes, attributes_file)
relationship_path = os.path.abspath('data/relations.json')
# Save relations to a JSON file
with open(relationship_path, 'w') as relations_file:
json.dump(relations, relations_file)
print("JSON files saved successfully.")
\ No newline at end of file
import nltk
nltk.download('wordnet')
matplotlib==3.7.1
nltk==3.8.1
numpy==1.23.5
pandas==2.0.2
scikit-learn==1.2.2
seaborn==0.12.2
joblib==1.2.0
imutils==0.5.4
Flask==2.3.2
keras-ocr==0.8.9
openai==0.27.8
tensorflow==2.12.0
seaborn==0.12.2
wheel==0.40.0
spellchecker==0.4
yarl==1.9.2
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Add the Bootstrap CSS link here -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- Add Font Awesome CSS link here -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard</title>
<style>
/* Additional CSS styles */
.navbar {
background-color: #333;
}
.navbar-nav .nav-link {
color: white;
}
.navbar-nav .nav-link:hover {
color: yellow;
}
.carousel-container {
background-color: #000; /* Set your desired background color */
overflow: hidden;
}
.carousel-item img {
width: 100%;
height: 100%;
object-fit: cover; /* Ensure the image covers the entire slide */
}
.carousel {
width: 100%; /* Set carousel width to 100% */
height: 100%;
}
</style>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar navbar-expand-lg navbar-dark">
<a class="navbar-brand" href="#">ER DIAGRAM TOOL</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav mr-auto">
{% if user_role == 'student' %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('generate_er_diagram') }}"><i class="fas fa-database"></i> ER Diagram Generator</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('quiz') }}"><i class="fas fa-question-circle"></i> AI Based Quiz</a>
</li>
{% elif user_role == 'teacher' %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('generate_er_diagram') }}"><i class="fas fa-database"></i> ER Diagram Generator</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('extract') }}"><i class="fas fa-project-diagram"></i> ER Diagram Extractor</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('similarity') }}"><i class="fas fa-search"></i> Similarity Checker</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('quiz_count') }}"><i class="fas fa-search"></i> Quiz count</a>
</li>
{% endif %}
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('logout') }}"><i class="fas fa-sign-out-alt"></i> Logout {{user_role}}</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('home') }}"><i class="fas fa-home"></i> Home</a>
</li>
</ul>
</div>
</nav>
<!-- Content Area -->
<!--<div class="container">-->
<div id="carouselExample" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="/static/diagram.webp" class="d-block w-100" alt="Slide 1">
</div>
<div class="carousel-item">
<img src="/static/diagram2.webp" class="d-block w-100" alt="Slide 2">
</div>
<div class="carousel-item">
<img src="/static/diagram3.webp" class="d-block w-100" alt="Slide 3">
</div>
<div class="carousel-item">
<img src="/static/diagram4.webp" class="d-block w-100" alt="Slide 4">
</div>
</div>
<a class="carousel-control-prev" href="#carouselExample" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExample" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<!--</div>-->
<!-- Bootstrap JS, Popper.js, and jQuery scripts -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@2.9.1/dist/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Add the Bootstrap CSS link here -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- Add Font Awesome CSS link here -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ER Diagram Generator</title>
<style>
/* Additional CSS styles */
/* Add your custom styles here */
</style>
</head>
<body>
<!-- Navigation Bar (if needed) -->
<!-- Content Area -->
<div class="container mt-4">
<h2>ER Diagram Generator</h2>
<form method="POST" action="{{ url_for('generate_er_diagram') }}">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.user_input.label(class="form-control-label") }}
{{ form.user_input(class="form-control") }}
</div>
<div class="row">
<div class="col-md-1">
<button type="submit" class="btn btn-primary custom-btn">Generate</button>
</div>
<div class="col-md-2">
<a href="{{ url_for('dashboard') }}" class="btn btn-secondary custom-btn">Back</a>
</div>
</div>
</form>
<!-- Display ER Diagram here -->
{% if er_diagram %}
<div class="mt-4">
<h3>Generated ER Diagram</h3>
<img src="{{ url_for('static', filename='er_diagram.png') }}" class="img-fluid" alt="ER Diagram">
<!-- Add a download button for the image -->
<a href="{{ url_for('static', filename='er_diagram.png') }}" download="er_diagram.png" class="btn btn-primary mt-2">
Download ER Diagram
</a>
</div>
{% endif %}
<!-- Display SQL Queries here -->
{% if sql_queries %}
<div class="mt-4">
<h3>Generated SQL Queries</h3>
<pre>{{ sql_queries }}</pre>
</div>
{% endif %}
</div>
<!-- Bootstrap JS scripts and other JS dependencies (if needed) -->
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Add the Bootstrap CSS link here -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ER Diagram Tool</title>
<style>
/* Additional CSS styles */
body, html {
height: 100%;
background: url('/static/back.png') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.card {
width: fit-content;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="card-body text-center">
<h1 class="card-title">WELCOME TO THE ER DIAGRAM TOOL</h1>
<p class="card-text">Please register or log in to use this tool.</p>
<a href="{{ url_for('login') }}" class="btn btn-primary btn-lg btn-block">Login</a>
<a href="{{ url_for('register') }}" class="btn btn-success btn-lg btn-block mt-3">Register</a>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Add the Bootstrap CSS link here -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<style>
body {
font-family: Arial, sans-serif;
background: url('/static/cover.png') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.card {
max-width: 400px;
width: 100%;
}
.card-body {
padding: 20px;
}
input[type="text"], input[type="password"] {
font-size: 16px;
}
</style>
</head>
<body>
<div class="card">
<div class="card-body text-center">
<h1 class="card-title">LOGIN PAGE</h1>
<form method="POST" action="">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username(class="form-control", placeholder="Username") }}
</div>
<div class="form-group">
{{ form.password(class="form-control", placeholder="Password") }}
</div>
<button type="submit" class="btn btn-primary btn-block">Login</button>
</form>
<a href="{{ url_for('register') }}" class="mt-3">Don't have an account? Sign Up</a>
<div>
<a href="{{ url_for('home') }}">Back to Home</a>
</div>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Add the Bootstrap CSS link here -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Register</title>
<style>
body {
font-family: Arial, sans-serif;
background: url('/static/cover.png') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.card {
max-width: 400px;
width: 100%;
}
.card-body {
padding: 20px;
}
input[type="text"], input[type="password"] {
font-size: 16px;
}
</style>
</head>
<body>
<div class="card">
<div class="card-body text-center">
<h1 class="card-title">REGISTER PAGE</h1>
<form method="POST" action="">
{{ form.hidden_tag() }}
<div class="form-group">
{{ form.username(class="form-control", placeholder="Username") }}
</div>
<div class="form-group">
{{ form.password(class="form-control", placeholder="Password") }}
</div>
<button type="submit" class="btn btn-success btn-block">Register</button>
</form>
<a href="{{ url_for('login') }}" class="mt-3">Already have an account? Log In</a>
<div>
<a href="{{ url_for('home') }}">Back to Home</a>
</div>
</div>
</div>
</body>
</html>
id,username,password,role
1,student,student,student
2,teacher,teacher,teacher
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment