This commit is contained in:
Sangga123 2025-07-14 13:31:13 +07:00
commit c54e3c2346
10 changed files with 1578 additions and 0 deletions

299
5-fold cross_validation.py Normal file
View File

@ -0,0 +1,299 @@
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder, MinMaxScaler, LabelEncoder
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.model_selection import KFold
import warnings
warnings.filterwarnings('ignore')
class JobRecommendationSystem:
def __init__(self):
self.skill_encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
self.interest_encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
self.major_encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
self.job_encoder = LabelEncoder()
self.ipk_scaler = MinMaxScaler()
self.is_fitted = False
def preprocess_data(self, df):
"""Preprocess data untuk feature engineering"""
# Copy data untuk menghindari modifikasi asli
data = df.copy()
# Normalisasi nama kolom
data.columns = data.columns.str.strip()
# Clean dan standardisasi text
data['keterampilan'] = data['keterampilan'].str.strip().str.lower()
data['minat'] = data['minat'].str.strip().str.lower()
data['Jurusan'] = data['Jurusan'].str.strip().str.lower()
data['dream job'] = data['dream job'].str.strip()
return data
def create_features(self, data, fit=False):
"""Membuat feature matrix dari data"""
# Reshape untuk encoder
skills = data['keterampilan'].values.reshape(-1, 1)
interests = data['minat'].values.reshape(-1, 1)
majors = data['Jurusan'].values.reshape(-1, 1)
ipk = data['IPK'].values.reshape(-1, 1)
if fit:
# Fit encoders
skill_features = self.skill_encoder.fit_transform(skills)
interest_features = self.interest_encoder.fit_transform(interests)
major_features = self.major_encoder.fit_transform(majors)
ipk_features = self.ipk_scaler.fit_transform(ipk)
else:
# Transform only
skill_features = self.skill_encoder.transform(skills)
interest_features = self.interest_encoder.transform(interests)
major_features = self.major_encoder.transform(majors)
ipk_features = self.ipk_scaler.transform(ipk)
# Gabungkan semua features
features = np.hstack([
ipk_features,
skill_features,
interest_features,
major_features
])
return features
def fit(self, X_train, y_train):
"""Fit model dengan training data"""
self.train_features = self.create_features(X_train, fit=True)
self.train_jobs = self.job_encoder.fit_transform(y_train)
self.train_job_names = y_train.values
self.is_fitted = True
def predict(self, X_test, k=3):
"""Predict jobs untuk test data menggunakan cosine similarity"""
if not self.is_fitted:
raise ValueError("Model belum di-fit!")
test_features = self.create_features(X_test, fit=False)
# Hitung cosine similarity
similarities = cosine_similarity(test_features, self.train_features)
predictions = []
for i, sim_scores in enumerate(similarities):
# Ambil k tetangga terdekat
top_k_indices = np.argsort(sim_scores)[::-1][:k]
# Ambil job dari tetangga terdekat
neighbor_jobs = [self.train_job_names[idx] for idx in top_k_indices]
# Hitung frequency-based recommendation
job_counts = {}
for job in neighbor_jobs:
job_counts[job] = job_counts.get(job, 0) + 1
# Ambil job dengan frekuensi tertinggi
recommended_job = max(job_counts.keys(), key=job_counts.get)
predictions.append(recommended_job)
return predictions
def predict_top_k(self, X_test, k=3, top_jobs=3):
"""Predict top-k jobs untuk test data"""
if not self.is_fitted:
raise ValueError("Model belum di-fit!")
test_features = self.create_features(X_test, fit=False)
similarities = cosine_similarity(test_features, self.train_features)
predictions = []
for i, sim_scores in enumerate(similarities):
top_k_indices = np.argsort(sim_scores)[::-1][:k]
neighbor_jobs = [self.train_job_names[idx] for idx in top_k_indices]
# Hitung job frequency
job_counts = {}
for job in neighbor_jobs:
job_counts[job] = job_counts.get(job, 0) + 1
# Ambil top jobs berdasarkan frequency
sorted_jobs = sorted(job_counts.items(), key=lambda x: x[1], reverse=True)
top_recommended = [job for job, count in sorted_jobs[:top_jobs]]
predictions.append(top_recommended)
return predictions
def evaluate_model(df, n_splits=5, k_neighbors=5):
"""Evaluasi model menggunakan 5-fold cross validation"""
# Preprocess data
model = JobRecommendationSystem()
processed_data = model.preprocess_data(df)
# Inisialisasi KFold
kf = KFold(n_splits=n_splits, shuffle=True, random_state=42)
# Metrics untuk setiap fold
fold_results = []
print("=" * 80)
print("EVALUASI 5-FOLD CROSS-VALIDATION DENGAN COSINE SIMILARITY")
print("=" * 80)
print()
for fold, (train_idx, test_idx) in enumerate(kf.split(processed_data), 1):
print(f"Processing Fold {fold}...")
# Split data
train_data = processed_data.iloc[train_idx]
test_data = processed_data.iloc[test_idx]
X_train = train_data[['IPK', 'Jurusan', 'keterampilan', 'minat']]
y_train = train_data['dream job']
X_test = test_data[['IPK', 'Jurusan', 'keterampilan', 'minat']]
y_test = test_data['dream job']
# Fit dan predict
fold_model = JobRecommendationSystem()
fold_model.fit(X_train, y_train)
# Single prediction (top-1)
predictions_top1 = fold_model.predict(X_test, k=k_neighbors)
# Top-3 predictions
predictions_top3 = fold_model.predict_top_k(X_test, k=k_neighbors, top_jobs=3)
# Hitung metrics
# Accuracy (exact match)
exact_matches = sum(1 for pred, actual in zip(predictions_top1, y_test)
if pred.lower() == actual.lower())
accuracy = exact_matches / len(y_test)
# Top-3 accuracy
top3_matches = 0
for pred_list, actual in zip(predictions_top3, y_test):
if any(pred.lower() == actual.lower() for pred in pred_list):
top3_matches += 1
top3_accuracy = top3_matches / len(y_test)
# Partial match (similar to original hit rate)
partial_matches = 0
for pred, actual in zip(predictions_top1, y_test):
pred_lower = pred.lower()
actual_lower = actual.lower()
if pred_lower in actual_lower or actual_lower in pred_lower:
partial_matches += 1
partial_accuracy = partial_matches / len(y_test)
# Simpan hasil fold
fold_result = {
'fold': fold,
'train_size': len(train_data),
'test_size': len(test_data),
'exact_accuracy': accuracy,
'partial_accuracy': partial_accuracy,
'top3_accuracy': top3_accuracy,
'predictions': predictions_top1,
'actual': y_test.tolist()
}
fold_results.append(fold_result)
# Print hasil fold
print(f"Fold {fold} Results:")
print(f" Train Size: {len(train_data)}, Test Size: {len(test_data)}")
print(f" Exact Accuracy: {accuracy:.3f} ({accuracy*100:.1f}%)")
print(f" Partial Accuracy: {partial_accuracy:.3f} ({partial_accuracy*100:.1f}%)")
print(f" Top-3 Accuracy: {top3_accuracy:.3f} ({top3_accuracy*100:.1f}%)")
print()
return fold_results
def analyze_results(fold_results):
"""Analisis hasil cross-validation"""
print("=" * 80)
print("RINGKASAN HASIL 5-FOLD CROSS-VALIDATION")
print("=" * 80)
# Hitung rata-rata metrics
exact_accs = [result['exact_accuracy'] for result in fold_results]
partial_accs = [result['partial_accuracy'] for result in fold_results]
top3_accs = [result['top3_accuracy'] for result in fold_results]
print(f"\nRata-rata Metrics:")
print(f"Exact Accuracy: {np.mean(exact_accs):.3f} ± {np.std(exact_accs):.3f}")
print(f"Partial Accuracy: {np.mean(partial_accs):.3f} ± {np.std(partial_accs):.3f}")
print(f"Top-3 Accuracy: {np.mean(top3_accs):.3f} ± {np.std(top3_accs):.3f}")
print(f"\nDetail per Fold:")
print(f"{'Fold':<6} {'Exact':<8} {'Partial':<8} {'Top-3':<8}")
print("-" * 35)
for result in fold_results:
print(f"{result['fold']:<6} {result['exact_accuracy']:.3f} {result['partial_accuracy']:.3f} {result['top3_accuracy']:.3f}")
# Analisis error
print(f"\nAnalisis Kesalahan Prediksi:")
all_predictions = []
all_actual = []
for result in fold_results:
all_predictions.extend(result['predictions'])
all_actual.extend(result['actual'])
# Hitung confusion untuk job yang sering salah
error_analysis = {}
for pred, actual in zip(all_predictions, all_actual):
if pred.lower() != actual.lower():
key = f"'{actual}''{pred}'"
error_analysis[key] = error_analysis.get(key, 0) + 1
print("\nKesalahan Prediksi Terbanyak:")
sorted_errors = sorted(error_analysis.items(), key=lambda x: x[1], reverse=True)
for error, count in sorted_errors[:10]:
print(f" {error}: {count} kali")
return {
'mean_exact_accuracy': np.mean(exact_accs),
'std_exact_accuracy': np.std(exact_accs),
'mean_partial_accuracy': np.mean(partial_accs),
'std_partial_accuracy': np.std(partial_accs),
'mean_top3_accuracy': np.mean(top3_accs),
'std_top3_accuracy': np.std(top3_accs),
'fold_results': fold_results
}
def main():
"""Fungsi utama untuk menjalankan evaluasi"""
# Load data
try:
df = pd.read_csv('student.csv')
print(f"Data berhasil dimuat: {len(df)} records")
print(f"Kolom: {list(df.columns)}")
print()
except FileNotFoundError:
print("File student.csv tidak ditemukan!")
return
# Jalankan evaluasi
fold_results = evaluate_model(df, n_splits=5, k_neighbors=5)
# Analisis hasil
summary = analyze_results(fold_results)
print("\n" + "=" * 80)
print("KESIMPULAN")
print("=" * 80)
print(f"Model Cosine Similarity dengan 5-fold CV menunjukkan:")
print(f"• Exact Match Accuracy: {summary['mean_exact_accuracy']:.1%} ± {summary['std_exact_accuracy']:.1%}")
print(f"• Partial Match Accuracy: {summary['mean_partial_accuracy']:.1%} ± {summary['std_partial_accuracy']:.1%}")
print(f"• Top-3 Accuracy: {summary['mean_top3_accuracy']:.1%} ± {summary['std_top3_accuracy']:.1%}")
print()
print("Metode ini menggunakan kesamaan profil mahasiswa (IPK, jurusan, keterampilan, minat)")
print("untuk merekomendasikan pekerjaan berdasarkan tetangga terdekat.")
if __name__ == "__main__":
main()

