IQKillerv2 / interview_guide_generator.py
AvikalpK's picture
πŸš€ Enhanced IQKiller with Next.js Vercel version
0939a57
#!/usr/bin/env python3
"""
Enhanced Interview Guide Generator - InterviewGuideGPT Format
Generates polished, role-specific interview guides following exact structure requirements
"""
import re
import json
from typing import Dict, List, Any
from dataclasses import dataclass
@dataclass
class GuideData:
"""Structured data for interview guide generation"""
role_title: str
company: str
match_score: float
user_overview: str
user_skills: List[str]
role_skills: List[str]
team_context: str
interview_rounds: int
process_notes: List[str]
key_projects: List[str] = None
candidate_strengths: List[str] = None
skill_gaps: List[str] = None
class InterviewGuideGPT:
"""Elite career-coach AI for generating polished interview guides"""
def __init__(self):
self.tech_skills = [
"Python", "JavaScript", "Java", "SQL", "React", "Node.js",
"AWS", "Docker", "Git", "Machine Learning", "Data Science",
"Analytics", "R", "Tableau", "Pandas", "NumPy", "TensorFlow",
"Kubernetes", "MongoDB", "PostgreSQL", "Redis", "Apache Spark",
"Scala", "Hadoop", "Spark", "Kafka", "Elasticsearch"
]
self.company_insights = {
"spotify": "Spotify prizes data-driven creativity in music.",
"google": "Google values innovation and technical excellence at scale.",
"amazon": "Amazon focuses on customer obsession and operational excellence.",
"microsoft": "Microsoft emphasizes collaboration and empowering others.",
"meta": "Meta drives connection and community through technology.",
"apple": "Apple pursues perfection in user experience and design.",
"netflix": "Netflix champions freedom, responsibility, and context over control."
}
def analyze_resume_and_job(self, resume_text: str, job_text: str) -> GuideData:
"""Analyze resume and job to extract structured data"""
# Extract user data
user_skills = self._extract_skills(resume_text)
user_overview = self._extract_user_overview(resume_text)
# Extract job data
role_title, company = self._extract_role_and_company(job_text)
role_skills = self._extract_skills(job_text)
team_context = self._extract_team_context(job_text)
# Calculate match score
match_score = self._calculate_match_score(user_skills, role_skills, resume_text, job_text)
# Generate process info
interview_rounds = self._estimate_interview_rounds(company, role_title)
process_notes = self._generate_process_notes(company, role_title)
# Extract additional data
key_projects = self._extract_key_projects(resume_text)
candidate_strengths = self._extract_strengths(resume_text, user_skills)
skill_gaps = list(set(role_skills) - set(user_skills))
return GuideData(
role_title=role_title,
company=company,
match_score=match_score,
user_overview=user_overview,
user_skills=user_skills,
role_skills=role_skills,
team_context=team_context,
interview_rounds=interview_rounds,
process_notes=process_notes,
key_projects=key_projects,
candidate_strengths=candidate_strengths,
skill_gaps=skill_gaps
)
def _extract_skills(self, text: str) -> List[str]:
"""Extract technical skills from text"""
skills = []
text_lower = text.lower()
for skill in self.tech_skills:
if skill.lower() in text_lower:
skills.append(skill)
# Add soft skills
soft_skills = ["Leadership", "Communication", "Project Management", "Team Work", "Problem Solving"]
for skill in soft_skills:
if skill.lower() in text_lower or any(word in text_lower for word in skill.lower().split()):
skills.append(skill)
return list(set(skills))
def _extract_user_overview(self, resume_text: str) -> str:
"""Extract user overview from resume"""
# Look for experience years
experience_match = re.search(r'(\d+)[\s\+]*years?\s+(?:of\s+)?experience', resume_text, re.IGNORECASE)
years = experience_match.group(1) if experience_match else "several"
# Look for degree/education
education_patterns = [
r'(bachelor|master|phd|doctorate|degree)',
r'(computer science|data science|engineering|mathematics|statistics)'
]
education = "degree"
for pattern in education_patterns:
match = re.search(pattern, resume_text, re.IGNORECASE)
if match:
education = match.group(1)
break
return f"Professional with {years} years of experience and {education} background"
def _extract_role_and_company(self, job_text: str) -> tuple:
"""Extract role title and company from job text"""
# Extract company
company_patterns = [
r'at\s+([A-Z][a-zA-Z\s&\.]+?)(?:\s|$|,|\n)',
r'([A-Z][a-zA-Z\s&\.]+?)\s+is\s+(?:hiring|looking)',
r'join\s+([A-Z][a-zA-Z\s&\.]+?)(?:\s|$|,|\n)',
]
company = "Company"
for pattern in company_patterns:
match = re.search(pattern, job_text, re.IGNORECASE)
if match:
company = match.group(1).strip()
break
# Extract role
role_patterns = [
r'(senior\s+)?(data\s+scientist|software\s+engineer|product\s+manager|analyst|developer)',
r'position[:\s]+(senior\s+)?([a-zA-Z\s]+)',
r'role[:\s]+(senior\s+)?([a-zA-Z\s]+)',
]
role = "Role"
for pattern in role_patterns:
match = re.search(pattern, job_text, re.IGNORECASE)
if match:
groups = match.groups()
if len(groups) >= 2:
senior_part = groups[0] or ""
role_part = groups[1] or groups[-1]
role = (senior_part + role_part).strip().title()
break
return role, company
def _extract_team_context(self, job_text: str) -> str:
"""Extract team context from job description"""
context_keywords = [
"team", "collaborate", "cross-functional", "stakeholder",
"partner", "work with", "engineering", "product", "data"
]
sentences = job_text.split('.')
for sentence in sentences:
if any(keyword in sentence.lower() for keyword in context_keywords):
return sentence.strip()
return "Collaborative team environment focused on innovation and results"
def _calculate_match_score(self, user_skills: List[str], role_skills: List[str], resume_text: str, job_text: str) -> float:
"""Calculate match score between user and role"""
if not role_skills:
return 0.75
# Skill overlap
skill_overlap = len(set(user_skills) & set(role_skills))
skill_score = skill_overlap / len(role_skills) if role_skills else 0.5
# Experience factor
experience_match = re.search(r'(\d+)[\s\+]*years?\s+(?:of\s+)?experience', resume_text, re.IGNORECASE)
experience_years = int(experience_match.group(1)) if experience_match else 3
experience_score = min(experience_years * 0.15, 1.0)
# Education factor
education_score = 0.2 if any(word in resume_text.lower() for word in ['degree', 'bachelor', 'master']) else 0.1
# Role relevance
role_keywords = ['engineer', 'scientist', 'analyst', 'manager', 'developer']
role_relevance = 0.2 if any(keyword in resume_text.lower() for keyword in role_keywords) else 0.1
final_score = (skill_score * 0.5 + experience_score * 0.3 + education_score * 0.1 + role_relevance * 0.1)
return min(max(final_score, 0.4), 0.97)
def _estimate_interview_rounds(self, company: str, role: str) -> int:
"""Estimate number of interview rounds"""
if any(term in company.lower() for term in ['startup', 'small']):
return 3
elif any(term in company.lower() for term in ['google', 'amazon', 'microsoft', 'apple', 'meta']):
return 5
else:
return 4
def _generate_process_notes(self, company: str, role: str) -> List[str]:
"""Generate interview process notes"""
base_process = [
"Phone/Video Screen",
"Technical Assessment",
"Behavioral Interview",
"Final Round"
]
if any(term in role.lower() for term in ['senior', 'lead', 'principal']):
base_process.insert(-1, "Leadership Interview")
return base_process
def _extract_key_projects(self, resume_text: str) -> List[str]:
"""Extract key projects from resume"""
project_indicators = [
r'built\s+([^\.]+)',
r'developed\s+([^\.]+)',
r'created\s+([^\.]+)',
r'led\s+([^\.]+)',
r'implemented\s+([^\.]+)'
]
projects = []
for pattern in project_indicators:
matches = re.findall(pattern, resume_text, re.IGNORECASE)
projects.extend([match.strip() for match in matches[:2]]) # Limit to 2 per pattern
return projects[:6] # Max 6 projects
def _extract_strengths(self, resume_text: str, skills: List[str]) -> List[str]:
"""Extract candidate strengths"""
strengths = []
# Add top skills as strengths
strengths.extend(skills[:3])
# Add experience-based strengths
if re.search(r'(\d+)[\s\+]*years', resume_text, re.IGNORECASE):
strengths.append("Extensive experience")
if any(word in resume_text.lower() for word in ['led', 'managed', 'supervised']):
strengths.append("Leadership experience")
if any(word in resume_text.lower() for word in ['scaled', 'optimized', 'improved']):
strengths.append("Performance optimization")
return strengths[:6]
def generate_interview_guide(self, guide_data: GuideData) -> str:
"""Generate interview guide following exact InterviewGuideGPT format"""
# Calculate derived helpers
match_bucket, emoji = self._get_match_bucket(guide_data.match_score)
percent = round(guide_data.match_score * 100, 1)
user_skills_set = set(guide_data.user_skills)
role_skills_set = set(guide_data.role_skills)
strong = len(user_skills_set & role_skills_set)
partial = len(user_skills_set) - strong
gaps = len(role_skills_set) - strong
# Get company insight
company_insight = self._get_company_insight(guide_data.company)
# Generate sections
intro = self._generate_introduction(guide_data)
tech_questions = self._generate_technical_questions(guide_data)
behavioral_questions = self._generate_behavioral_questions(guide_data)
culture_questions = self._generate_culture_questions(guide_data)
talking_points = self._generate_talking_points(guide_data)
smart_questions = self._generate_smart_questions(guide_data)
# Format the complete guide
guide = f"""# Personalized Interview Guide: {guide_data.role_title} at {guide_data.company}
**Match Score: {emoji} {match_bucket} Match ({percent}%)**
---
## Introduction
{intro}
## πŸ“Š Skills Match Analysis
**Overall Assessment:** Strong technical foundation with {strong} direct skill matches and proven experience in {guide_data.user_overview.split()[-2]} {guide_data.user_overview.split()[-1]}.
```text
Skills Breakdown
Strong Matches {'β–ˆ' * min(20, strong * 2)} {strong}
Partial Matches {partial}
Skill Gaps {gaps}
```
βœ… **Your Strengths:** {', '.join(guide_data.user_skills[:6])}
## 🎯 Interview Process at {guide_data.company}
1. **Typical rounds:** {guide_data.interview_rounds}
2. **Stages:** {', '.join(guide_data.process_notes)}
3. **Timeline:** 3-4 weeks (typical)
4. **Company insight:** {company_insight}
## πŸ”§ Technical & Problem-Solving Questions
{tech_questions}
## 🀝 Behavioral & Experience Questions
{behavioral_questions}
## 🏒 Company & Culture Questions
{culture_questions}
## πŸ“… Preparation Strategy
**Immediate priorities:** Review core technical concepts β€’ Prepare STAR examples β€’ Research company background
**Study schedule:** Technical 60% β€’ Behavioral 25% β€’ Company 15%
**Time allocation:** 5–7 hours over 3–5 days
## πŸ’¬ Key Talking Points
{talking_points}
## ❓ Smart Questions to Ask
{smart_questions}
## πŸ—“οΈ Day-of-Interview Checklist
– Morning review of key concepts
– Confirm logistics and timing
– Mental preparation and confidence building
– Arrive 10 minutes early
## βœ… Success Metrics
– Demonstrated {len(guide_data.user_skills)} core strengths
– Asked β‰₯4 thoughtful questions
– Showed enthusiasm & growth mindset
## πŸš€ Conclusion
You're an excellent fitβ€”be confident. Good luck! πŸš€
---
*Generated with IQKiller v2.0 – no data retained.*"""
return guide
def _get_match_bucket(self, score: float) -> tuple:
"""Get match bucket and emoji"""
if score >= 0.90:
return "Excellent", "🟒"
elif score >= 0.80:
return "Strong", "🟑"
else:
return "Developing", "πŸ”΄"
def _get_company_insight(self, company: str) -> str:
"""Get company-specific insight"""
company_lower = company.lower()
for key, insight in self.company_insights.items():
if key in company_lower:
return insight
return f"{company} values innovation and excellence in their field."
def _generate_introduction(self, guide_data: GuideData) -> str:
"""Generate introduction section"""
return f"This {guide_data.role_title} position at {guide_data.company} represents an excellent opportunity for someone with your background. Your {guide_data.user_overview} aligns well with {guide_data.team_context.lower()}. With your technical skills and experience, you're well-positioned to contribute meaningfully to their mission."
def _generate_technical_questions(self, guide_data: GuideData) -> str:
"""Generate exactly 3 technical questions"""
questions = []
# Question 1: System design
q1 = f"""**1. How would you design a system to handle {guide_data.role_title.lower()} requirements at scale?**
*Why they ask:* Tests your system design skills and understanding of scalability challenges.
*How to answer:* Start with requirements gathering, discuss architecture, data flow, and scaling considerations.
*Key points:* System architecture understanding, scalability considerations, technology trade-offs"""
# Question 2: Technical depth
main_skill = guide_data.user_skills[0] if guide_data.user_skills else "your main technology"
q2 = f"""**2. Given your experience with {main_skill}, how would you approach solving a complex data problem?**
*Why they ask:* Assesses your problem-solving approach and technical depth in {main_skill}.
*How to answer:* Break down the problem, discuss methodology, mention specific tools and techniques.
*Key points:* Deep knowledge of {main_skill}, problem decomposition skills, practical application"""
# Question 3: Role-specific
q3 = f"""**3. Describe how you would optimize performance in a {guide_data.role_title.lower()} context.**
*Why they ask:* Evaluates your understanding of performance optimization specific to this role.
*How to answer:* Discuss monitoring, bottleneck identification, and optimization strategies.
*Key points:* Performance metrics understanding, optimization techniques, real-world experience"""
return f"{q1}\n\n{q2}\n\n{q3}"
def _generate_behavioral_questions(self, guide_data: GuideData) -> str:
"""Generate exactly 3 behavioral questions"""
q1 = """**1. Tell me about a time when you had to learn a new technology quickly for a project.**
*STAR Framework:* Situation - Task - Action - Result
*Focus on:* Learning agility, problem-solving approach, impact of quick learning"""
q2 = """**2. Describe a situation where you had to work with a difficult team member or stakeholder.**
*STAR Framework:* Situation - Task - Action - Result
*Focus on:* Communication skills, conflict resolution, collaboration approach"""
q3 = """**3. Give me an example of a project where you had to make trade-offs between competing priorities.**
*STAR Framework:* Situation - Task - Action - Result
*Focus on:* Decision-making process, stakeholder management, outcome evaluation"""
return f"{q1}\n\n{q2}\n\n{q3}"
def _generate_culture_questions(self, guide_data: GuideData) -> str:
"""Generate exactly 3 culture questions"""
q1 = f"""**1. Why are you interested in working at {guide_data.company} specifically?**
*Purpose:* Tests genuine interest and company research.
*Approach:* Connect company mission to your values and career goals."""
q2 = f"""**2. How do you stay current with industry trends and continue learning in your field?**
*Purpose:* Assesses growth mindset and continuous learning.
*Approach:* Share specific resources, communities, and learning practices."""
q3 = f"""**3. Describe your ideal work environment and team dynamics.**
*Purpose:* Evaluates cultural fit and team compatibility.
*Approach:* Align your preferences with {guide_data.company}'s known culture."""
return f"{q1}\n\n{q2}\n\n{q3}"
def _generate_talking_points(self, guide_data: GuideData) -> str:
"""Generate key talking points"""
points = []
# Add background
points.append(f"– {guide_data.user_overview}")
# Add key projects
if guide_data.key_projects:
points.append(f"– {len(guide_data.key_projects)} key projects including {', '.join(guide_data.key_projects[:2])}")
# Add skills highlights
top_skills = guide_data.user_skills[:3]
points.append(f"– Technical expertise: {' + '.join(top_skills)} highlights")
return '\n'.join(points)
def _generate_smart_questions(self, guide_data: GuideData) -> str:
"""Generate smart questions to ask"""
questions = [
"– What does success look like in the first 90 days?",
"– What's the biggest technical challenge facing the team?",
f"– How does {guide_data.company} support professional development and career growth?",
f"– What do you enjoy most about working at {guide_data.company}?",
"– How do you measure the impact of this role on company objectives?",
f"– What opportunities exist for innovation within the {guide_data.role_title} position?"
]
return '\n'.join(questions)
# Main function to generate guide from resume and job text
def generate_interviewgpt_guide(resume_text: str, job_text: str) -> str:
"""Generate interview guide using InterviewGuideGPT format"""
generator = InterviewGuideGPT()
guide_data = generator.analyze_resume_and_job(resume_text, job_text)
return generator.generate_interview_guide(guide_data)
# Legacy compatibility
class ComprehensiveAnalyzer:
"""Legacy wrapper for backward compatibility"""
def __init__(self):
self.generator = InterviewGuideGPT()
def generate_comprehensive_guide(self, resume_text: str, job_input: str):
"""Legacy method for backward compatibility"""
guide_data = self.generator.analyze_resume_and_job(resume_text, job_input)
return MockGuide(self.generator.generate_interview_guide(guide_data))
class MockGuide:
"""Mock guide object for legacy compatibility"""
def __init__(self, content):
self.content = content
def format_interview_guide_html(guide) -> str:
"""Convert markdown guide to HTML for display"""
import re
html_content = guide.content
# Convert markdown headers to HTML
html_content = re.sub(r'^# (.*)', r'<h1 style="color: white; text-align: center; margin-bottom: 20px;">\1</h1>', html_content, flags=re.MULTILINE)
html_content = re.sub(r'^## (.*)', r'<h2 style="color: white; margin: 30px 0 20px 0;">\1</h2>', html_content, flags=re.MULTILINE)
# Convert markdown bold to HTML
html_content = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', html_content)
# Convert markdown code blocks
html_content = re.sub(r'```text\n(.*?)\n```', r'<pre style="background: rgba(0,0,0,0.3); padding: 15px; border-radius: 8px; color: white; font-family: monospace;">\1</pre>', html_content, flags=re.DOTALL)
# Convert lists
html_content = re.sub(r'^– (.*)', r'<li style="color: rgba(255,255,255,0.9); margin: 5px 0;">\1</li>', html_content, flags=re.MULTILINE)
html_content = re.sub(r'^βœ… (.*)', r'<p style="color: var(--apple-green); margin: 15px 0;"><strong>βœ… \1</strong></p>', html_content, flags=re.MULTILINE)
# Convert line breaks to HTML
html_content = html_content.replace('\n\n', '</p><p style="color: rgba(255,255,255,0.9); line-height: 1.6; margin: 15px 0;">')
html_content = html_content.replace('\n', '<br>')
# Wrap in container
html_content = f'''
<div class="result-card slide-in" style="max-width: 1200px; margin: 0 auto; background: var(--glass-bg); border-radius: 16px; padding: 30px; backdrop-filter: blur(15px); box-shadow: var(--shadow-soft);">
<p style="color: rgba(255,255,255,0.9); line-height: 1.6; margin: 15px 0;">
{html_content}
</p>
</div>
'''
return html_content