-
Notifications
You must be signed in to change notification settings - Fork 448
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
Feat: Add BIT personal background to MS schema #1092
base: bit
Are you sure you want to change the base?
Changes from 1 commit
781ffe4
bbcdb42
7f63bee
fd33624
dc4cee2
235aecf
394c664
759d39e
9a7791f
f8c0c12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,146 @@ | ||||||
from sqlalchemy import null | ||||||
from app.database.sqlalchemy_extension import db | ||||||
from app.database.db_types.JsonCustomType import JsonCustomType | ||||||
from app.utils.bitschema_utils import ( | ||||||
Gender, | ||||||
Age, | ||||||
Ethnicity, | ||||||
SexualOrientation, | ||||||
Religion, | ||||||
PhysicalAbility, | ||||||
MentalAbility, | ||||||
SocioEconomic, | ||||||
HighestEducation, | ||||||
YearsOfExperience, | ||||||
) | ||||||
|
||||||
|
||||||
class PersonalBackgroundModel(db.Model): | ||||||
"""Defines attributes for user's personal background. | ||||||
|
||||||
Attributes: | ||||||
user_id: An integer for storing the user's id. | ||||||
gender: A string for storing the user's gender. | ||||||
age: A string for storing the user's age. | ||||||
ethnicity: A string for storing the user's wthnicity. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @mtreacy002 this is not resolved yet |
||||||
sexual_orientation: A string for storing the user's sexual orientation. | ||||||
religion: A string for storing the user's religion. | ||||||
physical_ability: A string for storing the user's physical ability. | ||||||
mental_ability: A string for storing the user's mental ability. | ||||||
socio_economic: A string for storing the user's socio economic level. | ||||||
highest_education: A string for storing the user's highest education level. | ||||||
years_of_experience: A string for storing the user's length of expeprience in the It related area. | ||||||
others: A JSON data type for storing users descriptions of 'other' fields. | ||||||
is_public: A boolean indicating if user has agreed to display their personal background information publicly to other members. | ||||||
""" | ||||||
|
||||||
# Specifying database table used for PersonalBackgroundModel | ||||||
__tablename__ = "personal_backgrounds" | ||||||
__table_args__ = {"extend_existing": True} | ||||||
|
||||||
id = db.Column(db.Integer, primary_key=True) | ||||||
|
||||||
# User's personal background data | ||||||
user_id = db.Column( | ||||||
db.Integer, | ||||||
db.ForeignKey("users.id", ondelete="CASCADE"), | ||||||
nullable=False, | ||||||
unique=True, | ||||||
) | ||||||
gender = db.Column(db.Enum(Gender)) | ||||||
age = db.Column(db.Enum(Age)) | ||||||
ethnicity = db.Column(db.Enum(Ethnicity)) | ||||||
sexual_orientation = db.Column(db.Enum(SexualOrientation)) | ||||||
religion = db.Column(db.Enum(Religion)) | ||||||
physical_ability = db.Column(db.Enum(PhysicalAbility)) | ||||||
mental_ability = db.Column(db.Enum(MentalAbility)) | ||||||
socio_economic = db.Column(db.Enum(SocioEconomic)) | ||||||
highest_education = db.Column(db.Enum(HighestEducation)) | ||||||
years_of_experience = db.Column(db.Enum(YearsOfExperience)) | ||||||
others = db.Column(JsonCustomType) | ||||||
is_public = db.Column(db.Boolean) | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure why exactly we would need such information. I'll leave that to @isabelcosta There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epicadk , do you mean years of experience? First of all, I believe this is relevant to support one of BIT goals which is to improve equity in IT because many with no to limited years of experience in IT were left out from employment opportunity. We often see a position for entry level required more than 3 - 5 years of experience. Stating this years of experience encouraging industries to target people within the lower years of experience to be the mentee and people with the higher level of experience to be the mentor. Their willingness to go against the norm in employment market (aka to be more inclusive by targeting those within the minority groups, e.g. minimal years of experience) is going to be highlighted in the BIT Landing page as per the Mockup in my GSoC20 proposal. |
||||||
def __init__( | ||||||
self, | ||||||
user_id, | ||||||
gender, | ||||||
age, | ||||||
ethnicity, | ||||||
sexual_orientation, | ||||||
religion, | ||||||
physical_ability, | ||||||
mental_ability, | ||||||
socio_economic, | ||||||
highest_education, | ||||||
years_of_experience, | ||||||
): | ||||||
"""Initialises PersonalBackgroundModel class.""" | ||||||
## required fields | ||||||
self.user_id = user_id | ||||||
self.gender = gender | ||||||
self.age = age | ||||||
self.ethnicity = ethnicity | ||||||
self.sexual_orientation = sexual_orientation | ||||||
self.religion = religion | ||||||
self.physical_ability = physical_ability | ||||||
self.mental_ability = mental_ability | ||||||
self.socio_economic = socio_economic | ||||||
self.highest_education = highest_education | ||||||
self.years_of_experience = years_of_experience | ||||||
|
||||||
# default values | ||||||
self.others = None | ||||||
self.is_public = False | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should not be a boolean option.
|
||||||
|
||||||
def json(self): | ||||||
"""Returns PersonalBackgroundModel object in json format.""" | ||||||
return { | ||||||
"id": self.id, | ||||||
"user_id": self.user_id, | ||||||
"age": self.age, | ||||||
"ethnicity": self.ethnicity, | ||||||
"sexual_orientation": self.sexual_orientation, | ||||||
"religion": self.religion, | ||||||
"physical_ability": self.physical_ability, | ||||||
"mental_ability": self.mental_ability, | ||||||
"socio_economic": self.socio_economic, | ||||||
"highest_education": self.highest_education, | ||||||
"years_of_experience": self.years_of_experience, | ||||||
"others": self.others, | ||||||
"is_public": self.is_public, | ||||||
} | ||||||
|
||||||
def __repr__(self): | ||||||
"""Returns user's background.""" | ||||||
|
||||||
return ( | ||||||
f"User's id is {self.user_id}.\n" | ||||||
f"User's age is: {self.age}\n" | ||||||
f"User's ethnicity is: {self.ethnicity}\n" | ||||||
f"User's sexual orientation is: {self.sexual_orientation}\n" | ||||||
f"User's religion is: {self.religion}\n" | ||||||
f"User's physical ability is: {self.physical_ability}\n" | ||||||
f"User's mental ability is: {self.mental_ability}\n" | ||||||
f"User's socio economic category is: {self.socio_economic}\n" | ||||||
f"User's highest level of education is: {self.highest_education}\n" | ||||||
f"User's length of experience is: {self.years_of_experience}\n" | ||||||
) | ||||||
|
||||||
@classmethod | ||||||
def find_by_user_id(cls, user_id) -> "PersonalBackgroundModel": | ||||||
|
||||||
"""Returns the user's background that has the passed user id. | ||||||
Args: | ||||||
_id: The id of a user. | ||||||
""" | ||||||
return cls.query.filter_by(user_id=user_id).first() | ||||||
|
||||||
def save_to_db(self) -> None: | ||||||
"""Adds user's personal background to the database.""" | ||||||
db.session.add(self) | ||||||
db.session.commit() | ||||||
|
||||||
def delete_from_db(self) -> None: | ||||||
"""Deletes user's personal background from the database.""" | ||||||
db.session.delete(self) | ||||||
db.session.commit() |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -597,3 +597,167 @@ class Timezone(Enum): | |
|
||
def timezone(self): | ||
return list(map(str, self)) | ||
|
||
|
||
# Enum related to personal background | ||
@unique | ||
class ProgramStatus(Enum): | ||
DRAFT = "Draft" | ||
OPEN = "Open" | ||
IN_PROGRESS = "In_Progress" | ||
COMPLETED = "Completed" | ||
CLOSED = "Closed" | ||
|
||
def programStatus(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class OrganizationStatus(Enum): | ||
DRAFT = "Draft" | ||
PUBLISH = "Publish" | ||
ARCHIVED = "Archived" | ||
|
||
def OrganizationStatus(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class Gender(Enum): | ||
FEMALE = "Female" | ||
MALE = "Male" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def gender(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class Age(Enum): | ||
UNDER_18 = "Under 18" | ||
AGE_18_TO_20 = "Between 18 to 20 yo" | ||
AGE_21_TO_24 = "Between 21 to 24 yo" | ||
AGE_25_TO_34 = "Between 25 to 34 yo" | ||
AGE_35_TO_44 = "Between 35 to 44 yo" | ||
AGE_45_TO_54 = "Between 45 to 54 yo" | ||
AGE_55_TO_64 = "Between 55 to 64 yo" | ||
ABOVE_65_YO = "Above 65 yo" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def age(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class Ethnicity(Enum): | ||
AFRICAN_AMERICAN = "African-American/Black" | ||
CAUCASIAN = "Caucasian/White" | ||
HISPANIC = "Hispanic/Latinx" | ||
NATIVE_AMERICAN = "Native American/Alaska Native/First Nations" | ||
MIDDLE_EASTERN = "Middle Eastern/North African (MENA)" | ||
ASIAN = "Asian" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def ethnicity(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class SexualOrientation(Enum): | ||
HETEROSEXUAL = "Heterosexual/Straight" | ||
LGBTIA = "LGBTIA+" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you forgot the Q There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will make the change soon 😉 |
||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def sexualOrientation(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class Religion(Enum): | ||
CHRISTIANITY = "Christianity" | ||
JUDAISM = "Judaism" | ||
ISLAM = "Islam" | ||
HINDUISM = "Hinduism" | ||
BUDDHISM = "Buddhism" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def religion(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class PhysicalAbility(Enum): | ||
WITH_DISABILITY = "With/had limited physical ability (or with/had some type of physical disability/ies)" | ||
WITHOUT_DISABILITY = "Without/have no limitation to physical ability/ies" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def physicalAbility(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class MentalAbility(Enum): | ||
WITH_DISORDER = "With/previously had some type of mental disorders" | ||
WITHOUT_DISORDER = "Without/have no mental disorders" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def mentalAbility(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class SocioEconomic(Enum): | ||
UPPER = "Upper class/Elite" | ||
UPPER_MIDDLE = "Upper Middle class (or High-level Professionals/white collars e.g. enginers/accountants/lawyers/architects/managers/directors" | ||
LOWER_MIDDLE = "Lower Middle class (e.g. blue collars in skilled trades/Paralegals/Bank tellers/Sales/Clerical-Admin/other support workers)" | ||
WORKING = "Working class (e.g. craft workers factory labourers restaurant/delivery services workers" | ||
BELOW_POVERTY = "Underclass working but with wages under poverty line receiving Social Benefit from Government" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def socioEconomic(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class HighestEducation(Enum): | ||
BELOW_HIGH_SCHOOL = "Have/did not completed High School" | ||
HIGH_SCHOOL = "High School Diploma" | ||
ASSOCIATE = "Associate Degree" | ||
BACHELOR = "Bachelor's Degree" | ||
MASTER = "Master's Degree" | ||
PHD = "PhD or other Doctorate Degrees" | ||
OTHER = "Other" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def highestEducation(self): | ||
return list(map(str, self)) | ||
|
||
|
||
@unique | ||
class YearsOfExperience(Enum): | ||
UNDER_ONE = "Less than a year" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to just store numbers (number of years of experience) in the database instead of storing strings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epicadk , the reason I did it like this (in word instead of number) is because IMO it makes more sense when an organization open a mentoring program opportunity, they can state the target candidate based on a range of years of experience (e.g. between 3 to 5 years) instead of a distinct year 1,2,3, or 4 yr etc. This is also to make it easier for later when we make the logic which allows user to filter mentoring program based on certain categories (e.g. years of experience required "between 3 - 5 years" instead of selecting a particular number like 1,2,3 or 4 yr etc). This way it also limits the options to 5 only. Hope this makes sense 😉 . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can still make the same query with databases ( possibly more optimized as well if we use indexing) further every year we could just ++ the count in the database rather than having to migrate the strings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @epicadk , what do you mean by
Do you mean we need to make a scheduler to automatically add one year to the years of experience of each users who have this data instead of users manually updating their years of experience from their end? We could do that I suppose, but we're at disadvantage when the user is no longer in the industry but hasn't cancelled their membership/delete their account with us as that would be an inefficient use of overhead, plus we don't know how many of our users are in this category 🤔 . Let's wait for @isabelcosta's opinion on this 😉 . |
||
UP_TO_3 = "Between 1 to 3 years" | ||
UP_TO_5 = "Between 3 to 5 years" | ||
UP_TO_10 = "Between 5 to 10 year" | ||
OVER_10 = "Over 10 years of experience" | ||
DECLINED = "Prefer not to say" | ||
NOT_APPLICABLE = "Not Applicable" | ||
|
||
def yearsOfExperience(self): | ||
return list(map(str, self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment here specifying that this is a BIT extension?