221
hit_rate_119.py Normal file
View File

@ -0,0 +1,221 @@
import pandas as pd
import random
# Data jurusan dan rekomendasi (tetap sama)
jurusan_data = {
"teknik informatika": {
"keterampilan": [
"spreadsheet", "python", "analisis data", "visualisasi data",
"pengujian perangkat lunak", "dokumentasi kasus uji", "manajemen waktu",
"html", "css", "javascript", "java", "node.js", "sql", "devops", "aws", "azure",
"react", "angular", "statistik", "machine learning", "cloud operation", "ruby",
"database", "desain", "pemrograman", "keamanan digital", "troubleshooting",
"kotlin", "swift", "objective-c", "r", "preprocessing data", "penyebaran model",
"manajemen proyek", "pemahaman operasi bisnis", "unity", "unreal engine", "c#", "c++"
],
"minat": [
"investigative (analitis)", "conventional (terstruktur)", "artistic (kreatif)",
"realistic (praktis, teknis)", "enterprising (memimpin)", "social (sosial)"
]
},
"sistem informasi": {
"keterampilan": [
"spreadsheet", "python", "analisis data", "visualisasi data",
"database", "sql", "manajemen proyek", "pemahaman operasi bisnis",
"administrasi jaringan", "troubleshooting", "dukungan teknis perangkat keras dan perangkat lunak"
],
"minat": ["investigative (analitis)", "conventional (terstruktur)", "realistic (praktis, teknis)", "social (sosial)"]
},
"matematika": {
"keterampilan": ["spreadsheet", "python", "analisis data", "visualisasi data", "statistik", "machine learning", "r"],
"minat": ["investigative (analitis)"]
},
"teknik komputer": {
"keterampilan": [
"html", "css", "javascript", "python", "java", "node.js", "sql", "devops", "aws", "azure",
"cloud operation", "ruby", "pemrograman", "keamanan digital", "troubleshooting",
"kotlin", "swift", "objective-c", "administrasi jaringan"
],
"minat": ["conventional (terstruktur)", "artistic (kreatif)", "realistic (praktis, teknis)", "enterprising (memimpin)"]
},
"desain komunikasi visual": {
"keterampilan": ["html", "css", "javascript", "react", "angular", "desain"],
"minat": ["artistic (kreatif)"]
},
"statistik": {
"keterampilan": ["statistik", "machine learning", "python", "r"],
"minat": ["investigative (analitis)"]
},
"ilmu komputer": {
"keterampilan": ["database", "sql"],
"minat": ["investigative (analitis)"]
}
}
def get_recommendation(ipk, jurusan):
"""Generate recommendation based on IPK and major"""
jurusan_lower = jurusan.lower()
if jurusan_lower in ["teknik informatika", "sistem informasi"]:
if ipk >= 3.7:
return ["Data Scientist", "Machine Learning Engineer", "Software Engineer"]
elif ipk >= 3.5:
return ["Data Analyst", "Web Developer", "Software Engineer"]
else:
return ["Junior Developer", "IT Support", "System Administrator"]
elif jurusan_lower == "matematika":
return ["Data Scientist", "Statistician", "Data Analyst"]
elif jurusan_lower == "desain komunikasi visual":
return ["UI/UX Designer", "Graphic Designer", "Web Designer"]
elif jurusan_lower == "teknik komputer":
return ["System Administrator", "Network Engineer", "DevOps Engineer"]
elif jurusan_lower == "statistik":
return ["Data Analyst", "Statistician", "Research Analyst"]
else:
return ["Database Administrator", "Data Analyst", "System Analyst"]
def check_hit(target, recommendations):
"""Check if target job matches any recommendation"""
target_lower = target.lower()
for rec in recommendations:
rec_lower = rec.lower()
# Check if target contains recommendation or vice versa
if target_lower in rec_lower or rec_lower in target_lower:
return True
return False
# Load CSV data
try:
df = pd.read_csv('student.csv')
print(f"Data berhasil dimuat: {len(df)} records")
except FileNotFoundError:
print("File student.csv tidak ditemukan!")
exit()
# Process data
uji_coba = []
total = len(df)
hit = 0
print("=" * 120)
print("PENGUJIAN HIT RATE SISTEM IPKMATCHER - MENGGUNAKAN DATASET CSV")
print("=" * 120)
print()
print("{:<3} {:<5} {:<5} {:<20} {:<20} {:<25} {:<35} {:<18} {:<4}".format(
"No", "NIM", "IPK", "Jurusan", "Keterampilan", "Minat", "Rekomendasi Sistem", "Target", "Hit"))
print("-" * 120)
for index, row in df.iterrows():
nim = row['NIM']
ipk = row['IPK']
jurusan = row['Jurusan']
target = row['dream job']
keterampilan = row['keterampilan']
minat = row['minat']
# Generate recommendations
rekomendasi = get_recommendation(ipk, jurusan)
# Check hit
is_hit = check_hit(target, rekomendasi)
if is_hit:
hit += 1
# Store for analysis
uji_coba.append({
"nim": nim,
"ipk": ipk,
"jurusan": jurusan,
"keterampilan": keterampilan,
"minat": minat,
"rekomendasi": rekomendasi,
"target": target,
"hit": is_hit
})
# Format for display
jurusan_short = (jurusan[:17] + "...") if len(jurusan) > 20 else jurusan
keterampilan_short = (keterampilan[:17] + "...") if len(keterampilan) > 20 else keterampilan
minat_short = (minat[:22] + "...") if len(minat) > 25 else minat
rekom_short = (", ".join(rekomendasi)[:32] + "...") if len(", ".join(rekomendasi)) > 35 else ", ".join(rekomendasi)
target_short = (target[:15] + "...") if len(target) > 18 else target
print("{:<3} {:<5} {:<5} {:<20} {:<20} {:<25} {:<35} {:<18} {:<4}".format(
index + 1, nim, ipk, jurusan_short, keterampilan_short, minat_short,
rekom_short, target_short, "" if is_hit else ""))
# Calculate hit rate
hit_rate = hit / total
print("-" * 120)
print(f"HASIL PENGUJIAN:")
print(f"Total Hit: {hit} dari {total} kasus")
print(f"Hit Rate: {hit_rate:.3f} ({hit_rate * 100:.1f}%)")
print()
# Analysis per major
print("ANALISIS PER JURUSAN:")
print("-" * 50)
jurusan_stats = {}
for case in uji_coba:
jurusan = case["jurusan"]
if jurusan not in jurusan_stats:
jurusan_stats[jurusan] = {"total": 0, "hit": 0}
jurusan_stats[jurusan]["total"] += 1
jurusan_stats[jurusan]["hit"] += case["hit"]
for jurusan, stats in jurusan_stats.items():
rate = stats["hit"] / stats["total"]
print(f"{jurusan:<25}: {stats['hit']}/{stats['total']} ({rate*100:.1f}%)")
# Analysis per IPK range
print("\nANALISIS PER RENTANG IPK:")
print("-" * 50)
ipk_ranges = {
"3.8-4.0": {"min": 3.8, "max": 4.0, "total": 0, "hit": 0},
"3.5-3.79": {"min": 3.5, "max": 3.79, "total": 0, "hit": 0},
"3.0-3.49": {"min": 3.0, "max": 3.49, "total": 0, "hit": 0},
"<3.0": {"min": 0, "max": 2.99, "total": 0, "hit": 0}
}
for case in uji_coba:
ipk = case["ipk"]
for range_name, range_info in ipk_ranges.items():
if range_info["min"] <= ipk <= range_info["max"]:
range_info["total"] += 1
range_info["hit"] += case["hit"]
break
for range_name, stats in ipk_ranges.items():
if stats["total"] > 0:
rate = stats["hit"] / stats["total"]
print(f"IPK {range_name:<10}: {stats['hit']}/{stats['total']} ({rate*100:.1f}%)")
print("=" * 120)
# Detailed results
# print("\nDETAIL LENGKAP HASIL PENGUJIAN:")
# print("=" * 80)
# for i, case in enumerate(uji_coba, 1):
# print(f"\nTest Case {i}:")
# print(f" NIM: {case['nim']}")
# print(f" IPK: {case['ipk']}")
# print(f" Jurusan: {case['jurusan']}")
# print(f" Keterampilan: {case['keterampilan']}")
# print(f" Minat: {case['minat']}")
# print(f" Rekomendasi: {', '.join(case['rekomendasi'])}")
# print(f" Target (Dream Job): {case['target']}")
# print(f" Status: {'✓ HIT' if case['hit'] else '✗ MISS'}")
# print(f" {'-'*40}")
# Summary of missed predictions
print("\nANALISIS PREDIKSI YANG MELESET:")
print("=" * 80)
missed_cases = [case for case in uji_coba if not case['hit']]
print(f"Total kasus yang meleset: {len(missed_cases)}")
if missed_cases:
print("\nContoh kasus yang meleset:")
for i, case in enumerate(missed_cases[:10], 1): # Show first 10 missed cases
print(f"{i}. NIM {case['nim']}: Target '{case['target']}' vs Rekomendasi {case['rekomendasi']}")

188
hit_rate_20.py Normal file
View File

