Spaces:
Sleeping
Sleeping
ejqs commited on
Commit ·
de3d639
1
Parent(s): 621f0b8
Add function to format years of experience and update HTML output accordingly
Browse files
app.py
CHANGED
|
@@ -387,6 +387,21 @@ def process_resume(resume_text: str, job_skills: List[str], progress=None, progr
|
|
| 387 |
|
| 388 |
return formatted_result
|
| 389 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
def create_html_output(job_result: Dict, resume_results: List[Dict], filenames: List[str] = None) -> str:
|
| 391 |
"""Create HTML output for the interface"""
|
| 392 |
html = "<div style='font-family: Arial, sans-serif;'>"
|
|
@@ -522,9 +537,32 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 522 |
# Create a list of resume data for sorting
|
| 523 |
resume_data = []
|
| 524 |
for i, resume_result in enumerate(resume_results, 1):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
# Calculate skill match
|
| 526 |
-
resume_skills = [skill['text'].lower() for skill in resume_result['skills']]
|
| 527 |
-
matched_skills = [skill for skill in resume_skills if skill in job_skills]
|
| 528 |
match_count = len(matched_skills)
|
| 529 |
match_percentage = round((match_count / job_result['total_skills'] * 100) if job_result['total_skills'] > 0 else 0, 1)
|
| 530 |
|
|
@@ -568,28 +606,7 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 568 |
match_category = "Weak Quality Match (Collaboration)"
|
| 569 |
|
| 570 |
|
| 571 |
-
|
| 572 |
-
primary_skills = {}
|
| 573 |
-
skill_exp = {} # Create a new dict to aggregate experience
|
| 574 |
-
|
| 575 |
-
# First, aggregate all experience for each skill
|
| 576 |
-
for skill_name, years in skill_experience_maps[i-1].items():
|
| 577 |
-
skill_name_lower = skill_name.lower()
|
| 578 |
-
if skill_name_lower in skill_exp:
|
| 579 |
-
skill_exp[skill_name_lower] = max(skill_exp[skill_name_lower], years) # Take the max experience
|
| 580 |
-
else:
|
| 581 |
-
skill_exp[skill_name_lower] = years
|
| 582 |
-
|
| 583 |
-
# Get unique resume skills
|
| 584 |
-
resume_skills = set(skill['text'].lower() for skill in resume_result['skills'])
|
| 585 |
-
|
| 586 |
-
# Only include skills that are in both the resume and job requirements
|
| 587 |
-
matched_skills = []
|
| 588 |
-
for skill in job_skills:
|
| 589 |
-
if skill.lower() in resume_skills:
|
| 590 |
-
matched_skills.append(skill)
|
| 591 |
-
if skill.lower() in skill_exp:
|
| 592 |
-
primary_skills[skill] = skill_exp[skill.lower()]
|
| 593 |
|
| 594 |
# Add to resume data list for sorting
|
| 595 |
resume_data.append({
|
|
@@ -628,7 +645,7 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 628 |
# Show the first matched skill and its experience
|
| 629 |
skill = resume_data['matched_skills'][0]
|
| 630 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{skill}</td>"
|
| 631 |
-
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{resume_data['primary_skills'].get(skill, 0)}</td>"
|
| 632 |
else:
|
| 633 |
# Show dashes for no matches
|
| 634 |
html += "<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>-</td>"
|
|
@@ -657,7 +674,7 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 657 |
html += "<td style='padding: 8px; border: 1px solid #ddd;'></td>"
|
| 658 |
# Skill and Experience
|
| 659 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{skill}</td>"
|
| 660 |
-
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{resume_data['primary_skills'].get(skill, 0)}</td>"
|
| 661 |
# Empty cells for the remaining columns
|
| 662 |
html += "<td style='padding: 8px; border: 1px solid #ddd;'></td>"
|
| 663 |
html += "<td style='padding: 8px; border: 1px solid #ddd;'></td>"
|
|
@@ -701,7 +718,7 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 701 |
|
| 702 |
html += f"<p><strong>Leadership Sentences:</strong> {leadership_count}</p>"
|
| 703 |
html += f"<p><strong>Collaboration Sentences:</strong> {collaboration_count}</p>"
|
| 704 |
-
html += f"<p><strong>Total Years of Experience:</strong> {total_experience}</p>"
|
| 705 |
html += f"<p><strong>Category:</strong> {category}</p>"
|
| 706 |
|
| 707 |
# Get the filename for this resume
|
|
@@ -802,7 +819,7 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 802 |
# Add row to summary table
|
| 803 |
html += f"<tr class='skill-row{i}' data-match='{str(data['is_match']).lower()}' style='display: {display};'>"
|
| 804 |
html += f"<td style='padding: 8px; border: 1px solid #ddd;'>{data['skill']}</td>"
|
| 805 |
-
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{data['years']
|
| 806 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{data['leadership_count']}</td>"
|
| 807 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{data['collaboration_count']}</td>"
|
| 808 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd; color: {'green' if data['is_match'] else 'red'};'>{'Yes' if data['is_match'] else 'No'}</td></tr>"
|
|
@@ -826,7 +843,7 @@ def create_html_output(job_result: Dict, resume_results: List[Dict], filenames:
|
|
| 826 |
|
| 827 |
# Add years of experience for this skill if available
|
| 828 |
skill_years = skill_experience.get(skill_text, 0)
|
| 829 |
-
experience_text = f" ({skill_years}
|
| 830 |
|
| 831 |
html += f"<span style='background-color: {bg_color}; padding: 2px 5px; margin: 2px; border-radius: 3px; display: inline-block;'>{skill['text']}{experience_text}</span>"
|
| 832 |
added_skills.add(skill_text)
|
|
|
|
| 387 |
|
| 388 |
return formatted_result
|
| 389 |
|
| 390 |
+
# Create a helper function to format years of experience in a readable format
|
| 391 |
+
def format_years_of_experience(years):
|
| 392 |
+
"""Format years as a combination of years and months"""
|
| 393 |
+
full_years = int(years)
|
| 394 |
+
months = int(round((years - full_years) * 12))
|
| 395 |
+
|
| 396 |
+
if full_years > 0 and months > 0:
|
| 397 |
+
return f"{full_years}y {months}m"
|
| 398 |
+
elif full_years > 0:
|
| 399 |
+
return f"{full_years}y"
|
| 400 |
+
elif months > 0:
|
| 401 |
+
return f"{months}m"
|
| 402 |
+
else:
|
| 403 |
+
return "0"
|
| 404 |
+
|
| 405 |
def create_html_output(job_result: Dict, resume_results: List[Dict], filenames: List[str] = None) -> str:
|
| 406 |
"""Create HTML output for the interface"""
|
| 407 |
html = "<div style='font-family: Arial, sans-serif;'>"
|
|
|
|
| 537 |
# Create a list of resume data for sorting
|
| 538 |
resume_data = []
|
| 539 |
for i, resume_result in enumerate(resume_results, 1):
|
| 540 |
+
# Get primary skills (Java and React in this case, as per image)
|
| 541 |
+
primary_skills = {}
|
| 542 |
+
skill_exp = {} # Create a new dict to aggregate experience
|
| 543 |
+
|
| 544 |
+
# First, aggregate all experience for each skill
|
| 545 |
+
for skill_name, years in skill_experience_maps[i-1].items():
|
| 546 |
+
skill_name_lower = skill_name.lower()
|
| 547 |
+
if skill_name_lower in skill_exp:
|
| 548 |
+
skill_exp[skill_name_lower] = max(skill_exp[skill_name_lower], years) # Take the max experience
|
| 549 |
+
else:
|
| 550 |
+
skill_exp[skill_name_lower] = years
|
| 551 |
+
|
| 552 |
+
# Get unique resume skills
|
| 553 |
+
resume_skills = set(skill['text'].lower() for skill in resume_result['skills'])
|
| 554 |
+
|
| 555 |
+
# Only include skills that are in both the resume and job requirements
|
| 556 |
+
matched_skills = []
|
| 557 |
+
for skill in job_skills:
|
| 558 |
+
if skill.lower() in resume_skills:
|
| 559 |
+
matched_skills.append(skill)
|
| 560 |
+
if skill.lower() in skill_exp:
|
| 561 |
+
primary_skills[skill] = skill_exp[skill.lower()]
|
| 562 |
+
|
| 563 |
# Calculate skill match
|
| 564 |
+
# resume_skills = [skill['text'].lower() for skill in resume_result['skills']]
|
| 565 |
+
# matched_skills = [skill for skill in resume_skills if skill in job_skills]
|
| 566 |
match_count = len(matched_skills)
|
| 567 |
match_percentage = round((match_count / job_result['total_skills'] * 100) if job_result['total_skills'] > 0 else 0, 1)
|
| 568 |
|
|
|
|
| 606 |
match_category = "Weak Quality Match (Collaboration)"
|
| 607 |
|
| 608 |
|
| 609 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 610 |
|
| 611 |
# Add to resume data list for sorting
|
| 612 |
resume_data.append({
|
|
|
|
| 645 |
# Show the first matched skill and its experience
|
| 646 |
skill = resume_data['matched_skills'][0]
|
| 647 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{skill}</td>"
|
| 648 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{format_years_of_experience(resume_data['primary_skills'].get(skill, 0))}</td>"
|
| 649 |
else:
|
| 650 |
# Show dashes for no matches
|
| 651 |
html += "<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>-</td>"
|
|
|
|
| 674 |
html += "<td style='padding: 8px; border: 1px solid #ddd;'></td>"
|
| 675 |
# Skill and Experience
|
| 676 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{skill}</td>"
|
| 677 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{format_years_of_experience(resume_data['primary_skills'].get(skill, 0))}</td>"
|
| 678 |
# Empty cells for the remaining columns
|
| 679 |
html += "<td style='padding: 8px; border: 1px solid #ddd;'></td>"
|
| 680 |
html += "<td style='padding: 8px; border: 1px solid #ddd;'></td>"
|
|
|
|
| 718 |
|
| 719 |
html += f"<p><strong>Leadership Sentences:</strong> {leadership_count}</p>"
|
| 720 |
html += f"<p><strong>Collaboration Sentences:</strong> {collaboration_count}</p>"
|
| 721 |
+
html += f"<p><strong>Total Years of Experience:</strong> {format_years_of_experience(total_experience)}</p>"
|
| 722 |
html += f"<p><strong>Category:</strong> {category}</p>"
|
| 723 |
|
| 724 |
# Get the filename for this resume
|
|
|
|
| 819 |
# Add row to summary table
|
| 820 |
html += f"<tr class='skill-row{i}' data-match='{str(data['is_match']).lower()}' style='display: {display};'>"
|
| 821 |
html += f"<td style='padding: 8px; border: 1px solid #ddd;'>{data['skill']}</td>"
|
| 822 |
+
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{format_years_of_experience(data['years'])}</td>"
|
| 823 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{data['leadership_count']}</td>"
|
| 824 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd;'>{data['collaboration_count']}</td>"
|
| 825 |
html += f"<td style='padding: 8px; text-align: center; border: 1px solid #ddd; color: {'green' if data['is_match'] else 'red'};'>{'Yes' if data['is_match'] else 'No'}</td></tr>"
|
|
|
|
| 843 |
|
| 844 |
# Add years of experience for this skill if available
|
| 845 |
skill_years = skill_experience.get(skill_text, 0)
|
| 846 |
+
experience_text = f" ({format_years_of_experience(skill_years)})" if skill_years > 0 else ""
|
| 847 |
|
| 848 |
html += f"<span style='background-color: {bg_color}; padding: 2px 5px; margin: 2px; border-radius: 3px; display: inline-block;'>{skill['text']}{experience_text}</span>"
|
| 849 |
added_skills.add(skill_text)
|