3
\$\begingroup\$

I'm beginner in django and python. I have models :

 class Employee(models.Model):
 full_name = models.CharField(max_length = 64)
 title = models.CharField(max_length = 64)
 def __str__(self):
 return f"{self.full_name} ( {self.title} )"
class Skill(models.Model):
 name = models.CharField(max_length = 64)
 def __str__(self):
 return f"{self.name}"
class Candidate(models.Model):
 employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name="employee")
 skill = models.ForeignKey(Skill, on_delete=models.CASCADE, related_name="skill")
 def __str__(self):
 return f"{self.id}: {self.employee} knows - {self.skill}"
class Job(models.Model):
 title = models.CharField(max_length = 64)
 skills = models.ManyToManyField(Skill, blank=True, related_name="Jobs")
 def __str__(self):
 return f"{self.title}"

In views.py, i have 'finder' function :

def finder(job_id):
 job = Job.objects.get(id=job_id) # get the specific job
 relevant_candidates = [] # all the relevant candidates of this kob
 common = [] # number of common skills between the employee_skill and the 
 relevant_employees_by_title = Employee.objects.filter(title = job.title) # first filter the candidates by the job title 
 job_skills = []
 for skill in job.skills.all():
 print(skill.id)
 job_skills.append(skill.id)
 for employee in relevant_employees_by_title: 
 employee_skills =[]
 candidateCorrect = Candidate.objects.filter(employee__id = employee.id).values_list('skill', flat=True)
 for skill in candidateCorrect:
 employee_skills.append(skill)
 common_skills = list(set(job_skills) & set(employee_skills))
 
 if (len(common_skills)>0): #if there are common skills
 relevant_candidates.append(employee) 
 common.append(len(common_skills))
 candidates = zip(relevant_candidates,common)
 candidates = sorted(candidates,key = lambda t: t[1], reverse = True) # sort the candidates by the number of common skiils , descending order
 candidates = candidates[:50] # Select the best 50 candidates
 return candidates

This function get the job_id and need to find the best candidates for this job : first by matching between the job title to the employee title (for ex' : software developer), and then matching between candidate's skills to job's required skiils .

I think that my function is inefficient. Someone has any idea how to write it in efficient way?

asked Feb 18, 2021 at 13:31
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You could use comprehensions to greater effect (here: directly build job_skills using a set comprehension) and also let got of having to put everything into a list.

You could also store your suitable candidates in a collections.Counter, to get the most_common(n) method for free.

from collections import Counter
def finder(job_id, n=50):
 job_skills = {skill.id for skill in Job.objects.get(id=job_id).skills.all()}
 candidates = Counter()
 for employee in Employee.objects.filter(title=job.title): 
 employee_skills = Candidate.objects\
 .filter(employee__id=employee.id)\
 .values_list('skill', flat=True)
 common_skills = len(job_skills.intersection(employee_skills))
 if common_skills:
 candidates[employee] = common_skills
 return candidates.most_common(n)

I also followed Python's official style-guide, PEP8, which recommends not surrounding = with spaces when using it for keyword arguments, used the fact that the number 0 is falsey, while all other numbers are truthy and made the number of candidates to return configurable (with 50 the default value).


Note that this task would have been slightly easier, if the Employee object already had the skill attached, or at least a link to the Candidate object.

answered Feb 19, 2021 at 14:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.