@ -0,0 +1,188 @@
import random
jurusan_data = {
"teknik informatika": {
"keterampilan": [
"spreadsheet", "python", "analisis data", "visualisasi data",
"pengujian perangkat lunak", "dokumentasi kasus uji", "manajemen waktu",
"html", "css", "javascript", "java", "node.js", "sql", "devops", "aws", "azure",
"react", "angular", "statistik", "machine learning", "cloud operation", "ruby",
"database", "desain", "pemrograman", "keamanan digital", "troubleshooting",
"kotlin", "swift", "objective-c", "r", "preprocessing data", "penyebaran model",
"manajemen proyek", "pemahaman operasi bisnis", "unity", "unreal engine", "c#", "c++"
],
"minat": [
"investigative (analitis)", "conventional (terstruktur)", "artistic (kreatif)",
"realistic (praktis, teknis)", "enterprising (memimpin)", "social (sosial)"
]
},
"sistem informasi": {
"keterampilan": [
"spreadsheet", "python", "analisis data", "visualisasi data",
"database", "sql", "manajemen proyek", "pemahaman operasi bisnis",
"administrasi jaringan", "troubleshooting", "dukungan teknis perangkat keras dan perangkat lunak"
],
"minat": ["investigative (analitis)", "conventional (terstruktur)", "realistic (praktis, teknis)", "social (sosial)"]
},
"matematika": {
"keterampilan": ["spreadsheet", "python", "analisis data", "visualisasi data", "statistik", "machine learning", "r"],
"minat": ["investigative (analitis)"]
},
"teknik komputer": {
"keterampilan": [
"html", "css", "javascript", "python", "java", "node.js", "sql", "devops", "aws", "azure",
"cloud operation", "ruby", "pemrograman", "keamanan digital", "troubleshooting",
"kotlin", "swift", "objective-c", "administrasi jaringan"
],
"minat": ["conventional (terstruktur)", "artistic (kreatif)", "realistic (praktis, teknis)", "enterprising (memimpin)"]
},
"desain komunikasi visual": {
"keterampilan": ["html", "css", "javascript", "react", "angular", "desain"],
"minat": ["artistic (kreatif)"]
},
"statistik": {
"keterampilan": ["statistik", "machine learning", "python", "r"],
"minat": ["investigative (analitis)"]
},
"ilmu komputer": {
"keterampilan": ["database", "sql"],
"minat": ["investigative (analitis)"]
}
}
def get_random_skills_interests(jurusan):
if jurusan in jurusan_data:
keterampilan = random.choice(jurusan_data[jurusan]["keterampilan"])
minat = random.choice(jurusan_data[jurusan]["minat"])
return keterampilan, minat
return "python", "investigative (analitis)" # default
random.seed(42)
uji_coba = []
test_cases_data = [
{"nama": "Ahmad", "ipk": 3.78, "jurusan": "teknik informatika", "target": "Web Developer"},
{"nama": "Sari", "ipk": 3.50, "jurusan": "sistem informasi", "target": "Data Analyst"},
{"nama": "Budi", "ipk": 3.83, "jurusan": "teknik informatika", "target": "Data Scientist"},
{"nama": "Rina", "ipk": 3.91, "jurusan": "teknik informatika", "target": "Quality Assurance"},
{"nama": "Doni", "ipk": 3.83, "jurusan": "sistem informasi", "target": "Data Analyst"},
{"nama": "Lisa", "ipk": 3.78, "jurusan": "teknik informatika", "target": "Web Developer"},
{"nama": "Agus", "ipk": 3.71, "jurusan": "teknik informatika", "target": "Frontend Developer"},
{"nama": "Maya", "ipk": 3.74, "jurusan": "desain komunikasi visual", "target": "UI/UX Designer"},
{"nama": "Rudi", "ipk": 3.92, "jurusan": "teknik informatika", "target": "Machine Learning Engineer"},
{"nama": "Dewi", "ipk": 3.95, "jurusan": "matematika", "target": "Data Scientist"},
{"nama": "Andi", "ipk": 3.25, "jurusan": "teknik komputer", "target": "System Administrator"},
{"nama": "Nina", "ipk": 3.65, "jurusan": "statistik", "target": "Data Analyst"},
{"nama": "Hadi", "ipk": 3.45, "jurusan": "ilmu komputer", "target": "Database Administrator"},
{"nama": "Tina", "ipk": 3.88, "jurusan": "teknik informatika", "target": "Software Engineer"},
{"nama": "Bayu", "ipk": 3.55, "jurusan": "sistem informasi", "target": "Business Analyst"},
{"nama": "Sinta", "ipk": 3.72, "jurusan": "desain komunikasi visual", "target": "UI/UX Designer"},
{"nama": "Dika", "ipk": 3.33, "jurusan": "teknik komputer", "target": "Network Engineer"},
{"nama": "Lusi", "ipk": 3.67, "jurusan": "matematika", "target": "Statistician"},
{"nama": "Yoga", "ipk": 3.81, "jurusan": "teknik informatika", "target": "DevOps Engineer"},
{"nama": "Eka", "ipk": 3.59, "jurusan": "sistem informasi", "target": "IT Support"}
]
for case_data in test_cases_data:
keterampilan, minat = get_random_skills_interests(case_data["jurusan"])
if case_data["jurusan"] in ["teknik informatika", "sistem informasi"]:
if case_data["ipk"] >= 3.7:
rekomendasi = ["Data Scientist", "Machine Learning Engineer", "Software Engineer"]
elif case_data["ipk"] >= 3.5:
rekomendasi = ["Data Analyst", "Web Developer", "Software Engineer"]
else:
rekomendasi = ["Junior Developer", "IT Support", "System Administrator"]
elif case_data["jurusan"] == "matematika":
rekomendasi = ["Data Scientist", "Statistician", "Data Analyst"]
elif case_data["jurusan"] == "desain komunikasi visual":
rekomendasi = ["UI/UX Designer", "Graphic Designer", "Web Designer"]
elif case_data["jurusan"] == "teknik komputer":
rekomendasi = ["System Administrator", "Network Engineer", "DevOps Engineer"]
elif case_data["jurusan"] == "statistik":
rekomendasi = ["Data Analyst", "Statistician", "Research Analyst"]
else:
rekomendasi = ["Database Administrator", "Data Analyst", "System Analyst"]
uji_coba.append({
"nama": case_data["nama"],
"ipk": case_data["ipk"],
"jurusan": case_data["jurusan"],
"keterampilan": keterampilan,
"minat": minat,
"rekomendasi": rekomendasi,
"target": case_data["target"]
})
total = len(uji_coba)
hit = 0
print("=" * 120)
print("PENGUJIAN HIT RATE SISTEM IPKMATCHER")
print("=" * 120)
print()
print("{:<3} {:<8} {:<5} {:<20} {:<20} {:<25} {:<35} {:<18} {:<4}".format(
"No", "Nama", "IPK", "Jurusan", "Keterampilan", "Minat", "Rekomendasi Sistem", "Target", "Hit"))
print("-" * 120)
for i, case in enumerate(uji_coba, 1):
nama = case["nama"]
ipk = case["ipk"]
jurusan = case["jurusan"]
keterampilan = case["keterampilan"]
minat = case["minat"]
rekom = case["rekomendasi"]
target = case["target"]
is_hit = 1 if any(target.lower() in rec.lower() or rec.lower() in target.lower() for rec in rekom) else 0
hit += is_hit
jurusan_short = (jurusan[:17] + "...") if len(jurusan) > 20 else jurusan
keterampilan_short = (keterampilan[:17] + "...") if len(keterampilan) > 20 else keterampilan
minat_short = (minat[:22] + "...") if len(minat) > 25 else minat
rekom_short = (", ".join(rekom)[:32] + "...") if len(", ".join(rekom)) > 35 else ", ".join(rekom)
target_short = (target[:15] + "...") if len(target) > 18 else target
print("{:<3} {:<8} {:<5} {:<20} {:<20} {:<25} {:<35} {:<18} {:<4}".format(
i, nama, ipk, jurusan_short, keterampilan_short, minat_short, rekom_short, target_short, "" if is_hit else ""))
hit_rate = hit / total
print("-" * 120)
print(f"HASIL PENGUJIAN:")
print(f"Total Hit: {hit} dari {total} kasus")
print(f"Hit Rate: {hit_rate:.3f} ({hit_rate * 100:.1f}%)")
print()
print("ANALISIS PER JURUSAN:")
print("-" * 50)
jurusan_stats = {}
for case in uji_coba:
jurusan = case["jurusan"]
if jurusan not in jurusan_stats:
jurusan_stats[jurusan] = {"total": 0, "hit": 0}
jurusan_stats[jurusan]["total"] += 1
is_hit = 1 if any(case["target"].lower() in rec.lower() or rec.lower() in case["target"].lower() for rec in case["rekomendasi"]) else 0
jurusan_stats[jurusan]["hit"] += is_hit
for jurusan, stats in jurusan_stats.items():
rate = stats["hit"] / stats["total"]
print(f"{jurusan.title():<25}: {stats['hit']}/{stats['total']} ({rate*100:.1f}%)")
print("=" * 120)
print("\nDETAIL LENGKAP HASIL PENGUJIAN:")
print("=" * 80)
for i, case in enumerate(uji_coba, 1):
print(f"\nTest Case {i}:")
print(f" Nama: {case['nama']}")
print(f" IPK: {case['ipk']}")
print(f" Jurusan: {case['jurusan'].title()}")
print(f" Keterampilan: {case['keterampilan'].title()}")
print(f" Minat: {case['minat'].title()}")
print(f" Rekomendasi: {', '.join(case['rekomendasi'])}")
print(f" Target: {case['target']}")
is_hit = 1 if any(case["target"].lower() in rec.lower() or rec.lower() in case["target"].lower() for rec in case["rekomendasi"]) else 0
print(f" Status: {'✓ HIT' if is_hit else '✗ MISS'}")
print(f" {'-'*40}")

21
job_profiles.csv Normal file
View File

