Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] View access #130

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions Entity/ProfessorSectionView.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from sqlalchemy import Column, Integer, String, Enum, Text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.dialects.mysql import SET
import enum

Base = declarative_base()


class SectionType(enum.Enum):
activity = Act = 0
seminar = Sem = 1
independent = Ind = 2
lab = 3
lecture = Lec = 4


class ProfessorSectionView(Base):
__tablename__ = "Professor_Teaches_Section"
id = Column(Integer, primary_key=True)
id_sections = Column(Integer)
profAliasId = Column(Integer)
section_name = Column(String(255))
instructor = Column(String(255))
profEmailAlias = Column(String(255))
title = Column(String(255))
phone = Column(String(255))
office = Column(String(255))
type = Column(Enum(SectionType))
days = Column(SET('M', 'T', 'W', 'R', 'F'))
start = Column(String(255))
end = Column(String(255))
location = Column(String(255))
department = Column(String(255))
firstName = Column(String(50))
lastName = Column(String(50))
phoneNumber = Column(String(20))
researchInterests = Column(Text)
email = Column(String(255))

def __repr__(self):
D = self.__dict__
attributes = [
f"{k}={D.get(k)}" for k in self.__dir__() if not k.startswith("_")
]
attributes_string = ", ".join(attributes)
return f"{self.__class__.__name__}({attributes_string})"
39 changes: 36 additions & 3 deletions database_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
from Entity.QuestionAnswerPair import QuestionAnswerPair, AnswerType
from Entity.Professors import Professors, ProfessorsProperties
from Entity.Clubs import Clubs
from Entity.Sections import Sections, SectionType
from Entity.Sections import Sections
from Entity.ProfessorSectionView import ProfessorSectionView

from fuzzywuzzy import fuzz

Expand All @@ -50,6 +51,7 @@
Professors: {"firstName", "lastName"},
Clubs: {"club_name"},
Sections: {"section_name"},
ProfessorSectionView: {"firstName", "lastName"}
}

EXPECTED_KEYS_BY_ENTITY = {
Expand Down Expand Up @@ -164,7 +166,7 @@ def __init__(self, message: str):

def get_current_time():
"""
Useful for answering questions like "Is prof availible now/tomorrow?"
Useful for answering questions like "Is prof available now/tomorrow?"
"""
pass

Expand Down Expand Up @@ -343,6 +345,7 @@ def __init__(self, config_file: str = "config.json") -> None:
self.AudioSampleMetaData = AudioSampleMetaData
self.Locations = Locations
self.QuestionAnswerPair = QuestionAnswerPair
self.ProfessorSectionViews = ProfessorSectionView
self.inspector = inspect(self.engine)
self._create_database_session()
print("initialized NimbusMySQLAlchemy")
Expand Down Expand Up @@ -415,6 +418,7 @@ def __safe_create(SQLAlchemy_object):
__safe_create(self.AudioSampleMetaData)
__safe_create(self.Locations)
__safe_create(self.QuestionAnswerPair)
__safe_create(self.ProfessorSectionViews)

def _create_database_session(self):
Session = sessionmaker(bind=self.engine)
Expand Down Expand Up @@ -466,6 +470,35 @@ def get_property_from_entity(
)
>>> ["[email protected]"]

Args:
prop: the relevant property value to retrieve from matching entities
entity: the type of entity we want to get the property from
identifier: a string that identifies the entity in some way (i.e., a professor's name)
tag_column_map: a dictionary mapping entity types to columns that identify the entities
ex:
{Professors: {"firstName", "lastName"}}

Returns:
The closest value of `prop`,
such that the `entity` matches `identifier`.
"""
return self._get_property_from_entity(
prop,
entity,
identifier,
tag_column_map
)[-1][2]

def _get_property_from_entity(
self,
prop: str,
entity: UNION_ENTITIES,
identifier: str,
tag_column_map: dict = default_tag_column_dict,
):
"""
Returns a full list of matching entities. Used by get_property_from_entity()

Args:
prop: the relevant property value to retrieve from matching entities
entity: the type of entity we want to get the property from
Expand Down Expand Up @@ -506,7 +539,7 @@ def get_property_from_entity(
return None

sorted_results = sorted(results, key=lambda pair: pair[0])
return sorted_results[-1][2]
return sorted_results

def get_course_properties(
self, department: str, course_num: Union[str, int]
Expand Down
4 changes: 1 addition & 3 deletions flask_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

Contains all the handlers for the API. Also the main code to run Flask.
"""
import json

from flask import Flask, jsonify, request
from flask_cors import CORS
from pydrive.auth import GoogleAuth
Expand Down Expand Up @@ -435,4 +433,4 @@ def convert_to_mfcc():
if __name__ == '__main__':
app.run(host='0.0.0.0',
debug=gunicorn_config.DEBUG_MODE,
port=gunicorn_config.PORT)
port=gunicorn_config.PORT)
18 changes: 14 additions & 4 deletions nimbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#
from werkzeug.exceptions import BadRequestKeyError
from QA import create_qa_mapping, generate_fact_QA
from nimbus_nlp.NIMBUS_NLP import NIMBUS_NLP
from nimbus_nlp.NIMBUS_NLP import NimbusNLP


class Nimbus:
Expand All @@ -16,24 +16,34 @@ def __init__(self):
self.qa_dict = create_qa_mapping(
generate_fact_QA("q_a_pairs.csv")
)
self.nimbus_nlp = NimbusNLP()

def answer_question(self, question):
ans_dict = NIMBUS_NLP.predict_question(question)
ans_dict = self.nimbus_nlp.predict_question(question)
print(ans_dict)
try:
qa = self.qa_dict[ans_dict["question class"]]
except KeyError:
# Printed if question isn't found. This occurs because the training set is broader
# than the answerable question set.
return "I'm sorry, I don't understand. Please try another question."
else:
answer = qa.answer(ans_dict)
if answer is None:
# Printed when a database query was made and a null value was returned.
# Should be handled in the QA class in the future.
return("I'm sorry, I understand your question but was unable to find an answer. "
"Please try another question.")
else:
return answer


if __name__ == "__main__":
nimbus = Nimbus()
# print(nimbus.answer_question("What is Irene's phone number?"))
# print(nimbus.answer_question("What is Dr. Khosmood's email?"))
# print(nimbus.answer_question("What are the prerequisites for CPE 357?"))
while True:
question = input("Enter a question: ")
print(nimbus.answer_question(question))
q = input("Enter a question: ")
print(nimbus.answer_question(q))
print(nimbus.answer_question(q))
Loading