Skip to content

Commit

Permalink
matching-algorithm-soft-hard-skills-deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
krugergui authored Oct 24, 2023
1 parent a1e47ec commit f5eecb1
Show file tree
Hide file tree
Showing 5 changed files with 298 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ secrets/
rest_framework/
django_extensions/
admin/
.env

# Created by https://www.toptal.com/developers/gitignore/api/django
# Edit at https://www.toptal.com/developers/gitignore?templates=django
Expand Down
129 changes: 129 additions & 0 deletions backend/api/migrate_skills_to_long.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
from api.models import Candidates, Jobs, SoftSkills, Skills
import json


def migrate_candidates_soft_skills_to_long():
candidates = Candidates.objects.all().values("candidate_id", "soft_skills")

set_soft_skills: set = set()

dict_candidates_soft_skills: dict = {}
dict_soft_skills: dict = {}

for cand in candidates.iterator():
cand_soft_skills: list = json.loads(cand["soft_skills"].replace("'", '"'))
dict_candidates_soft_skills[cand["candidate_id"]] = cand_soft_skills

set_soft_skills.update(cand_soft_skills)

soft_skills = SoftSkills.objects.filter(soft_skill_name__in=set_soft_skills)

dict_soft_skills = {
ss.soft_skill_name: ss.soft_skill_id for ss in soft_skills.iterator()
}

for cand, cand_skills in dict_candidates_soft_skills.items():
for i in cand_skills:
if i in dict_soft_skills:
print(dict_soft_skills[i])

dict_candidates_soft_skills[cand] = [
dict_soft_skills[i] for i in cand_skills if i in dict_soft_skills
]

for id, items in dict_candidates_soft_skills.items():
if len(items) > 0:
Candidates.objects.get(pk=id).soft_skill_test_matching.set(items)


def migrate_candidates_hard_skills_to_long():
candidates = Candidates.objects.all().values("candidate_id", "hard_skills")

set_soft_skills: set = set()

dict_candidates_soft_skills: dict = {}
dict_soft_skills: dict = {}

for cand in candidates.iterator():
if type(cand["hard_skills"]) == str:
cand_soft_skills: list = cand["hard_skills"].split(", ")
dict_candidates_soft_skills[cand["candidate_id"]] = cand_soft_skills

set_soft_skills.update(cand_soft_skills)

soft_skills = Skills.objects.filter(skill_name__in=set_soft_skills)

dict_soft_skills = {ss.skill_name: ss.skill_id for ss in soft_skills.iterator()}

for cand, cand_skills in dict_candidates_soft_skills.items():
# for i in cand_skills:
# if i in dict_soft_skills:
# print(dict_soft_skills[i])

dict_candidates_soft_skills[cand] = [
dict_soft_skills[i] for i in cand_skills if i in dict_soft_skills
]

for id, items in dict_candidates_soft_skills.items():
if len(items) > 0:
Candidates.objects.get(pk=id).hard_skill_test_matching.set(items)


def migrate_job_hard_skills_to_long():
candidates = Jobs.objects.all().values("job_id", "hard_skills")

set_soft_skills: set = set()

dict_candidates_soft_skills: dict = {}
dict_soft_skills: dict = {}

for cand in candidates.iterator():
if type(cand["hard_skills"]) == str:
cand_soft_skills: list = json.loads(cand["hard_skills"])
dict_candidates_soft_skills[cand["job_id"]] = cand_soft_skills

set_soft_skills.update(cand_soft_skills)

soft_skills = Skills.objects.filter(skill_name__in=set_soft_skills)

dict_soft_skills = {ss.skill_name: ss.skill_id for ss in soft_skills.iterator()}

for cand, cand_skills in dict_candidates_soft_skills.items():
dict_candidates_soft_skills[cand] = [
dict_soft_skills[i] for i in cand_skills if i in dict_soft_skills
]

for id, items in dict_candidates_soft_skills.items():
if len(items) > 0:
Jobs.objects.get(pk=id).hard_skill_test_matching.set(items)


def migrate_job_soft_skills_to_long():
candidates = Jobs.objects.all().values("job_id", "soft_skills")

set_soft_skills: set = set()

dict_candidates_soft_skills: dict = {}
dict_soft_skills: dict = {}

for cand in candidates.iterator():
if type(cand["soft_skills"]) == str:
cand_soft_skills: list = json.loads(cand["soft_skills"])
dict_candidates_soft_skills[cand["job_id"]] = cand_soft_skills

set_soft_skills.update(cand_soft_skills)

soft_skills = SoftSkills.objects.filter(soft_skill_name__in=set_soft_skills)

dict_soft_skills = {
ss.soft_skill_name: ss.soft_skill_id for ss in soft_skills.iterator()
}