@ -0,0 +1,21 @@
dream job,IPK,keterampilan_Administrasi Jaringan,keterampilan_Algoritma Machine Learning,keterampilan_Analisis Data,keterampilan_Azure,keterampilan_C#,keterampilan_C++,keterampilan_CSS,keterampilan_Cloud Operation,keterampilan_Database,keterampilan_Desain,keterampilan_Dokumentasi Kasus Uji,keterampilan_Dukungan Teknis Perangkat Keras dan Perangkat Lunak,keterampilan_HTML,keterampilan_Java,keterampilan_JavaScript,keterampilan_Javascript,keterampilan_Keamanan Digital,keterampilan_Kotlin,keterampilan_Kotlin ,keterampilan_Machine Learning,keterampilan_Manajemen Penyimpanan Database,keterampilan_Manajemen Proyek,keterampilan_Manajemen Waktu,keterampilan_Node.js,keterampilan_Pemahaman Operasi Bisnis,keterampilan_Pemrograman,keterampilan_Pengujian Perangkat Lunak,keterampilan_Preprocessing Data,keterampilan_Python,keterampilan_React,keterampilan_Ruby,keterampilan_SQL,keterampilan_Spreadsheet,keterampilan_Statistik,keterampilan_Swift,keterampilan_Troubleshooting,keterampilan_Unity,keterampilan_Unreal Engine,keterampilan_Visualisasi Data,minat_Artistic (Kreatif),minat_Conventional (Terstruktur),minat_Enterprising (Memimpin),minat_Investigative (Analitis),"minat_Realistic (Praktis, Teknis)",minat_Social (Sosial)
Backend Developer,0.5707079106380618,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.6666666666666666,0.0,0.16666666666666666,0.16666666666666666,0.0
Business Intelligence Developer,0.7181107600199566,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.5,0.0,0.0,0.0,1.0,0.0,0.0
Cloud Engineer,0.6885913853317809,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.8333333333333334,0.0
Cybersecurity Analyst,0.7101557736016407,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.5,0.0,0.0,0.0,0.0,0.16666666666666666,0.3333333333333333,0.3333333333333333,0.16666666666666666,0.0
Data Analyst,0.735953054097075,0.0,0.0,0.42857142857142855,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.14285714285714285,0.0,0.0,0.0,0.14285714285714285,0.0,0.0,0.0,0.0,0.0,0.2857142857142857,0.0,0.0,0.0,1.0,0.0,0.0
Data Engineer,0.7873219136315758,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.6666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.5,0.3333333333333333,0.0
Data Scientist,0.7581905870613669,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0
Database Administrator,0.5515383336105103,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.2,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.8,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0
DevOps Engineer,0.7336049670159097,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0
Frontend Developer,0.6585730916347909,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0
Game Developer,0.637091856533067,0.0,0.0,0.0,0.0,0.3333333333333333,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.16666666666666666,0.0,1.0,0.0,0.0,0.0,0.0,0.0
IT Project Manager,0.7553356616220409,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.6666666666666666
IT Support Specialist,0.7002605465934916,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0
Machine Learning Engineer,0.7346859582016739,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0
Mobile App Developer,0.6177726038028714,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.3333333333333333,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0
Network Administrator,0.745689894118299,0.6666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.3333333333333333,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0
Quality Assurance,0.6567104606685512,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.2,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.6,0.0,0.0,0.0,0.2,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0
Software Engineer,0.7200510006097897,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.5,0.5,0.0,0.0,0.0,0.0
UI/UX Designer,0.6349021564388267,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0
Web Developer,0.6734297910083704,0.0,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.0,0.0,0.0,0.16666666666666666,0.0,0.0,0.6666666666666666,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0
1 dream job IPK keterampilan_Administrasi Jaringan keterampilan_Algoritma Machine Learning keterampilan_Analisis Data keterampilan_Azure keterampilan_C# keterampilan_C++ keterampilan_CSS keterampilan_Cloud Operation keterampilan_Database keterampilan_Desain keterampilan_Dokumentasi Kasus Uji keterampilan_Dukungan Teknis Perangkat Keras dan Perangkat Lunak keterampilan_HTML keterampilan_Java keterampilan_JavaScript keterampilan_Javascript keterampilan_Keamanan Digital keterampilan_Kotlin keterampilan_Kotlin keterampilan_Machine Learning keterampilan_Manajemen Penyimpanan Database keterampilan_Manajemen Proyek keterampilan_Manajemen Waktu keterampilan_Node.js keterampilan_Pemahaman Operasi Bisnis keterampilan_Pemrograman keterampilan_Pengujian Perangkat Lunak keterampilan_Preprocessing Data keterampilan_Python keterampilan_React keterampilan_Ruby keterampilan_SQL keterampilan_Spreadsheet keterampilan_Statistik keterampilan_Swift keterampilan_Troubleshooting keterampilan_Unity keterampilan_Unreal Engine keterampilan_Visualisasi Data minat_Artistic (Kreatif) minat_Conventional (Terstruktur) minat_Enterprising (Memimpin) minat_Investigative (Analitis) minat_Realistic (Praktis, Teknis) minat_Social (Sosial)
2 Backend Developer 0.5707079106380618 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.6666666666666666 0.0 0.16666666666666666 0.16666666666666666 0.0
3 Business Intelligence Developer 0.7181107600199566 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 1.0 0.0 0.0
4 Cloud Engineer 0.6885913853317809 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.8333333333333334 0.0
5 Cybersecurity Analyst 0.7101557736016407 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.0 0.16666666666666666 0.3333333333333333 0.3333333333333333 0.16666666666666666 0.0
6 Data Analyst 0.735953054097075 0.0 0.0 0.42857142857142855 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.14285714285714285 0.0 0.0 0.0 0.14285714285714285 0.0 0.0 0.0 0.0 0.0 0.2857142857142857 0.0 0.0 0.0 1.0 0.0 0.0
7 Data Engineer 0.7873219136315758 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.6666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.5 0.3333333333333333 0.0
8 Data Scientist 0.7581905870613669 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0
9 Database Administrator 0.5515383336105103 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.8 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0
10 DevOps Engineer 0.7336049670159097 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0
11 Frontend Developer 0.6585730916347909 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
12 Game Developer 0.637091856533067 0.0 0.0 0.0 0.0 0.3333333333333333 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.16666666666666666 0.0 1.0 0.0 0.0 0.0 0.0 0.0
13 IT Project Manager 0.7553356616220409 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.6666666666666666
14 IT Support Specialist 0.7002605465934916 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0
15 Machine Learning Engineer 0.7346859582016739 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.5 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0
16 Mobile App Developer 0.6177726038028714 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.3333333333333333 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
17 Network Administrator 0.745689894118299 0.6666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.3333333333333333 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0
18 Quality Assurance 0.6567104606685512 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.6 0.0 0.0 0.0 0.2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0
19 Software Engineer 0.7200510006097897 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.5 0.5 0.0 0.0 0.0 0.0
20 UI/UX Designer 0.6349021564388267 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
21 Web Developer 0.6734297910083704 0.0 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.0 0.0 0.0 0.16666666666666666 0.0 0.0 0.6666666666666666 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0

BIN
jobs.xlsx Normal file

Binary file not shown.

BIN
requirements.txt Normal file

Binary file not shown.

240
server.py Normal file
View File

@ -0,0 +1,240 @@
from flask import Flask, render_template, request, redirect, url_for
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.preprocessing import MinMaxScaler
import logging
import jinja2
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
app = Flask(__name__)
def load_data(job_file):
try:
jobs = pd.read_excel(job_file)
expected_job_columns = ['id', 'job', 'min_ipk', 'job_desc', 'jurusan', 'keterampilan', 'minat']
# Debug: tampilkan kolom yang ada
logger.info(f"Kolom yang ditemukan di {job_file}: {list(jobs.columns)}")
logger.info(f"Kolom yang diharapkan: {expected_job_columns}")
# Cek apakah semua kolom yang diperlukan ada (tidak harus urutan yang sama)
missing_columns = [col for col in expected_job_columns if col not in jobs.columns]
if missing_columns:
logger.error(f"Kolom yang hilang: {missing_columns}")
raise ValueError(f"File {job_file} harus memiliki kolom: {expected_job_columns}. Kolom yang hilang: {missing_columns}")
# Reorder kolom sesuai ekspektasi dan hapus kolom yang tidak diperlukan
jobs = jobs[expected_job_columns]
jobs = jobs.dropna()
jobs['jurusan'] = jobs['jurusan'].str.split(',').str[0].str.strip().str.lower().str.rstrip('.')
jobs['keterampilan'] = jobs['keterampilan'].str.split(',').apply(lambda x: [skill.strip().lower() for skill in x])
jobs['minat'] = jobs['minat'].str.strip().str.lower()
logger.info(f"Data jobs berhasil dimuat dan dibersihkan. Shape: {jobs.shape}")
logger.info(f"Sample data:\n{jobs.head()}")
return jobs
except Exception as e:
logger.error(f"Error memuat data: {e}")
raise
def preprocess_data(jobs, ipk, jurusan, keterampilan, minat):
try:
# Dapatkan semua nilai unik
all_jurusan = sorted(set(jobs['jurusan']).union([jurusan.lower()]))
all_keterampilan = sorted(set([skill for sublist in jobs['keterampilan'] for skill in sublist]).union([keterampilan.lower()]))
all_minat = sorted(set(jobs['minat']).union([minat.lower()]))
logger.info(f"Total jurusan unik: {len(all_jurusan)}")
logger.info(f"Total keterampilan unik: {len(all_keterampilan)}")
logger.info(f"Total minat unik: {len(all_minat)}")
def to_one_hot(value, all_values):
vector = np.array([1 if value.lower() == val else 0 for val in all_values])
return vector
# Buat vektor untuk jobs
job_jurusan_vectors = np.array([to_one_hot(jurusan, all_jurusan) for jurusan in jobs['jurusan']])
job_minat_vectors = np.array([to_one_hot(minat, all_minat) for minat in jobs['minat']])
# Buat vektor keterampilan untuk jobs
job_keterampilan_vectors = np.zeros((len(jobs), len(all_keterampilan)))
for i, skills in enumerate(jobs['keterampilan']):
for skill in skills:
if skill in all_keterampilan:
job_keterampilan_vectors[i, all_keterampilan.index(skill)] = 1
# Normalisasi IPK
scaler = MinMaxScaler()
job_gpa = scaler.fit_transform(jobs['min_ipk'].values.reshape(-1, 1)).flatten() # Flatten untuk 1D
user_gpa = scaler.transform(np.array([[ipk]])).flatten() # Flatten untuk 1D
# Debug dimensi sebelum hstack
logger.info(f"Dimensi job_jurusan_vectors: {job_jurusan_vectors.shape}")
logger.info(f"Dimensi job_keterampilan_vectors: {job_keterampilan_vectors.shape}")
logger.info(f"Dimensi job_minat_vectors: {job_minat_vectors.shape}")
logger.info(f"Dimensi job_gpa: {job_gpa.shape}")
# Gabungkan semua vektor jobs
job_vectors = np.hstack([
job_jurusan_vectors,
job_keterampilan_vectors,
job_minat_vectors,
job_gpa.reshape(-1, 1) # Reshape untuk konsistensi
])
# Buat vektor user
user_jurusan_vector = to_one_hot(jurusan, all_jurusan)
user_keterampilan_vector = to_one_hot(keterampilan, all_keterampilan)
user_minat_vector = to_one_hot(minat, all_minat)
# Debug dimensi user vectors
logger.info(f"Dimensi user_jurusan_vector: {user_jurusan_vector.shape}")
logger.info(f"Dimensi user_keterampilan_vector: {user_keterampilan_vector.shape}")
logger.info(f"Dimensi user_minat_vector: {user_minat_vector.shape}")
logger.info(f"Dimensi user_gpa: {user_gpa.shape}")
# Gabungkan vektor user
user_vector = np.hstack([
user_jurusan_vector,
user_keterampilan_vector,
user_minat_vector,
user_gpa
])
logger.info(f"Dimensi final job_vectors: {job_vectors.shape}")
logger.info(f"Dimensi final user_vector: {user_vector.shape}")
return job_vectors, user_vector, all_jurusan, all_keterampilan, all_minat
except Exception as e:
logger.error(f"Error dalam preprocess_data: {e}")
import traceback
logger.error(f"Traceback: {traceback.format_exc()}")
raise
def recommend_jobs(job_vectors, user_vector, jobs, ipk, top_n=3):
try:
eligible_jobs = jobs[jobs['min_ipk'] <= ipk].copy()
if eligible_jobs.empty:
logger.info(f"Tidak ada pekerjaan yang memenuhi syarat untuk IPK {ipk}")
return eligible_jobs
eligible_indices = eligible_jobs.index
eligible_job_vectors = job_vectors[eligible_indices]
# Reshape user_vector untuk cosine_similarity
user_vector_reshaped = user_vector.reshape(1, -1)
logger.info(f"Dimensi eligible_job_vectors: {eligible_job_vectors.shape}")
logger.info(f"Dimensi user_vector_reshaped: {user_vector_reshaped.shape}")
similarity_scores = cosine_similarity(user_vector_reshaped, eligible_job_vectors)
top_indices = np.argsort(similarity_scores[0])[::-1][:min(top_n, len(eligible_jobs))]
recommendations = eligible_jobs.iloc[top_indices].copy()
recommendations['similarity_score'] = similarity_scores[0][top_indices]
logger.info(f"Rekomendasi untuk IPK {ipk}: {len(recommendations)} pekerjaan ditemukan")
return recommendations
except Exception as e:
logger.error(f"Error dalam recommend_jobs: {e}")
import traceback
logger.error(f"Traceback: {traceback.format_exc()}")
raise
@app.route('/')
def index():
return render_template('index.html')
@app.route('/recommend', methods=['POST'])
def recommend():
try:
# Debug: Print semua data yang diterima
logger.info("=== DEBUG: Data yang diterima dari form ===")
for key, value in request.form.items():
logger.info(f"{key}: '{value}' (type: {type(value)}, len: {len(value)})")
nama = request.form['nama'].strip()
ipk_input = request.form['ipk'].strip()
jurusan = request.form['jurusan'].strip().lower() or 'teknik informatika'
keterampilan = request.form['keterampilan'].strip().lower() or 'python'
minat = request.form['minat'].strip().lower() or 'investigative (analitis)'
logger.info(f"=== DEBUG: Data setelah processing ===")
logger.info(f"nama: '{nama}'")
logger.info(f"ipk_input: '{ipk_input}'")
logger.info(f"jurusan: '{jurusan}'")
logger.info(f"keterampilan: '{keterampilan}'")
logger.info(f"minat: '{minat}'")
# Debug: Cek apakah IPK kosong atau None
if not ipk_input:
logger.error("IPK input kosong!")
return render_template('index.html', error="IPK tidak boleh kosong!")
# Replace koma dengan titik
ipk_input = ipk_input.replace(',', '.')
logger.info(f"IPK setelah replace koma: '{ipk_input}'")
# Coba konversi ke float
try:
ipk = float(ipk_input)
logger.info(f"IPK berhasil dikonversi: {ipk} (type: {type(ipk)})")
except ValueError as e:
logger.error(f"Gagal konversi IPK '{ipk_input}' ke float: {e}")
return render_template('index.html', error=f"IPK harus berupa angka desimal yang valid (contoh: 3.50)! Input: '{ipk_input}'")
# Validasi range IPK
if not (0.0 <= ipk <= 4.0):
logger.warning(f"IPK {ipk} tidak valid, harus antara 0.0 dan 4.0")
return render_template('index.html', error=f"IPK harus antara 0.0 dan 4.0! IPK Anda: {ipk}")
# Validasi dropdown
if not jurusan or not keterampilan or not minat:
logger.warning("Salah satu dropdown tidak dipilih")
logger.warning(f"jurusan: '{jurusan}', keterampilan: '{keterampilan}', minat: '{minat}'")
return render_template('index.html', error="Harap pilih jurusan, keterampilan, dan minat!")
logger.info("Semua validasi berhasil, memproses rekomendasi...")
logger.info("Loading jobs.xlsx")
jobs = load_data('jobs.xlsx')
logger.info("Preprocessing data")
job_vectors, user_vector, _, _, _ = preprocess_data(jobs, ipk, jurusan, keterampilan, minat)
logger.info("Generating recommendations")
recommendations = recommend_jobs(job_vectors, user_vector, jobs, ipk)
logger.info(f"Recommendations generated: {len(recommendations)} jobs")
return render_template('result.html',
user_name=nama,
user_ipk=ipk,
user_jurusan=jurusan,
user_keterampilan=keterampilan,
user_minat=minat,
recommendations=recommendations.to_dict(orient='records'))
except ValueError as e:
logger.error(f"ValueError: {e}")
return render_template('index.html', error=f"Terjadi kesalahan pemrosesan data: {str(e)}")
except FileNotFoundError as e:
logger.error(f"FileNotFoundError: {e}")
return render_template('index.html', error="File jobs.xlsx tidak ditemukan!")
except jinja2.exceptions.TemplateNotFound as e:
logger.error(f"TemplateNotFound: {e}")
return render_template('index.html', error=f"Template {e} tidak ditemukan!")
except jinja2.exceptions.TemplateSyntaxError as e:
logger.error(f"TemplateSyntaxError: {e}")
return render_template('index.html', error=f"Kesalahan sintaks di template: {e}")
except Exception as e:
logger.error(f"Unexpected error: {e}")
import traceback
logger.error(f"Traceback: {traceback.format_exc()}")
return render_template('index.html', error=f"Terjadi kesalahan: {e}")
if __name__ == '__main__':
app.run(debug=True)

120
student.csv Normal file
View File

@ -0,0 +1,120 @@
NIM,IPK,Jurusan,dream job,keterampilan,minat
1,3.78,Teknik Informatika,Mobile App Developer,Java,Artistic (Kreatif)
2,3.50,Teknik Informatika,Data Scientist,Statistik,Investigative (Analitis)
3,3.83,Teknik Informatika,UI/UX Designer,Desain,Artistic (Kreatif)
4,3.91,Teknik Informatika,Backend Developer,Node.js,Conventional (Terstruktur)
5,3.83,Teknik Informatika,IT Support Specialist,Dukungan Teknis Perangkat Keras dan Perangkat Lunak,Social (Sosial)
6,3.64,Teknik Informatika,Web Developer,Javascript,Artistic (Kreatif)
7,3.63,Teknik Informatika,Cloud Engineer,Manajemen Penyimpanan Database,"Realistic (Praktis, Teknis)"
8,3.88,Teknik Informatika,Data Analyst,Visualisasi Data,Investigative (Analitis)
9,3.64,Teknik Informatika,Cybersecurity Analyst,Troubleshooting,Enterprising (Memimpin)
10,3.72,Teknik Informatika,Software Engineer,Pemrograman,Conventional (Terstruktur)
11,3.58,Teknik Informatika,Game Developer,C#,Artistic (Kreatif)
12,3.8,Teknik Informatika,DevOps Engineer,Ruby,"Realistic (Praktis, Teknis)"
13,3.52,Teknik Informatika,Database Administrator,SQL,"Realistic (Praktis, Teknis)"
14,3.68,Teknik Informatika,IT Project Manager,Manajemen Proyek,Social (Sosial)
15,3.56,Teknik Informatika,Machine Learning Engineer,Python,Investigative (Analitis)
16,3.79,Teknik Informatika,Business Intelligence Developer,Analisis Data,Investigative (Analitis)
17,3.77,Teknik Informatika,Frontend Developer,CSS,Artistic (Kreatif)
18,3.6,Teknik Informatika,Network Administrator,Administrasi Jaringan,"Realistic (Praktis, Teknis)"
19,3.68,Teknik Informatika,Data Engineer,Database,Investigative (Analitis)
20,3.34,Teknik Informatika,Quality Assurance,Dokumentasi Kasus Uji,Conventional (Terstruktur)
21,3.76,Teknik Informatika,Data Analyst,Spreadsheet,Investigative (Analitis)
22,3.87,Teknik Informatika,Web Developer,HTML,Artistic (Kreatif)
23,3.69,Teknik Informatika,Software Engineer,Pemrograman,Conventional (Terstruktur)
24,3.69,Teknik Informatika,Mobile App Developer,Kotlin,Artistic (Kreatif)
25,3.61,Teknik Informatika,Frontend Developer,JavaScript,Artistic (Kreatif)
26,3.89,Teknik Informatika,Data Scientist,Python,Investigative (Analitis)
27,3.08,Teknik Informatika,DevOps Engineer,Cloud Operation,"Realistic (Praktis, Teknis)"
28,3.46,Teknik Informatika,UI/UX Designer,Desain,Artistic (Kreatif)
29,3.5,Teknik Informatika,Cybersecurity Analyst,Keamanan Digital,Enterprising (Memimpin)
30,3.21,Teknik Informatika,Backend Developer,Java,Conventional (Terstruktur)
31,3.36,Teknik Informatika,Cloud Engineer,Manajemen Penyimpanan Database,"Realistic (Praktis, Teknis)"
32,3.48,Teknik Informatika,IT Support Specialist,Dukungan Teknis Perangkat Keras dan Perangkat Lunak,Social (Sosial)
33,3.78,Teknik Informatika,Machine Learning Engineer,Preprocessing Data,Investigative (Analitis)
34,3.64,Teknik Informatika,Database Administrator,SQL,"Realistic (Praktis, Teknis)"
35,3.78,Teknik Informatika,Business Intelligence Developer,Pemahaman Operasi Bisnis,Investigative (Analitis)
36,3.2,Teknik Informatika,Game Developer,Unreal Engine,Artistic (Kreatif)
37,3.54,Teknik Informatika,Data Engineer,Database,Investigative (Analitis)
38,3.79,Teknik Informatika,IT Project Manager,Manajemen Proyek,Enterprising (Memimpin)
39,3.53,Teknik Informatika,Network Administrator,Administrasi Jaringan,"Realistic (Praktis, Teknis)"
40,3.78,Teknik Informatika,Quality Assurance,Manajemen Waktu,Conventional (Terstruktur)
41,3.71,Teknik Informatika,Web Developer,CSS,Artistic (Kreatif)
42,3.66,Teknik Informatika,Data Analyst,Analisis Data,Investigative (Analitis)
43,3.58,Teknik Informatika,Software Engineer,Pemrograman,Artistic (Kreatif)
44,3.1,Teknik Informatika,Frontend Developer,JavaScript,Artistic (Kreatif)
45,2.93,Teknik Informatika,Mobile App Developer,Swift,Artistic (Kreatif)
46,3.06,Teknik Informatika,Backend Developer,Azure,Conventional (Terstruktur)
47,3.83,Teknik Informatika,DevOps Engineer,Ruby,"Realistic (Praktis, Teknis)"
48,3.63,Teknik Informatika,UI/UX Designer,Desain,Artistic (Kreatif)
49,3.63,Teknik Informatika,Cybersecurity Analyst,Troubleshooting,Investigative (Analitis)
50,3.48,Teknik Informatika,Data Scientist,Statistik,Investigative (Analitis)
51,3.86,Teknik Informatika,Cloud Engineer,Manajemen Penyimpanan Database,"Realistic (Praktis, Teknis)"
52,3.62,Teknik Informatika,Network Administrator,Troubleshooting,"Realistic (Praktis, Teknis)"
53,3.58,Teknik Informatika,Machine Learning Engineer,Machine Learning,Investigative (Analitis)
54,3.5,Teknik Informatika,IT Project Manager,Manajemen Proyek,Social (Sosial)
55,3.13,Teknik Informatika,Business Intelligence Developer,Visualisasi Data,Investigative (Analitis)
56,3.45,Teknik Informatika,Game Developer,C++,Artistic (Kreatif)
57,3.81,Teknik Informatika,Data Engineer,SQL,Conventional (Terstruktur)
58,3.23,Teknik Informatika,IT Support Specialist,Dukungan Teknis Perangkat Keras dan Perangkat Lunak,Social (Sosial)
59,2.97,Teknik Informatika,Database Administrator,Database,"Realistic (Praktis, Teknis)"
60,3.19,Teknik Informatika,Quality Assurance,Pengujian Perangkat Lunak,Conventional (Terstruktur)
61,3.24,Teknik Informatika,Data Analyst,Analisis Data,Investigative (Analitis)
62,3.3,Teknik Informatika,Web Developer,Javascript,Artistic (Kreatif)
63,3.51,Teknik Informatika,Software Engineer,Pemrograman,Artistic (Kreatif)
64,3.77,Teknik Informatika,Data Scientist,Machine Learning,Investigative (Analitis)
65,3.78,Teknik Informatika,Frontend Developer,HTML,Artistic (Kreatif)
66,3.71,Teknik Informatika,Backend Developer,Java,Conventional (Terstruktur)
67,3.74,Teknik Informatika,DevOps Engineer,Python,"Realistic (Praktis, Teknis)"
68,3.92,Teknik Informatika,UI/UX Designer,Desain,Artistic (Kreatif)
69,3.95,Teknik Informatika,Cybersecurity Analyst,Troubleshooting,Investigative (Analitis)
70,3.93,Teknik Informatika,Mobile App Developer,Java,Artistic (Kreatif)
71,3.85,Teknik Informatika,Cloud Engineer,Manajemen Penyimpanan Database,"Realistic (Praktis, Teknis)"
72,3.56,Teknik Informatika,Network Administrator,Administrasi Jaringan,"Realistic (Praktis, Teknis)"
73,3.63,Teknik Informatika,Machine Learning Engineer,Python,Investigative (Analitis)
74,3.9,Teknik Informatika,IT Project Manager,Manajemen Proyek,Social (Sosial)
75,3.81,Teknik Informatika,Business Intelligence Developer,Visualisasi Data,Investigative (Analitis)
76,3.55,Teknik Informatika,Game Developer,Unity,Artistic (Kreatif)
77,3.89,Teknik Informatika,Data Engineer,Database,"Realistic (Praktis, Teknis)"
78,3.75,Teknik Informatika,IT Support Specialist,Dukungan Teknis Perangkat Keras dan Perangkat Lunak,Social (Sosial)
79,3.53,Teknik Informatika,Database Administrator,SQL,"Realistic (Praktis, Teknis)"
80,3.8,Teknik Informatika,Quality Assurance,Manajemen Waktu,Conventional (Terstruktur)
81,3.9,Teknik Informatika,Data Analyst,Visualisasi Data,Investigative (Analitis)
82,3.68,Teknik Informatika,Web Developer,Javascript,Artistic (Kreatif)
83,3.71,Teknik Informatika,Software Engineer,Pemrograman,Artistic (Kreatif)
84,3.76,Teknik Informatika,Data Scientist,Machine Learning,Investigative (Analitis)
85,3.56,Teknik Informatika,Frontend Developer,React,Artistic (Kreatif)
86,3.58,Teknik Informatika,Backend Developer,Python,Investigative (Analitis)
87,3.93,Teknik Informatika,DevOps Engineer,Cloud Operation,"Realistic (Praktis, Teknis)"
88,3.44,Teknik Informatika,UI/UX Designer,Desain,Artistic (Kreatif)
89,3.92,Teknik Informatika,Cybersecurity Analyst,Keamanan Digital,"Realistic (Praktis, Teknis)"
90,3.45,Teknik Informatika,Mobile App Developer,Kotlin,Artistic (Kreatif)
91,3.62,Teknik Informatika,Cloud Engineer,Manajemen Penyimpanan Database,Conventional (Terstruktur)
92,3.95,Teknik Informatika,Network Administrator,Troubleshooting,"Realistic (Praktis, Teknis)"
93,3.76,Teknik Informatika,Machine Learning Engineer,Python,Investigative (Analitis)
94,3.76,Teknik Informatika,IT Project Manager,Manajemen Proyek,Social (Sosial)
95,3.76,Teknik Informatika,Business Intelligence Developer,Visualisasi Data,Investigative (Analitis)
96,3.92,Teknik Informatika,Game Developer,C#,Artistic (Kreatif)
97,3.65,Teknik Informatika,Data Engineer,Database,"Realistic (Praktis, Teknis)"
98,3.86,Teknik Informatika,IT Support Specialist,Dukungan Teknis Perangkat Keras dan Perangkat Lunak,Social (Sosial)
99,3.81,Teknik Informatika,Database Administrator,SQL,"Realistic (Praktis, Teknis)"
100,3.89,Teknik Informatika,Quality Assurance,Manajemen Waktu,Conventional (Terstruktur)
101,3.54,Teknik Informatika,Data Analyst,Python,Investigative (Analitis)
102,3.5,Teknik Informatika,Web Developer,Javascript,Artistic (Kreatif)
103,3.77,Teknik Informatika,Software Engineer,Pemrograman,Conventional (Terstruktur)
104,3.81,Teknik Informatika,Data Scientist,Statistik,Investigative (Analitis)
105,3.79,Teknik Informatika,Frontend Developer,JavaScript,Artistic (Kreatif)
106,3.6,Teknik Informatika,Backend Developer,Node.js,"Realistic (Praktis, Teknis)"
107,3.69,Teknik Informatika,DevOps Engineer,Ruby,"Realistic (Praktis, Teknis)"
108,3.19,Teknik Informatika,UI/UX Designer,Desain,Artistic (Kreatif)
109,3.29,Teknik Informatika,Cybersecurity Analyst,Keamanan Digital,Conventional (Terstruktur)
110,3.58,Teknik Informatika,Mobile App Developer,Kotlin ,Artistic (Kreatif)
111,3.47,Teknik Informatika,Cloud Engineer,Manajemen Penyimpanan Database,"Realistic (Praktis, Teknis)"
112,3.88,Teknik Informatika,Network Administrator,Administrasi Jaringan,"Realistic (Praktis, Teknis)"
113,3.76,Teknik Informatika,Machine Learning Engineer,Machine Learning,Investigative (Analitis)
114,3.57,Teknik Informatika,IT Project Manager,Manajemen Proyek,Enterprising (Memimpin)
115,3.7,Teknik Informatika,Business Intelligence Developer,Pemahaman Operasi Bisnis,Investigative (Analitis)
116,3.78,Teknik Informatika,Game Developer,C++,Artistic (Kreatif)
117,3.82,Teknik Informatika,Data Engineer,SQL,Investigative (Analitis)
118,3.72,Teknik Informatika,IT Support Specialist,Dukungan Teknis Perangkat Keras dan Perangkat Lunak,Social (Sosial)
119,3.78,Teknik Informatika,Data Analyst,Analisis Data,Investigative (Analitis)
1 NIM IPK Jurusan dream job keterampilan minat
2 1 3.78 Teknik Informatika Mobile App Developer Java Artistic (Kreatif)
3 2 3.50 Teknik Informatika Data Scientist Statistik Investigative (Analitis)
4 3 3.83 Teknik Informatika UI/UX Designer Desain Artistic (Kreatif)
5 4 3.91 Teknik Informatika Backend Developer Node.js Conventional (Terstruktur)
6 5 3.83 Teknik Informatika IT Support Specialist Dukungan Teknis Perangkat Keras dan Perangkat Lunak Social (Sosial)
7 6 3.64 Teknik Informatika Web Developer Javascript Artistic (Kreatif)
8 7 3.63 Teknik Informatika Cloud Engineer Manajemen Penyimpanan Database Realistic (Praktis, Teknis)
9 8 3.88 Teknik Informatika Data Analyst Visualisasi Data Investigative (Analitis)
10 9 3.64 Teknik Informatika Cybersecurity Analyst Troubleshooting Enterprising (Memimpin)
11 10 3.72 Teknik Informatika Software Engineer Pemrograman Conventional (Terstruktur)
12 11 3.58 Teknik Informatika Game Developer C# Artistic (Kreatif)
13 12 3.8 Teknik Informatika DevOps Engineer Ruby Realistic (Praktis, Teknis)
14 13 3.52 Teknik Informatika Database Administrator SQL Realistic (Praktis, Teknis)
15 14 3.68 Teknik Informatika IT Project Manager Manajemen Proyek Social (Sosial)
16 15 3.56 Teknik Informatika Machine Learning Engineer Python Investigative (Analitis)
17 16 3.79 Teknik Informatika Business Intelligence Developer Analisis Data Investigative (Analitis)
18 17 3.77 Teknik Informatika Frontend Developer CSS Artistic (Kreatif)
19 18 3.6 Teknik Informatika Network Administrator Administrasi Jaringan Realistic (Praktis, Teknis)
20 19 3.68 Teknik Informatika Data Engineer Database Investigative (Analitis)
21 20 3.34 Teknik Informatika Quality Assurance Dokumentasi Kasus Uji Conventional (Terstruktur)
22 21 3.76 Teknik Informatika Data Analyst Spreadsheet Investigative (Analitis)
23 22 3.87 Teknik Informatika Web Developer HTML Artistic (Kreatif)
24 23 3.69 Teknik Informatika Software Engineer Pemrograman Conventional (Terstruktur)
25 24 3.69 Teknik Informatika Mobile App Developer Kotlin Artistic (Kreatif)
26 25 3.61 Teknik Informatika Frontend Developer JavaScript Artistic (Kreatif)
27 26 3.89 Teknik Informatika Data Scientist Python Investigative (Analitis)
28 27 3.08 Teknik Informatika DevOps Engineer Cloud Operation Realistic (Praktis, Teknis)
29 28 3.46 Teknik Informatika UI/UX Designer Desain Artistic (Kreatif)
30 29 3.5 Teknik Informatika Cybersecurity Analyst Keamanan Digital Enterprising (Memimpin)
31 30 3.21 Teknik Informatika Backend Developer Java Conventional (Terstruktur)
32 31 3.36 Teknik Informatika Cloud Engineer Manajemen Penyimpanan Database Realistic (Praktis, Teknis)
33 32 3.48 Teknik Informatika IT Support Specialist Dukungan Teknis Perangkat Keras dan Perangkat Lunak Social (Sosial)
34 33 3.78 Teknik Informatika Machine Learning Engineer Preprocessing Data Investigative (Analitis)
35 34 3.64 Teknik Informatika Database Administrator SQL Realistic (Praktis, Teknis)
36 35 3.78 Teknik Informatika Business Intelligence Developer Pemahaman Operasi Bisnis Investigative (Analitis)
37 36 3.2 Teknik Informatika Game Developer Unreal Engine Artistic (Kreatif)
38 37 3.54 Teknik Informatika Data Engineer Database Investigative (Analitis)
39 38 3.79 Teknik Informatika IT Project Manager Manajemen Proyek Enterprising (Memimpin)
40 39 3.53 Teknik Informatika Network Administrator Administrasi Jaringan Realistic (Praktis, Teknis)
41 40 3.78 Teknik Informatika Quality Assurance Manajemen Waktu Conventional (Terstruktur)
42 41 3.71 Teknik Informatika Web Developer CSS Artistic (Kreatif)
43 42 3.66 Teknik Informatika Data Analyst Analisis Data Investigative (Analitis)
44 43 3.58 Teknik Informatika Software Engineer Pemrograman Artistic (Kreatif)
45 44 3.1 Teknik Informatika Frontend Developer JavaScript Artistic (Kreatif)
46 45 2.93 Teknik Informatika Mobile App Developer Swift Artistic (Kreatif)
47 46 3.06 Teknik Informatika Backend Developer Azure Conventional (Terstruktur)
48 47 3.83 Teknik Informatika DevOps Engineer Ruby Realistic (Praktis, Teknis)
49 48 3.63 Teknik Informatika UI/UX Designer Desain Artistic (Kreatif)
50 49 3.63 Teknik Informatika Cybersecurity Analyst Troubleshooting Investigative (Analitis)
51 50 3.48 Teknik Informatika Data Scientist Statistik Investigative (Analitis)
52 51 3.86 Teknik Informatika Cloud Engineer Manajemen Penyimpanan Database Realistic (Praktis, Teknis)
53 52 3.62 Teknik Informatika Network Administrator Troubleshooting Realistic (Praktis, Teknis)
54 53 3.58 Teknik Informatika Machine Learning Engineer Machine Learning Investigative (Analitis)
55 54 3.5 Teknik Informatika IT Project Manager Manajemen Proyek Social (Sosial)
56 55 3.13 Teknik Informatika Business Intelligence Developer Visualisasi Data Investigative (Analitis)
57 56 3.45 Teknik Informatika Game Developer C++ Artistic (Kreatif)
58 57 3.81 Teknik Informatika Data Engineer SQL Conventional (Terstruktur)
59 58 3.23 Teknik Informatika IT Support Specialist Dukungan Teknis Perangkat Keras dan Perangkat Lunak Social (Sosial)
60 59 2.97 Teknik Informatika Database Administrator Database Realistic (Praktis, Teknis)
61 60 3.19 Teknik Informatika Quality Assurance Pengujian Perangkat Lunak Conventional (Terstruktur)
62 61 3.24 Teknik Informatika Data Analyst Analisis Data Investigative (Analitis)
63 62 3.3 Teknik Informatika Web Developer Javascript Artistic (Kreatif)
64 63 3.51 Teknik Informatika Software Engineer Pemrograman Artistic (Kreatif)
65 64 3.77 Teknik Informatika Data Scientist Machine Learning Investigative (Analitis)
66 65 3.78 Teknik Informatika Frontend Developer HTML Artistic (Kreatif)
67 66 3.71 Teknik Informatika Backend Developer Java Conventional (Terstruktur)
68 67 3.74 Teknik Informatika DevOps Engineer Python Realistic (Praktis, Teknis)
69 68 3.92 Teknik Informatika UI/UX Designer Desain Artistic (Kreatif)
70 69 3.95 Teknik Informatika Cybersecurity Analyst Troubleshooting Investigative (Analitis)
71 70 3.93 Teknik Informatika Mobile App Developer Java Artistic (Kreatif)
72 71 3.85 Teknik Informatika Cloud Engineer Manajemen Penyimpanan Database Realistic (Praktis, Teknis)
73 72 3.56 Teknik Informatika Network Administrator Administrasi Jaringan Realistic (Praktis, Teknis)
74 73 3.63 Teknik Informatika Machine Learning Engineer Python Investigative (Analitis)
75 74 3.9 Teknik Informatika IT Project Manager Manajemen Proyek Social (Sosial)
76 75 3.81 Teknik Informatika Business Intelligence Developer Visualisasi Data Investigative (Analitis)
77 76 3.55 Teknik Informatika Game Developer Unity Artistic (Kreatif)
78 77 3.89 Teknik Informatika Data Engineer Database Realistic (Praktis, Teknis)
79 78 3.75 Teknik Informatika IT Support Specialist Dukungan Teknis Perangkat Keras dan Perangkat Lunak Social (Sosial)
80 79 3.53 Teknik Informatika Database Administrator SQL Realistic (Praktis, Teknis)
81 80 3.8 Teknik Informatika Quality Assurance Manajemen Waktu Conventional (Terstruktur)
82 81 3.9 Teknik Informatika Data Analyst Visualisasi Data Investigative (Analitis)
83 82 3.68 Teknik Informatika Web Developer Javascript Artistic (Kreatif)
84 83 3.71 Teknik Informatika Software Engineer Pemrograman Artistic (Kreatif)
85 84 3.76 Teknik Informatika Data Scientist Machine Learning Investigative (Analitis)
86 85 3.56 Teknik Informatika Frontend Developer React Artistic (Kreatif)
87 86 3.58 Teknik Informatika Backend Developer Python Investigative (Analitis)
88 87 3.93 Teknik Informatika DevOps Engineer Cloud Operation Realistic (Praktis, Teknis)
89 88 3.44 Teknik Informatika UI/UX Designer Desain Artistic (Kreatif)
90 89 3.92 Teknik Informatika Cybersecurity Analyst Keamanan Digital Realistic (Praktis, Teknis)
91 90 3.45 Teknik Informatika Mobile App Developer Kotlin Artistic (Kreatif)
92 91 3.62 Teknik Informatika Cloud Engineer Manajemen Penyimpanan Database Conventional (Terstruktur)
93 92 3.95 Teknik Informatika Network Administrator Troubleshooting Realistic (Praktis, Teknis)
94 93 3.76 Teknik Informatika Machine Learning Engineer Python Investigative (Analitis)
95 94 3.76 Teknik Informatika IT Project Manager Manajemen Proyek Social (Sosial)
96 95 3.76 Teknik Informatika Business Intelligence Developer Visualisasi Data Investigative (Analitis)
97 96 3.92 Teknik Informatika Game Developer C# Artistic (Kreatif)
98 97 3.65 Teknik Informatika Data Engineer Database Realistic (Praktis, Teknis)
99 98 3.86 Teknik Informatika IT Support Specialist Dukungan Teknis Perangkat Keras dan Perangkat Lunak Social (Sosial)
100 99 3.81 Teknik Informatika Database Administrator SQL Realistic (Praktis, Teknis)
101 100 3.89 Teknik Informatika Quality Assurance Manajemen Waktu Conventional (Terstruktur)
102 101 3.54 Teknik Informatika Data Analyst Python Investigative (Analitis)
103 102 3.5 Teknik Informatika Web Developer Javascript Artistic (Kreatif)
104 103 3.77 Teknik Informatika Software Engineer Pemrograman Conventional (Terstruktur)
105 104 3.81 Teknik Informatika Data Scientist Statistik Investigative (Analitis)
106 105 3.79 Teknik Informatika Frontend Developer JavaScript Artistic (Kreatif)
107 106 3.6 Teknik Informatika Backend Developer Node.js Realistic (Praktis, Teknis)
108 107 3.69 Teknik Informatika DevOps Engineer Ruby Realistic (Praktis, Teknis)
109 108 3.19 Teknik Informatika UI/UX Designer Desain Artistic (Kreatif)
110 109 3.29 Teknik Informatika Cybersecurity Analyst Keamanan Digital Conventional (Terstruktur)
111 110 3.58 Teknik Informatika Mobile App Developer Kotlin Artistic (Kreatif)
112 111 3.47 Teknik Informatika Cloud Engineer Manajemen Penyimpanan Database Realistic (Praktis, Teknis)
113 112 3.88 Teknik Informatika Network Administrator Administrasi Jaringan Realistic (Praktis, Teknis)
114 113 3.76 Teknik Informatika Machine Learning Engineer Machine Learning Investigative (Analitis)
115 114 3.57 Teknik Informatika IT Project Manager Manajemen Proyek Enterprising (Memimpin)
116 115 3.7 Teknik Informatika Business Intelligence Developer Pemahaman Operasi Bisnis Investigative (Analitis)
117 116 3.78 Teknik Informatika Game Developer C++ Artistic (Kreatif)
118 117 3.82 Teknik Informatika Data Engineer SQL Investigative (Analitis)
119 118 3.72 Teknik Informatika IT Support Specialist Dukungan Teknis Perangkat Keras dan Perangkat Lunak Social (Sosial)
120 119 3.78 Teknik Informatika Data Analyst Analisis Data Investigative (Analitis)