for cand, cand_skills in dict_candidates_soft_skills.items():
dict_candidates_soft_skills[cand] = [
dict_soft_skills[i] for i in cand_skills if i in dict_soft_skills
]

for id, items in dict_candidates_soft_skills.items():
if len(items) > 0:
Jobs.objects.get(pk=id).soft_skill_test_matching.set(items)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 4.2.5 on 2023-10-23 08:18

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0028_alter_jobs_company_alter_jobs_hard_skills_and_more'),
]

operations = [
migrations.AddField(
model_name='candidates',
name='hard_skill_test_matching',
field=models.ManyToManyField(to='api.skills'),
),
migrations.AddField(
model_name='candidates',
name='soft_skill_test_matching',
field=models.ManyToManyField(to='api.softskills'),
),
migrations.AddField(
model_name='jobs',
name='hard_skill_test_matching',
field=models.ManyToManyField(to='api.skills'),
),
migrations.AddField(
model_name='jobs',
name='soft_skill_test_matching',
field=models.ManyToManyField(to='api.softskills'),
),
]
83 changes: 66 additions & 17 deletions backend/api/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Iterator
from django.db import models
from api.auth_models import AuthUsers
import os
Expand All @@ -6,6 +7,28 @@
DEFAULT_MAX_LENGTH = 255


class Skills(models.Model):
skill_id = models.AutoField(primary_key=True)
skill_name = models.CharField(max_length=DEFAULT_MAX_LENGTH)

class Meta:
db_table = "skills"

def __str__(self):
return self.skill_name


class SoftSkills(models.Model):
soft_skill_id = models.AutoField(primary_key=True)
soft_skill_name = models.CharField(max_length=DEFAULT_MAX_LENGTH)

def __str__(self):
return self.soft_skill_name

class Meta:
db_table = "soft_skills"


class AssociationUsers(models.Model):
association_user_id = models.AutoField(primary_key=True)
supabase_authenticaiton_uuid = models.UUIDField()
Expand Down Expand Up @@ -109,6 +132,39 @@ class Candidates(models.Model):
last_update = models.DateTimeField(auto_now=True, null=True)
created_at = models.DateTimeField(auto_now_add=True, null=True)

soft_skill_test_matching = models.ManyToManyField(SoftSkills)
hard_skill_test_matching = models.ManyToManyField(Skills)

def get_match_percentage(
self, list_skills_id: Iterator, soft_or_hard_skill: str
) -> int:
"""
Calculate the percentage of matching skills between the input list of skills and the skills in the database.
Args:
list_skills_id (Iterator): An iterator of integers representing the IDs of the skills to be matched.
soft_or_hard_skill (str): A string indicating whether to match soft or hard skills.
Returns:
int: The percentage of matching skills between the input list of skills and the skills in the database.
"""
if soft_or_hard_skill == "soft":
skills = self.soft_skill_test_matching.values_list(
"soft_skill_id", flat=True
)
elif soft_or_hard_skill == "hard":
skills = self.hard_skill_test_matching.values_list("skill_id", flat=True)
else:
raise ValueError

skills = list(skills)

return (
len(set(list_skills_id).intersection(set(skills))) / len(list_skills_id)
if len(list_skills_id) > 0
else 0
) * 100

def __str__(self):
return f"{self.candidate_id} - {self.first_name} {self.last_name}"

Expand Down Expand Up @@ -237,13 +293,22 @@ class Jobs(models.Model):
soft_skills = models.TextField(blank=True, null=True)
hard_skills = models.TextField(blank=True, null=True)
languages = models.TextField(blank=True, null=True)

open = models.BooleanField(default=True, blank=True, null=True)

soft_skill_test_matching = models.ManyToManyField(SoftSkills)
hard_skill_test_matching = models.ManyToManyField(Skills)

last_day_to_apply = models.DateField(blank=True, null=True)
closed_at = models.DateTimeField(blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)

@property
def matches(self):
matched_soft_candidates = Candidates.objects.filter(
soft_skill_test_matching__in=self.soft_skill_test_matching.iterator()
)
return matched_soft_candidates

class Meta:
db_table = "jobs"

Expand Down Expand Up @@ -418,22 +483,6 @@ class Meta:
db_table = "personality_candidates"


class Skills(models.Model):
skill_id = models.AutoField(primary_key=True)
skill_name = models.CharField(max_length=DEFAULT_MAX_LENGTH)

class Meta:
db_table = "skills"


class SoftSkills(models.Model):
soft_skill_id = models.AutoField(primary_key=True)
soft_skill_name = models.CharField(max_length=DEFAULT_MAX_LENGTH)

class Meta:
db_table = "soft_skills"


class Status(models.Model):
status_id = models.AutoField(primary_key=True)
status_descrption = models.CharField(max_length=DEFAULT_MAX_LENGTH)
Expand Down
Loading

0 comments on commit f5eecb1

Please sign in to comment.