330
templates/index.html Normal file
View File

@ -0,0 +1,330 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>IPKMatcher</title>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
background-color: #f7ecda;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 20px;
box-sizing: border-box;
}
.container {
text-align: center;
width: 100%;
max-width: 400px;
padding: 20px;
background-color: white;
border-radius: 20px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 32px;
color: #4c2e2e;
margin-bottom: 10px;
}
.subtitle {
font-size: 16px;
color: #9c9c9c;
margin-bottom: 30px;
}
form {
display: flex;
flex-direction: column;
text-align: left;
}
label {
margin-bottom: 5px;
font-weight: 500;
color: #3e3e3e;
}
input, select {
padding: 12px;
margin-bottom: 20px;
border: none;
border-radius: 20px;
background-color: #c2bcb3;
color: #333;
font-size: 14px;
box-sizing: border-box;
}
input::placeholder {
color: #888;
}
select {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml;utf8,<svg fill='black' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>");
background-repeat: no-repeat;
background-position-x: 95%;
background-position-y: 50%;
cursor: pointer;
}
button {
padding: 12px;
border: none;
border-radius: 20px;
background-color: #4c2e2e;
color: white;
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #3b2222;
}
.error {
color: red;
margin-top: 10px;
padding: 10px;
background-color: #ffe6e6;
border-radius: 10px;
font-size: 14px;
text-align: center;
}
.debug-info {
background-color: #f0f8ff;
border: 1px solid #ccc;
padding: 10px;
margin-top: 10px;
border-radius: 5px;
font-size: 12px;
text-align: left;
}
</style>
</head>
<body>
<div class="container">
<h1><strong>IPKMatcher</strong></h1>
<p class="subtitle">Mulai tentukan karier Anda.</p>
<form id="recommendForm" action="/recommend" method="POST">
<label for="nama">Nama:</label>
<input type="text" id="nama" name="nama" placeholder="Masukkan Nama Anda" required value="">
<label for="ipk">IPK:</label>
<input type="number" id="ipk" name="ipk" step="0.01" min="0" max="4" placeholder="Masukkan IPK Anda" required>
<label for="jurusan">Jurusan:</label>
<select id="jurusan" name="jurusan" required>
<option value="" disabled selected>Pilih Jurusan</option>
<option value="teknik informatika">Teknik Informatika</option>
<option value="sistem informasi">Sistem Informasi</option>
<option value="matematika">Matematika</option>
<option value="teknik komputer">Teknik Komputer</option>
<option value="desain komunikasi visual">Desain Komunikasi Visual</option>
<option value="statistik">Statistik</option>
<option value="ilmu komputer">Ilmu Komputer</option>
</select>
<label for="keterampilan">Keterampilan:</label>
<select id="keterampilan" name="keterampilan" required>
<option value="" disabled selected>Pilih Keterampilan</option>
</select>
<label for="minat">Minat:</label>
<select id="minat" name="minat" required>
<option value="" disabled selected>Pilih Minat</option>
</select>
<button type="submit">Cari Rekomendasi</button>
</form>
{% if error %}
<div class="error">{{ error }}</div>
{% endif %}
</div>
<script>
const jurusanData = {
"teknik informatika": {
keterampilan: [
"Spreadsheet", "Python", "Analisis Data", "Visualisasi Data",
"Pengujian Perangkat Lunak", "Dokumentasi Kasus Uji", "Manajemen Waktu",
"HTML", "CSS", "Javascript", "Java", "Node.js", "SQL", "DevOps", "AWS", "Azure",
"React", "Angular", "Statistik", "Machine Learning", "Cloud Operation", "Ruby",
"Database", "Desain", "Pemrograman", "Keamanan Digital", "Troubleshooting",
"Kotlin", "Swift", "Objective-C", "R", "Preprocessing Data", "Penyebaran Model",
"Manajemen Proyek", "Pemahaman Operasi Bisnis", "Unity", "Unreal Engine", "C#", "C++"
],
minat: [
"Investigative (Analitis)", "Conventional (Terstruktur)", "Artistic (Kreatif)",
"Realistic (Praktis, Teknis)", "Enterprising (Memimpin)", "Social (Sosial)"
]
},
"sistem informasi": {
keterampilan: [
"Spreadsheet", "Python", "Analisis Data", "Visualisasi Data",
"Database", "SQL", "Manajemen Proyek", "Pemahaman Operasi Bisnis",
"Administrasi Jaringan", "Troubleshooting", "Dukungan Teknis Perangkat Keras dan Perangkat Lunak"
],
minat: ["Investigative (Analitis)", "Conventional (Terstruktur)", "Realistic (Praktis, Teknis)", "Social (Sosial)"]
},
"matematika": {
keterampilan: ["Spreadsheet", "Python", "Analisis Data", "Visualisasi Data", "Statistik", "Machine Learning", "R"],
minat: ["Investigative (Analitis)"]
},
"teknik komputer": {
keterampilan: [
"HTML", "CSS", "Javascript", "Python", "Java", "Node.js", "SQL", "DevOps", "AWS", "Azure",
"Cloud Operation", "Ruby", "Pemrograman", "Keamanan Digital", "Troubleshooting",
"Kotlin", "Swift", "Objective-C", "Administrasi Jaringan"
],
minat: ["Conventional (Terstruktur)", "Artistic (Kreatif)", "Realistic (Praktis, Teknis)", "Enterprising (Memimpin)"]
},
"desain komunikasi visual": {
keterampilan: ["HTML", "CSS", "Javascript", "React", "Angular", "Desain"],
minat: ["Artistic (Kreatif)"]
},
"statistik": {
keterampilan: ["Statistik", "Machine Learning", "Python", "R"],
minat: ["Investigative (Analitis)"]
},
"ilmu komputer": {
keterampilan: ["Database", "SQL"],
minat: ["Investigative (Analitis)"]
}
};
function updateDropdowns() {
const jurusanSelect = document.getElementById('jurusan');
const keterampilanSelect = document.getElementById('keterampilan');
const minatSelect = document.getElementById('minat');
const selectedJurusan = jurusanSelect.value;
// Reset dropdowns
keterampilanSelect.innerHTML = '';
minatSelect.innerHTML = '';
// Add default options
const defaultKeterampilanOption = document.createElement('option');
defaultKeterampilanOption.value = '';
defaultKeterampilanOption.text = 'Pilih Keterampilan';
defaultKeterampilanOption.disabled = true;
defaultKeterampilanOption.selected = true;
keterampilanSelect.appendChild(defaultKeterampilanOption);
const defaultMinatOption = document.createElement('option');
defaultMinatOption.value = '';
defaultMinatOption.text = 'Pilih Minat';
defaultMinatOption.disabled = true;
defaultMinatOption.selected = true;
minatSelect.appendChild(defaultMinatOption);
if (selectedJurusan && jurusanData[selectedJurusan]) {
const { keterampilan, minat } = jurusanData[selectedJurusan];
// Populate keterampilan
keterampilan.forEach(skill => {
const option = document.createElement('option');
option.value = skill.toLowerCase();
option.text = skill;
keterampilanSelect.appendChild(option);
});
// Populate minat
minat.forEach(interest => {
const option = document.createElement('option');
option.value = interest.toLowerCase();
option.text = interest;
minatSelect.appendChild(option);
});
}
}
// Form validation
document.getElementById('recommendForm').addEventListener('submit', function(event) {
const namaInput = document.getElementById('nama').value.trim();
const ipkInput = document.getElementById('ipk').value.trim();
const jurusanSelect = document.getElementById('jurusan').value;
const keterampilanSelect = document.getElementById('keterampilan').value;
const minatSelect = document.getElementById('minat').value;
console.log('Form submission data:', {
nama: namaInput,
ipk: ipkInput,
jurusan: jurusanSelect,
keterampilan: keterampilanSelect,
minat: minatSelect
});
// Check if all fields are filled
if (!namaInput) {
event.preventDefault();
alert('Nama harus diisi!');
return;
}
if (!ipkInput) {
event.preventDefault();
alert('IPK harus diisi!');
return;
}
// Validate IPK format
const ipkValue = ipkInput.replace(',', '.');
const ipk = parseFloat(ipkValue);
if (isNaN(ipk)) {
event.preventDefault();
alert('IPK harus berupa angka yang valid!');
return;
}
if (ipk < 0 || ipk > 4) {
event.preventDefault();
alert('IPK harus antara 0.0 dan 4.0!');
return;
}
if (!jurusanSelect) {
event.preventDefault();
alert('Harap pilih jurusan!');
return;
}
if (!keterampilanSelect) {
event.preventDefault();
alert('Harap pilih keterampilan!');
return;
}
if (!minatSelect) {
event.preventDefault();
alert('Harap pilih minat!');
return;
}
console.log('Form validation passed, submitting...');
});
// Initialize dropdowns on page load
document.addEventListener('DOMContentLoaded', function() {
updateDropdowns();
});
// Update dropdowns when jurusan changes
document.getElementById('jurusan').addEventListener('change', updateDropdowns);
</script>
</body>
</html>

159
templates/result.html Normal file
View File

@ -0,0 +1,159 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hasil Rekomendasi - IPKMatcher</title>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
background-color: #f7ecda;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
background-color: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 32px;
color: #4c2e2e;
text-align: center;
margin-bottom: 10px;
}
.user-info {
background-color: #f8f9fa;
padding: 20px;
border-radius: 15px;
margin-bottom: 30px;
}
.user-info h2 {
color: #4c2e2e;
margin-bottom: 15px;
}
.user-info p {
margin: 5px 0;
color: #333;
}
.recommendations {
margin-top: 30px;
}
.recommendations h2 {
color: #4c2e2e;
margin-bottom: 20px;
}
.job-card {
background-color: #f8f9fa;
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
border-left: 5px solid #4c2e2e;
}
.job-title {
font-size: 20px;
font-weight: bold;
color: #4c2e2e;
margin-bottom: 10px;
}
.job-desc {
color: #555;
margin-bottom: 10px;
line-height: 1.5;
}
.job-details {
font-size: 14px;
color: #777;
}
.similarity-score {
background-color: #4c2e2e;
color: white;
padding: 5px 10px;
border-radius: 20px;
font-size: 12px;
display: inline-block;
margin-top: 10px;
}
.back-button {
display: inline-block;
padding: 12px 24px;
background-color: #4c2e2e;
color: white;
text-decoration: none;
border-radius: 20px;
margin-top: 20px;
text-align: center;
}
.back-button:hover {
background-color: #3b2222;
}
.no-results {
text-align: center;
color: #777;
font-style: italic;
padding: 40px;
}
</style>
</head>
<body>
<div class="container">
<h1><strong>IPKMatcher</strong></h1>
<div class="user-info">
<h2>Profil Anda</h2>
<p><strong>Nama:</strong> {{ user_name }}</p>
<p><strong>IPK:</strong> {{ user_ipk }}</p>
<p><strong>Jurusan:</strong> {{ user_jurusan|title }}</p>
<p><strong>Keterampilan:</strong> {{ user_keterampilan|title }}</p>
<p><strong>Minat:</strong> {{ user_minat|title }}</p>
</div>
<div class="recommendations">
<h2>Rekomendasi Pekerjaan</h2>
{% if recommendations %}
{% for job in recommendations %}
<div class="job-card">
<div class="job-title">{{ job.job }}</div>
<div class="job-desc">{{ job.job_desc }}</div>
<div class="job-details">
<strong>IPK Minimum:</strong> {{ job.min_ipk }} |
<strong>Jurusan:</strong> {{ job.jurusan|title }} |
<strong>Keterampilan:</strong> {{ job.keterampilan|join(', ')|title }} |
<strong>Minat:</strong> {{ job.minat|title }}
</div>
<div class="similarity-score">
Kesesuaian: {{ "%.1f"|format(job.similarity_score * 100) }}%
</div>
</div>
{% endfor %}
{% else %}
<div class="no-results">
<p>Maaf, tidak ada pekerjaan yang sesuai dengan profil Anda.</p>
<p>Cobalah meningkatkan IPK atau mengembangkan keterampilan lain.</p>
</div>
{% endif %}
</div>
<a href="{{ url_for('index') }}" class="back-button">Kembali ke Beranda</a>
</div>
</body>
</html>