feat: initial commit project tracer study TA D4 TIF

This commit is contained in:
SyifaSyarifah 2026-10-29 14:08:07 +07:00
commit 8e94efc788
277 changed files with 67589 additions and 0 deletions

46
.gitignore vendored Normal file
View File

@ -0,0 +1,46 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.claude
# Python & Virtual Environments
venv/
ENV/
env/
.venv/
**/venv/
**/__pycache__/
*.py[cod]
*$py.class
Backend/venv/
# Environment Variables & Secrets
.env
*.env
!.env.example
Backend/.env
# Local logs
*.log
Backend/*.log

8
.oxlintrc.json Normal file
View File

@ -0,0 +1,8 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": ["react", "oxc"],
"rules": {
"react/rules-of-hooks": "error",
"react/only-export-components": ["warn", { "allowConstantExport": true }]
}
}

79
App.js Normal file
View File

@ -0,0 +1,79 @@
import { useEffect } from "react";
import { Routes, Route, Navigate, useNavigate, useLocation } from "react-router-dom";
import LoginPage from "./src/Login/login";
import Dashboard from "./src/dashboard";
import AlumniForm from "./src/form-alumni";
import ExportKlasifikasi from "./src/Export-Klasifikasi";
import ForgotPassword from "./src/forgot-password";
import ProsesKlasifikasi from "./src/proses-klasifikasi";
import ResetPassword from "./src/reset-password";
import TahunAngkatan from "./src/tahun-angkatan";
import ImportData from "./src/ImportData";
import KuesionerAlumni from "./src/kuesioner-alumni";
import KamusKataKunci from "./src/kamus-kata-kunci";
function ProtectedRoute({ children }) {
const navigate = useNavigate();
const location = useLocation();
useEffect(() => {
const checkAuth = () => {
const token = localStorage.getItem('token');
const username = localStorage.getItem('username');
if (!token || !username) {
navigate('/', { replace: true });
}
};
checkAuth();
// Dengarkan saat logout dari tab browser lain
const handleStorageChange = (e) => {
if (e.key === 'token' || e.key === 'username' || e.key === null) {
checkAuth();
}
};
window.addEventListener('storage', handleStorageChange);
return () => window.removeEventListener('storage', handleStorageChange);
}, [navigate, location]);
const token = localStorage.getItem('token');
const username = localStorage.getItem('username');
if (!token || !username) {
return <Navigate to="/" replace />;
}
return children;
}
function App() {
return (
<Routes>
{/* Rute Publik */}
<Route path="/" element={<LoginPage />} />
<Route path="/register" element={<Navigate to="/" replace />} />
<Route path="/forgot-password" element={<ForgotPassword />} />
<Route path="/reset-password" element={<ResetPassword />} />
<Route path="/kuesioner" element={<KuesionerAlumni />} />
<Route path="/tracer-study" element={<KuesionerAlumni />} />
{/* Rute Terproteksi (Wajib Login) */}
<Route path="/dashboard" element={<ProtectedRoute><Dashboard /></ProtectedRoute>} />
<Route path="/alumni" element={<ProtectedRoute><AlumniForm /></ProtectedRoute>} />
<Route path="/export-klasifikasi" element={<ProtectedRoute><ExportKlasifikasi /></ProtectedRoute>} />
<Route path="/proses-klasifikasi" element={<ProtectedRoute><ProsesKlasifikasi /></ProtectedRoute>} />
<Route path="/tahun-angkatan" element={<ProtectedRoute><TahunAngkatan /></ProtectedRoute>} />
<Route path="/import" element={<ProtectedRoute><ImportData standalone={true} /></ProtectedRoute>} />
<Route path="/keywords" element={<ProtectedRoute><KamusKataKunci standalone={true} /></ProtectedRoute>} />
<Route path="/kamus-kata-kunci" element={<ProtectedRoute><KamusKataKunci standalone={true} /></ProtectedRoute>} />
{/* Fallback jika route tidak ditemukan */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
);
}
export default App;

18
Backend/.env.example Normal file
View File

@ -0,0 +1,18 @@
# Application Config
APP_NAME="FastAPI TA Alumni"
DEBUG=True
API_PREFIX="/api/v1"
# Database Connection
# SQLite (Local Dev Default):
DATABASE_URL="sqlite:///./ta_database.db"
# PostgreSQL Example:
# DATABASE_URL="postgresql://username:password@localhost:5432/dbname"
# MySQL Example:
# DATABASE_URL="mysql+pymysql://username:password@localhost:3306/dbname"
# Security & JWT Token
# Generate a secure key: openssl rand -hex 32
JWT_SECRET_KEY="replace_this_with_a_very_long_random_hex_string_in_production"
JWT_ALGORITHM="HS256"
ACCESS_TOKEN_EXPIRE_MINUTES=1440

209
Backend/Model/README.md Normal file
View File

@ -0,0 +1,209 @@
# 🤖 Machine Learning Model
## Deskripsi
Model Machine Learning untuk clustering alumni berdasarkan kompetensi menggunakan Text Mining (TF-IDF) dan K-Means Clustering.
## Struktur Folder
```
Model/
├── __init__.py
├── main.py # Pipeline utama
├── preprocessing/
│ └── text_preprocessing.py # Text preprocessing
├── feature_engineering/
│ └── tfidf.py # TF-IDF extraction
├── clustering/
│ └── kmeans.py # K-Means clustering
├── utils/
├── data/
│ ├── raw/ # Data mentah
│ ├── processed/ # Data sudah diproses
│ └── result/ # Hasil clustering
└── README.md
```
## Instalasi Dependencies
```bash
pip install pandas scikit-learn nltk sastrawi
```
## Penggunaan Dasar
### 1. Import Pipeline
```python
import pandas as pd
from Model.main import AlumniClusteringPipeline
# Siapkan data
data = pd.DataFrame({
'nama': ['Ali', 'Budi', 'Citra'],
'perusahaan': ['Google', 'Tokopedia', 'Gojek'],
'jabatan': ['Engineer', 'Analyst', 'Manager']
})
# Jalankan pipeline
pipeline = AlumniClusteringPipeline(n_clusters=3)
result = pipeline.fit_transform(data)
print(result)
```
### 2. Auto-Detect K Optimal
```python
pipeline = AlumniClusteringPipeline(n_clusters=3, auto_k=True)
result = pipeline.fit_transform(data)
```
### 3. Simpan Hasil
```python
# Simpan ke CSV
result.to_csv('hasil_clustering.csv', index=False)
# Lihat distribusi cluster
print(result['cluster_label'].value_counts())
# Lihat ringkasan
summary = pipeline.get_cluster_summary(result)
print(summary)
```
## Input Model
Model menerima DataFrame dengan kolom:
| Kolom | Deskripsi |
|-------|-----------|
| `nama` | Nama lengkap alumni |
| `perusahaan` | Nama perusahaan/instansi |
| `jabatan` | Jabatan/posisi |
## Output Model
DataFrame dengan kolom tambahan:
| Kolom | Deskripsi |
|-------|-----------|
| `cluster` | Nomor cluster (0, 1, 2, ...) |
| `cluster_label` | Label cluster ("Cluster_0", "Cluster_1", ...) |
## CLI Usage
```bash
cd Model
python main.py [input.csv] [n_clusters] [output.csv]
```
Contoh:
```bash
python main.py ../data/raw/alumni.csv 3 ../data/result/hasil.csv
```
## Integrasi dengan Backend
Model sudah diintegrasikan dengan Backend FastAPI melalui `ml_service.py`.
Endpoint untuk clustering tersedia di `/api/v1/clustering`.
Lihat `Backend/app/services/ml_service.py` untuk detail.
----------------------------------------
## Update Progress (2026-08-28)
### Pipeline ML Selesai (6 Tahap)
| Tahap | Script | Fungsi |
|-------|--------|--------|
| 1 | `column_mapping.json` | Mapping kolom 2019-2025 |
| 2 | `merge_data.py` | Merge data multi-file CSV |
| 3 | `text_preprocessing.py` | Text preprocessing + Sastrawi |
| 4 | `clustering.py` | TF-IDF + K-Means K=4 |
| 5 | `interpretasi.py` | Interpretasi C0-C3 |
| 6 | `dashboard.py` | Generate visualisasi |
### Cara Menjalankan Pipeline
```bash
cd Model/preprocessing
python merge_data.py # Tahap 1-2
python text_preprocessing.py # Tahap 3
python clustering.py # Tahap 4
python interpretasi.py # Tahap 5
python dashboard.py # Tahap 6
```
### Data Sources
| Tahun | File CSV | Records |
|-------|----------|---------|
| 2019 | Data_2019_Tracer_study.csv | 30 |
| 2020 | Data_2020_Tracer_study.csv | 31 |
| 2021 | Data_2021_Tracer_study.csv | 237 |
| 2022 | Data_2022_Tracer_study.csv | 211 |
| 2023 | Data_2023_Tracer_study.csv | 268 |
| 2024 | Data_2024_Tracer_study.csv | 361 |
| 2025 | Data_2025_Tracer_study_*.csv (5 file) | 458 |
| **Total** | | **1596** |
### Hasil
- **Total Alumni:** 1596
- **Data untuk Clustering:** 1114
- **K-Means K:** 4 (sesuai PRD)
- **Silhouette Score:** 0.1034
- **TF-IDF Features:** 500
### Distribusi Cluster
| Cluster | Jumlah | % | Top Terms |
|---------|--------|---|-----------|
| 0 | 587 | 52.7% | perintah, bumn, bnpp, jember, staff |
| 1 | 146 | 13.1% | freelance, kerja lepas |
| 2 | 183 | 16.4% | wiraswasta, usaha sendiri |
| 3 | 198 | 17.8% | swasta, usaha swasta, indonesia |
### Distribusi Kategori C0-C3
| Kategori | Deskripsi | Jumlah | % |
|----------|-----------|--------|---|
| C0 | Sesuai Profil Lulusan | 223 | 13.97% |
| C1 | Bidang Diketahui (BUMN, pemerintah, dll) | 385 | 24.12% |
| C2 | Bidang Tidak Jelas | 506 | 31.70% |
| C3 | Belum/Tidak Bekerja | 482 | 30.20% |
### Catatan Hasil
- **C0 (14%)**: Alumni bekerja di bidang sesuai prodi (IT, jaringan, dll)
- **C1 (24%)**: Bekerja di bidang non-teknis (BUMN, pemerintah, dll)
- **C2 (32%)**: Bidang pekerjaan tidak teridentifikasi jelas
- **C3 (30%)**: Alumni belum/tidak bekerja saat tracer study
### Distribusi per Prodi
| Prodi | Kode | C0 | C1 | C2 | C3 |
|-------|------|----|----|----|----|
| TIF | 55301 | 13 | 135 | 365 | 169 |
| MIF | 57401 | 10 | 66 | 226 | 136 |
| TKK | 56401 | 13 | 48 | 217 | 122 |
### Output Files
```
Model/data/
├── standardized/
│ └── unified_dataset.csv # Data setelah merge
├── processed/
│ ├── dataset_untuk_clustering.csv
│ ├── clustering_results.csv
│ ├── model_info.json
│ └── dashboard/
│ └── dashboard.html # Dashboard interaktif
└── result/
└── interpretasi_results.csv # Hasil C0-C3
```

View File

@ -0,0 +1 @@
# Model Module

View File

@ -0,0 +1 @@
# Clustering module

View File

@ -0,0 +1,176 @@
"""
K-Means Clustering Module
Mengelompokkan alumni berdasarkan kompetensi menggunakan algoritma K-Means Clustering.
Modul ini mencakup wrapper class untuk scikit-learn KMeans, pencarian k optimal (Elbow Method & Silhouette),
serta ringkasan statistik setiap kelompok (cluster).
"""
# Mengimpor modul Any untuk type hint fleksibel
from typing import Any
# Mengimpor modul KMeans dari pustaka scikit-learn (sklearn.cluster) untuk implementasi algoritma clustering berbasis centroid
from sklearn.cluster import KMeans
# Mengimpor fungsi silhouette_score untuk mengukur seberapa baik data terkelompok dalam cluster-nya dibandingkan cluster tetangga
from sklearn.metrics import silhouette_score
# Mengimpor pustaka numpy untuk operasi array numerik dan manipulasi matriks fitur
import numpy as np
# Mendefinisikan class KMeansClustering sebagai pembungkus (wrapper) model KMeans Scikit-Learn
class KMeansClustering:
"""K-Means Clustering wrapper: Memudahkan inisialisasi, pelatihan (fit), dan prediksi klaster."""
# Metode konstruktor class yang dijalankan saat objek pertama kali diinisialisasi
def __init__(self, n_clusters: int = 3, random_state: int = 42):
"""
Inisialisasi hyperparameter algoritma K-Means:
Args:
n_clusters: Jumlah cluster (k) yang diinginkan (default: 3)
random_state: Seed acak untuk memastikan hasil inisialisasi centroid selalu sama/reproducible (default: 42)
"""
# Menyimpan nilai jumlah cluster ke dalam atribut instance objek
self.n_clusters = n_clusters
# Menyimpan nilai seed acak ke dalam atribut instance objek
self.random_state = random_state
# Menginstansiasi objek model KMeans dari Scikit-Learn
# n_init='auto': Algoritma secara otomatis menentukan jumlah inisialisasi centroid awal berbasis heuristik Scikit-Learn modern
self.model = KMeans(
n_clusters=n_clusters,
random_state=random_state,
n_init='auto'
)
# Menyiapkan atribut untuk menyimpan label cluster dari tiap data setelah model dilatih (default None)
self.labels_ = None
# Menyiapkan atribut untuk menyimpan nilai inertia (Within-Cluster Sum of Squares) setelah dilatih (default None)
self.inertia_ = None
# Metode fit untuk melatih model K-Means pada dataset masukan X
def fit(self, X) -> 'KMeansClustering':
"""Melatih (fit) model K-Means terhadap matriks data/fitur X"""
# Menjalankan proses clustering pada matriks fitur X hingga posisi centroid konvergen
self.model.fit(X)
# Menyimpan label cluster hasil fitting (0, 1, 2, ...) ke atribut labels_
self.labels_ = self.model.labels_
# Mengambil nilai inertia (jumlah kuadrat jarak titik ke centroid terdekat) dari model terlatih
self.inertia_ = self.model.inertia_
# Mengembalikan instance objek diri sendiri (self) untuk chaining method jika diperlukan
return self
# Metode predict untuk memprediksi cluster data baru tanpa melatih ulang posisi centroid
def predict(self, X) -> Any:
"""Memprediksi label cluster untuk data baru berdasarkan centroid yang telah terbentuk"""
# Mengembalikan array numpy berisi label cluster hasil prediksi jarak Euclidean terdekat ke centroid
return self.model.predict(X)
# Metode fit_predict untuk melatih model sekaligus menghasilkan prediksi label cluster data dalam satu langkah
def fit_predict(self, X) -> Any:
"""Melatih model sekaligus menghasilkan label cluster secara langsung"""
# Menjalankan proses fitting dan langsung mengembalikan array label cluster
self.labels_ = self.model.fit_predict(X)
# Menyimpan nilai inersia akhir dari proses klastering
self.inertia_ = self.model.inertia_
# Mengembalikan array label cluster numerik
return self.labels_
# Fungsi untuk mencari nilai k optimal menggunakan kombinasi Elbow Method dan Silhouette Score
def find_optimal_k(X, k_range: range = range(2, 11)) -> dict:
"""
Mencari jumlah cluster optimal (k) menggunakan Elbow Method dan Silhouette Analysis.
Args:
X: Matriks fitur (feature matrix) yang telah melalui tahap preprocessing dan feature engineering
k_range: Rentang nilai k yang akan diuji (default: dari k=2 hingga k=10)
Returns:
Dictionary berisi daftar nilai k, inertia, dan silhouette score untuk setiap k yang diuji
"""
# Menyiapkan struktur data dictionary untuk menampung riwayat evaluasi
results = {
'k': [], # Menyimpan nilai k yang diuji
'inertia': [], # Menyimpan nilai inertia untuk grafik Elbow
'silhouette': [] # Menyimpan nilai rata-rata Silhouette Coefficient
}
# Melakukan iterasi untuk setiap nilai k dalam rentang k_range
for k in k_range:
# Menginisialisasi objek KMeans dengan jumlah cluster k saat ini (n_init='auto' sesuai standar Scikit-Learn terbaru)
kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto')
# Melatih model dan memperoleh label pengelompokan cluster untuk matriks data X
labels = kmeans.fit_predict(X)
# Menambahkan nilai k saat ini ke list hasil
results['k'].append(k)
# Menambahkan nilai inertia (WCSS - Within-Cluster Sum of Squares) ke list hasil
results['inertia'].append(kmeans.inertia_)
# Silhouette score hanya dapat dihitung jika k > 1 dan terdapat lebih dari 1 kelompok cluster unik yang terbentuk
if k > 1 and len(set(labels)) > 1:
# Menghitung skor silhouette dan menambahkannya ke list hasil
results['silhouette'].append(silhouette_score(X, labels))
else:
# Jika kondisi tidak terpenuhi, set nilai skor silhouette menjadi 0
results['silhouette'].append(0)
# Mengembalikan dictionary lengkap berisi hasil pengujian seluruh nilai k
return results
# Fungsi untuk menghitung ringkasan statistik dan distribusi data di setiap kelompok klaster
def get_cluster_summary(df, labels: np.ndarray) -> dict:
"""
Mendapatkan ringkasan profil statistik setiap cluster hasil pengelompokan.
Args:
df: DataFrame pandas berisi data asli alumni sebelum ditransformasi
labels: Array numpy yang berisi label cluster dari setiap baris data
Returns:
Dictionary yang berisi jumlah data (count), persentase, dan contoh data per cluster
"""
# Membuat salinan (copy) DataFrame asli agar tidak memodifikasi data induk
df_result = df.copy()
# Menambahkan kolom baru 'cluster' yang berisi label klaster hasil prediksi K-Means
df_result['cluster'] = labels
# Menyiapkan dictionary untuk menampung ringkasan tiap cluster
summary = {}
# Melakukan perulangan untuk setiap ID klaster unik yang sudah diurutkan (0, 1, 2, ...)
for cluster_id in sorted(df_result['cluster'].unique()):
# Memfilter baris data yang masuk ke dalam ID cluster saat ini
cluster_data = df_result[df_result['cluster'] == cluster_id]
# Mengisi ringkasan informasi cluster (jumlah baris, persentase dari total data, dan 3 sampel data teratas)
summary[f'Cluster_{cluster_id}'] = {
'count': len(cluster_data), # Jumlah anggota klaster
'percentage': round(len(cluster_data) / len(df_result) * 100, 2), # Persentase terhadap total populasi
'sample_data': cluster_data.head(3).to_dict('records') # 3 sampel baris data berformat list of dict
}
# Mengembalikan dictionary ringkasan klaster
return summary
# Blok pengetesan lokal yang hanya dijalankan ketika file ini dieksekusi langsung di terminal (bukan diimpor)
if __name__ == "__main__":
# Mengimpor modul make_blobs untuk membuat dataset sintesis tiruan untuk keperluan unit testing
from sklearn.datasets import make_blobs
# Membuat 100 sampel data tiruan dengan 3 pusat klaster untuk menguji fungsionalitas modul
blob_data = make_blobs(n_samples=100, centers=3, random_state=42)
# Mengambil matriks fitur X dari data sintesis
X = blob_data[0]
# Menjalankan fungsi pencarian k optimal
results = find_optimal_k(X)
print("Elbow Method Results:")
# Menampilkan hasil evaluasi inertia dan silhouette score untuk setiap nilai k
for i in range(len(results['k'])):
print(f" K={results['k'][i]}: Inertia={results['inertia'][i]:.2f}, Silhouette={results['silhouette'][i]:.4f}")
# Menguji proses klastering akhir dengan k=3
kmeans = KMeansClustering(n_clusters=3)
# Melakukan fitting dan prediksi
labels = kmeans.fit_predict(X)
# Menampilkan label unik yang terbentuk
print(f"\nClustering complete! Labels: {np.unique(labels)}")

View File

@ -0,0 +1,5 @@
from .default_keywords import (
PRODI_CODES,
DEFAULT_KEYWORD_DICTIONARY,
DEFAULT_BIDANG_KERJA_UMUM,
)

View File

@ -0,0 +1,134 @@
"""
=============================================================
MASTER CONFIGURATION: KAMUS PROFIL LULUSAN & SEKTOR PEKERJAAN
=============================================================
PRD Reference: Section 7, 18, & 24
Dokumen ini berisi kamus acuan default untuk profil kurikulum
program studi Jurusan Teknologi Informasi (D4 TIF, D3 MIF, D3 TKK)
dan daftar sektor industri kerja umum.
=============================================================
"""
# Pemetaan Kode Program Studi ke Singkatan Resmi
PRODI_CODES = {
# Kode Resmi Nasional (PDDIKTI)
'55301': 'TIF',
'57401': 'MIF',
'56401': 'TKK',
# Kode Internal & PDD
'21': 'TIF',
'19': 'MIF',
'20': 'TKK',
'22': 'TIF', # Kampus Nganjuk
'23': 'TIF', # Kampus Sidoarjo
# Format Deskriptif Teks
'Teknik Informatika (55301)': 'TIF',
'Manajemen Informatika (57401)': 'MIF',
'Teknik Komputer (56401)': 'TKK',
'Teknik Informatika Kampus Kab. Nganjuk (55302)': 'TIF',
'Teknik Informatika Kampus Kab. Sidoarjo (55304)': 'TIF',
'D4 Teknik Informatika': 'TIF',
'D3 Manajemen Informatika': 'MIF',
'D3 Teknik Komputer': 'TKK',
'TIF': 'TIF',
'MIF': 'MIF',
'TKK': 'TKK',
}
# Kamus Profil Lulusan Per Program Studi (Untuk Kategori C0 - Sesuai Profil)
DEFAULT_KEYWORD_DICTIONARY = {
'TIF': [
'software engineer', 'software developer', 'software development', 'software',
'programmer', 'programming', 'coder', 'coding', 'koding', 'code', 'dev', 'developer', 'development',
'quality assurance', 'qa engineer', 'qa tester', 'software tester', 'tester', 'testing', 'qa', 'qc software',
'it consultant', 'konsultan it', 'konsultan perangkat lunak', 'konsultan software',
'project manager it', 'manajemen proyek it', 'manajemen proyek', 'project manager',
'scrum master', 'system analyst', 'analis sistem', 'analisis sistem', 'teknik informatika',
'algoritma', 'pengembangan software', 'pengembangan aplikasi', 'app developer',
'aplikasi', 'sistem informasi', 'teknologi informasi', 'informatika',
'mobile developer', 'web developer', 'android developer', 'ios developer',
'frontend', 'frontend developer', 'backend', 'backend developer', 'fullstack', 'fullstack developer',
'game developer', 'game programmer', 'game', 'gaming', 'cyber security',
'cyber', 'keamanan sistem', 'keamanan siber', 'keamanan jaringan',
'machine learning', 'artificial intelligence', 'data scientist', 'data science',
'cloud', 'cloud computing', 'devops', 'devops engineer', 'site reliability engineer', 'sre',
'prompt engineer', 'ai engineer', 'nlp engineer', 'computer vision', 'cloud architect',
'it specialist', 'it staff', 'staff it', 'it officer', 'it programmer', 'lead developer',
'tech lead', 'solutions architect', 'software architect', 'security engineer',
'soc analyst', 'penetration tester', 'pentester', 'flutter', 'flutter developer',
'react developer', 'laravel developer', 'golang', 'python developer', 'java developer',
'automation engineer', 'automation tester', 'it auditor',
'startup teknologi', 'tech startup', 'software house', 'it entrepreneur',
'tokopedia', 'shopee', 'bukalapak', 'sevima', 'sentra vidya utama', 'traveloka',
'gojek', 'grab', 'tiket', 'edutech', 'fintech', 'edtech', 'dot indonesia',
'tech', 'technology', 'teknologi', 'technocraft', 'solusindo', 'solusitama', 'infomedia', 'telkom',
'entrepreneur', 'startup', 'technopreneur', 'founder', 'owner', 'co founder', 'ceo', 'cto', 'cio', 'wirausaha'
],
'MIF': [
'programmer', 'programming', 'coder', 'coding', 'koding', 'code', 'dev', 'development',
'software developer', 'software developer desktop', 'software development',
'software developer web', 'software developer mobile', 'web developer', 'mobile developer',
'frontend developer', 'backend developer', 'fullstack developer', 'database administrator',
'developer', 'database', 'dba', 'sql', 'mysql', 'postgresql', 'oracle', 'mongodb',
'data analyst', 'analis data', 'analisis data', 'data warehouse', 'etl',
'business intelligence', 'bi analyst', 'bi developer', 'data visualization', 'visualisasi data',
'data engineer', 'database engineer', 'data specialist', 'power bi', 'tableau',
'business analyst', 'analis bisnis', 'product owner', 'product manager',
'erd', 'manajemen database', 'database management', 'backend', 'frontend',
'fullstack', 'aplikasi', 'sistem informasi', 'manajemen informatika', 'pemrograman',
'teknologi informasi', 'komputer', 'android developer', 'ios developer',
'android', 'ios', 'mobile', 'ui ux', 'ui ux designer', 'ui designer', 'ux designer',
'product designer', 'graphic designer', 'desain grafis', 'desain logo', 'desain',
'design', 'multimedia', 'animasi', 'web designer', 'web master', 'wordpress developer',
'erp specialist', 'sap consultant', 'odoo', 'odoo developer',
'software house', 'tokopedia', 'shopee', 'bukalapak', 'sevima',
'sentra vidya utama', 'traveloka', 'gojek', 'grab', 'edutech', 'fintech', 'edtech',
'tech', 'technology', 'teknologi',
'it entrepreneur', 'founder', 'owner', 'co founder', 'ceo', 'wirausaha'
],
'TKK': [
'jaringan', 'network', 'networking', 'network administrator', 'network engineer',
'network security', 'administrator jaringan', 'jaringan komputer', 'teknisi jaringan komputer',
'lan wan', 'lan', 'wan', 'cloud computing', 'cloud', 'iot', 'internet of things',
'iot engineer', 'embedded', 'embedded system', 'firmware', 'hardware', 'sysadmin',
'system administrator', 'server administrator', 'datacenter engineer', 'noc engineer',
'noc technician', 'field engineer it', 'fiber optic', 'teknisi fiber',
'robotika', 'robotics', 'plc', 'scada', 'cctv technician', 'teknisi cctv',
'server', 'mikrotik', 'cisco', 'komputer', 'teknisi komputer', 'service komputer',
'infrastruktur', 'datacenter', 'teknik komputer', 'it support', 'it technician', 'helpdesk it',
'teknisi jaringan', 'admin jaringan', 'computer', 'laptop', 'pc',
'cell', 'cellular', 'seluler', 'telekomunikasi', 'telecommunication', 'teknisi',
'telkomsel', 'telkom', 'nexwave', 'huawei', 'zte', 'indosat', 'xl axiata', 'smartfren',
'fiber', 'optik', 'fiberstar', 'biznet', 'cbn', 'myrepublic', 'noc', 'tower', 'bts',
'tech', 'technology', 'teknologi', 'technopreneur',
'wirausaha bidang teknik komputer', 'founder', 'owner', 'co founder', 'ceo', 'wirausaha'
]
}
# Daftar Sektor Pekerjaan Formal Non-IT (Untuk Kategori C1 - Bidang Diketahui)
DEFAULT_BIDANG_KERJA_UMUM = [
# Perbankan & Lembaga Keuangan
'bank', 'bni', 'bri', 'mandiri', 'bca', 'btn', 'btpn', 'bank jatim', 'bsi', 'mega', 'muamalat', 'cimb',
'perbankan', 'koperasi', 'leasing', 'asuransi', 'pegadaian', 'akuntan', 'accounting',
'finance', 'keuangan', 'perpajakan', 'pajak', 'teller', 'kasir', 'finansial',
# Manajemen, Administrasi & Staf Formal
'manager', 'supervisor', 'staff', 'admin', 'administrasi', 'hrd', 'personalia',
'receptionist', 'customer service', 'cs', 'operator', 'sekretaris', 'notaris',
# Pemasaran, Penjualan & Retail
'marketing', 'sales', 'sales promotion', 'spg', 'spb', 'telemarketing', 'account executive',
'toko', 'minimarket', 'indomaret', 'alfamart', 'supermarket', 'mart', 'distributor', 'agen',
# Industri Manufaktur, Migas, Energi, Pertanian
'migas', 'pelangi migas', 'oil', 'gas', 'pertamina', 'pln', 'pdam', 'bumn', 'bumd',
'tjiwi kimia', 'pabrik', 'manufaktur', 'industri', 'produksi', 'qc', 'qa qc', 'gudang', 'warehouse',
'east west seed', 'seed', 'benih', 'pertanian', 'perkebunan', 'peternakan', 'agro', 'pupuk',
'cosmetindo', 'moro ayu', 'kosmetik', 'farmasi', 'apotek', 'apoteker', 'kimia', 'tekstil',
# Pendidikan & Kesehatan
'guru', 'dosen', 'pengajar', 'instruktur', 'tutor', 'trainer', 'sekolah', 'kampus',
'politeknik', 'universitas', 'sd', 'smp', 'sma', 'smk', 'madrasah', 'pesantren',
'perawat', 'bidan', 'dokter', 'rumah sakit', 'rsud', 'klinik', 'puskesmas', 'laboratorium',
# Jasa Lapangan, Logistik, Kuliner & Instansi Publik
'driver', 'kurir', 'pengemudi', 'security', 'satpam', 'mekanik', 'bengkel',
'barista', 'koki', 'chef', 'waiter', 'pelayan', 'restoran', 'cafe', 'kafe', 'hotel', 'catering',
'penulis', 'editor', 'fotografer', 'videografer',
'pns', 'asn', 'polisi', 'tni', 'pemerintah', 'dinas', 'kelurahan', 'kecamatan', 'balai', 'kantor desa'
]

View File

@ -0,0 +1,66 @@
{
"0": {
"jumlah": 587,
"persentase": 52.69299820466786,
"top_terms": [
"perintah",
"bumn",
"bnpp",
"jember",
"staff",
"swasta",
"instansi perintah",
"instansi",
"founder",
"negeri"
]
},
"1": {
"jumlah": 146,
"persentase": 13.10592459605027,
"top_terms": [
"kerja",
"freelance",
"kerja lepas",
"lepas",
"freelance kerja",
"usaha",
"usaha sendiri",
"sendiri",
"wiraswasta usaha",
"lain tulis"
]
},
"2": {
"jumlah": 183,
"persentase": 16.427289048473966,
"top_terms": [
"wiraswasta",
"wiraswasta usaha",
"usaha sendiri",
"sendiri",
"usaha",
"toko",
"founder",
"wiraswasta toko",
"jaya",
"wiraswasta freelance"
]
},
"3": {
"jumlah": 198,
"persentase": 17.7737881508079,
"top_terms": [
"swasta",
"usaha swasta",
"usaha",
"staff",
"indonesia",
"swasta staff",
"founder",
"swasta founder",
"digital",
"media"
]
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
============================================================
CLUSTERING SUMMARY
Tanggal: 2026-08-28 04:27:42
============================================================
[MODEL INFO]
K = 4 (sesuai PRD)
Inertia: 893.89
Silhouette Score: 0.1034
Total Samples: 1114
Total Features: 500
[EVALUATION RESULTS]
K=2: Inertia=992.52, Silhouette=0.0595
K=3: Inertia=937.51, Silhouette=0.0833
K=4: Inertia=893.89, Silhouette=0.1034
K=5: Inertia=868.63, Silhouette=0.1151
K=6: Inertia=854.48, Silhouette=0.1154
[CLUSTER DISTRIBUTION]
Cluster 0: 587 (52.7%)
Cluster 1: 146 (13.1%)
Cluster 2: 183 (16.4%)
Cluster 3: 198 (17.8%)
[TOP TERMS PER CLUSTER]
Cluster 0: perintah, bumn, bnpp, jember, staff
Cluster 1: kerja, freelance, kerja lepas, lepas, freelance kerja
Cluster 2: wiraswasta, wiraswasta usaha, usaha sendiri, sendiri, usaha
Cluster 3: swasta, usaha swasta, usaha, staff, indonesia
============================================================

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

@ -0,0 +1,350 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Clustering Alumni - Politeknik Negeri Jember</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
.header {
background: white;
border-radius: 15px;
padding: 30px;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.header h1 {
color: #2c3e50;
font-size: 28px;
margin-bottom: 10px;
}
.header p {
color: #7f8c8d;
font-size: 14px;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.card {
background: white;
border-radius: 15px;
padding: 25px;
text-align: center;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
transition: transform 0.3s;
}
.card:hover {
transform: translateY(-5px);
}
.card-value {
font-size: 42px;
font-weight: bold;
margin-bottom: 5px;
}
.card-label {
font-size: 14px;
color: #7f8c8d;
}
.card-c0 { color: #2ecc71; }
.card-c1 { color: #3498db; }
.card-c2 { color: #f39c12; }
.card-c3 { color: #e74c3c; }
.card-tif { color: #9b59b6; }
.card-mif { color: #1abc9c; }
.card-tkk { color: #e67e22; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 20px;
}
.chart-container {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.chart-title {
font-size: 18px;
font-weight: bold;
color: #2c3e50;
margin-bottom: 20px;
text-align: center;
}
.chart-wrapper {
position: relative;
height: 300px;
}
.definitions {
background: white;
border-radius: 15px;
padding: 25px;
margin-top: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.definitions h2 {
color: #2c3e50;
margin-bottom: 15px;
}
.definition-item {
display: flex;
align-items: center;
margin-bottom: 12px;
padding: 10px;
border-radius: 8px;
background: #f8f9fa;
}
.definition-badge {
padding: 8px 15px;
border-radius: 20px;
font-weight: bold;
color: white;
margin-right: 15px;
min-width: 50px;
text-align: center;
}
.badge-c0 { background: #2ecc71; }
.badge-c1 { background: #3498db; }
.badge-c2 { background: #f39c12; }
.badge-c3 { background: #e74c3c; }
.footer {
text-align: center;
margin-top: 30px;
color: white;
font-size: 12px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Dashboard Clustering Alumni</h1>
<p>Sistem Pengelompokan Pekerjaan Alumni dengan Kompetensi Lulusan - Jurusan Teknologi Informasi, Politeknik Negeri Jember</p>
</div>
<div class="cards">
<div class="card">
<div class="card-value card-tif">347</div>
<div class="card-label">Teknik Informatika (TIF)</div>
</div>
<div class="card">
<div class="card-value card-mif">236</div>
<div class="card-label">Manajemen Informatika (MIF)</div>
</div>
<div class="card">
<div class="card-value card-tkk">194</div>
<div class="card-label">Teknik Komputer (TKK)</div>
</div>
<div class="card">
<div class="card-value" style="color:#2c3e50">1596</div>
<div class="card-label">Total Alumni</div>
</div>
</div>
<div class="cards">
<div class="card">
<div class="card-value card-c0">223</div>
<div class="card-label">Sesuai Profil (C0)</div>
</div>
<div class="card">
<div class="card-value card-c1">385</div>
<div class="card-label">Bidang Diketahui (C1)</div>
</div>
<div class="card">
<div class="card-value card-c2">506</div>
<div class="card-label">Bidang Tidak Jelas (C2)</div>
</div>
<div class="card">
<div class="card-value card-c3">482</div>
<div class="card-label">Belum Bekerja (C3)</div>
</div>
</div>
<div class="grid">
<div class="chart-container">
<div class="chart-title">Distribusi Kategori Alumni (C0-C3)</div>
<div class="chart-wrapper">
<canvas id="kategoriChart"></canvas>
</div>
</div>
<div class="chart-container">
<div class="chart-title">Distribusi per Program Studi</div>
<div class="chart-wrapper">
<canvas id="prodiChart"></canvas>
</div>
</div>
</div>
<div class="grid" style="margin-top:20px">
<div class="chart-container">
<div class="chart-title">Distribusi Cluster K-Means (K=4)</div>
<div class="chart-wrapper">
<canvas id="clusterChart"></canvas>
</div>
</div>
<div class="chart-container">
<div class="chart-title">Match Rate per Program Studi</div>
<div class="chart-wrapper">
<canvas id="matchChart"></canvas>
</div>
</div>
</div>
<div class="definitions">
<h2>Definisi Kategori</h2>
<div class="definition-item">
<span class="definition-badge badge-c0">C0</span>
<span><strong>Sesuai Profil Lulusan:</strong> Alumni bekerja dan pekerjaan match dengan kamus kata kunci profil lulusannya.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c1">C1</span>
<span><strong>Bidang Diketahui:</strong> Alumni bekerja, bidang pekerjaan jelas, tapi tidak match kamus prodi.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c2">C2</span>
<span><strong>Bidang Tidak Teridentifikasi:</strong> Alumni bekerja tapi informasi pekerjaan kurang jelas atau terlalu umum.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c3">C3</span>
<span><strong>Belum/Tidak Bekerja:</strong> Alumni belum bekerja atau tidak bekerja saat tracer study.</span>
</div>
</div>
<div class="footer">
<p>Generated: 2026-08-28 04:48:41</p>
<p>Sistem Clustering Alumni - Politeknik Negeri Jember</p>
</div>
</div>
<script>
// Kategori Chart
new Chart(document.getElementById('kategoriChart'), {
type: 'doughnut',
data: {
labels: ['C0 - Sesuai Profil', 'C1 - Bidang Diketahui', 'C2 - Bidang Tidak Jelas', 'C3 - Belum Bekerja'],
datasets: [{
data: [
223,
385,
506,
482
],
backgroundColor: ['#2ecc71', '#3498db', '#f39c12', '#e74c3c']
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { position: 'bottom' }
}
}
});
// Prodi Chart
new Chart(document.getElementById('prodiChart'), {
type: 'bar',
data: {
labels: ['TIF', 'MIF', 'TKK'],
datasets: [{
label: 'Jumlah Alumni',
data: [
347,
236,
194
],
backgroundColor: ['#9b59b6', '#1abc9c', '#e67e22']
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false }
}
}
});
// Cluster Chart
new Chart(document.getElementById('clusterChart'), {
type: 'pie',
data: {
labels: ['Cluster 0', 'Cluster 1', 'Cluster 2', 'Cluster 3'],
datasets: [{
data: [326, 27, 66, 100],
backgroundColor: ['#3498db', '#2ecc71', '#f39c12', '#9b59b6']
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
// Match Rate Chart
new Chart(document.getElementById('matchChart'), {
type: 'bar',
data: {
labels: ['TIF', 'MIF', 'TKK'],
datasets: [{
label: 'Match Rate (%)',
data: [2.22, 1.82, 6.90],
backgroundColor: ['#9b59b6', '#1abc9c', '#e67e22']
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 10
}
},
plugins: {
legend: { display: false }
}
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,455 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Clustering Alumni - Politeknik Negeri Jember</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
min-height: 100vh;
padding: 20px;
color: white;
}
.container {
max-width: 1400px;
margin: 0 auto;
}
.header {
background: rgba(255,255,255,0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
margin-bottom: 30px;
text-align: center;
border: 1px solid rgba(255,255,255,0.1);
}
.header h1 {
font-size: 32px;
margin-bottom: 10px;
background: linear-gradient(90deg, #00d9ff, #00ff88);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.header p {
color: #a0a0a0;
font-size: 14px;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 20px;
margin-bottom: 25px;
}
.card {
background: rgba(255,255,255,0.05);
backdrop-filter: blur(10px);
border-radius: 15px;
padding: 25px;
text-align: center;
border: 1px solid rgba(255,255,255,0.1);
transition: all 0.3s;
}
.card:hover {
transform: translateY(-5px);
border-color: rgba(255,255,255,0.3);
}
.card-value {
font-size: 38px;
font-weight: bold;
margin-bottom: 5px;
}
.card-label {
font-size: 12px;
color: #a0a0a0;
text-transform: uppercase;
letter-spacing: 1px;
}
.card-c0 { color: #2ecc71; }
.card-c1 { color: #3498db; }
.card-c2 { color: #f39c12; }
.card-c3 { color: #e74c3c; }
.card-tif { color: #a855f7; }
.card-mif { color: #14b8a6; }
.card-tkk { color: #f97316; }
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(380px, 1fr));
gap: 25px;
}
.chart-container {
background: rgba(255,255,255,0.05);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 30px;
border: 1px solid rgba(255,255,255,0.1);
}
.chart-title {
font-size: 18px;
font-weight: 600;
margin-bottom: 20px;
text-align: center;
color: #fff;
}
.chart-wrapper {
position: relative;
height: 280px;
}
.definitions {
background: rgba(255,255,255,0.05);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 35px;
margin-top: 30px;
border: 1px solid rgba(255,255,255,0.1);
}
.definitions h2 {
margin-bottom: 20px;
font-size: 22px;
background: linear-gradient(90deg, #00d9ff, #00ff88);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.definition-item {
display: flex;
align-items: center;
margin-bottom: 15px;
padding: 15px;
border-radius: 12px;
background: rgba(255,255,255,0.05);
}
.definition-badge {
padding: 8px 16px;
border-radius: 25px;
font-weight: bold;
color: white;
margin-right: 20px;
min-width: 50px;
text-align: center;
font-size: 14px;
}
.badge-c0 { background: #2ecc71; }
.badge-c1 { background: #3498db; }
.badge-c2 { background: #f39c12; }
.badge-c3 { background: #e74c3c; }
.definition-text {
color: #ccc;
font-size: 14px;
line-height: 1.5;
}
.definition-text strong {
color: #fff;
}
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-top: 25px;
}
.stat-box {
background: rgba(255,255,255,0.05);
border-radius: 12px;
padding: 20px;
text-align: center;
border: 1px solid rgba(255,255,255,0.1);
}
.stat-number {
font-size: 28px;
font-weight: bold;
color: #00d9ff;
}
.stat-label {
font-size: 12px;
color: #a0a0a0;
margin-top: 5px;
}
.footer {
text-align: center;
margin-top: 40px;
padding: 20px;
color: #666;
font-size: 12px;
}
@media (max-width: 768px) {
.grid {
grid-template-columns: 1fr;
}
.header h1 {
font-size: 24px;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Sistem Clustering Alumni</h1>
<p>Jurusan Teknologi Informasi - Politeknik Negeri Jember</p>
</div>
<div class="cards">
<div class="card">
<div class="card-value card-tif">225</div>
<div class="card-label">Teknik Informatika</div>
</div>
<div class="card">
<div class="card-value card-mif">165</div>
<div class="card-label">Manajemen Informatika</div>
</div>
<div class="card">
<div class="card-value card-tkk">145</div>
<div class="card-label">Teknik Komputer</div>
</div>
<div class="card">
<div class="card-value" style="color:#fff">535</div>
<div class="card-label">Total Alumni</div>
</div>
</div>
<div class="cards">
<div class="card">
<div class="card-value card-c0">18</div>
<div class="card-label">C0 - Sesuai Profil</div>
</div>
<div class="card">
<div class="card-value card-c1">85</div>
<div class="card-label">C1 - Bidang Diketahui</div>
</div>
<div class="card">
<div class="card-value card-c2">416</div>
<div class="card-label">C2 - Bidang Tidak Jelas</div>
</div>
<div class="card">
<div class="card-value card-c3">16</div>
<div class="card-label">C3 - Belum Bekerja</div>
</div>
</div>
<div class="stats-row">
<div class="stat-box">
<div class="stat-number">519</div>
<div class="stat-label">Data di-Cluster</div>
</div>
<div class="stat-box">
<div class="stat-number">4</div>
<div class="stat-label">Jumlah Cluster (K)</div>
</div>
<div class="stat-box">
<div class="stat-number">0.16</div>
<div class="stat-label">Silhouette Score</div>
</div>
<div class="stat-box">
<div class="stat-number">3.36%</div>
<div class="stat-label">Match Rate C0</div>
</div>
</div>
<div class="grid" style="margin-top:30px">
<div class="chart-container">
<div class="chart-title">Distribusi Kategori Alumni (C0-C3)</div>
<div class="chart-wrapper">
<canvas id="kategoriChart"></canvas>
</div>
</div>
<div class="chart-container">
<div class="chart-title">Distribusi per Program Studi</div>
<div class="chart-wrapper">
<canvas id="prodiChart"></canvas>
</div>
</div>
</div>
<div class="grid" style="margin-top:25px">
<div class="chart-container">
<div class="chart-title">Distribusi Cluster K-Means (K=4)</div>
<div class="chart-wrapper">
<canvas id="clusterChart"></canvas>
</div>
</div>
<div class="chart-container">
<div class="chart-title">Distribusi C0-C3 per Prodi</div>
<div class="chart-wrapper">
<canvas id="prodiKategoriChart"></canvas>
</div>
</div>
</div>
<div class="definitions">
<h2>Definisi Kategori C0-C3</h2>
<div class="definition-item">
<span class="definition-badge badge-c0">C0</span>
<span class="definition-text"><strong>Sesuai Profil Lulusan:</strong> Alumni bekerja dan pekerjaan memiliki kecocokan dengan kamus kata kunci profil lulusannya berdasarkan prodi asal.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c1">C1</span>
<span class="definition-text"><strong>Bidang Diketahui:</strong> Alumni bekerja dan bidang pekerjaan dapat diidentifikasi dengan jelas, tetapi tidak match dengan kamus prodi.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c2">C2</span>
<span class="definition-text"><strong>Bidang Tidak Teridentifikasi:</strong> Alumni bekerja tetapi informasi pekerjaan tidak cukup jelas untuk menentukan bidang pekerjaan.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c3">C3</span>
<span class="definition-text"><strong>Belum/Tidak Bekerja:</strong> Alumni belum bekerja atau berstatus tidak bekerja saat tracer study.</span>
</div>
</div>
<div class="footer">
<p>Sistem Pengelompokan Pekerjaan Alumni dengan Kompetensi Lulusan</p>
<p>Generated: 2026-08-28</p>
</div>
</div>
<script>
// Kategori Chart
new Chart(document.getElementById('kategoriChart'), {
type: 'doughnut',
data: {
labels: ['C0 - Sesuai Profil', 'C1 - Bidang Diketahui', 'C2 - Bidang Tidak Jelas', 'C3 - Belum Bekerja'],
datasets: [{
data: [18, 85, 416, 16],
backgroundColor: ['#2ecc71', '#3498db', '#f39c12', '#e74c3c'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#fff', padding: 15 }
}
}
}
});
// Prodi Chart
new Chart(document.getElementById('prodiChart'), {
type: 'bar',
data: {
labels: ['TIF', 'MIF', 'TKK'],
datasets: [{
label: 'Jumlah Alumni',
data: [225, 165, 145],
backgroundColor: ['#a855f7', '#14b8a6', '#f97316'],
borderRadius: 8
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false }
},
scales: {
y: {
beginAtZero: true,
grid: { color: 'rgba(255,255,255,0.1)' },
ticks: { color: '#fff' }
},
x: {
grid: { display: false },
ticks: { color: '#fff' }
}
}
}
});
// Cluster Chart
new Chart(document.getElementById('clusterChart'), {
type: 'pie',
data: {
labels: ['Cluster 0 (62.8%)', 'Cluster 1 (5.2%)', 'Cluster 2 (12.7%)', 'Cluster 3 (19.3%)'],
datasets: [{
data: [326, 27, 66, 100],
backgroundColor: ['#3498db', '#2ecc71', '#f39c12', '#9b59b6'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#fff', padding: 10 }
}
}
}
});
// Prodi Kategori Chart
new Chart(document.getElementById('prodiKategoriChart'), {
type: 'bar',
data: {
labels: ['TIF', 'MIF', 'TKK'],
datasets: [
{ label: 'C0', data: [5, 3, 10], backgroundColor: '#2ecc71' },
{ label: 'C1', data: [53, 20, 12], backgroundColor: '#3498db' },
{ label: 'C2', data: [162, 134, 120], backgroundColor: '#f39c12' },
{ label: 'C3', data: [5, 8, 3], backgroundColor: '#e74c3c' }
]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#fff', padding: 10 }
}
},
scales: {
y: {
beginAtZero: true,
stacked: true,
grid: { color: 'rgba(255,255,255,0.1)' },
ticks: { color: '#fff' }
},
x: {
stacked: true,
grid: { display: false },
ticks: { color: '#fff' }
}
}
}
});
</script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -0,0 +1,483 @@
kode_prodi,nim,nama,tahun_lulus,status_pekerjaan,jenis_perusahaan,nama_perusahaan,jabatan,sumber_file,teks_pekerjaan_raw,teks_pekerjaan,kategori_pengalaman
57401,E31160678,RIZKA NURUL KHAKIKI,2019.0,bekerja,3,,,Data_2019_Tracer_study.csv,swasta,swasta,tidak_berpengalaman
55301,E41150211,DEWI AYU ITIKAF,2019.0,mencari_kerja,0,0,0.0,Data_2019_Tracer_study.csv,0 0.0,,tidak_berpengalaman
57401,E31151401,Aza Pascaeka,2019.0,belum_kerja,4,,,Data_2019_Tracer_study.csv,wiraswasta,wiraswasta,tidak_berpengalaman
57401,E31130845,MOCH. RIVALDI AFTONI,2019.0,bekerja,5,,,Data_2019_Tracer_study.csv,lainnya,lain,tidak_berpengalaman
57401,E31160328,Afega Wira Pradana,2019.0,bekerja,3,,,Data_2019_Tracer_study.csv,swasta,swasta,tidak_berpengalaman
57401,E31161719,Reza Septia Safirah,2019.0,belum_kerja,4,,,Data_2019_Tracer_study.csv,wiraswasta,wiraswasta,tidak_berpengalaman
56401,E32160904,ONGKY OKTAFIAN DWI JOHANSYAH,2019.0,bekerja,3,,,Data_2019_Tracer_study.csv,swasta,swasta,tidak_berpengalaman
55301,E41150068,MUHAMMAD HAFIDH FIRMANSYAH,2019.0,bekerja,5,,,Data_2019_Tracer_study.csv,lainnya,lain,tidak_berpengalaman
55301,E41151584,Risqi Ahmad Sultoni,2019.0,bekerja,3,,,Data_2019_Tracer_study.csv,swasta,swasta,tidak_berpengalaman
57401,E31151214,Nita Wahyu Lianti,2019.0,belum_kerja,4,,,Data_2019_Tracer_study.csv,wiraswasta,wiraswasta,tidak_berpengalaman
57401,E31160306,Faiqotul Hikmah,2019.0,bekerja,3,,,Data_2019_Tracer_study.csv,swasta,swasta,tidak_berpengalaman
57401,E31160852,MOHAMMAD IMRAN,2020.0,mencari_kerja,0,0,0.0,Data_2020_Tracer_study.csv,0 0.0,,tidak_berpengalaman
57401,E31171030,Nur Intan Nida,2020.0,mencari_kerja,0,0,0.0,Data_2020_Tracer_study.csv,0 0.0,,tidak_berpengalaman
56401,E32170720,Sisca Nurmala,2020.0,mencari_kerja,0,0,0.0,Data_2020_Tracer_study.csv,0 0.0,,tidak_berpengalaman
56401,E32170564,M Ibnu Wildan,2020.0,mencari_kerja,4,Seblak Preanger,3.0,Data_2020_Tracer_study.csv,wiraswasta Seblak Preanger 3.0,wiraswasta seblak preanger,tidak_berpengalaman
57401,E31170717,M. Fuat,2020.0,mencari_kerja,0,0,0.0,Data_2020_Tracer_study.csv,0 0.0,,tidak_berpengalaman
56401,E32162050,Akhmad Rizky Sangaji,2020.0,belum_kerja,4,,,Data_2020_Tracer_study.csv,wiraswasta,wiraswasta,tidak_berpengalaman
56401,E32161727,Moch Samsy,2020.0,belum_kerja,4,,,Data_2020_Tracer_study.csv,wiraswasta,wiraswasta,tidak_berpengalaman
55301,E41190053,DIAN WAHYUNI,2020.0,bekerja,1,0,3.0,Data_2020_Tracer_study.csv,pemerintah 0 3.0,perintah,tidak_berpengalaman
57401,E31171653,Ahmad Faqih Hamdani,2020.0,bekerja,7,0,3.0,Data_2020_Tracer_study.csv,nirlaba 0 3.0,nirlaba,tidak_berpengalaman
55301,E41170333 ,CICILIA SELVY ERIANTHY,2021.0,wiraswasta,4,tidak ada,1.0,Data_2021_Tracer_study.csv,wiraswasta tidak ada 1.0,wiraswasta,tidak_berpengalaman
57401,E31182203 ,Rofi Berliana Mahanani,2021.0,melanjutkan_studi,3,-,,Data_2021_Tracer_study.csv,swasta -,swasta,tidak_berpengalaman
56401,E32180554 ,Akhmad Farizi,2021.0,melanjutkan_studi,3,tidak ada,4.0,Data_2021_Tracer_study.csv,swasta tidak ada 4.0,swasta,tidak_berpengalaman
55301,E41170562 ,KRISOPRAS EPIKUROS,2021.0,wiraswasta,3,PT.,4.0,Data_2021_Tracer_study.csv,swasta PT. 4.0,swasta,tidak_berpengalaman
56401,E32182061 ,OZSA DEWANGGA PRADANA,2021.0,melanjutkan_studi,2,-,,Data_2021_Tracer_study.csv,bnpp -,bnpp,tidak_berpengalaman
57401,E31200908,ROBBY ASY'ARI,2022.0,wiraswasta,4,,3.0,Data_2022_Tracer_study.csv,wiraswasta 3.0,wiraswasta,tidak_berpengalaman
57401,E31191006,AGUS ARDIANSYAH,2022.0,bekerja,4,PT PN,4.0,Data_2022_Tracer_study.csv,wiraswasta PT PN 4.0,wiraswasta,tidak_berpengalaman
56401,E32191199,RIVAI NUR ROHMAN,2022.0,wiraswasta,6,,3.0,Data_2022_Tracer_study.csv,bumn 3.0,bumn,tidak_berpengalaman
57401,E31192382,AINUR KARINA ABI RAHMADIYAN,2022.0,wiraswasta,3,,3.0,Data_2022_Tracer_study.csv,swasta 3.0,swasta,tidak_berpengalaman
57401,E31191195,NOVIEKA MUTIARA FIRDAUSIAH,2022.0,wiraswasta,4,,1.0,Data_2022_Tracer_study.csv,wiraswasta 1.0,wiraswasta,tidak_berpengalaman
56401,E32191236,DAFFA PUTRA JAYA PERMANA,2022.0,wiraswasta,4,,1.0,Data_2022_Tracer_study.csv,wiraswasta 1.0,wiraswasta,tidak_berpengalaman
55301,E41182080,MUHAMMAD ILMI QOLBI IMANNI,2022.0,wiraswasta,7,,4.0,Data_2022_Tracer_study.csv,nirlaba 4.0,nirlaba,tidak_berpengalaman
55301,E41201788,ARIF RAHMAN HAKIM,2022.0,wiraswasta,3,,3.0,Data_2022_Tracer_study.csv,swasta 3.0,swasta,tidak_berpengalaman
55301,E41200889,AHMAD FAQIH ARDINATA,2022.0,wiraswasta,3,,4.0,Data_2022_Tracer_study.csv,swasta 4.0,swasta,tidak_berpengalaman
55301,E41180632,FRENGKI ELISTANTO,2022.0,wiraswasta,1,,4.0,Data_2022_Tracer_study.csv,pemerintah 4.0,perintah,tidak_berpengalaman
57401,E31192117,AULIA DININ PUTRI ALIFIAH,2022.0,melanjutkan_studi,1,,4.0,Data_2022_Tracer_study.csv,pemerintah 4.0,perintah,tidak_berpengalaman
57401,E31191120,SHINDI FATIKA SARI,2022.0,melanjutkan_studi,3,,4.0,Data_2022_Tracer_study.csv,swasta 4.0,swasta,tidak_berpengalaman
56401,E32190383,GALANG PAHALA,2022.0,melanjutkan_studi,3,,3.0,Data_2022_Tracer_study.csv,swasta 3.0,swasta,tidak_berpengalaman
57401,E31191849,Silfi Gabrilia Choirun Nisa,2022.0,melanjutkan_studi,4,,2.0,Data_2022_Tracer_study.csv,wiraswasta 2.0,wiraswasta,tidak_berpengalaman
56401,E32190887,Amirul Faisal,2022.0,melanjutkan_studi,3,,4.0,Data_2022_Tracer_study.csv,swasta 4.0,swasta,tidak_berpengalaman
55301,E41171991,FEBRERO ARAYA KUSUMATMAJA,2022.0,wiraswasta,7,,4.0,Data_2022_Tracer_study.csv,nirlaba 4.0,nirlaba,tidak_berpengalaman
57401,E31191300,IWANG PRADIPTA DINOTO,2022.0,melanjutkan_studi,6,,3.0,Data_2022_Tracer_study.csv,bumn 3.0,bumn,tidak_berpengalaman
57401,E31191982,GALUH LAKSITA NARASWARI,2022.0,melanjutkan_studi,6,,3.0,Data_2022_Tracer_study.csv,bumn 3.0,bumn,tidak_berpengalaman
57401,E31191433,Muhammad Naufal Zuhdi,2022.0,melanjutkan_studi,6,,1.0,Data_2022_Tracer_study.csv,bumn 1.0,bumn,tidak_berpengalaman
56401,E32191840,Wahyu Musthofa,2022.0,melanjutkan_studi,1,,2.0,Data_2022_Tracer_study.csv,pemerintah 2.0,perintah,tidak_berpengalaman
55301,E41161215,HENDRA LAKSMANA,2022.0,melanjutkan_studi,6,,1.0,Data_2022_Tracer_study.csv,bumn 1.0,bumn,tidak_berpengalaman
55301,E41182248,ABDUR RAZAK SEBASTIAN,2022.0,melanjutkan_studi,7,,4.0,Data_2022_Tracer_study.csv,nirlaba 4.0,nirlaba,tidak_berpengalaman
55301,E41181028,AISHA RAHMAYANTI,2022.0,melanjutkan_studi,4,,3.0,Data_2022_Tracer_study.csv,wiraswasta 3.0,wiraswasta,tidak_berpengalaman
55301,E41182048,MUHAMMAD ANSORI,2022.0,melanjutkan_studi,4,,4.0,Data_2022_Tracer_study.csv,wiraswasta 4.0,wiraswasta,tidak_berpengalaman
55301,E41212442,AFDUL ANWAR ADANI,2022.0,melanjutkan_studi,3,,4.0,Data_2022_Tracer_study.csv,swasta 4.0,swasta,tidak_berpengalaman
55301,E41212449,RIZAL WAHYU UTAMA,2022.0,melanjutkan_studi,4,,4.0,Data_2022_Tracer_study.csv,wiraswasta 4.0,wiraswasta,tidak_berpengalaman
55301,E41212470,RIZQIAH DWI AGUSTIN,2022.0,melanjutkan_studi,3,,3.0,Data_2022_Tracer_study.csv,swasta 3.0,swasta,tidak_berpengalaman
57401,E31192264,ALVIN YUDHA EKA PRADISTYA,2022.0,melanjutkan_studi,6,,2.0,Data_2022_Tracer_study.csv,bumn 2.0,bumn,tidak_berpengalaman
55301,E41171763,TABHRANY ODI ASMORO,2022.0,melanjutkan_studi,,,,Data_2022_Tracer_study.csv,,,tidak_berpengalaman
55301,E41181135,Harisman Siihombing,2022.0,bekerja,3,-,3.0,Data_2022_Tracer_study.csv,swasta - 3.0,swasta,tidak_berpengalaman
55301,E41180749,MUHAMMAD HANAFI ABROR,2022.0,melanjutkan_studi,,,,Data_2022_Tracer_study.csv,,,tidak_berpengalaman
57401,E31191250,MUHAMMAD PUTRA ADIKUSUMA,2022.0,bekerja,3,,3.0,Data_2022_Tracer_study.csv,swasta 3.0,swasta,tidak_berpengalaman
55301,E41181773,MUHAMMAD FARHAN NUR PRATAMA,2022.0,melanjutkan_studi,,,,Data_2022_Tracer_study.csv,,,tidak_berpengalaman
55301,E41180879,YUDISTIONO,2022.0,wiraswasta,,,,Data_2022_Tracer_study.csv,,,tidak_berpengalaman
55301,E41212443,GALUH MAHENDRA,2022.0,wiraswasta,,,4.0,Data_2022_Tracer_study.csv,4.0,,tidak_berpengalaman
57401,E31192064,LUSY DWI WILUJENG,2022.0,wiraswasta,,,,Data_2022_Tracer_study.csv,,,tidak_berpengalaman
Manajemen Informatika (57401),E31191738,ABDULLAH SYIHABUDIN AL ACHYAR,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,3 - Staff,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 3 - Staff",lain tulis staff,tidak_berpengalaman
Teknik Informatika (55301),E41201747,M. YOGA ANDRIAN PUTRA,2024.0,belum_kerja,Belum Bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,Belum Bekerja 4 - Freelance/Kerja Lepas,belum kerja freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31210257,MUHAMMAD ZIDAN PRASETYO,2024.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
Manajemen Informatika (57401),E31211910,DAVIN FADHLILLAH YUDANTO,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41201781,WIDYA OCTAVIOLA NURYA,2024.0,belum_kerja,6 - BUMN/BUMD,,2 - Co-Founder,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 2 - Co-Founder,bumn bumd founder,tidak_berpengalaman
Manajemen Informatika (57401),E31211936,RAHMANDA RICO LUTFIANSYAH,2024.0,belum_kerja,7 - Institusi/Organisasi Multilateral,,1 - Founder,Data_2024_Tracer_study.csv,7 - Institusi/Organisasi Multilateral 1 - Founder,institusi organisasi multilateral founder,tidak_berpengalaman
Teknik Informatika (55301),E41202091,NUR HASANAH,2024.0,belum_kerja,6 - BUMN/BUMD,,1 - Founder,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 1 - Founder,bumn bumd founder,tidak_berpengalaman
Teknik Informatika (55301),E41200569,NURILLAHILWAFI,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,1 - Founder,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 1 - Founder",lain tulis founder,tidak_berpengalaman
Manajemen Informatika (57401),E31211906,STEVEN RIO CHANDRA PURNAMA,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas",lain tulis freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202429,AZRIL NUR RAHMAN,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31210717,FARA ISTIGHFAR SARI,2024.0,belum_kerja,belum bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,belum bekerja 4 - Freelance/Kerja Lepas,belum kerja freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202281,BAHRUL AJI SANTOSO,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,1 - Founder,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 1 - Founder,wiraswasta usaha sendiri founder,tidak_berpengalaman
Manajemen Informatika (57401),E31211900,MARSHA ARLINDA PUTRI,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31211896,REIHAN JANUWISESA FATIH ATTARIANSYAH,2024.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
Manajemen Informatika (57401),E31210592,YUYUN INE FEBRIANI,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas",lain tulis freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41201153,BIMA ANGGARA WIRASATYA,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31210385,ELA ERWITA SISILIA,2024.0,belum_kerja,6 - BUMN/BUMD,,3 - Staff,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 3 - Staff,bumn bumd staff,tidak_berpengalaman
Teknik Informatika (55301),E41201302,FAHMI DAFRIN MAULANA,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202383,ARIEF ANASTIAR SUHARSONO,2024.0,belum_kerja,6 - BUMN/BUMD,,1 - Founder,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 1 - Founder,bumn bumd founder,tidak_berpengalaman
Teknik Komputer (56401),E32211535,MOHAMMAD IRNANDA,2024.0,belum_kerja,Belum Bekerja,,1 - Founder,Data_2024_Tracer_study.csv,Belum Bekerja 1 - Founder,belum kerja founder,tidak_berpengalaman
Teknik Informatika (55301),E41202280,ASIF MAHARDHIKA RAMADAN,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202254,NIKI MUHAMMAD NAFIS,2024.0,belum_kerja,Belum Bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,Belum Bekerja 4 - Freelance/Kerja Lepas,belum kerja freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31212365,BAGUS DAFFA FIRMANSYAH,2024.0,belum_kerja,6 - BUMN/BUMD,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 4 - Freelance/Kerja Lepas,bumn bumd freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31212295,DAFFA ATHALA ZAGHAZY,2024.0,belum_kerja,3 - Perusahaan swasta,,2 - Co-Founder,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 2 - Co-Founder,usaha swasta founder,tidak_berpengalaman
Teknik Komputer (56401),E32210989,NARARGA MAULANA,2024.0,belum_kerja,3 - Perusahaan swasta,,3 - Staff,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
Teknik Komputer (56401),E32210755,SAHRUL GUNAWAN,2024.0,belum_kerja,3 - Perusahaan swasta,,1 - Founder,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 1 - Founder,usaha swasta founder,tidak_berpengalaman
Teknik Informatika (55301),E41201212,MUHAMMAD AKBAR RAYYAN AL-FATH,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210897,MUFIDAH EKA ALVA NADYA,2024.0,belum_kerja,6 - BUMN/BUMD,Bumn,1 - Founder,Data_2024_Tracer_study.csv,6 - BUMN/BUMD Bumn 1 - Founder,bumn bumd bumn founder,tidak_berpengalaman
Teknik Informatika (55301),E41202411,LUQMAN HAKIM,2024.0,belum_kerja,3 - Perusahaan swasta,,1 - Founder,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 1 - Founder,usaha swasta founder,tidak_berpengalaman
Teknik Informatika (55301),E41200415,NOGA MUKTIWATI,2024.0,belum_kerja,6 - BUMN/BUMD,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 4 - Freelance/Kerja Lepas,bumn bumd freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31212340,AHMAD SAIFUL SEPTIAWAN,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,1 - Founder,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 1 - Founder,wiraswasta usaha sendiri founder,tidak_berpengalaman
Teknik Komputer (56401),E32210743,GUSTI ARLIZ NANDITO,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas",lain tulis freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32211375,NELSEN ARDIANSAH,2024.0,belum_kerja,Belum bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,Belum bekerja 4 - Freelance/Kerja Lepas,belum kerja freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210111,DANY FERDYANSYAH,2024.0,belum_kerja,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas,organisasi non profit lembaga swadaya masyarakat freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202285,ALI IMRON SAEFULLAH,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210675,SYLVA ADITYA ARFIANSYAH,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,3 - Staff,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 3 - Staff",lain tulis staff,tidak_berpengalaman
Teknik Komputer (56401),E32211395,LUTFI ARDIANSYAH,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210736,MUHAMMAD NAUFAL AFFAN SAMUDRA,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas",lain tulis freelance kerja lepas,tidak_berpengalaman
Manajemen Informatika (57401),E31211386,REFYAN GIGAS ZIDANE HERDINAND PRATAMA,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas",lain tulis freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210813,MUTYARA PERTIWI,2024.0,belum_kerja,"5 - Lainnya, Tuliskan",,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,"5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas",lain tulis freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202298,FIRDAUS FIRMANSYAH,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41200363,ALFIAN EZZA RADITYA,2024.0,belum_kerja,6 - BUMN/BUMD,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 4 - Freelance/Kerja Lepas,bumn bumd freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E32211505,MUHAMMAD AMAN AHCYAD,2024.0,belum_kerja,Belum bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,Belum bekerja 4 - Freelance/Kerja Lepas,belum kerja freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32212364,RIDHO DWICAHYA WIJAYA,2024.0,belum_kerja,Tidak Bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,Tidak Bekerja 4 - Freelance/Kerja Lepas,kerja freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210095,DAMAR RAWUH SARJITO,2024.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
Teknik Komputer (56401),E32210053,DIMAS DWI APRILIYANTO,2024.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
Teknik Komputer (56401),E32210055,RACHMAN TIO MAULANA,2024.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
Teknik Komputer (56401),E32200666,MOHAMMAD RODIVOL HAK,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,Better Of Life,1 - Founder,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri Better Of Life 1 - Founder,wiraswasta usaha sendiri better life founder,tidak_berpengalaman
Manajemen Informatika (57401),E31211055,AHMAD MAULANA SUBANDRIO,2024.0,belum_kerja,1 - Instansi pemerintah,,1 - Founder,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 1 - Founder,instansi perintah founder,tidak_berpengalaman
Teknik Komputer (56401),E32212287,RAGA MULYA PRATAMA PUTRA,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32200194,NANDA FATHURAHMA,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,1 - Founder,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 1 - Founder,wiraswasta usaha sendiri founder,tidak_berpengalaman
Teknik Komputer (56401),E32210446,RYAN AJENG SUKMA DEWI TITAH PRATAMA,2024.0,belum_kerja,belom bekerja,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,belom bekerja 4 - Freelance/Kerja Lepas,bom kerja freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32210771,M. FAJARSYAH EKA PERMANA,2024.0,belum_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32212333,INDRA WIJAYA,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,,1 - Founder,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri 1 - Founder,wiraswasta usaha sendiri founder,tidak_berpengalaman
Teknik Komputer (56401),E32210826,RIZKI ROMADHONI,2024.0,belum_kerja,3 - Perusahaan swasta,,1 - Founder,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 1 - Founder,usaha swasta founder,tidak_berpengalaman
Teknik Komputer (56401),E32212138,CINDY AFCARINA,2024.0,belum_kerja,3 - Perusahaan swasta,,3 - Staff,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
Teknik Komputer (56401),E32210344,REZA ANGGARA JANUARTA PUTRA BAYU SYAFIRA,2024.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2024_Tracer_study.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
Teknik Komputer (56401),E32212299,ANANDA ANGGI DWI CAHYO,2024.0,belum_kerja,Berencana ingin bekerja di instansi pemerintah atau di BUMN,,3 - Staff,Data_2024_Tracer_study.csv,Berencana ingin bekerja di instansi pemerintah atau di BUMN 3 - Staff,rencana ingin kerja instansi perintah bumn staff,tidak_berpengalaman
Teknik Komputer (56401),E32211429,I PUTU SRI KRESNA LORU ARIASA,2024.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,Freelance,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,4 - Wiraswasta/perusahaan sendiri Freelance 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32212309,KHOIRUL TAMAMI,2024.0,belum_kerja,6 - BUMN/BUMD,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 4 - Freelance/Kerja Lepas,bumn bumd freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41202408,BRIANTI BELLA PRASNITIA,2024.0,belum_kerja,3 - Perusahaan swasta,,1 - Founder,Data_2024_Tracer_study.csv,3 - Perusahaan swasta 1 - Founder,usaha swasta founder,tidak_berpengalaman
Teknik Komputer (56401),E32212239,NURUL HUDA,2024.0,belum_kerja,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas,organisasi non profit lembaga swadaya masyarakat freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32211014,HABIB MAULANA,2024.0,belum_kerja,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat,,4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas,organisasi non profit lembaga swadaya masyarakat freelance kerja lepas,tidak_berpengalaman
Teknik Komputer (56401),E32212181,FITRAH DESTRA PUTRA,2024.0,belum_kerja,6 - BUMN/BUMD,,2 - Co-Founder,Data_2024_Tracer_study.csv,6 - BUMN/BUMD 2 - Co-Founder,bumn bumd founder,tidak_berpengalaman
Teknik Informatika (55301),E41182272,BAYU JAYA ILHAM ALHAMDA,2024.0,belum_kerja,Traveloka,TRAVELOKA (ND TRAVELINDO),4 - Freelance/Kerja Lepas,Data_2024_Tracer_study.csv,Traveloka TRAVELOKA (ND TRAVELINDO) 4 - Freelance/Kerja Lepas,traveloka traveloka travelindo freelance kerja lepas,tidak_berpengalaman
Teknik Informatika (55301),E41201220,INDAH NUR MAHMUDA,2024.0,belum_kerja,,,,Data_2024_Tracer_study.csv,,,tidak_berpengalaman
Manajemen Informatika (57401),E31210927,INTAN DELVE ATIKA,2024.0,melanjutkan_studi,,,,Data_2024_Tracer_study.csv,,,tidak_berpengalaman
Manajemen Informatika (57401),E31210287,ABEL JATAYU WAHYU AJI,2024.0,belum_kerja,,,,Data_2024_Tracer_study.csv,,,tidak_berpengalaman
Manajemen Informatika (57401),E31211810,SITI RUSDANIYAH,2024.0,bekerja,,,,Data_2024_Tracer_study.csv,,,tidak_berpengalaman
Teknik Komputer (56401),E32211859,AHMAD RIDHO,2024.0,belum_kerja,,,,Data_2024_Tracer_study.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221235,SITI LAILATUL AMALIA,2025.0,mencari_kerja,3 - Perusahaan swasta,,3 - Staff,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221213,NURUL QOMARIA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221281,MUHAMMAD RIZAL FAHLEVI,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222492,JA'FAR SHODIQ,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222519,MOH. DANI KURNIAWAN SUGIARTO,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221248,BELLA ERVINA FERDIANTI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221247,DIVIA ANGGRAINI,2025.0,mencari_kerja,7 - Institusi/Organisasi Multilateral,,,Data_2025_Tracer_study_D3MIF.csv,7 - Institusi/Organisasi Multilateral,institusi organisasi multilateral,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222451,ADILA JELITA PUTRI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220215,NUR MITA UPI LESTARI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,Jasain aja,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,4 - Wiraswasta/perusahaan sendiri Jasain aja 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri jasain freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222461,GADIS MICHELLIA PUTRI,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221480,NOVITA YUNDA FAJRIYAH,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221305,MALEMNA SWARI TARIGAN,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221259,Ratna Sari Dewi,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222656,JEREMY VAHARDIKA JAYA,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222327,FARISA RAHMASARI,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222455,Salma Banafsha Safa Fitria,2025.0,mencari_kerja,6 - BUMN/BUMD,,2 - Co-Founder,Data_2025_Tracer_study_D3MIF.csv,6 - BUMN/BUMD 2 - Co-Founder,bumn bumd founder,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222398,Wisnu Hadi Mahendra,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220218,ELSA SURYA AGUSTIN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221236,REYNAVA AURELLIA DAMAYANTI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220197,IHYA ULUMUDDIN,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221142,MUHAMMAD HERIYANTO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222387,SEPTIANO RIZKI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,3 - Staff,Data_2025_Tracer_study_D3MIF.csv,4 - Wiraswasta/perusahaan sendiri 3 - Staff,wiraswasta usaha sendiri staff,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222680,NADEA MEFIRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221420,ANINDYA HUDAA KUMALA TANTRI,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221209,Ayu Eka Ciptasari,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222823,MARCELLINO RHADITYA ROSANDI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221108,SHAMITA YASMIN R,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222307,Alfiansyah Pradinata Putra,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222756,SYEBA WARDAHANI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221484,MIFTAH FARID GUNAWAN,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222365,ADINDA KHOFIFA AZIZ,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",Politeknik Negeri jember,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) Politeknik Negeri jember 4 - Freelance/Kerja Lepas",lain tulis f1102 politeknik negeri jember freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221225,RIFQI NURUL QOMARIAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222586,NURUL FAJRI MAULIDYA,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222541,MUHAMMAD ARYA FATHOROZI,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222658,LINTANG SURURUM SALSAFAIZ MARTALIA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221299,OKTAVIARLEN SETYA WARDANI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221315,WILLIAN ANGGI DEVAYU,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222629,SHERLY WELYANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222389,Muhammad Alfin Faiz,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220442,Ulil Farhah,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222534,ADINDA WIDYA PUTRI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222508,Diana Oktavia Rachmad,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221264,GITA YASINDA PUTRI CAHYANI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221244,MUHAMMAD AGI PRASETYO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221325,MEY NUR AFNI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220954,MUHAMAD FAIS AIZAT,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220577,DINDA NAUSA KUSUMA WARDANI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220334,ISNAINI QAYYUM AZIZAH,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D3MIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221357,NISWAH TRIAS QUROTUL A'YUN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222653,FIRDATURROFIAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222870,SATRIA HILMI AN'AMTA CAHYONO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222313,AGYA RIZKINTA WILDANTI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221269,Mohammad Iqbal Abdillah,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221263,TEGAR FEBRIANSYAH PUTRA NURULLAH,2025.0,mencari_kerja,3 - Perusahaan swasta,HIJIGROUP,,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta HIJIGROUP,usaha swasta hijigroup,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222450,NUR FUADI MUHAMMAD,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222582,Hilda Eva Stefhany,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,,Data_2025_Tracer_study_D3MIF.csv,4 - Wiraswasta/perusahaan sendiri,wiraswasta usaha sendiri,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222691,ANNAJWA SHOHIBUZZAHRO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222606,AHMAD ZAENAL ABIDIN,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220412,ALFIN FADLI,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222851,ENDY FADLULLAH,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222888,ALIZAR MUHARROM,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,,Data_2025_Tracer_study_D3MIF.csv,4 - Wiraswasta/perusahaan sendiri,wiraswasta usaha sendiri,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222641,Firman Agung Alamsyah,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222381,BRAHMI HAWA SAWITRI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222344,SOVIA LAJUBA,2025.0,mencari_kerja,,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,4 - Freelance/Kerja Lepas,freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222663,ROFIATUL ANDAWIYAH,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",PT. Lambda Solusi Informatika,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) PT. Lambda Solusi Informatika",lain tulis f1102 lambda solusi informatika,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221397,VICKY FERNANDO ANGGARA PUTRA IKHWANTO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222379,FAHMI KURNIAWAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221009,AISYAH SALSHABILLA SISKA PUTRI,2025.0,belum_kerja,3 - Perusahaan swasta,PT. Young Tree,,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta PT. Young Tree,usaha swasta young tree,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221306,MUHAMMAD RAMA PRADIPA WIJAYA,2025.0,mencari_kerja,3 - Perusahaan swasta,,3 - Staff,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222696,FITRI AMALIA SAQILA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",PT China Communications Construction Indonesia (CCCI).,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) PT China Communications Construction Indonesia (CCCI). 4 - Freelance/Kerja Lepas",lain tulis f1102 china communications construction indonesia ccci freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221407,M. FAHIM DAVID BACHTIAR,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222518,MUHAMMAD ALFIN ALFAUZI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222765,DINA AYU AISYAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31210646,ATIKAH NURI HAZMA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",Yasmine Fashion,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) Yasmine Fashion",lain tulis f1102 yasmine fashion,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221245,ALFIONINA DWI RACHMALIA,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220095,GALUH REVIKO SATYA KIRANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221222,DIYO ANGGARA PRADIPA PUTRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222366,Arya Advicenna,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221360,IQBAL AMIN,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220277,PUTRI AYU WULANDARI,2025.0,mencari_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2025_Tracer_study_D3MIF.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222540,Haikal Muna'amul Islam,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31200086,DANIEL ABDULLAH AFANDI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",Belum Mendapatkan Pekerjaan,,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) Belum Mendapatkan Pekerjaan",lain tulis f1102 belum dapat kerja,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222707,ADELIA SARI DEWI,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222544,Sultan Arya Maulana,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222854,Irfan Dimas Riyadi,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",belum ada,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,"5 - Lainnya, Tuliskan (f1102) belum ada 4 - Freelance/Kerja Lepas",lain tulis f1102 belum freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222846,MOCHAMMAD GINATA FEBRYANSYAH,2025.0,belum_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3MIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222882,Stephen Gesityan,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31220567,PUTRI NABILAH HUWAIDAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222881,ALE ANDRA PRIANDANI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3MIF.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221388,Alya Nirmala Putri,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222699,MOCH ADIM RIZKY SYAH PUTRA,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31222596,ALYA LUFRIDA AFIFAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
19. Manajemen Informatika (57401),E31221361,Algoritma Dwifebri fathiyakan,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3MIF.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221234,RAHMAD ERA SUGIARTO,2025.0,mencari_kerja,,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,4 - Freelance/Kerja Lepas,freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32222388,SYAHMI NAUFAL SAPUTRA,2025.0,mencari_kerja,,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,4 - Freelance/Kerja Lepas,freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32220022,TUTIK NOER KHOLIFAH,2025.0,mencari_kerja,,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,4 - Freelance/Kerja Lepas,freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32220375,MUHAMMAD YUSUF SHOLEHUDIN RENDY,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221231,REYHAN NAUFAL TSAQIF,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D3TKK.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
20. Teknik Komputer (56401),E32222300,SHAMIR FAIZAL THALIB,2025.0,mencari_kerja,3 - Perusahaan swasta,Pt. Semen imasco asiatic,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta Pt. Semen imasco asiatic,usaha swasta semen imasco asiatic,tidak_berpengalaman
20. Teknik Komputer (56401),E32220274,MOCH RENDY ARDIYANTO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221274,SAKTI BAYU NUGRAHA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32220671,AHMAD ADIB AKBAR,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221002,Muhammad Ardi Aziz Saputra,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,,Data_2025_Tracer_study_D3TKK.csv,4 - Wiraswasta/perusahaan sendiri,wiraswasta usaha sendiri,tidak_berpengalaman
20. Teknik Komputer (56401),E32222748,IQBAL FIKHRIANSYAH ROMADHONA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222626,DIYAN SHINTIA BELLA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222585,YUSRIL ROMIZA PUTRA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221390,SERIAN ANAK AYUT,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",belum memiliki pekerjaan,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102) belum memiliki pekerjaan 4 - Freelance/Kerja Lepas",lain tulis f1102 belum milik kerja freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32222403,Ahmad Furqon Saputra,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222434,YOVITA SARI CAHYANINGTYAS,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222503,MUHAMMAD RISKI ARDIANSYAH,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221196,RIFQY ZIDANE HARTONO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32222444,Wildan Abbrhory,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",0,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102) 0 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32222530,MOHAMMAD RIZKY ROMADHON,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222650,MUHAMMAD HISYAMUDDIN,2025.0,bekerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32220549,URIP AGILA SETIO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",-,3 - Staff,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102) - 3 - Staff",lain tulis f1102 staff,tidak_berpengalaman
20. Teknik Komputer (56401),E32221220,Muhammad Miftahul Huda,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222571,MOCHAMAD ALBANUS FAHREZI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221098,JERY NAUVAL NICKOLAS,2025.0,mencari_kerja,6 - BUMN/BUMD,PLN Icon Plus SBU RJBT,,Data_2025_Tracer_study_D3TKK.csv,6 - BUMN/BUMD PLN Icon Plus SBU RJBT,bumn bumd pln icon plus sbu rjbt,tidak_berpengalaman
20. Teknik Komputer (56401),E32222548,NADIA EMILIANA RAISSA,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222628,GHAIDA SORAYA M.,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221354,MOCH. RIZQ YUNIARIEVAL,2025.0,belum_kerja,6 - BUMN/BUMD,belum kerja,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,6 - BUMN/BUMD belum kerja 4 - Freelance/Kerja Lepas,bumn bumd belum kerja freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32221146,JOHARDIO EKA PUTRA ARIV,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222572,AMALIA KHOIRUN NISA',2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222484,EGA SAPUTRA WICAKSANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221324,MUHAMMAD ABIL SYUGRON HABIBILLAH,2025.0,mencari_kerja,7 - Institusi/Organisasi Multilateral,,,Data_2025_Tracer_study_D3TKK.csv,7 - Institusi/Organisasi Multilateral,institusi organisasi multilateral,tidak_berpengalaman
20. Teknik Komputer (56401),E32221349,MOHAMMAD FARIS VICO PRADIFA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222371,Ferdiansyah Maula Syarif,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222580,ALI SYARIEF,2025.0,mencari_kerja,3 - Perusahaan swasta,Pt.Iwip,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta Pt.Iwip,usaha swasta iwip,tidak_berpengalaman
20. Teknik Komputer (56401),E32221431,DELI SAFITRI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,Ayam Petelur Pak Dela,3 - Staff,Data_2025_Tracer_study_D3TKK.csv,4 - Wiraswasta/perusahaan sendiri Ayam Petelur Pak Dela 3 - Staff,wiraswasta usaha sendiri ayam telur dela staff,tidak_berpengalaman
20. Teknik Komputer (56401),E32220213,SADDAM ANDIKA PUTRA,2025.0,belum_kerja,3 - Perusahaan swasta,Rumah,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta Rumah,usaha swasta rumah,tidak_berpengalaman
20. Teknik Komputer (56401),E32221348,DWI FITRIYAH KHAERULINA,2025.0,mencari_kerja,1 - Instansi pemerintah,,,Data_2025_Tracer_study_D3TKK.csv,1 - Instansi pemerintah,instansi perintah,tidak_berpengalaman
20. Teknik Komputer (56401),E32220937,AHYAR NUR ALIF,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221287,MONANG MANGATA TAMPUBOLON,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
20. Teknik Komputer (56401),E32222411,Alfian Dani Ahmad Prasetyo,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221271,LINDA DWI WINANDHA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222685,AMRI MURSALIINA DARINTO,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
20. Teknik Komputer (56401),E32222481,ARDHA PRIA PRAMBUDI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,1 - Founder,Data_2025_Tracer_study_D3TKK.csv,4 - Wiraswasta/perusahaan sendiri 1 - Founder,wiraswasta usaha sendiri founder,tidak_berpengalaman
20. Teknik Komputer (56401),E32222855,Imam Ghazali Munir,2025.0,mencari_kerja,1 - Instansi pemerintah,,,Data_2025_Tracer_study_D3TKK.csv,1 - Instansi pemerintah,instansi perintah,tidak_berpengalaman
20. Teknik Komputer (56401),E32221335,HENDRI GUNAWAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222352,IVAN ARIESNA NUGROHO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222693,MOCHAMAD ALIF RIDHO AULIA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222304,MUCHAMAD NASRULLAH SYAHBANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221375,KEVIN RIANG EKA PRASETYA,2025.0,mencari_kerja,6 - BUMN/BUMD,PLN ICON PLUS,,Data_2025_Tracer_study_D3TKK.csv,6 - BUMN/BUMD PLN ICON PLUS,bumn bumd pln icon plus,tidak_berpengalaman
20. Teknik Komputer (56401),E32221275,FARHAN PRATAMA PUTRA,2025.0,mencari_kerja,6 - BUMN/BUMD,PLN ICON PLUS SURABAYA,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,6 - BUMN/BUMD PLN ICON PLUS SURABAYA 4 - Freelance/Kerja Lepas,bumn bumd pln icon plus surabaya freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32222396,RIZAL MAULANA ALIF,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222672,VERGIAWAN KURNIALISTIANTO,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D3TKK.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
20. Teknik Komputer (56401),E32222440,ALIF ABDAUL KARIM,2025.0,belum_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
20. Teknik Komputer (56401),E32220565,Adam Darmawansa,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222868,DANDHI DWI ARI PRASETYA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222363,ROBBY DWI JAYANTO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222356,ALIYA NABILLA PUTRI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32220496,BIMA PUTRA ADITYA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221343,ANANG SANDI PRASETYO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221328,MOHAMMAD IRSYAD ROSIDI,2025.0,mencari_kerja,3 - Perusahaan swasta,PT Global Media Data Prima,3 - Staff,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta PT Global Media Data Prima 3 - Staff,usaha swasta global media data prima staff,tidak_berpengalaman
20. Teknik Komputer (56401),E32221364,Nisa Carolina Putri,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222865,AHMAD DHANI ALVARISI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222869,GALIH RIANTIARNO,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32212281,Ghilman Roif Zakiri,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221413,MOH. ANWAR,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221425,KELVIN MAULANA SHOFANI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222437,RIDHO FAISAL HAKKI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222349,AKHMAD MARTA ADI PUTRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221434,TEGUH SETYO BUDI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32222377,Akbar Maulana Agritanto,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222362,FASHA GALIH PUTRA ARIFANDI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32220150,RAFI ABIYYU YAKIN,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
20. Teknik Komputer (56401),e32222568,BIMO RAHMAD DIANSYAH,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222430,DANIEL KEANNY HEBERT,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32222355,Putraku Nabil Rabbani,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D3TKK.csv,,,tidak_berpengalaman
20. Teknik Komputer (56401),E32221448,AIDIL ARDIANSYAH,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D3TKK.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
20. Teknik Komputer (56401),E32222341,NURUL RIZQI AKBARSYAH ASH SHIDDIQIE,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D3TKK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
20. Teknik Komputer (56401),E32221382,FATHUR RIZQI GINANDA ARIKUSUMA,2025.0,belum_kerja,3 - Perusahaan swasta,,3 - Staff,Data_2025_Tracer_study_D3TKK.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
Teknik Informatika (55301),E41232153,RIDLOWAN EKA NUR CAHYA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
Teknik Informatika (55301),E41232322,SYABRIANT BAGUS YANUAR,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
Teknik Informatika (55301),E41180538,Rendra Adji Prayudi,2025.0,mencari_kerja,3 - Perusahaan swasta,PT Mulya Menara Sejahtera,,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta PT Mulya Menara Sejahtera,usaha swasta mulya menara sejahtera,tidak_berpengalaman
21. Teknik Informatika (55301),E41202152,putri Adelwis,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",belum,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) belum 4 - Freelance/Kerja Lepas",lain tulis f1102 belum freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41202502,WIAN ADIYATMA BISMA RAZAAK,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41201544,NOVITA BENING WIDYASTUTI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41232033,ALVIN YUDHA EKA PRADISTYA,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41232270,DEDI HARIYANTO,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
21. Teknik Informatika (55301),E41232102,Iwang Pradipta Dinoto,2025.0,belum_kerja,1 - Instansi pemerintah,,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,1 - Instansi pemerintah 3 - Staff,instansi perintah staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41232545,Desy Nur Alviah,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41232176,BAGUS IKA PUTRANTO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
21. Teknik Informatika (55301),E41212022,DEO ANDREAS SYAPUTRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210014,FAISAL OKTABRIAN SHOLIHIN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210003,EDY ATTHOILLAH,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41211496,NILLA PUTRI ROSIDANIA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210373,NADIA AYU SAFITRI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210026,REGINA JUNIANTIKA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210369,RAIHAN ACHMAD DANI FIRMANSYAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210089,DAFFA AFIFI SYAHRONY,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210372,KURROTA AKYUN,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210005,NAJWA AMALIA MAHARANI,2025.0,mencari_kerja,3 - Perusahaan swasta,Megata,,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta Megata,usaha swasta megata,tidak_berpengalaman
21. Teknik Informatika (55301),E41211247,POPO ZAKARIA,2025.0,mencari_kerja,3 - Perusahaan swasta,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas,usaha swasta freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210602,RESTU FAHIMUROID,2025.0,melanjutkan_studi,,,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,3 - Staff,staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41210004,Mokhamad Farhan Abdillah,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,Freelance,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri Freelance 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210800,FARHAN HILMY ARWANTO,2025.0,mencari_kerja,7 - Institusi/Organisasi Multilateral,,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,7 - Institusi/Organisasi Multilateral 3 - Staff,institusi organisasi multilateral staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41210674,ATHIYAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),e41211491,Rayhan Febriansyah,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210930,FILLAH SEPTIAN,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
21. Teknik Informatika (55301),E41210679,FAQIH MUSTAFA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212169,ELISA FEBRIAN SHOLEHA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212166,FARA DERLIANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212128,ANDINI PUTRI RAMADHANI,2025.0,mencari_kerja,,-,,Data_2025_Tracer_study_D4TIF.csv,-,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210069,SHILMIA MADINA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210096,BABYLINA VINDAROSITA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211320,Achmad Zakariya,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
21. Teknik Informatika (55301),E41232544,VENI KURNIA DEWI,2025.0,mencari_kerja,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat,Sekolah,,Data_2025_Tracer_study_D4TIF.csv,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat Sekolah,organisasi non profit lembaga swadaya masyarakat sekolah,tidak_berpengalaman
21. Teknik Informatika (55301),E41211144,ADHE WAHYU TRILAKSANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210998,JACINDA OLGA NABILA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",-,,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) -",lain tulis f1102,tidak_berpengalaman
21. Teknik Informatika (55301),E41212091,AISYAH FIKRI NABILAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210477,FIKRI AHDIAR,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,RELIS,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri RELIS 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri rel freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41211039,AIKO MAWARDI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210099,FIRDIYATUS SHOLIHAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210436,THORIQ LUKMAN HAKIM,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
21. Teknik Informatika (55301),E41202343,PUTRI SALSABHILA FAHIRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212168,INDRA PRASETYO WIJAYA,2025.0,mencari_kerja,6 - BUMN/BUMD,-,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD -,bumn bumd,tidak_berpengalaman
21. Teknik Informatika (55301),E41212253,KRISNA CHOIRIL ANDIKA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211969,AHMAD TAUFIQ RIDHO'I,2025.0,bekerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210598,EKA SULISTYANINGSIH,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
21. Teknik Informatika (55301),E41210731,IDA SEVIA,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
21. Teknik Informatika (55301),E41212069,ALIF TRIADI AGUNG WICAKSONO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
21. Teknik Informatika (55301),E41211478,GYMNASTIAR ALMA GHIFARI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211245,MUHAMMAD REZA IVANO PAHLEVI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41232549,RISMA DEWI SEPTIANI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212097,AKNEZ NURIL MAHMUDA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41232541,MUHAMMAD FARRAS WIRAWAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210132,GEMA HANNA NAPITUPULU,2025.0,mencari_kerja,6 - BUMN/BUMD,MASPION,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD MASPION,bumn bumd maspion,tidak_berpengalaman
21. Teknik Informatika (55301),E41212025,IRMA FIRNANDA,2025.0,mencari_kerja,6 - BUMN/BUMD,PT PETROKIMIA GRESIK,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD PT PETROKIMIA GRESIK 3 - Staff,bumn bumd petrokimia gresik staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41232537,Anang Prayoga,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211551,AHMAD HIPNIE KHOIRI,2025.0,mencari_kerja,,infinite,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,infinite 4 - Freelance/Kerja Lepas,infinite freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41232538,HUSNUL PUTRI CANDRA BUANA,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212174,FATHAN MAULANA RIFQI HARTONO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211978,AMELIA FAWWAZ ZAIN,2025.0,mencari_kerja,,PELINDO,,Data_2025_Tracer_study_D4TIF.csv,PELINDO,pelindo,tidak_berpengalaman
21. Teknik Informatika (55301),E41210172,ADITYA IBRAR ABDILLAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212151,ISMIATI EKA OKTAFIA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212101,EKA PUTRI YULIANA,2025.0,mencari_kerja,6 - BUMN/BUMD,,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD,bumn bumd,tidak_berpengalaman
21. Teknik Informatika (55301),E41211128,KRISTOPHER YOHANES IMMANUEL TAMBUNAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212068,ADELIA AYU AVISTA,2025.0,mencari_kerja,6 - BUMN/BUMD,,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD 3 - Staff,bumn bumd staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41211217,GIGIH DWI CAHYO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210716,KHOFIFAH AINURROHMAH,2025.0,mencari_kerja,6 - BUMN/BUMD,BUMN,,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD BUMN,bumn bumd bumn,tidak_berpengalaman
21. Teknik Informatika (55301),E41232547,FIRDA ULFA UNSILAH,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41232542,MUHAMMAD ILHAM YUAL MAULANA,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,milik sensiri,1 - Founder,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri milik sensiri 1 - Founder,wiraswasta usaha sendiri milik sensiri founder,tidak_berpengalaman
21. Teknik Informatika (55301),E41232540,MUHAMAD BAYU CANDRA PAMUNGKAS,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210002,RESTU AJI PRASETYO SAPUTRA,2025.0,mencari_kerja,,-,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,- 3 - Staff,staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41211570,WISHAL AZHARYAN AL HISYAM,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,1 - Founder,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri 1 - Founder,wiraswasta usaha sendiri founder,tidak_berpengalaman
21. Teknik Informatika (55301),E41211408,DAFFA FAUZI RAHMAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210766,Akbar Ramadhani Firdaus,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210603,DAVID ARROZAQI,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211220,YUNAN ADITYA PRIMAWATDANA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211107,MUHAMMAD ZAINAL ABIDIN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210798,Yusuf Firmansyah Adi Basuni,2025.0,melanjutkan_studi,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212285,ELISA CHRISTIAN ALFRIDO MANTOLAS,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211257,MUHAMMAD ILHAM IKHWANUL AKRAM,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",belum bekerja,,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) belum bekerja",lain tulis f1102 belum kerja,tidak_berpengalaman
21. Teknik Informatika (55301),E41211111,ALIF IMANULLAH KRISNA ALAM,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212263,ZULFIANTI RAHMAWATI ASHILAH,2025.0,mencari_kerja,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat,-,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,2 - Organisasi non-profit/Lembaga Swadaya Masyarakat - 4 - Freelance/Kerja Lepas,organisasi non profit lembaga swadaya masyarakat freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210698,MUHAMMAD MAULANA MALIK IBRAHIM,2025.0,mencari_kerja,1 - Instansi pemerintah,Pemerintah Daerah,,Data_2025_Tracer_study_D4TIF.csv,1 - Instansi pemerintah Pemerintah Daerah,instansi perintah perintah daerah,tidak_berpengalaman
21. Teknik Informatika (55301),E41210960,Rio Javier Reyhan,2025.0,mencari_kerja,7 - Institusi/Organisasi Multilateral,,,Data_2025_Tracer_study_D4TIF.csv,7 - Institusi/Organisasi Multilateral,institusi organisasi multilateral,tidak_berpengalaman
21. Teknik Informatika (55301),E41212254,Fahmy Rosyadi,2025.0,mencari_kerja,3 - Perusahaan swasta,Profile Image Studio,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta Profile Image Studio 4 - Freelance/Kerja Lepas,usaha swasta profile image studio freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41212217,ABDULLAH ALI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211349,FREDA ADI FARDANA,2025.0,mencari_kerja,3 - Perusahaan swasta,,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41211473,RINA WULANDHARI,2025.0,wiraswasta,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211200,EGA SYAHRUL RAMADHANTO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211601,MUHAMMAD LUTFI ZE'IN AMINULLAH,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41191074,EVRA MARIO SIRAIT,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210022,LIZA INDARWATI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,ADB Programming,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri ADB Programming 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri adb programming freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41211463,REZKY AGUS SETIAWAN,2025.0,belum_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
21. Teknik Informatika (55301),E41210905,NABILA ZHAFARINA,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210730,ADINDA EKA MAYANG WIJAYANTI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211975,ANIK SAHILAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211194,LUTFI AMELIYA PUTRI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,Mad Buah Home,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri Mad Buah Home 4 - Freelance/Kerja Lepas,wiraswasta usaha sendiri mad buah home freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41211319,AMMAR AKHTAR ADDANY,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210647,KHAIRATUZ ZAHRO,2025.0,belum_kerja,6 - BUMN/BUMD,,3 - Staff,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD 3 - Staff,bumn bumd staff,tidak_berpengalaman
21. Teknik Informatika (55301),E41212252,MAULANA IBRAHIM,2025.0,mencari_kerja,6 - BUMN/BUMD,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,6 - BUMN/BUMD 4 - Freelance/Kerja Lepas,bumn bumd freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41212368,BHAKTI DWI RAMADHANI HENDARTO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",Tidak Ada,1 - Founder,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) Tidak Ada 1 - Founder",lain tulis f1102 founder,tidak_berpengalaman
21. Teknik Informatika (55301),E41212221,Naufal Alif Nur Muhammad Rahmadhan,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212297,ANGGA PRABASWARA PUTRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41191683,AULIA NOVRIN HARLEYANTO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41202549,MUHAMMAD NAFIL,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",WFH,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) WFH 4 - Freelance/Kerja Lepas",lain tulis f1102 wfh freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41210746,MOCH IQBAL MAULANA FIEKRI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211965,AYU ANGGRAINI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211674,MUHAMAD SLAMET DAROENI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41212104,NIECOLA JODY SETIAWAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41211209,AKBAR FIRMANSYAH,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",saya belum bekerja,1 - Founder,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) saya belum bekerja 1 - Founder",lain tulis f1102 belum kerja founder,tidak_berpengalaman
21. Teknik Informatika (55301),E41210223,MOH FARRIJ WAJDI,2025.0,mencari_kerja,,,1 - Founder,Data_2025_Tracer_study_D4TIF.csv,1 - Founder,founder,tidak_berpengalaman
21. Teknik Informatika (55301),E41210734,ANDRE KHARISMA DWI THANSA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41232548,NOFAIRA AMIN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41231543,Muhamad Nusayif Jassim,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri,wiraswasta usaha sendiri,tidak_berpengalaman
21. Teknik Informatika (55301),E41211762,FIRMANSYAH FIKRIAWAN,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIF.csv,"5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas",lain tulis f1102 freelance kerja lepas,tidak_berpengalaman
21. Teknik Informatika (55301),E41212008,AFI ZAIN RAMADANA,2025.0,belum_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
21. Teknik Informatika (55301),E41210176,ADAM KARSAR NUGROHO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIF.csv,,,tidak_berpengalaman
Teknik Informatika (55301),E41191405,ACHMAD AJI WICAKSONO,2025.0,belum_kerja,3 - Perusahaan swasta,4 - Freelance/Kerja Lepas,1 - Lokal/wilayah/wiraswasta tidak berbadan hukum,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta 4 - Freelance/Kerja Lepas 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum,usaha swasta freelance kerja lepas lokal wilayah wiraswasta badan hukum,tidak_berpengalaman
Teknik Informatika (55301),E41191211,TEGAR AR RASYIID SAIFULAH,2025.0,belum_kerja,Usaha Sampingan,1 - Founder,1 - Lokal/wilayah/wiraswasta tidak berbadan hukum,Data_2025_Tracer_study_D4TIF.csv,Usaha Sampingan 1 - Founder 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum,usaha samping founder lokal wilayah wiraswasta badan hukum,tidak_berpengalaman
Teknik Informatika (55301),E41201609,BOY DYMAS HIDAYAT,2025.0,belum_kerja,4 - Wiraswasta/perusahaan sendiri,3 - Staff,1 - Lokal/wilayah/wiraswasta tidak berbadan hukum,Data_2025_Tracer_study_D4TIF.csv,4 - Wiraswasta/perusahaan sendiri 3 - Staff 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum,wiraswasta usaha sendiri staff lokal wilayah wiraswasta badan hukum,tidak_berpengalaman
Teknik Informatika (55301),E41232136,SILFI GABRILIA CHOIRUN NISA,2025.0,belum_kerja,3 - Perusahaan swasta,3 - Staff,,Data_2025_Tracer_study_D4TIF.csv,3 - Perusahaan swasta 3 - Staff,usaha swasta staff,tidak_berpengalaman
Teknik Informatika (55301),E41232098,Moch. Iqbal Rosyidi,2025.0,belum_kerja,tidak bekerja,4 - Freelance/Kerja Lepas,,Data_2025_Tracer_study_D4TIF.csv,tidak bekerja 4 - Freelance/Kerja Lepas,kerja freelance kerja lepas,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211358,DAFFA ADITYA REJASA RUSWANTO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41210291,SANGGA DEWA RAMADHAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211399,ERLYNA BERLIAN PRASTITI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211493,ENDIENING NUR PUSPITASARI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211253,ENGGAR SUSMITA,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212020,MOCHAMAD FARIS HASAN FEBRIANSHAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212241,RAKHA ARIAN ARCHANIGA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212173,PRISCILIA HILDA AGUSTIN,2025.0,mencari_kerja,,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIFNGANJUK.csv,4 - Freelance/Kerja Lepas,freelance kerja lepas,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212036,AHMAD CHOIRUL UMAM ALI ROZAQI,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212313,M. BRILLIANT RIDHO SISWANTO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212290,DIMAS ADI PUTRA ARIFIN,2025.0,mencari_kerja,7 - Institusi/Organisasi Multilateral,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,7 - Institusi/Organisasi Multilateral,institusi organisasi multilateral,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),e41212053,RENGGA DWI PRIBADI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211051,HABIB ANDRIANTITO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211995,Wijang Afdholanabil Kusuma,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211993,RATIH DEWI SETIANI,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,-,3 - Staff,Data_2025_Tracer_study_D4TIFNGANJUK.csv,4 - Wiraswasta/perusahaan sendiri - 3 - Staff,wiraswasta usaha sendiri staff,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212331,CORNELIA RAHMAWATI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212136,ROSITA CATUR SEPTIANINGSIH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212095,MOCHAMAD YUNUS IKHSANODIN,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212133,Naufal Kadhafi,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41210983,ROSYIDA ARIAN RAHMA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFNGANJUK.csv,,,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211992,FAUZIAN AQZZAL HAFIDZ,2025.0,mencari_kerja,3 - Perusahaan swasta,Polije,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIFNGANJUK.csv,3 - Perusahaan swasta Polije 4 - Freelance/Kerja Lepas,usaha swasta polije freelance kerja lepas,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41212268,BAGUS HARIS SUHARTONO,2025.0,mencari_kerja,3 - Perusahaan swasta,Starpace,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIFNGANJUK.csv,3 - Perusahaan swasta Starpace 4 - Freelance/Kerja Lepas,usaha swasta starpace freelance kerja lepas,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211384,AHMAD EDZAM PRASETYA,2025.0,mencari_kerja,3 - Perusahaan swasta,Politeknik Negeri Jember,1 - Founder,Data_2025_Tracer_study_D4TIFNGANJUK.csv,3 - Perusahaan swasta Politeknik Negeri Jember 1 - Founder,usaha swasta politeknik negeri jember founder,tidak_berpengalaman
22. Teknik Informatika Kampus Kab. Nganjuk (55302),E41211952,NOVA NUR ANGGRAINI,2025.0,belum_kerja,1 - Instansi pemerintah,Komisi Pemilihan Umum,3 - Staff,Data_2025_Tracer_study_D4TIFNGANJUK.csv,1 - Instansi pemerintah Komisi Pemilihan Umum 3 - Staff,instansi perintah komisi pilih umum staff,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212013,ABHINAYA FAHAR LAILA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212046,Achmad Baihaqi,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41211994,ACH. FASIHUL LISAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212260,RIZQI AZIZISSANI,2025.0,mencari_kerja,3 - Perusahaan swasta,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,3 - Perusahaan swasta,usaha swasta,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212060,OCTAVIAN DAVA PUTRA CAHYONO,2025.0,mencari_kerja,,,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,4 - Freelance/Kerja Lepas,freelance kerja lepas,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212099,KENNYO GENDIS PUTRI HARLI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212139,JESSICA DESI IMELDA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212081,CAHAYA CITRA AZZAHRO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212058,MOCH GHAZY AL GHIFARI HAFID,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,4 - Wiraswasta/perusahaan sendiri,wiraswasta usaha sendiri,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212126,MARZUKI AKMAL,2025.0,mencari_kerja,4 - Wiraswasta/perusahaan sendiri,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,4 - Wiraswasta/perusahaan sendiri,wiraswasta usaha sendiri,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212044,DAFFA AGUNG NUGROHO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212358,MUHAMMAD ANDRA KUSUMA RAMADHAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212045,ILHAM GUSTI SYAH PUTRO,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,"5 - Lainnya, Tuliskan (f1102)",lain tulis f1102,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212055,JOHAN KRISBIMA ABI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212037,BILAL SHANDYARTA SYAMSUDIN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212026,BIMA PRAYOGA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212359,OWEN PRATAMA ENDRAMAWAN,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212250,HERLAMBANG SATRIA WIJAYA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212129,NABILA RAHMA YUSRILFA TRISYAYANTI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212063,ASMIRANTI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212079,FADLIL LIWAUL HAMDI,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212006,MOCHAMMAD ENRIQUE LAZUARDI RAMADANY,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",-,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,"5 - Lainnya, Tuliskan (f1102) -",lain tulis f1102,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212125,DINA DWI ARIKA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212057,FACHRY RIZKY PRASETYA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212012,HARIS ASYSYAUQI,2025.0,mencari_kerja,3 - Perusahaan swasta,PT Rexline Engineering Indonesia,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,3 - Perusahaan swasta PT Rexline Engineering Indonesia,usaha swasta rexline engineering indonesia,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212105,FATKHUL HIDAYAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41211962,LYA NURUL ULLA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212270,MOH. FERDI ANDRIANSYAH,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212137,AGIL GILANG CHANDRA SAPUTRA,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212403,MUHAMMAD SHALAHUDIN AYUBI FIRMANSYAH,2025.0,mencari_kerja,"5 - Lainnya, Tuliskan (f1102)",belum bekerja,4 - Freelance/Kerja Lepas,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,"5 - Lainnya, Tuliskan (f1102) belum bekerja 4 - Freelance/Kerja Lepas",lain tulis f1102 belum kerja freelance kerja lepas,tidak_berpengalaman
23. Teknik Informatika Kampus Kab. Sidoarjo (55304),E41212054,DYIONO,2025.0,mencari_kerja,,,,Data_2025_Tracer_study_D4TIFSIDOARJO.csv,,,tidak_berpengalaman
1 kode_prodi nim nama tahun_lulus status_pekerjaan jenis_perusahaan nama_perusahaan jabatan sumber_file teks_pekerjaan_raw teks_pekerjaan kategori_pengalaman
2 57401 E31160678 RIZKA NURUL KHAKIKI 2019.0 bekerja 3 Data_2019_Tracer_study.csv swasta swasta tidak_berpengalaman
3 55301 E41150211 DEWI AYU ITIKAF 2019.0 mencari_kerja 0 0 0.0 Data_2019_Tracer_study.csv 0 0.0 tidak_berpengalaman
4 57401 E31151401 Aza Pascaeka 2019.0 belum_kerja 4 Data_2019_Tracer_study.csv wiraswasta wiraswasta tidak_berpengalaman
5 57401 E31130845 MOCH. RIVALDI AFTONI 2019.0 bekerja 5 Data_2019_Tracer_study.csv lainnya lain tidak_berpengalaman
6 57401 E31160328 Afega Wira Pradana 2019.0 bekerja 3 Data_2019_Tracer_study.csv swasta swasta tidak_berpengalaman
7 57401 E31161719 Reza Septia Safirah 2019.0 belum_kerja 4 Data_2019_Tracer_study.csv wiraswasta wiraswasta tidak_berpengalaman
8 56401 E32160904 ONGKY OKTAFIAN DWI JOHANSYAH 2019.0 bekerja 3 Data_2019_Tracer_study.csv swasta swasta tidak_berpengalaman
9 55301 E41150068 MUHAMMAD HAFIDH FIRMANSYAH 2019.0 bekerja 5 Data_2019_Tracer_study.csv lainnya lain tidak_berpengalaman
10 55301 E41151584 Risqi Ahmad Sultoni 2019.0 bekerja 3 Data_2019_Tracer_study.csv swasta swasta tidak_berpengalaman
11 57401 E31151214 Nita Wahyu Lianti 2019.0 belum_kerja 4 Data_2019_Tracer_study.csv wiraswasta wiraswasta tidak_berpengalaman
12 57401 E31160306 Faiqotul Hikmah 2019.0 bekerja 3 Data_2019_Tracer_study.csv swasta swasta tidak_berpengalaman
13 57401 E31160852 MOHAMMAD IMRAN 2020.0 mencari_kerja 0 0 0.0 Data_2020_Tracer_study.csv 0 0.0 tidak_berpengalaman
14 57401 E31171030 Nur Intan Nida 2020.0 mencari_kerja 0 0 0.0 Data_2020_Tracer_study.csv 0 0.0 tidak_berpengalaman
15 56401 E32170720 Sisca Nurmala 2020.0 mencari_kerja 0 0 0.0 Data_2020_Tracer_study.csv 0 0.0 tidak_berpengalaman
16 56401 E32170564 M Ibnu Wildan 2020.0 mencari_kerja 4 Seblak Preanger 3.0 Data_2020_Tracer_study.csv wiraswasta Seblak Preanger 3.0 wiraswasta seblak preanger tidak_berpengalaman
17 57401 E31170717 M. Fuat 2020.0 mencari_kerja 0 0 0.0 Data_2020_Tracer_study.csv 0 0.0 tidak_berpengalaman
18 56401 E32162050 Akhmad Rizky Sangaji 2020.0 belum_kerja 4 Data_2020_Tracer_study.csv wiraswasta wiraswasta tidak_berpengalaman
19 56401 E32161727 Moch Samsy 2020.0 belum_kerja 4 Data_2020_Tracer_study.csv wiraswasta wiraswasta tidak_berpengalaman
20 55301 E41190053 DIAN WAHYUNI 2020.0 bekerja 1 0 3.0 Data_2020_Tracer_study.csv pemerintah 0 3.0 perintah tidak_berpengalaman
21 57401 E31171653 Ahmad Faqih Hamdani 2020.0 bekerja 7 0 3.0 Data_2020_Tracer_study.csv nirlaba 0 3.0 nirlaba tidak_berpengalaman
22 55301 E41170333 CICILIA SELVY ERIANTHY 2021.0 wiraswasta 4 tidak ada 1.0 Data_2021_Tracer_study.csv wiraswasta tidak ada 1.0 wiraswasta tidak_berpengalaman
23 57401 E31182203 Rofi Berliana Mahanani 2021.0 melanjutkan_studi 3 - Data_2021_Tracer_study.csv swasta - swasta tidak_berpengalaman
24 56401 E32180554 Akhmad Farizi 2021.0 melanjutkan_studi 3 tidak ada 4.0 Data_2021_Tracer_study.csv swasta tidak ada 4.0 swasta tidak_berpengalaman
25 55301 E41170562 KRISOPRAS EPIKUROS 2021.0 wiraswasta 3 PT. 4.0 Data_2021_Tracer_study.csv swasta PT. 4.0 swasta tidak_berpengalaman
26 56401 E32182061 OZSA DEWANGGA PRADANA 2021.0 melanjutkan_studi 2 - Data_2021_Tracer_study.csv bnpp - bnpp tidak_berpengalaman
27 57401 E31200908 ROBBY ASY'ARI 2022.0 wiraswasta 4 3.0 Data_2022_Tracer_study.csv wiraswasta 3.0 wiraswasta tidak_berpengalaman
28 57401 E31191006 AGUS ARDIANSYAH 2022.0 bekerja 4 PT PN 4.0 Data_2022_Tracer_study.csv wiraswasta PT PN 4.0 wiraswasta tidak_berpengalaman
29 56401 E32191199 RIVAI NUR ROHMAN 2022.0 wiraswasta 6 3.0 Data_2022_Tracer_study.csv bumn 3.0 bumn tidak_berpengalaman
30 57401 E31192382 AINUR KARINA ABI RAHMADIYAN 2022.0 wiraswasta 3 3.0 Data_2022_Tracer_study.csv swasta 3.0 swasta tidak_berpengalaman
31 57401 E31191195 NOVIEKA MUTIARA FIRDAUSIAH 2022.0 wiraswasta 4 1.0 Data_2022_Tracer_study.csv wiraswasta 1.0 wiraswasta tidak_berpengalaman
32 56401 E32191236 DAFFA PUTRA JAYA PERMANA 2022.0 wiraswasta 4 1.0 Data_2022_Tracer_study.csv wiraswasta 1.0 wiraswasta tidak_berpengalaman
33 55301 E41182080 MUHAMMAD ILMI QOLBI IMANNI 2022.0 wiraswasta 7 4.0 Data_2022_Tracer_study.csv nirlaba 4.0 nirlaba tidak_berpengalaman
34 55301 E41201788 ARIF RAHMAN HAKIM 2022.0 wiraswasta 3 3.0 Data_2022_Tracer_study.csv swasta 3.0 swasta tidak_berpengalaman
35 55301 E41200889 AHMAD FAQIH ARDINATA 2022.0 wiraswasta 3 4.0 Data_2022_Tracer_study.csv swasta 4.0 swasta tidak_berpengalaman
36 55301 E41180632 FRENGKI ELISTANTO 2022.0 wiraswasta 1 4.0 Data_2022_Tracer_study.csv pemerintah 4.0 perintah tidak_berpengalaman
37 57401 E31192117 AULIA DININ PUTRI ALIFIAH 2022.0 melanjutkan_studi 1 4.0 Data_2022_Tracer_study.csv pemerintah 4.0 perintah tidak_berpengalaman
38 57401 E31191120 SHINDI FATIKA SARI 2022.0 melanjutkan_studi 3 4.0 Data_2022_Tracer_study.csv swasta 4.0 swasta tidak_berpengalaman
39 56401 E32190383 GALANG PAHALA 2022.0 melanjutkan_studi 3 3.0 Data_2022_Tracer_study.csv swasta 3.0 swasta tidak_berpengalaman
40 57401 E31191849 Silfi Gabrilia Choirun Nisa 2022.0 melanjutkan_studi 4 2.0 Data_2022_Tracer_study.csv wiraswasta 2.0 wiraswasta tidak_berpengalaman
41 56401 E32190887 Amirul Faisal 2022.0 melanjutkan_studi 3 4.0 Data_2022_Tracer_study.csv swasta 4.0 swasta tidak_berpengalaman
42 55301 E41171991 FEBRERO ARAYA KUSUMATMAJA 2022.0 wiraswasta 7 4.0 Data_2022_Tracer_study.csv nirlaba 4.0 nirlaba tidak_berpengalaman
43 57401 E31191300 IWANG PRADIPTA DINOTO 2022.0 melanjutkan_studi 6 3.0 Data_2022_Tracer_study.csv bumn 3.0 bumn tidak_berpengalaman
44 57401 E31191982 GALUH LAKSITA NARASWARI 2022.0 melanjutkan_studi 6 3.0 Data_2022_Tracer_study.csv bumn 3.0 bumn tidak_berpengalaman
45 57401 E31191433 Muhammad Naufal Zuhdi 2022.0 melanjutkan_studi 6 1.0 Data_2022_Tracer_study.csv bumn 1.0 bumn tidak_berpengalaman
46 56401 E32191840 Wahyu Musthofa 2022.0 melanjutkan_studi 1 2.0 Data_2022_Tracer_study.csv pemerintah 2.0 perintah tidak_berpengalaman
47 55301 E41161215 HENDRA LAKSMANA 2022.0 melanjutkan_studi 6 1.0 Data_2022_Tracer_study.csv bumn 1.0 bumn tidak_berpengalaman
48 55301 E41182248 ABDUR RAZAK SEBASTIAN 2022.0 melanjutkan_studi 7 4.0 Data_2022_Tracer_study.csv nirlaba 4.0 nirlaba tidak_berpengalaman
49 55301 E41181028 AISHA RAHMAYANTI 2022.0 melanjutkan_studi 4 3.0 Data_2022_Tracer_study.csv wiraswasta 3.0 wiraswasta tidak_berpengalaman
50 55301 E41182048 MUHAMMAD ANSORI 2022.0 melanjutkan_studi 4 4.0 Data_2022_Tracer_study.csv wiraswasta 4.0 wiraswasta tidak_berpengalaman
51 55301 E41212442 AFDUL ANWAR ADANI 2022.0 melanjutkan_studi 3 4.0 Data_2022_Tracer_study.csv swasta 4.0 swasta tidak_berpengalaman
52 55301 E41212449 RIZAL WAHYU UTAMA 2022.0 melanjutkan_studi 4 4.0 Data_2022_Tracer_study.csv wiraswasta 4.0 wiraswasta tidak_berpengalaman
53 55301 E41212470 RIZQIAH DWI AGUSTIN 2022.0 melanjutkan_studi 3 3.0 Data_2022_Tracer_study.csv swasta 3.0 swasta tidak_berpengalaman
54 57401 E31192264 ALVIN YUDHA EKA PRADISTYA 2022.0 melanjutkan_studi 6 2.0 Data_2022_Tracer_study.csv bumn 2.0 bumn tidak_berpengalaman
55 55301 E41171763 TABHRANY ODI ASMORO 2022.0 melanjutkan_studi Data_2022_Tracer_study.csv tidak_berpengalaman
56 55301 E41181135 Harisman Siihombing 2022.0 bekerja 3 - 3.0 Data_2022_Tracer_study.csv swasta - 3.0 swasta tidak_berpengalaman
57 55301 E41180749 MUHAMMAD HANAFI ABROR 2022.0 melanjutkan_studi Data_2022_Tracer_study.csv tidak_berpengalaman
58 57401 E31191250 MUHAMMAD PUTRA ADIKUSUMA 2022.0 bekerja 3 3.0 Data_2022_Tracer_study.csv swasta 3.0 swasta tidak_berpengalaman
59 55301 E41181773 MUHAMMAD FARHAN NUR PRATAMA 2022.0 melanjutkan_studi Data_2022_Tracer_study.csv tidak_berpengalaman
60 55301 E41180879 YUDISTIONO 2022.0 wiraswasta Data_2022_Tracer_study.csv tidak_berpengalaman
61 55301 E41212443 GALUH MAHENDRA 2022.0 wiraswasta 4.0 Data_2022_Tracer_study.csv 4.0 tidak_berpengalaman
62 57401 E31192064 LUSY DWI WILUJENG 2022.0 wiraswasta Data_2022_Tracer_study.csv tidak_berpengalaman
63 Manajemen Informatika (57401) E31191738 ABDULLAH SYIHABUDIN AL ACHYAR 2024.0 belum_kerja 5 - Lainnya, Tuliskan 3 - Staff Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 3 - Staff lain tulis staff tidak_berpengalaman
64 Teknik Informatika (55301) E41201747 M. YOGA ANDRIAN PUTRA 2024.0 belum_kerja Belum Bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv Belum Bekerja 4 - Freelance/Kerja Lepas belum kerja freelance kerja lepas tidak_berpengalaman
65 Manajemen Informatika (57401) E31210257 MUHAMMAD ZIDAN PRASETYO 2024.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2024_Tracer_study.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
66 Manajemen Informatika (57401) E31211910 DAVIN FADHLILLAH YUDANTO 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
67 Teknik Informatika (55301) E41201781 WIDYA OCTAVIOLA NURYA 2024.0 belum_kerja 6 - BUMN/BUMD 2 - Co-Founder Data_2024_Tracer_study.csv 6 - BUMN/BUMD 2 - Co-Founder bumn bumd founder tidak_berpengalaman
68 Manajemen Informatika (57401) E31211936 RAHMANDA RICO LUTFIANSYAH 2024.0 belum_kerja 7 - Institusi/Organisasi Multilateral 1 - Founder Data_2024_Tracer_study.csv 7 - Institusi/Organisasi Multilateral 1 - Founder institusi organisasi multilateral founder tidak_berpengalaman
69 Teknik Informatika (55301) E41202091 NUR HASANAH 2024.0 belum_kerja 6 - BUMN/BUMD 1 - Founder Data_2024_Tracer_study.csv 6 - BUMN/BUMD 1 - Founder bumn bumd founder tidak_berpengalaman
70 Teknik Informatika (55301) E41200569 NURILLAHILWAFI 2024.0 belum_kerja 5 - Lainnya, Tuliskan 1 - Founder Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 1 - Founder lain tulis founder tidak_berpengalaman
71 Manajemen Informatika (57401) E31211906 STEVEN RIO CHANDRA PURNAMA 2024.0 belum_kerja 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas lain tulis freelance kerja lepas tidak_berpengalaman
72 Teknik Informatika (55301) E41202429 AZRIL NUR RAHMAN 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
73 Manajemen Informatika (57401) E31210717 FARA ISTIGHFAR SARI 2024.0 belum_kerja belum bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv belum bekerja 4 - Freelance/Kerja Lepas belum kerja freelance kerja lepas tidak_berpengalaman
74 Teknik Informatika (55301) E41202281 BAHRUL AJI SANTOSO 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 1 - Founder Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 1 - Founder wiraswasta usaha sendiri founder tidak_berpengalaman
75 Manajemen Informatika (57401) E31211900 MARSHA ARLINDA PUTRI 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
76 Manajemen Informatika (57401) E31211896 REIHAN JANUWISESA FATIH ATTARIANSYAH 2024.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2024_Tracer_study.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
77 Manajemen Informatika (57401) E31210592 YUYUN INE FEBRIANI 2024.0 belum_kerja 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas lain tulis freelance kerja lepas tidak_berpengalaman
78 Teknik Informatika (55301) E41201153 BIMA ANGGARA WIRASATYA 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
79 Manajemen Informatika (57401) E31210385 ELA ERWITA SISILIA 2024.0 belum_kerja 6 - BUMN/BUMD 3 - Staff Data_2024_Tracer_study.csv 6 - BUMN/BUMD 3 - Staff bumn bumd staff tidak_berpengalaman
80 Teknik Informatika (55301) E41201302 FAHMI DAFRIN MAULANA 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
81 Teknik Informatika (55301) E41202383 ARIEF ANASTIAR SUHARSONO 2024.0 belum_kerja 6 - BUMN/BUMD 1 - Founder Data_2024_Tracer_study.csv 6 - BUMN/BUMD 1 - Founder bumn bumd founder tidak_berpengalaman
82 Teknik Komputer (56401) E32211535 MOHAMMAD IRNANDA 2024.0 belum_kerja Belum Bekerja 1 - Founder Data_2024_Tracer_study.csv Belum Bekerja 1 - Founder belum kerja founder tidak_berpengalaman
83 Teknik Informatika (55301) E41202280 ASIF MAHARDHIKA RAMADAN 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
84 Teknik Informatika (55301) E41202254 NIKI MUHAMMAD NAFIS 2024.0 belum_kerja Belum Bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv Belum Bekerja 4 - Freelance/Kerja Lepas belum kerja freelance kerja lepas tidak_berpengalaman
85 Manajemen Informatika (57401) E31212365 BAGUS DAFFA FIRMANSYAH 2024.0 belum_kerja 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas bumn bumd freelance kerja lepas tidak_berpengalaman
86 Manajemen Informatika (57401) E31212295 DAFFA ATHALA ZAGHAZY 2024.0 belum_kerja 3 - Perusahaan swasta 2 - Co-Founder Data_2024_Tracer_study.csv 3 - Perusahaan swasta 2 - Co-Founder usaha swasta founder tidak_berpengalaman
87 Teknik Komputer (56401) E32210989 NARARGA MAULANA 2024.0 belum_kerja 3 - Perusahaan swasta 3 - Staff Data_2024_Tracer_study.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
88 Teknik Komputer (56401) E32210755 SAHRUL GUNAWAN 2024.0 belum_kerja 3 - Perusahaan swasta 1 - Founder Data_2024_Tracer_study.csv 3 - Perusahaan swasta 1 - Founder usaha swasta founder tidak_berpengalaman
89 Teknik Informatika (55301) E41201212 MUHAMMAD AKBAR RAYYAN AL-FATH 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
90 Teknik Komputer (56401) E32210897 MUFIDAH EKA ALVA NADYA 2024.0 belum_kerja 6 - BUMN/BUMD Bumn 1 - Founder Data_2024_Tracer_study.csv 6 - BUMN/BUMD Bumn 1 - Founder bumn bumd bumn founder tidak_berpengalaman
91 Teknik Informatika (55301) E41202411 LUQMAN HAKIM 2024.0 belum_kerja 3 - Perusahaan swasta 1 - Founder Data_2024_Tracer_study.csv 3 - Perusahaan swasta 1 - Founder usaha swasta founder tidak_berpengalaman
92 Teknik Informatika (55301) E41200415 NOGA MUKTIWATI 2024.0 belum_kerja 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas bumn bumd freelance kerja lepas tidak_berpengalaman
93 Manajemen Informatika (57401) E31212340 AHMAD SAIFUL SEPTIAWAN 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 1 - Founder Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 1 - Founder wiraswasta usaha sendiri founder tidak_berpengalaman
94 Teknik Komputer (56401) E32210743 GUSTI ARLIZ NANDITO 2024.0 belum_kerja 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas lain tulis freelance kerja lepas tidak_berpengalaman
95 Teknik Komputer (56401) E32211375 NELSEN ARDIANSAH 2024.0 belum_kerja Belum bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv Belum bekerja 4 - Freelance/Kerja Lepas belum kerja freelance kerja lepas tidak_berpengalaman
96 Teknik Komputer (56401) E32210111 DANY FERDYANSYAH 2024.0 belum_kerja 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas organisasi non profit lembaga swadaya masyarakat freelance kerja lepas tidak_berpengalaman
97 Teknik Informatika (55301) E41202285 ALI IMRON SAEFULLAH 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
98 Teknik Komputer (56401) E32210675 SYLVA ADITYA ARFIANSYAH 2024.0 belum_kerja 5 - Lainnya, Tuliskan 3 - Staff Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 3 - Staff lain tulis staff tidak_berpengalaman
99 Teknik Komputer (56401) E32211395 LUTFI ARDIANSYAH 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
100 Teknik Komputer (56401) E32210736 MUHAMMAD NAUFAL AFFAN SAMUDRA 2024.0 belum_kerja 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas lain tulis freelance kerja lepas tidak_berpengalaman
101 Manajemen Informatika (57401) E31211386 REFYAN GIGAS ZIDANE HERDINAND PRATAMA 2024.0 belum_kerja 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas lain tulis freelance kerja lepas tidak_berpengalaman
102 Teknik Komputer (56401) E32210813 MUTYARA PERTIWI 2024.0 belum_kerja 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 5 - Lainnya, Tuliskan 4 - Freelance/Kerja Lepas lain tulis freelance kerja lepas tidak_berpengalaman
103 Teknik Informatika (55301) E41202298 FIRDAUS FIRMANSYAH 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
104 Teknik Informatika (55301) E41200363 ALFIAN EZZA RADITYA 2024.0 belum_kerja 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas bumn bumd freelance kerja lepas tidak_berpengalaman
105 Teknik Informatika (55301) E32211505 MUHAMMAD AMAN AHCYAD 2024.0 belum_kerja Belum bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv Belum bekerja 4 - Freelance/Kerja Lepas belum kerja freelance kerja lepas tidak_berpengalaman
106 Teknik Komputer (56401) E32212364 RIDHO DWICAHYA WIJAYA 2024.0 belum_kerja Tidak Bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv Tidak Bekerja 4 - Freelance/Kerja Lepas kerja freelance kerja lepas tidak_berpengalaman
107 Teknik Komputer (56401) E32210095 DAMAR RAWUH SARJITO 2024.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2024_Tracer_study.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
108 Teknik Komputer (56401) E32210053 DIMAS DWI APRILIYANTO 2024.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2024_Tracer_study.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
109 Teknik Komputer (56401) E32210055 RACHMAN TIO MAULANA 2024.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2024_Tracer_study.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
110 Teknik Komputer (56401) E32200666 MOHAMMAD RODIVOL HAK 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri Better Of Life 1 - Founder Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri Better Of Life 1 - Founder wiraswasta usaha sendiri better life founder tidak_berpengalaman
111 Manajemen Informatika (57401) E31211055 AHMAD MAULANA SUBANDRIO 2024.0 belum_kerja 1 - Instansi pemerintah 1 - Founder Data_2024_Tracer_study.csv 1 - Instansi pemerintah 1 - Founder instansi perintah founder tidak_berpengalaman
112 Teknik Komputer (56401) E32212287 RAGA MULYA PRATAMA PUTRA 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
113 Teknik Komputer (56401) E32200194 NANDA FATHURAHMA 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 1 - Founder Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 1 - Founder wiraswasta usaha sendiri founder tidak_berpengalaman
114 Teknik Komputer (56401) E32210446 RYAN AJENG SUKMA DEWI TITAH PRATAMA 2024.0 belum_kerja belom bekerja 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv belom bekerja 4 - Freelance/Kerja Lepas bom kerja freelance kerja lepas tidak_berpengalaman
115 Teknik Komputer (56401) E32210771 M. FAJARSYAH EKA PERMANA 2024.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
116 Teknik Komputer (56401) E32212333 INDRA WIJAYA 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 1 - Founder Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri 1 - Founder wiraswasta usaha sendiri founder tidak_berpengalaman
117 Teknik Komputer (56401) E32210826 RIZKI ROMADHONI 2024.0 belum_kerja 3 - Perusahaan swasta 1 - Founder Data_2024_Tracer_study.csv 3 - Perusahaan swasta 1 - Founder usaha swasta founder tidak_berpengalaman
118 Teknik Komputer (56401) E32212138 CINDY AFCARINA 2024.0 belum_kerja 3 - Perusahaan swasta 3 - Staff Data_2024_Tracer_study.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
119 Teknik Komputer (56401) E32210344 REZA ANGGARA JANUARTA PUTRA BAYU SYAFIRA 2024.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2024_Tracer_study.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
120 Teknik Komputer (56401) E32212299 ANANDA ANGGI DWI CAHYO 2024.0 belum_kerja Berencana ingin bekerja di instansi pemerintah atau di BUMN 3 - Staff Data_2024_Tracer_study.csv Berencana ingin bekerja di instansi pemerintah atau di BUMN 3 - Staff rencana ingin kerja instansi perintah bumn staff tidak_berpengalaman
121 Teknik Komputer (56401) E32211429 I PUTU SRI KRESNA LORU ARIASA 2024.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri Freelance 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 4 - Wiraswasta/perusahaan sendiri Freelance 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance freelance kerja lepas tidak_berpengalaman
122 Teknik Komputer (56401) E32212309 KHOIRUL TAMAMI 2024.0 belum_kerja 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas bumn bumd freelance kerja lepas tidak_berpengalaman
123 Teknik Informatika (55301) E41202408 BRIANTI BELLA PRASNITIA 2024.0 belum_kerja 3 - Perusahaan swasta 1 - Founder Data_2024_Tracer_study.csv 3 - Perusahaan swasta 1 - Founder usaha swasta founder tidak_berpengalaman
124 Teknik Komputer (56401) E32212239 NURUL HUDA 2024.0 belum_kerja 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas organisasi non profit lembaga swadaya masyarakat freelance kerja lepas tidak_berpengalaman
125 Teknik Komputer (56401) E32211014 HABIB MAULANA 2024.0 belum_kerja 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat 4 - Freelance/Kerja Lepas organisasi non profit lembaga swadaya masyarakat freelance kerja lepas tidak_berpengalaman
126 Teknik Komputer (56401) E32212181 FITRAH DESTRA PUTRA 2024.0 belum_kerja 6 - BUMN/BUMD 2 - Co-Founder Data_2024_Tracer_study.csv 6 - BUMN/BUMD 2 - Co-Founder bumn bumd founder tidak_berpengalaman
127 Teknik Informatika (55301) E41182272 BAYU JAYA ILHAM ALHAMDA 2024.0 belum_kerja Traveloka TRAVELOKA (ND TRAVELINDO) 4 - Freelance/Kerja Lepas Data_2024_Tracer_study.csv Traveloka TRAVELOKA (ND TRAVELINDO) 4 - Freelance/Kerja Lepas traveloka traveloka travelindo freelance kerja lepas tidak_berpengalaman
128 Teknik Informatika (55301) E41201220 INDAH NUR MAHMUDA 2024.0 belum_kerja Data_2024_Tracer_study.csv tidak_berpengalaman
129 Manajemen Informatika (57401) E31210927 INTAN DELVE ATIKA 2024.0 melanjutkan_studi Data_2024_Tracer_study.csv tidak_berpengalaman
130 Manajemen Informatika (57401) E31210287 ABEL JATAYU WAHYU AJI 2024.0 belum_kerja Data_2024_Tracer_study.csv tidak_berpengalaman
131 Manajemen Informatika (57401) E31211810 SITI RUSDANIYAH 2024.0 bekerja Data_2024_Tracer_study.csv tidak_berpengalaman
132 Teknik Komputer (56401) E32211859 AHMAD RIDHO 2024.0 belum_kerja Data_2024_Tracer_study.csv tidak_berpengalaman
133 19. Manajemen Informatika (57401) E31221235 SITI LAILATUL AMALIA 2025.0 mencari_kerja 3 - Perusahaan swasta 3 - Staff Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
134 19. Manajemen Informatika (57401) E31221213 NURUL QOMARIA 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
135 19. Manajemen Informatika (57401) E31221281 MUHAMMAD RIZAL FAHLEVI 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
136 19. Manajemen Informatika (57401) E31222492 JA'FAR SHODIQ 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
137 19. Manajemen Informatika (57401) E31222519 MOH. DANI KURNIAWAN SUGIARTO 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
138 19. Manajemen Informatika (57401) E31221248 BELLA ERVINA FERDIANTI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
139 19. Manajemen Informatika (57401) E31221247 DIVIA ANGGRAINI 2025.0 mencari_kerja 7 - Institusi/Organisasi Multilateral Data_2025_Tracer_study_D3MIF.csv 7 - Institusi/Organisasi Multilateral institusi organisasi multilateral tidak_berpengalaman
140 19. Manajemen Informatika (57401) E31222451 ADILA JELITA PUTRI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
141 19. Manajemen Informatika (57401) E31220215 NUR MITA UPI LESTARI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Jasain aja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 4 - Wiraswasta/perusahaan sendiri Jasain aja 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri jasain freelance kerja lepas tidak_berpengalaman
142 19. Manajemen Informatika (57401) E31222461 GADIS MICHELLIA PUTRI 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
143 19. Manajemen Informatika (57401) E31221480 NOVITA YUNDA FAJRIYAH 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
144 19. Manajemen Informatika (57401) E31221305 MALEMNA SWARI TARIGAN 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
145 19. Manajemen Informatika (57401) E31221259 Ratna Sari Dewi 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
146 19. Manajemen Informatika (57401) E31222656 JEREMY VAHARDIKA JAYA 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
147 19. Manajemen Informatika (57401) E31222327 FARISA RAHMASARI 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
148 19. Manajemen Informatika (57401) E31222455 Salma Banafsha Safa Fitria 2025.0 mencari_kerja 6 - BUMN/BUMD 2 - Co-Founder Data_2025_Tracer_study_D3MIF.csv 6 - BUMN/BUMD 2 - Co-Founder bumn bumd founder tidak_berpengalaman
149 19. Manajemen Informatika (57401) E31222398 Wisnu Hadi Mahendra 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
150 19. Manajemen Informatika (57401) E31220218 ELSA SURYA AGUSTIN 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
151 19. Manajemen Informatika (57401) E31221236 REYNAVA AURELLIA DAMAYANTI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
152 19. Manajemen Informatika (57401) E31220197 IHYA ULUMUDDIN 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
153 19. Manajemen Informatika (57401) E31221142 MUHAMMAD HERIYANTO 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
154 19. Manajemen Informatika (57401) E31222387 SEPTIANO RIZKI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 3 - Staff Data_2025_Tracer_study_D3MIF.csv 4 - Wiraswasta/perusahaan sendiri 3 - Staff wiraswasta usaha sendiri staff tidak_berpengalaman
155 19. Manajemen Informatika (57401) E31222680 NADEA MEFIRA 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
156 19. Manajemen Informatika (57401) E31221420 ANINDYA HUDAA KUMALA TANTRI 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
157 19. Manajemen Informatika (57401) E31221209 Ayu Eka Ciptasari 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
158 19. Manajemen Informatika (57401) E31222823 MARCELLINO RHADITYA ROSANDI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
159 19. Manajemen Informatika (57401) E31221108 SHAMITA YASMIN R 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
160 19. Manajemen Informatika (57401) E31222307 Alfiansyah Pradinata Putra 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
161 19. Manajemen Informatika (57401) E31222756 SYEBA WARDAHANI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
162 19. Manajemen Informatika (57401) E31221484 MIFTAH FARID GUNAWAN 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
163 19. Manajemen Informatika (57401) E31222365 ADINDA KHOFIFA AZIZ 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Politeknik Negeri jember 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) Politeknik Negeri jember 4 - Freelance/Kerja Lepas lain tulis f1102 politeknik negeri jember freelance kerja lepas tidak_berpengalaman
164 19. Manajemen Informatika (57401) E31221225 RIFQI NURUL QOMARIAH 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
165 19. Manajemen Informatika (57401) E31222586 NURUL FAJRI MAULIDYA 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
166 19. Manajemen Informatika (57401) E31222541 MUHAMMAD ARYA FATHOROZI 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
167 19. Manajemen Informatika (57401) E31222658 LINTANG SURURUM SALSAFAIZ MARTALIA 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
168 19. Manajemen Informatika (57401) E31221299 OKTAVIARLEN SETYA WARDANI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
169 19. Manajemen Informatika (57401) E31221315 WILLIAN ANGGI DEVAYU 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
170 19. Manajemen Informatika (57401) E31222629 SHERLY WELYANA 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
171 19. Manajemen Informatika (57401) E31222389 Muhammad Alfin Faiz 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
172 19. Manajemen Informatika (57401) E31220442 Ulil Farhah 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
173 19. Manajemen Informatika (57401) E31222534 ADINDA WIDYA PUTRI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
174 19. Manajemen Informatika (57401) E31222508 Diana Oktavia Rachmad 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
175 19. Manajemen Informatika (57401) E31221264 GITA YASINDA PUTRI CAHYANI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
176 19. Manajemen Informatika (57401) E31221244 MUHAMMAD AGI PRASETYO 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
177 19. Manajemen Informatika (57401) E31221325 MEY NUR AFNI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
178 19. Manajemen Informatika (57401) E31220954 MUHAMAD FAIS AIZAT 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
179 19. Manajemen Informatika (57401) E31220577 DINDA NAUSA KUSUMA WARDANI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
180 19. Manajemen Informatika (57401) E31220334 ISNAINI QAYYUM AZIZAH 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D3MIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
181 19. Manajemen Informatika (57401) E31221357 NISWAH TRIAS QUROTUL A'YUN 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
182 19. Manajemen Informatika (57401) E31222653 FIRDATURROFIAH 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
183 19. Manajemen Informatika (57401) E31222870 SATRIA HILMI AN'AMTA CAHYONO 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
184 19. Manajemen Informatika (57401) E31222313 AGYA RIZKINTA WILDANTI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
185 19. Manajemen Informatika (57401) E31221269 Mohammad Iqbal Abdillah 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
186 19. Manajemen Informatika (57401) E31221263 TEGAR FEBRIANSYAH PUTRA NURULLAH 2025.0 mencari_kerja 3 - Perusahaan swasta HIJIGROUP Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta HIJIGROUP usaha swasta hijigroup tidak_berpengalaman
187 19. Manajemen Informatika (57401) E31222450 NUR FUADI MUHAMMAD 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
188 19. Manajemen Informatika (57401) E31222582 Hilda Eva Stefhany 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Data_2025_Tracer_study_D3MIF.csv 4 - Wiraswasta/perusahaan sendiri wiraswasta usaha sendiri tidak_berpengalaman
189 19. Manajemen Informatika (57401) E31222691 ANNAJWA SHOHIBUZZAHRO 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
190 19. Manajemen Informatika (57401) E31222606 AHMAD ZAENAL ABIDIN 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
191 19. Manajemen Informatika (57401) E31220412 ALFIN FADLI 2025.0 belum_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
192 19. Manajemen Informatika (57401) E31222851 ENDY FADLULLAH 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
193 19. Manajemen Informatika (57401) E31222888 ALIZAR MUHARROM 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Data_2025_Tracer_study_D3MIF.csv 4 - Wiraswasta/perusahaan sendiri wiraswasta usaha sendiri tidak_berpengalaman
194 19. Manajemen Informatika (57401) E31222641 Firman Agung Alamsyah 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
195 19. Manajemen Informatika (57401) E31222381 BRAHMI HAWA SAWITRI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
196 19. Manajemen Informatika (57401) E31222344 SOVIA LAJUBA 2025.0 mencari_kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 4 - Freelance/Kerja Lepas freelance kerja lepas tidak_berpengalaman
197 19. Manajemen Informatika (57401) E31222663 ROFIATUL ANDAWIYAH 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) PT. Lambda Solusi Informatika Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) PT. Lambda Solusi Informatika lain tulis f1102 lambda solusi informatika tidak_berpengalaman
198 19. Manajemen Informatika (57401) E31221397 VICKY FERNANDO ANGGARA PUTRA IKHWANTO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
199 19. Manajemen Informatika (57401) E31222379 FAHMI KURNIAWAN 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
200 19. Manajemen Informatika (57401) E31221009 AISYAH SALSHABILLA SISKA PUTRI 2025.0 belum_kerja 3 - Perusahaan swasta PT. Young Tree Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta PT. Young Tree usaha swasta young tree tidak_berpengalaman
201 19. Manajemen Informatika (57401) E31221306 MUHAMMAD RAMA PRADIPA WIJAYA 2025.0 mencari_kerja 3 - Perusahaan swasta 3 - Staff Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
202 19. Manajemen Informatika (57401) E31222696 FITRI AMALIA SAQILA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) PT China Communications Construction Indonesia (CCCI). 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) PT China Communications Construction Indonesia (CCCI). 4 - Freelance/Kerja Lepas lain tulis f1102 china communications construction indonesia ccci freelance kerja lepas tidak_berpengalaman
203 19. Manajemen Informatika (57401) E31221407 M. FAHIM DAVID BACHTIAR 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
204 19. Manajemen Informatika (57401) E31222518 MUHAMMAD ALFIN ALFAUZI 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
205 19. Manajemen Informatika (57401) E31222765 DINA AYU AISYAH 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
206 19. Manajemen Informatika (57401) E31210646 ATIKAH NURI HAZMA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Yasmine Fashion Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) Yasmine Fashion lain tulis f1102 yasmine fashion tidak_berpengalaman
207 19. Manajemen Informatika (57401) E31221245 ALFIONINA DWI RACHMALIA 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
208 19. Manajemen Informatika (57401) E31220095 GALUH REVIKO SATYA KIRANA 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
209 19. Manajemen Informatika (57401) E31221222 DIYO ANGGARA PRADIPA PUTRA 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
210 19. Manajemen Informatika (57401) E31222366 Arya Advicenna 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
211 19. Manajemen Informatika (57401) E31221360 IQBAL AMIN 2025.0 belum_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
212 19. Manajemen Informatika (57401) E31220277 PUTRI AYU WULANDARI 2025.0 mencari_kerja 1 - Instansi pemerintah 3 - Staff Data_2025_Tracer_study_D3MIF.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
213 19. Manajemen Informatika (57401) E31222540 Haikal Muna'amul Islam 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
214 19. Manajemen Informatika (57401) E31200086 DANIEL ABDULLAH AFANDI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Belum Mendapatkan Pekerjaan Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) Belum Mendapatkan Pekerjaan lain tulis f1102 belum dapat kerja tidak_berpengalaman
215 19. Manajemen Informatika (57401) E31222707 ADELIA SARI DEWI 2025.0 belum_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
216 19. Manajemen Informatika (57401) E31222544 Sultan Arya Maulana 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
217 19. Manajemen Informatika (57401) E31222854 Irfan Dimas Riyadi 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) belum ada 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 5 - Lainnya, Tuliskan (f1102) belum ada 4 - Freelance/Kerja Lepas lain tulis f1102 belum freelance kerja lepas tidak_berpengalaman
218 19. Manajemen Informatika (57401) E31222846 MOCHAMMAD GINATA FEBRYANSYAH 2025.0 belum_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3MIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
219 19. Manajemen Informatika (57401) E31222882 Stephen Gesityan 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
220 19. Manajemen Informatika (57401) E31220567 PUTRI NABILAH HUWAIDAH 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
221 19. Manajemen Informatika (57401) E31222881 ALE ANDRA PRIANDANI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3MIF.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
222 19. Manajemen Informatika (57401) E31221388 Alya Nirmala Putri 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
223 19. Manajemen Informatika (57401) E31222699 MOCH ADIM RIZKY SYAH PUTRA 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
224 19. Manajemen Informatika (57401) E31222596 ALYA LUFRIDA AFIFAH 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
225 19. Manajemen Informatika (57401) E31221361 Algoritma Dwifebri fathiyakan 2025.0 mencari_kerja Data_2025_Tracer_study_D3MIF.csv tidak_berpengalaman
226 20. Teknik Komputer (56401) E32221234 RAHMAD ERA SUGIARTO 2025.0 mencari_kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 4 - Freelance/Kerja Lepas freelance kerja lepas tidak_berpengalaman
227 20. Teknik Komputer (56401) E32222388 SYAHMI NAUFAL SAPUTRA 2025.0 mencari_kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 4 - Freelance/Kerja Lepas freelance kerja lepas tidak_berpengalaman
228 20. Teknik Komputer (56401) E32220022 TUTIK NOER KHOLIFAH 2025.0 mencari_kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 4 - Freelance/Kerja Lepas freelance kerja lepas tidak_berpengalaman
229 20. Teknik Komputer (56401) E32220375 MUHAMMAD YUSUF SHOLEHUDIN RENDY 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
230 20. Teknik Komputer (56401) E32221231 REYHAN NAUFAL TSAQIF 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D3TKK.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
231 20. Teknik Komputer (56401) E32222300 SHAMIR FAIZAL THALIB 2025.0 mencari_kerja 3 - Perusahaan swasta Pt. Semen imasco asiatic Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta Pt. Semen imasco asiatic usaha swasta semen imasco asiatic tidak_berpengalaman
232 20. Teknik Komputer (56401) E32220274 MOCH RENDY ARDIYANTO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
233 20. Teknik Komputer (56401) E32221274 SAKTI BAYU NUGRAHA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
234 20. Teknik Komputer (56401) E32220671 AHMAD ADIB AKBAR 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
235 20. Teknik Komputer (56401) E32221002 Muhammad Ardi Aziz Saputra 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Data_2025_Tracer_study_D3TKK.csv 4 - Wiraswasta/perusahaan sendiri wiraswasta usaha sendiri tidak_berpengalaman
236 20. Teknik Komputer (56401) E32222748 IQBAL FIKHRIANSYAH ROMADHONA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
237 20. Teknik Komputer (56401) E32222626 DIYAN SHINTIA BELLA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
238 20. Teknik Komputer (56401) E32222585 YUSRIL ROMIZA PUTRA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
239 20. Teknik Komputer (56401) E32221390 SERIAN ANAK AYUT 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) belum memiliki pekerjaan 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) belum memiliki pekerjaan 4 - Freelance/Kerja Lepas lain tulis f1102 belum milik kerja freelance kerja lepas tidak_berpengalaman
240 20. Teknik Komputer (56401) E32222403 Ahmad Furqon Saputra 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
241 20. Teknik Komputer (56401) E32222434 YOVITA SARI CAHYANINGTYAS 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
242 20. Teknik Komputer (56401) E32222503 MUHAMMAD RISKI ARDIANSYAH 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
243 20. Teknik Komputer (56401) E32221196 RIFQY ZIDANE HARTONO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
244 20. Teknik Komputer (56401) E32222444 Wildan Abbrhory 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 0 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) 0 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
245 20. Teknik Komputer (56401) E32222530 MOHAMMAD RIZKY ROMADHON 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
246 20. Teknik Komputer (56401) E32222650 MUHAMMAD HISYAMUDDIN 2025.0 bekerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
247 20. Teknik Komputer (56401) E32220549 URIP AGILA SETIO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) - 3 - Staff Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) - 3 - Staff lain tulis f1102 staff tidak_berpengalaman
248 20. Teknik Komputer (56401) E32221220 Muhammad Miftahul Huda 2025.0 belum_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
249 20. Teknik Komputer (56401) E32222571 MOCHAMAD ALBANUS FAHREZI 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
250 20. Teknik Komputer (56401) E32221098 JERY NAUVAL NICKOLAS 2025.0 mencari_kerja 6 - BUMN/BUMD PLN Icon Plus SBU RJBT Data_2025_Tracer_study_D3TKK.csv 6 - BUMN/BUMD PLN Icon Plus SBU RJBT bumn bumd pln icon plus sbu rjbt tidak_berpengalaman
251 20. Teknik Komputer (56401) E32222548 NADIA EMILIANA RAISSA 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
252 20. Teknik Komputer (56401) E32222628 GHAIDA SORAYA M. 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
253 20. Teknik Komputer (56401) E32221354 MOCH. RIZQ YUNIARIEVAL 2025.0 belum_kerja 6 - BUMN/BUMD belum kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 6 - BUMN/BUMD belum kerja 4 - Freelance/Kerja Lepas bumn bumd belum kerja freelance kerja lepas tidak_berpengalaman
254 20. Teknik Komputer (56401) E32221146 JOHARDIO EKA PUTRA ARIV 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
255 20. Teknik Komputer (56401) E32222572 AMALIA KHOIRUN NISA' 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
256 20. Teknik Komputer (56401) E32222484 EGA SAPUTRA WICAKSANA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
257 20. Teknik Komputer (56401) E32221324 MUHAMMAD ABIL SYUGRON HABIBILLAH 2025.0 mencari_kerja 7 - Institusi/Organisasi Multilateral Data_2025_Tracer_study_D3TKK.csv 7 - Institusi/Organisasi Multilateral institusi organisasi multilateral tidak_berpengalaman
258 20. Teknik Komputer (56401) E32221349 MOHAMMAD FARIS VICO PRADIFA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
259 20. Teknik Komputer (56401) E32222371 Ferdiansyah Maula Syarif 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
260 20. Teknik Komputer (56401) E32222580 ALI SYARIEF 2025.0 mencari_kerja 3 - Perusahaan swasta Pt.Iwip Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta Pt.Iwip usaha swasta iwip tidak_berpengalaman
261 20. Teknik Komputer (56401) E32221431 DELI SAFITRI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Ayam Petelur Pak Dela 3 - Staff Data_2025_Tracer_study_D3TKK.csv 4 - Wiraswasta/perusahaan sendiri Ayam Petelur Pak Dela 3 - Staff wiraswasta usaha sendiri ayam telur dela staff tidak_berpengalaman
262 20. Teknik Komputer (56401) E32220213 SADDAM ANDIKA PUTRA 2025.0 belum_kerja 3 - Perusahaan swasta Rumah Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta Rumah usaha swasta rumah tidak_berpengalaman
263 20. Teknik Komputer (56401) E32221348 DWI FITRIYAH KHAERULINA 2025.0 mencari_kerja 1 - Instansi pemerintah Data_2025_Tracer_study_D3TKK.csv 1 - Instansi pemerintah instansi perintah tidak_berpengalaman
264 20. Teknik Komputer (56401) E32220937 AHYAR NUR ALIF 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
265 20. Teknik Komputer (56401) E32221287 MONANG MANGATA TAMPUBOLON 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
266 20. Teknik Komputer (56401) E32222411 Alfian Dani Ahmad Prasetyo 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
267 20. Teknik Komputer (56401) E32221271 LINDA DWI WINANDHA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
268 20. Teknik Komputer (56401) E32222685 AMRI MURSALIINA DARINTO 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
269 20. Teknik Komputer (56401) E32222481 ARDHA PRIA PRAMBUDI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 1 - Founder Data_2025_Tracer_study_D3TKK.csv 4 - Wiraswasta/perusahaan sendiri 1 - Founder wiraswasta usaha sendiri founder tidak_berpengalaman
270 20. Teknik Komputer (56401) E32222855 Imam Ghazali Munir 2025.0 mencari_kerja 1 - Instansi pemerintah Data_2025_Tracer_study_D3TKK.csv 1 - Instansi pemerintah instansi perintah tidak_berpengalaman
271 20. Teknik Komputer (56401) E32221335 HENDRI GUNAWAN 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
272 20. Teknik Komputer (56401) E32222352 IVAN ARIESNA NUGROHO 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
273 20. Teknik Komputer (56401) E32222693 MOCHAMAD ALIF RIDHO AULIA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
274 20. Teknik Komputer (56401) E32222304 MUCHAMAD NASRULLAH SYAHBANA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
275 20. Teknik Komputer (56401) E32221375 KEVIN RIANG EKA PRASETYA 2025.0 mencari_kerja 6 - BUMN/BUMD PLN ICON PLUS Data_2025_Tracer_study_D3TKK.csv 6 - BUMN/BUMD PLN ICON PLUS bumn bumd pln icon plus tidak_berpengalaman
276 20. Teknik Komputer (56401) E32221275 FARHAN PRATAMA PUTRA 2025.0 mencari_kerja 6 - BUMN/BUMD PLN ICON PLUS SURABAYA 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 6 - BUMN/BUMD PLN ICON PLUS SURABAYA 4 - Freelance/Kerja Lepas bumn bumd pln icon plus surabaya freelance kerja lepas tidak_berpengalaman
277 20. Teknik Komputer (56401) E32222396 RIZAL MAULANA ALIF 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
278 20. Teknik Komputer (56401) E32222672 VERGIAWAN KURNIALISTIANTO 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D3TKK.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
279 20. Teknik Komputer (56401) E32222440 ALIF ABDAUL KARIM 2025.0 belum_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
280 20. Teknik Komputer (56401) E32220565 Adam Darmawansa 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
281 20. Teknik Komputer (56401) E32222868 DANDHI DWI ARI PRASETYA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
282 20. Teknik Komputer (56401) E32222363 ROBBY DWI JAYANTO 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
283 20. Teknik Komputer (56401) E32222356 ALIYA NABILLA PUTRI 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
284 20. Teknik Komputer (56401) E32220496 BIMA PUTRA ADITYA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
285 20. Teknik Komputer (56401) E32221343 ANANG SANDI PRASETYO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
286 20. Teknik Komputer (56401) E32221328 MOHAMMAD IRSYAD ROSIDI 2025.0 mencari_kerja 3 - Perusahaan swasta PT Global Media Data Prima 3 - Staff Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta PT Global Media Data Prima 3 - Staff usaha swasta global media data prima staff tidak_berpengalaman
287 20. Teknik Komputer (56401) E32221364 Nisa Carolina Putri 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
288 20. Teknik Komputer (56401) E32222865 AHMAD DHANI ALVARISI 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
289 20. Teknik Komputer (56401) E32222869 GALIH RIANTIARNO 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
290 20. Teknik Komputer (56401) E32212281 Ghilman Roif Zakiri 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
291 20. Teknik Komputer (56401) E32221413 MOH. ANWAR 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
292 20. Teknik Komputer (56401) E32221425 KELVIN MAULANA SHOFANI 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
293 20. Teknik Komputer (56401) E32222437 RIDHO FAISAL HAKKI 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
294 20. Teknik Komputer (56401) E32222349 AKHMAD MARTA ADI PUTRA 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
295 20. Teknik Komputer (56401) E32221434 TEGUH SETYO BUDI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
296 20. Teknik Komputer (56401) E32222377 Akbar Maulana Agritanto 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
297 20. Teknik Komputer (56401) E32222362 FASHA GALIH PUTRA ARIFANDI 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
298 20. Teknik Komputer (56401) E32220150 RAFI ABIYYU YAKIN 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
299 20. Teknik Komputer (56401) e32222568 BIMO RAHMAD DIANSYAH 2025.0 belum_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
300 20. Teknik Komputer (56401) E32222430 DANIEL KEANNY HEBERT 2025.0 melanjutkan_studi Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
301 20. Teknik Komputer (56401) E32222355 Putraku Nabil Rabbani 2025.0 mencari_kerja Data_2025_Tracer_study_D3TKK.csv tidak_berpengalaman
302 20. Teknik Komputer (56401) E32221448 AIDIL ARDIANSYAH 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D3TKK.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
303 20. Teknik Komputer (56401) E32222341 NURUL RIZQI AKBARSYAH ASH SHIDDIQIE 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D3TKK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
304 20. Teknik Komputer (56401) E32221382 FATHUR RIZQI GINANDA ARIKUSUMA 2025.0 belum_kerja 3 - Perusahaan swasta 3 - Staff Data_2025_Tracer_study_D3TKK.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
305 Teknik Informatika (55301) E41232153 RIDLOWAN EKA NUR CAHYA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
306 Teknik Informatika (55301) E41232322 SYABRIANT BAGUS YANUAR 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
307 Teknik Informatika (55301) E41180538 Rendra Adji Prayudi 2025.0 mencari_kerja 3 - Perusahaan swasta PT Mulya Menara Sejahtera Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta PT Mulya Menara Sejahtera usaha swasta mulya menara sejahtera tidak_berpengalaman
308 21. Teknik Informatika (55301) E41202152 putri Adelwis 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) belum 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) belum 4 - Freelance/Kerja Lepas lain tulis f1102 belum freelance kerja lepas tidak_berpengalaman
309 21. Teknik Informatika (55301) E41202502 WIAN ADIYATMA BISMA RAZAAK 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
310 21. Teknik Informatika (55301) E41201544 NOVITA BENING WIDYASTUTI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
311 21. Teknik Informatika (55301) E41232033 ALVIN YUDHA EKA PRADISTYA 2025.0 melanjutkan_studi Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
312 21. Teknik Informatika (55301) E41232270 DEDI HARIYANTO 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
313 21. Teknik Informatika (55301) E41232102 Iwang Pradipta Dinoto 2025.0 belum_kerja 1 - Instansi pemerintah 3 - Staff Data_2025_Tracer_study_D4TIF.csv 1 - Instansi pemerintah 3 - Staff instansi perintah staff tidak_berpengalaman
314 21. Teknik Informatika (55301) E41232545 Desy Nur Alviah 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
315 21. Teknik Informatika (55301) E41232176 BAGUS IKA PUTRANTO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
316 21. Teknik Informatika (55301) E41212022 DEO ANDREAS SYAPUTRA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
317 21. Teknik Informatika (55301) E41210014 FAISAL OKTABRIAN SHOLIHIN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
318 21. Teknik Informatika (55301) E41210003 EDY ATTHOILLAH 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
319 21. Teknik Informatika (55301) E41211496 NILLA PUTRI ROSIDANIA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
320 21. Teknik Informatika (55301) E41210373 NADIA AYU SAFITRI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
321 21. Teknik Informatika (55301) E41210026 REGINA JUNIANTIKA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
322 21. Teknik Informatika (55301) E41210369 RAIHAN ACHMAD DANI FIRMANSYAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
323 21. Teknik Informatika (55301) E41210089 DAFFA AFIFI SYAHRONY 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
324 21. Teknik Informatika (55301) E41210372 KURROTA AKYUN 2025.0 belum_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
325 21. Teknik Informatika (55301) E41210005 NAJWA AMALIA MAHARANI 2025.0 mencari_kerja 3 - Perusahaan swasta Megata Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta Megata usaha swasta megata tidak_berpengalaman
326 21. Teknik Informatika (55301) E41211247 POPO ZAKARIA 2025.0 mencari_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas usaha swasta freelance kerja lepas tidak_berpengalaman
327 21. Teknik Informatika (55301) E41210602 RESTU FAHIMUROID 2025.0 melanjutkan_studi 3 - Staff Data_2025_Tracer_study_D4TIF.csv 3 - Staff staff tidak_berpengalaman
328 21. Teknik Informatika (55301) E41210004 Mokhamad Farhan Abdillah 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Freelance 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri Freelance 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance freelance kerja lepas tidak_berpengalaman
329 21. Teknik Informatika (55301) E41210800 FARHAN HILMY ARWANTO 2025.0 mencari_kerja 7 - Institusi/Organisasi Multilateral 3 - Staff Data_2025_Tracer_study_D4TIF.csv 7 - Institusi/Organisasi Multilateral 3 - Staff institusi organisasi multilateral staff tidak_berpengalaman
330 21. Teknik Informatika (55301) E41210674 ATHIYAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
331 21. Teknik Informatika (55301) e41211491 Rayhan Febriansyah 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
332 21. Teknik Informatika (55301) E41210930 FILLAH SEPTIAN 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
333 21. Teknik Informatika (55301) E41210679 FAQIH MUSTAFA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
334 21. Teknik Informatika (55301) E41212169 ELISA FEBRIAN SHOLEHA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
335 21. Teknik Informatika (55301) E41212166 FARA DERLIANA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
336 21. Teknik Informatika (55301) E41212128 ANDINI PUTRI RAMADHANI 2025.0 mencari_kerja - Data_2025_Tracer_study_D4TIF.csv - tidak_berpengalaman
337 21. Teknik Informatika (55301) E41210069 SHILMIA MADINA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
338 21. Teknik Informatika (55301) E41210096 BABYLINA VINDAROSITA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
339 21. Teknik Informatika (55301) E41211320 Achmad Zakariya 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
340 21. Teknik Informatika (55301) E41232544 VENI KURNIA DEWI 2025.0 mencari_kerja 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat Sekolah Data_2025_Tracer_study_D4TIF.csv 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat Sekolah organisasi non profit lembaga swadaya masyarakat sekolah tidak_berpengalaman
341 21. Teknik Informatika (55301) E41211144 ADHE WAHYU TRILAKSANA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
342 21. Teknik Informatika (55301) E41210998 JACINDA OLGA NABILA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) - Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) - lain tulis f1102 tidak_berpengalaman
343 21. Teknik Informatika (55301) E41212091 AISYAH FIKRI NABILAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
344 21. Teknik Informatika (55301) E41210477 FIKRI AHDIAR 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri RELIS 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri RELIS 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri rel freelance kerja lepas tidak_berpengalaman
345 21. Teknik Informatika (55301) E41211039 AIKO MAWARDI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
346 21. Teknik Informatika (55301) E41210099 FIRDIYATUS SHOLIHAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
347 21. Teknik Informatika (55301) E41210436 THORIQ LUKMAN HAKIM 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
348 21. Teknik Informatika (55301) E41202343 PUTRI SALSABHILA FAHIRA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
349 21. Teknik Informatika (55301) E41212168 INDRA PRASETYO WIJAYA 2025.0 mencari_kerja 6 - BUMN/BUMD - Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD - bumn bumd tidak_berpengalaman
350 21. Teknik Informatika (55301) E41212253 KRISNA CHOIRIL ANDIKA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
351 21. Teknik Informatika (55301) E41211969 AHMAD TAUFIQ RIDHO'I 2025.0 bekerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
352 21. Teknik Informatika (55301) E41210598 EKA SULISTYANINGSIH 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
353 21. Teknik Informatika (55301) E41210731 IDA SEVIA 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
354 21. Teknik Informatika (55301) E41212069 ALIF TRIADI AGUNG WICAKSONO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
355 21. Teknik Informatika (55301) E41211478 GYMNASTIAR ALMA GHIFARI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
356 21. Teknik Informatika (55301) E41211245 MUHAMMAD REZA IVANO PAHLEVI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
357 21. Teknik Informatika (55301) E41232549 RISMA DEWI SEPTIANI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
358 21. Teknik Informatika (55301) E41212097 AKNEZ NURIL MAHMUDA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
359 21. Teknik Informatika (55301) E41232541 MUHAMMAD FARRAS WIRAWAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
360 21. Teknik Informatika (55301) E41210132 GEMA HANNA NAPITUPULU 2025.0 mencari_kerja 6 - BUMN/BUMD MASPION Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD MASPION bumn bumd maspion tidak_berpengalaman
361 21. Teknik Informatika (55301) E41212025 IRMA FIRNANDA 2025.0 mencari_kerja 6 - BUMN/BUMD PT PETROKIMIA GRESIK 3 - Staff Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD PT PETROKIMIA GRESIK 3 - Staff bumn bumd petrokimia gresik staff tidak_berpengalaman
362 21. Teknik Informatika (55301) E41232537 Anang Prayoga 2025.0 melanjutkan_studi Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
363 21. Teknik Informatika (55301) E41211551 AHMAD HIPNIE KHOIRI 2025.0 mencari_kerja infinite 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv infinite 4 - Freelance/Kerja Lepas infinite freelance kerja lepas tidak_berpengalaman
364 21. Teknik Informatika (55301) E41232538 HUSNUL PUTRI CANDRA BUANA 2025.0 melanjutkan_studi Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
365 21. Teknik Informatika (55301) E41212174 FATHAN MAULANA RIFQI HARTONO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
366 21. Teknik Informatika (55301) E41211978 AMELIA FAWWAZ ZAIN 2025.0 mencari_kerja PELINDO Data_2025_Tracer_study_D4TIF.csv PELINDO pelindo tidak_berpengalaman
367 21. Teknik Informatika (55301) E41210172 ADITYA IBRAR ABDILLAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
368 21. Teknik Informatika (55301) E41212151 ISMIATI EKA OKTAFIA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
369 21. Teknik Informatika (55301) E41212101 EKA PUTRI YULIANA 2025.0 mencari_kerja 6 - BUMN/BUMD Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD bumn bumd tidak_berpengalaman
370 21. Teknik Informatika (55301) E41211128 KRISTOPHER YOHANES IMMANUEL TAMBUNAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
371 21. Teknik Informatika (55301) E41212068 ADELIA AYU AVISTA 2025.0 mencari_kerja 6 - BUMN/BUMD 3 - Staff Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD 3 - Staff bumn bumd staff tidak_berpengalaman
372 21. Teknik Informatika (55301) E41211217 GIGIH DWI CAHYO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
373 21. Teknik Informatika (55301) E41210716 KHOFIFAH AINURROHMAH 2025.0 mencari_kerja 6 - BUMN/BUMD BUMN Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD BUMN bumn bumd bumn tidak_berpengalaman
374 21. Teknik Informatika (55301) E41232547 FIRDA ULFA UNSILAH 2025.0 melanjutkan_studi Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
375 21. Teknik Informatika (55301) E41232542 MUHAMMAD ILHAM YUAL MAULANA 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri milik sensiri 1 - Founder Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri milik sensiri 1 - Founder wiraswasta usaha sendiri milik sensiri founder tidak_berpengalaman
376 21. Teknik Informatika (55301) E41232540 MUHAMAD BAYU CANDRA PAMUNGKAS 2025.0 melanjutkan_studi Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
377 21. Teknik Informatika (55301) E41210002 RESTU AJI PRASETYO SAPUTRA 2025.0 mencari_kerja - 3 - Staff Data_2025_Tracer_study_D4TIF.csv - 3 - Staff staff tidak_berpengalaman
378 21. Teknik Informatika (55301) E41211570 WISHAL AZHARYAN AL HISYAM 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 1 - Founder Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri 1 - Founder wiraswasta usaha sendiri founder tidak_berpengalaman
379 21. Teknik Informatika (55301) E41211408 DAFFA FAUZI RAHMAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
380 21. Teknik Informatika (55301) E41210766 Akbar Ramadhani Firdaus 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
381 21. Teknik Informatika (55301) E41210603 DAVID ARROZAQI 2025.0 belum_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
382 21. Teknik Informatika (55301) E41211220 YUNAN ADITYA PRIMAWATDANA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
383 21. Teknik Informatika (55301) E41211107 MUHAMMAD ZAINAL ABIDIN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
384 21. Teknik Informatika (55301) E41210798 Yusuf Firmansyah Adi Basuni 2025.0 melanjutkan_studi Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
385 21. Teknik Informatika (55301) E41212285 ELISA CHRISTIAN ALFRIDO MANTOLAS 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
386 21. Teknik Informatika (55301) E41211257 MUHAMMAD ILHAM IKHWANUL AKRAM 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) belum bekerja Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) belum bekerja lain tulis f1102 belum kerja tidak_berpengalaman
387 21. Teknik Informatika (55301) E41211111 ALIF IMANULLAH KRISNA ALAM 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
388 21. Teknik Informatika (55301) E41212263 ZULFIANTI RAHMAWATI ASHILAH 2025.0 mencari_kerja 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat - 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 2 - Organisasi non-profit/Lembaga Swadaya Masyarakat - 4 - Freelance/Kerja Lepas organisasi non profit lembaga swadaya masyarakat freelance kerja lepas tidak_berpengalaman
389 21. Teknik Informatika (55301) E41210698 MUHAMMAD MAULANA MALIK IBRAHIM 2025.0 mencari_kerja 1 - Instansi pemerintah Pemerintah Daerah Data_2025_Tracer_study_D4TIF.csv 1 - Instansi pemerintah Pemerintah Daerah instansi perintah perintah daerah tidak_berpengalaman
390 21. Teknik Informatika (55301) E41210960 Rio Javier Reyhan 2025.0 mencari_kerja 7 - Institusi/Organisasi Multilateral Data_2025_Tracer_study_D4TIF.csv 7 - Institusi/Organisasi Multilateral institusi organisasi multilateral tidak_berpengalaman
391 21. Teknik Informatika (55301) E41212254 Fahmy Rosyadi 2025.0 mencari_kerja 3 - Perusahaan swasta Profile Image Studio 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta Profile Image Studio 4 - Freelance/Kerja Lepas usaha swasta profile image studio freelance kerja lepas tidak_berpengalaman
392 21. Teknik Informatika (55301) E41212217 ABDULLAH ALI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
393 21. Teknik Informatika (55301) E41211349 FREDA ADI FARDANA 2025.0 mencari_kerja 3 - Perusahaan swasta 3 - Staff Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
394 21. Teknik Informatika (55301) E41211473 RINA WULANDHARI 2025.0 wiraswasta Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
395 21. Teknik Informatika (55301) E41211200 EGA SYAHRUL RAMADHANTO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
396 21. Teknik Informatika (55301) E41211601 MUHAMMAD LUTFI ZE'IN AMINULLAH 2025.0 belum_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
397 21. Teknik Informatika (55301) E41191074 EVRA MARIO SIRAIT 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
398 21. Teknik Informatika (55301) E41210022 LIZA INDARWATI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri ADB Programming 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri ADB Programming 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri adb programming freelance kerja lepas tidak_berpengalaman
399 21. Teknik Informatika (55301) E41211463 REZKY AGUS SETIAWAN 2025.0 belum_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
400 21. Teknik Informatika (55301) E41210905 NABILA ZHAFARINA 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri freelance kerja lepas tidak_berpengalaman
401 21. Teknik Informatika (55301) E41210730 ADINDA EKA MAYANG WIJAYANTI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
402 21. Teknik Informatika (55301) E41211975 ANIK SAHILAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
403 21. Teknik Informatika (55301) E41211194 LUTFI AMELIYA PUTRI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Mad Buah Home 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri Mad Buah Home 4 - Freelance/Kerja Lepas wiraswasta usaha sendiri mad buah home freelance kerja lepas tidak_berpengalaman
404 21. Teknik Informatika (55301) E41211319 AMMAR AKHTAR ADDANY 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
405 21. Teknik Informatika (55301) E41210647 KHAIRATUZ ZAHRO 2025.0 belum_kerja 6 - BUMN/BUMD 3 - Staff Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD 3 - Staff bumn bumd staff tidak_berpengalaman
406 21. Teknik Informatika (55301) E41212252 MAULANA IBRAHIM 2025.0 mencari_kerja 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 6 - BUMN/BUMD 4 - Freelance/Kerja Lepas bumn bumd freelance kerja lepas tidak_berpengalaman
407 21. Teknik Informatika (55301) E41212368 BHAKTI DWI RAMADHANI HENDARTO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Tidak Ada 1 - Founder Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) Tidak Ada 1 - Founder lain tulis f1102 founder tidak_berpengalaman
408 21. Teknik Informatika (55301) E41212221 Naufal Alif Nur Muhammad Rahmadhan 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
409 21. Teknik Informatika (55301) E41212297 ANGGA PRABASWARA PUTRA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
410 21. Teknik Informatika (55301) E41191683 AULIA NOVRIN HARLEYANTO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
411 21. Teknik Informatika (55301) E41202549 MUHAMMAD NAFIL 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) WFH 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) WFH 4 - Freelance/Kerja Lepas lain tulis f1102 wfh freelance kerja lepas tidak_berpengalaman
412 21. Teknik Informatika (55301) E41210746 MOCH IQBAL MAULANA FIEKRI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
413 21. Teknik Informatika (55301) E41211965 AYU ANGGRAINI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
414 21. Teknik Informatika (55301) E41211674 MUHAMAD SLAMET DAROENI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
415 21. Teknik Informatika (55301) E41212104 NIECOLA JODY SETIAWAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
416 21. Teknik Informatika (55301) E41211209 AKBAR FIRMANSYAH 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) saya belum bekerja 1 - Founder Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) saya belum bekerja 1 - Founder lain tulis f1102 belum kerja founder tidak_berpengalaman
417 21. Teknik Informatika (55301) E41210223 MOH FARRIJ WAJDI 2025.0 mencari_kerja 1 - Founder Data_2025_Tracer_study_D4TIF.csv 1 - Founder founder tidak_berpengalaman
418 21. Teknik Informatika (55301) E41210734 ANDRE KHARISMA DWI THANSA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
419 21. Teknik Informatika (55301) E41232548 NOFAIRA AMIN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
420 21. Teknik Informatika (55301) E41231543 Muhamad Nusayif Jassim 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri wiraswasta usaha sendiri tidak_berpengalaman
421 21. Teknik Informatika (55301) E41211762 FIRMANSYAH FIKRIAWAN 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv 5 - Lainnya, Tuliskan (f1102) 4 - Freelance/Kerja Lepas lain tulis f1102 freelance kerja lepas tidak_berpengalaman
422 21. Teknik Informatika (55301) E41212008 AFI ZAIN RAMADANA 2025.0 belum_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
423 21. Teknik Informatika (55301) E41210176 ADAM KARSAR NUGROHO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIF.csv tidak_berpengalaman
424 Teknik Informatika (55301) E41191405 ACHMAD AJI WICAKSONO 2025.0 belum_kerja 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta 4 - Freelance/Kerja Lepas 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum usaha swasta freelance kerja lepas lokal wilayah wiraswasta badan hukum tidak_berpengalaman
425 Teknik Informatika (55301) E41191211 TEGAR AR RASYIID SAIFULAH 2025.0 belum_kerja Usaha Sampingan 1 - Founder 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum Data_2025_Tracer_study_D4TIF.csv Usaha Sampingan 1 - Founder 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum usaha samping founder lokal wilayah wiraswasta badan hukum tidak_berpengalaman
426 Teknik Informatika (55301) E41201609 BOY DYMAS HIDAYAT 2025.0 belum_kerja 4 - Wiraswasta/perusahaan sendiri 3 - Staff 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum Data_2025_Tracer_study_D4TIF.csv 4 - Wiraswasta/perusahaan sendiri 3 - Staff 1 - Lokal/wilayah/wiraswasta tidak berbadan hukum wiraswasta usaha sendiri staff lokal wilayah wiraswasta badan hukum tidak_berpengalaman
427 Teknik Informatika (55301) E41232136 SILFI GABRILIA CHOIRUN NISA 2025.0 belum_kerja 3 - Perusahaan swasta 3 - Staff Data_2025_Tracer_study_D4TIF.csv 3 - Perusahaan swasta 3 - Staff usaha swasta staff tidak_berpengalaman
428 Teknik Informatika (55301) E41232098 Moch. Iqbal Rosyidi 2025.0 belum_kerja tidak bekerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIF.csv tidak bekerja 4 - Freelance/Kerja Lepas kerja freelance kerja lepas tidak_berpengalaman
429 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211358 DAFFA ADITYA REJASA RUSWANTO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
430 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41210291 SANGGA DEWA RAMADHAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
431 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211399 ERLYNA BERLIAN PRASTITI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
432 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211493 ENDIENING NUR PUSPITASARI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
433 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211253 ENGGAR SUSMITA 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D4TIFNGANJUK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
434 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212020 MOCHAMAD FARIS HASAN FEBRIANSHAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
435 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212241 RAKHA ARIAN ARCHANIGA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
436 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212173 PRISCILIA HILDA AGUSTIN 2025.0 mencari_kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIFNGANJUK.csv 4 - Freelance/Kerja Lepas freelance kerja lepas tidak_berpengalaman
437 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212036 AHMAD CHOIRUL UMAM ALI ROZAQI 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D4TIFNGANJUK.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
438 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212313 M. BRILLIANT RIDHO SISWANTO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
439 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212290 DIMAS ADI PUTRA ARIFIN 2025.0 mencari_kerja 7 - Institusi/Organisasi Multilateral Data_2025_Tracer_study_D4TIFNGANJUK.csv 7 - Institusi/Organisasi Multilateral institusi organisasi multilateral tidak_berpengalaman
440 22. Teknik Informatika Kampus Kab. Nganjuk (55302) e41212053 RENGGA DWI PRIBADI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
441 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211051 HABIB ANDRIANTITO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
442 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211995 Wijang Afdholanabil Kusuma 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
443 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211993 RATIH DEWI SETIANI 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri - 3 - Staff Data_2025_Tracer_study_D4TIFNGANJUK.csv 4 - Wiraswasta/perusahaan sendiri - 3 - Staff wiraswasta usaha sendiri staff tidak_berpengalaman
444 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212331 CORNELIA RAHMAWATI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
445 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212136 ROSITA CATUR SEPTIANINGSIH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
446 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212095 MOCHAMAD YUNUS IKHSANODIN 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D4TIFNGANJUK.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
447 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212133 Naufal Kadhafi 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
448 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41210983 ROSYIDA ARIAN RAHMA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFNGANJUK.csv tidak_berpengalaman
449 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211992 FAUZIAN AQZZAL HAFIDZ 2025.0 mencari_kerja 3 - Perusahaan swasta Polije 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIFNGANJUK.csv 3 - Perusahaan swasta Polije 4 - Freelance/Kerja Lepas usaha swasta polije freelance kerja lepas tidak_berpengalaman
450 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41212268 BAGUS HARIS SUHARTONO 2025.0 mencari_kerja 3 - Perusahaan swasta Starpace 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIFNGANJUK.csv 3 - Perusahaan swasta Starpace 4 - Freelance/Kerja Lepas usaha swasta starpace freelance kerja lepas tidak_berpengalaman
451 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211384 AHMAD EDZAM PRASETYA 2025.0 mencari_kerja 3 - Perusahaan swasta Politeknik Negeri Jember 1 - Founder Data_2025_Tracer_study_D4TIFNGANJUK.csv 3 - Perusahaan swasta Politeknik Negeri Jember 1 - Founder usaha swasta politeknik negeri jember founder tidak_berpengalaman
452 22. Teknik Informatika Kampus Kab. Nganjuk (55302) E41211952 NOVA NUR ANGGRAINI 2025.0 belum_kerja 1 - Instansi pemerintah Komisi Pemilihan Umum 3 - Staff Data_2025_Tracer_study_D4TIFNGANJUK.csv 1 - Instansi pemerintah Komisi Pemilihan Umum 3 - Staff instansi perintah komisi pilih umum staff tidak_berpengalaman
453 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212013 ABHINAYA FAHAR LAILA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
454 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212046 Achmad Baihaqi 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
455 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41211994 ACH. FASIHUL LISAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
456 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212260 RIZQI AZIZISSANI 2025.0 mencari_kerja 3 - Perusahaan swasta Data_2025_Tracer_study_D4TIFSIDOARJO.csv 3 - Perusahaan swasta usaha swasta tidak_berpengalaman
457 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212060 OCTAVIAN DAVA PUTRA CAHYONO 2025.0 mencari_kerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIFSIDOARJO.csv 4 - Freelance/Kerja Lepas freelance kerja lepas tidak_berpengalaman
458 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212099 KENNYO GENDIS PUTRI HARLI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
459 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212139 JESSICA DESI IMELDA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
460 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212081 CAHAYA CITRA AZZAHRO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
461 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212058 MOCH GHAZY AL GHIFARI HAFID 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Data_2025_Tracer_study_D4TIFSIDOARJO.csv 4 - Wiraswasta/perusahaan sendiri wiraswasta usaha sendiri tidak_berpengalaman
462 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212126 MARZUKI AKMAL 2025.0 mencari_kerja 4 - Wiraswasta/perusahaan sendiri Data_2025_Tracer_study_D4TIFSIDOARJO.csv 4 - Wiraswasta/perusahaan sendiri wiraswasta usaha sendiri tidak_berpengalaman
463 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212044 DAFFA AGUNG NUGROHO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
464 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212358 MUHAMMAD ANDRA KUSUMA RAMADHAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
465 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212045 ILHAM GUSTI SYAH PUTRO 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) Data_2025_Tracer_study_D4TIFSIDOARJO.csv 5 - Lainnya, Tuliskan (f1102) lain tulis f1102 tidak_berpengalaman
466 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212055 JOHAN KRISBIMA ABI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
467 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212037 BILAL SHANDYARTA SYAMSUDIN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
468 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212026 BIMA PRAYOGA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
469 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212359 OWEN PRATAMA ENDRAMAWAN 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
470 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212250 HERLAMBANG SATRIA WIJAYA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
471 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212129 NABILA RAHMA YUSRILFA TRISYAYANTI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
472 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212063 ASMIRANTI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
473 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212079 FADLIL LIWAUL HAMDI 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
474 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212006 MOCHAMMAD ENRIQUE LAZUARDI RAMADANY 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) - Data_2025_Tracer_study_D4TIFSIDOARJO.csv 5 - Lainnya, Tuliskan (f1102) - lain tulis f1102 tidak_berpengalaman
475 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212125 DINA DWI ARIKA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
476 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212057 FACHRY RIZKY PRASETYA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
477 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212012 HARIS ASYSYAUQI 2025.0 mencari_kerja 3 - Perusahaan swasta PT Rexline Engineering Indonesia Data_2025_Tracer_study_D4TIFSIDOARJO.csv 3 - Perusahaan swasta PT Rexline Engineering Indonesia usaha swasta rexline engineering indonesia tidak_berpengalaman
478 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212105 FATKHUL HIDAYAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
479 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41211962 LYA NURUL ULLA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
480 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212270 MOH. FERDI ANDRIANSYAH 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
481 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212137 AGIL GILANG CHANDRA SAPUTRA 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman
482 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212403 MUHAMMAD SHALAHUDIN AYUBI FIRMANSYAH 2025.0 mencari_kerja 5 - Lainnya, Tuliskan (f1102) belum bekerja 4 - Freelance/Kerja Lepas Data_2025_Tracer_study_D4TIFSIDOARJO.csv 5 - Lainnya, Tuliskan (f1102) belum bekerja 4 - Freelance/Kerja Lepas lain tulis f1102 belum kerja freelance kerja lepas tidak_berpengalaman
483 23. Teknik Informatika Kampus Kab. Sidoarjo (55304) E41212054 DYIONO 2025.0 mencari_kerja Data_2025_Tracer_study_D4TIFSIDOARJO.csv tidak_berpengalaman

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -0,0 +1,536 @@
nim,nama,kode_prodi,status_pekerjaan,cluster,teks_pekerjaan,kategori,match_profil,matched_keywords
E31160241,Rizki Firmansyah,57401.0,bekerja,0,nirlaba irsyad islamiyyah jember,C2,False,
E32160207,Afrizal Gita Putra Laksono,56401.0,bekerja,3,swasta nexwave,C2,False,
E31161703,Lilik Widayanti,57401.0,bekerja,0,perintah balai desa sumbermujur,C2,False,
E31160798,LUKMAN HARUN,57401.0,wiraswasta,0,wiraswasta barokah cell,C2,False,
E41150080,DAVID SUGIANTO,55301.0,bekerja,3,swasta tokopedia,C2,False,
E41151627,Ahmad Syamsul Arifin,55301.0,wiraswasta,2,wiraswasta dafidea technocraft,C0,True,tech
E31161033,Ayu Diyah Purwanti,57401.0,bekerja,0,bumn bank negara indonesia tbk,C2,False,
E41151085,Yunita Dwi Pujianti,55301.0,bekerja,1,nirlaba politeknik negeri jember,C1,False,
E41151776,Mahbubi Ilham Nafiulalam,55301.0,bekerja,3,swasta tjiwi kimia tbk,C2,False,
E31161241,Aulia Rafi Dika Pekasih,57401.0,bekerja,3,swasta yaffi solusi internasional,C2,False,
E31161816,Dhimas Ulfa Lathifah,57401.0,bekerja,3,swasta moro ayu cosmetindo,C2,False,
E41150057,DITA PUSPITA RAHMA PUTRI,55301.0,bekerja,3,swasta sentra vidya utama sevima,C2,False,
E41150559,RAYHAN SAVERO ARIL,55301.0,bekerja,3,swasta telkomsel,C2,False,
E32161301,Muhammad Isbi Romadhoni,56401.0,bekerja,0,swasta east west seed indonesia,C2,False,
E32160628,SANDY KURNIAWAN,56401.0,bekerja,3,swasta pelangi migas abadi,C0,True,lan
E32160392,MOHAMMAD FADHUR ROHMAN,56401.0,bekerja,3,swasta enggar media sentana,C2,False,
E32160891,MUHAMMAD ALY ROFIE,56401.0,bekerja,0,bumn asuransi jiwasraya,C2,False,
E41151925,Wahyu Kartini Putri Aditya,55301.0,bekerja,3,swasta yayasan imam syafi,C2,False,
E32161373,Yuni Syafarinda,56401.0,bekerja,0,swasta idn boarding school,C2,False,
E41171583 ,AHMAD FAKIH HASBULLAH,55301.0,bekerja,0,wiraswasta usaha bisnis kembang konten creator,C2,False,
E41171389 ,SEPTIAJI WARAGA FILA,55301.0,wiraswasta,2,wiraswasta lilik collection,C2,False,
E41171753 ,Rikky Ihza Pratama,55301.0,bekerja,0,bnpp maulid teknologi kreatif,C1,False,
E41172249 ,RENDHY PRATAMA PUTRA,55301.0,bekerja,1,nirlaba politeknik negeri jember,C1,False,
E31181391 ,AN NISSA SAFITRI,57401.0,bekerja,2,wiraswasta mustikatama,C2,False,
E32180649 ,DEWI MAGREZA ALFIONITA,56401.0,bekerja,0,bnpp appen,C2,False,
E41170896 ,SYAVINA OCTAVIA PARAHITA,55301.0,bekerja,0,perintah dinas sosial kabupaten jember,C2,False,
E32181095 ,Helen Uni Dewi Samima,56401.0,wiraswasta,0,wiraswasta jual umpan ikan,C2,False,
E31151415 ,DENNY SETIADY PRABOWO,57401.0,bekerja,2,wiraswasta forensmith,C1,False,
E32181826 ,YUNDA CHONITA,56401.0,bekerja,0,nirlaba arsenet global solusi,C2,False,
E41171926 ,YOSEF YOGA HIMAWAN,55301.0,bekerja,0,wiraswasta araya media,C2,False,
E32180259 ,YUSRON WIDAD SYARFAN,56401.0,bekerja,0,bumn lintas nusantara,C2,False,
E32180470 ,ACHMAD MAULUDI FATHONY,56401.0,bekerja,0,bnpp kantor bank,C2,False,
E41172060 ,ROKI PRASETYO ADI,55301.0,bekerja,0,bnpp smk pancasila jember,C2,False,
,KHOSNOL KHOTIMATUL ARIFAH,55301.0,bekerja,0,bumn maulid teknologi kreatif,C1,False,
E32181653 ,Firdaus Andy Muhammad,56401.0,wiraswasta,0,wiraswasta jual baju,C2,False,
E31181032 ,MAULIEN JULYA SELEBRITISH,57401.0,wiraswasta,2,wiraswasta wiraswasta,C2,False,
E31181280 ,WULAN CAHYA WANDANI,57401.0,bekerja,0,perintah diskominfo,C2,False,
E41171613 ,GALIH BAGUS PRAKASA,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E31182077 ,RIVALDY NUR IDRIS,57401.0,bekerja,0,wiraswasta polije,C2,False,
E31180387 ,KANISA SHEILA IN ALVIONITA,57401.0,bekerja,0,bnpp jtv,C2,False,
E41171308 ,BAWIK ARDIYAN RAMADHAN,55301.0,bekerja,0,bnpp techno,C0,True,tech
E32181021 ,MOH. YOGI FERNANDA,56401.0,bekerja,0,bnpp kcm,C2,False,
E41171749 ,ALI MANSUR,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E31180464 ,SEPTIYAN YULIONO,57401.0,bekerja,2,wiraswasta karpet,C2,False,
E31180691 ,AHMAD FARHAN ALI,57401.0,wiraswasta,2,wiraswasta dmsncloth,C2,False,
E31180638 ,NAILUL AZMI ZIDNI ILMA,57401.0,wiraswasta,2,wiraswasta atapbesi,C2,False,
E31180819 ,MOCH. IQBAL ROSYIDI,57401.0,melanjutkan_studi,0,wiraswasta kerja,C2,False,
E31180838 ,YUANA DWI PANGESTU,57401.0,bekerja,2,wiraswasta cafe,C2,False,
E32181637 ,MUHAMMAD ADITYA MARTONO,56401.0,bekerja,2,wiraswasta mie terror,C2,False,
E31182176 ,JOSANTHA MARSHEL VALENDRA,57401.0,bekerja,0,wiraswasta esolusindo,C2,False,
E41170291 ,ALI WAJHAH,55301.0,bekerja,0,wiraswasta jember muslim store,C2,False,
E41161315 ,RIFQI HAKIM ARIESDIANTO,55301.0,wiraswasta,2,wiraswasta king kalkun,C2,False,
E31181297 ,SASTI WIDIYAS SARI,57401.0,bekerja,0,wiraswasta rumah,C2,False,
E41172069 ,AKHLAQ KHAN,55301.0,bekerja,0,wiraswasta toko bang mansur,C2,False,
E41170916 ,MUHAMMAD KHOIRIRI,55301.0,wiraswasta,2,wiraswasta pemuda padi,C2,False,
E41170897 ,RIDI YOGA PRATAMA,55301.0,bekerja,0,nirlaba pondok pesantren ibnu katsir,C2,False,
E31160935 ,RISANG AYU LARASATI,57401.0,wiraswasta,2,wiraswasta pawon uti,C2,False,
E41171041 ,MAKHI HAKIM HAKIKI,55301.0,bekerja,1,perintah man jember,C2,False,
E32181772 ,MOH. NUR AHSAN,56401.0,bekerja,0,nirlaba zamzee computer,C2,False,
E32180529 ,MUHAMMAD NASRUL FATTAH,56401.0,bekerja,0,wiraswasta sahabat bangun,C2,False,
E32181708 ,APRILLIO DOVAN ARIESA,56401.0,melanjutkan_studi,0,wiraswasta toko azahra,C2,False,
E31181204 ,FARIZ GUSTAFIANTO,57401.0,wiraswasta,0,wiraswasta zayid persada,C2,False,
E31181830 ,DITA SHAFIRA WAHYUDI,57401.0,melanjutkan_studi,2,wiraswasta yudi net,C2,False,
E41171120 ,MUHAMMAD ARIEF RACHMAN MUTTAQIEN,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E31182013 ,ABDANIAL PRADITYA,56401.0,bekerja,3,swasta proxinet,C2,False,
E41172068 ,AFFAN TOHARI,55301.0,bekerja,0,bnpp bikea tekno,C2,False,
E31180187 ,PUSPITA SARI RAKHMATULLAH,57401.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E31180222 ,ELLA WAHYUNINGTYAS,57401.0,bekerja,0,wiraswasta polije,C2,False,
E32180842 ,NURUL QOMARIYAH,56401.0,bekerja,0,bumn pdam bondowoso,C2,False,
E41171252 ,NIKO WAHYU FITRIANTO,55301.0,bekerja,0,swasta indomarco prismatama,C2,False,
E31181955 ,M. PANDU GAUTAMA WIRANAGARA,57401.0,bekerja,0,wiraswasta freelance,C2,False,
E31180112 ,INTA OKTA RESTANTI,57401.0,bekerja,0,bumn kopegtel,C2,False,
E32181801 ,REY DICO PERWINA AMADA N.,56401.0,bekerja,2,wiraswasta albertacommunity,C1,False,
E31180686 ,HIKMAH QUR'ANING TYAS,57401.0,bekerja,0,wiraswasta shopee,C2,False,
E41170204 ,DANI ARDIYANSYAH,55301.0,bekerja,0,bumn pertamina,C2,False,
E31180256 ,Alfira Rosalina Damela,57401.0,bekerja,0,bumn antam tbk,C2,False,
E41170873 ,ACHSANUL KHIZAM,55301.0,bekerja,0,bnpp jatilindo,C2,False,
E32180210 ,FIKRI HAIKAL,56401.0,bekerja,0,bnpp karya cipta mekatronika,C2,False,
E41170676 ,ANGGI TRIKUSUMA DEWI,55301.0,bekerja,0,wiraswasta avatar solution,C2,False,
E32182281 ,ROSITA B KASIPDANA,56401.0,bekerja,0,perintah kantor bupati,C2,False,
E41171452 ,ADY BAGUS SUGIH SUSANTO,55301.0,bekerja,0,swasta indomarco prismatama,C2,False,
E32160410 ,ANDRE KRISNA PRATAMA,56401.0,bekerja,3,swasta bima technologies,C2,False,
E31181496 ,MURPY SATRIYA NUGRAHA,57401.0,bekerja,0,swasta maulid teknologi kreatif maulid games,C1,False,
E31181929 ,Andaru Bagus Gandhy Nurwidigdo,57401.0,bekerja,3,swasta bencoolencoffee,C2,False,
E41171829 ,MEGA SILVIA,55301.0,bekerja,3,swasta mang sabay rumah makan,C2,False,
E32181586 ,HARFI KURNIA HADIPUTRA,56401.0,bekerja,0,perintah diskominfo bondowoso,C2,False,
E41170438 ,MOHAMAD RIZAL RAMLI,55301.0,bekerja,0,swasta xeno persada teknologi,C1,False,
E41170753 ,DHENI TEGUH PRAMONO,55301.0,wiraswasta,2,wiraswasta bajukita id,C1,False,
E31180825 ,KEVIN ADITYAPUTRA ADRIANSYAH,57401.0,wiraswasta,2,wiraswasta mitreka karsa,C1,False,
E41170740 ,ABDILANA MOHTALIA SAPUTRA,55301.0,bekerja,0,perintah rsud koesnadi bondowoso,C2,False,
E41170164 ,Rizkika Zakka Palindungan,55301.0,bekerja,0,swasta xeno persada teknologi,C1,False,
E31180427 ,REZA ROMADHONI ALWI,57401.0,bekerja,3,swasta usaha swasta,C2,False,
E32180687 ,FARHAN IRZYAM ARI GUNTARA,56401.0,wiraswasta,0,wiraswasta ataraxia group,C2,False,
E41190088 ,Dimas Fariztha Hadiyatullah,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E31181553 ,LADINA PUTRI ANDITYANDARI,57401.0,bekerja,3,swasta strawberry preschool and daycare,C2,False,
E41172253 ,Fahrizal Azi Ferdiansyah,55301.0,bekerja,3,swasta devivace,C2,False,
E31182056 ,MOHAMMAD NAZIL ZAINUDDIN,57401.0,bekerja,2,wiraswasta tich,C2,False,
E32180275 ,MOH HAIRUL ARIFIN,56401.0,wiraswasta,2,wiraswasta arifnet,C2,False,
E32180653 ,SHOFIAH NUR MAZIDA,56401.0,wiraswasta,0,wiraswasta rumah dannis,C2,False,
E41170809 ,KURNIA MUTIARA SEPTI,55301.0,wiraswasta,2,wiraswasta aara dekorasi,C2,False,
E41171994 ,SASQIA DWI ARTA NOVIA,55301.0,bekerja,0,bnpp bank mega syariah,C2,False,
E41171742 ,RIDWAN HANANTO AJI ARIFIN,55301.0,bekerja,0,wiraswasta prodevis team,C2,False,
E41171660 ,REFI TRI HIDAYATULLAH,55301.0,wiraswasta,0,wiraswasta jasa buat website,C1,False,
E31180926 ,MUSBIHATUL CHORIROH,57401.0,bekerja,0,perintah perintah kabupaten nganjuk,C2,False,
E31180696 ,RIZQIANA AMITASARI,57401.0,wiraswasta,0,wiraswasta toko baju,C2,False,
E41170926 ,FAHRIZA RAMADHANI PUTRA,55301.0,bekerja,0,perintah polda jatim,C2,False,
E31180892 ,RURY AGISTA ASMININGSIH,57401.0,bekerja,0,perintah diskominfo,C2,False,
E41170061 ,Elsa Manora Ramadania,55301.0,bekerja,1,wiraswasta politeknik negeri jember,C1,False,
E32181667 ,ROBERT MUHAJIR,56401.0,wiraswasta,2,wiraswasta osingart,C2,False,
E32180251 ,MIFTAHUL HUDA,56401.0,bekerja,0,perintah dinas komunikasi informatika,C2,False,
E31170392 ,WAHYU RAMA FIJAYANDI,57401.0,bekerja,3,swasta sinikopi,C2,False,
E31181091 ,CAMALLA SABRINA YUSVIAZAH,57401.0,bekerja,0,wiraswasta warung soto ayu,C2,False,
E41170241 ,INANT KHARISMA,55301.0,wiraswasta,0,wiraswasta digital,C1,False,
E41171111 ,MUHAMMAD IRFAN SHIDQI LAKSONO,55301.0,bekerja,1,bumn politeknik negeri jember,C1,False,
E31180949 ,AKBAR IMAWAN DWI CAHYA,57401.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E31181452 ,SITI ANISAH,57401.0,bekerja,0,perintah smp negeri wuluhan,C2,False,
E31181709 ,M ALI ROMADONI,57401.0,bekerja,3,swasta cybers global indonesia,C2,False,
E32181993 ,MALIK ABDUL AZIZ,56401.0,bekerja,0,perintah jaksa agung,C2,False,
E31180332 ,DEWI RATIH TILAMSARI WIBOWO,57401.0,bekerja,3,swasta mensa binasukses,C0,True,bi
E32181873 ,MOH GUFRON AZIZI,56401.0,bekerja,0,bumn kominfo,C2,False,
E32182153 ,Arshi Wisnu Wardhana,56401.0,bekerja,0,bnpp bsi,C2,False,
E32181449 ,MOCHAMMAD ALIF RAMADHANI,56401.0,bekerja,0,bnpp mitra tani,C1,False,
E41170090 ,Ari Baskara,55301.0,bekerja,0,wiraswasta freelance,C2,False,
E41171164 ,Adi Lukito,55301.0,bekerja,0,bnpp mitra surabaya,C1,False,
E31181436 ,NUR KUMALA SARI,57401.0,bekerja,0,bnpp kodig teknologi indonesia maju,C1,False,
E31180703 ,ANITA KURNIAWATI,57401.0,bekerja,0,bumn bank bni,C2,False,
E41171725 ,KHOSNOL KHOTIMATUL ARIFAH,55301.0,bekerja,0,bumn maulid teknologi kreatif,C1,False,
E41172165 ,MOCHAMMAD LEMBAR ADJIE BRAMANTYA,55301.0,bekerja,0,wiraswasta distributor skincare personal beauty,C2,False,
E32180234 ,Reza Firjatullah Rahman,56401.0,bekerja,0,bnpp asuransi ramayana,C2,False,
E32181238 ,FRENDY YASO MAYDALAN,56401.0,bekerja,0,bumn bumn,C2,False,
E32180323 ,GHALIB GIANARKAN BUSTIN,56401.0,bekerja,0,bnpp ptpn,C2,False,
E32180800 ,ANDI NURFANSYAH,56401.0,bekerja,0,bumn ptpn,C2,False,
E41171171 ,ATHO' FAJARIANTO,55301.0,bekerja,0,bnpp bumi suksesindo,C2,False,
E32181742 ,MOCHAMAD FIO BAITUL HUDA,56401.0,bekerja,0,bnpp art photography,C2,False,
E32181959 ,FERNANDA TERESIA VENTURIN,56401.0,bekerja,0,perintah bank bni,C2,False,
E41171092 ,GALANG PUTRA FENDRIANSYAH,55301.0,bekerja,0,bnpp denso,C2,False,
E32180381 ,MUHAMMAD RAFI,56401.0,bekerja,0,bumn pdam tirta balur,C2,False,
E41170735 ,DESTINO DEWANTARA PRATAMA,55301.0,bekerja,0,bumn bank bri,C2,False,
E32180897 ,RIFQI ABRORI,56401.0,bekerja,0,bnpp trans surabaya,C2,False,
E41170613 ,MONIKA KUSUMA DEWI,55301.0,bekerja,0,bnpp mitra umkm indomaret,C1,False,
E41170190 ,WINDA KURNIAWATI,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E32180459 ,RIFQIE BAGUS FIRMANSYAH,55301.0,bekerja,0,perintah dinas duduk,C2,False,
E32181934 ,FABIO QADAFI SUGESTI,56401.0,bekerja,0,bumn kai,C2,False,
E31182299 ,RISMA MULIYAWATI,57401.0,bekerja,0,perintah tri komunikasi informatika,C2,False,
E31180306 ,NOFITA OKTA SASMITA,57401.0,bekerja,0,bumn bps,C2,False,
E31180575 ,ELLEN MELINDA PUTRI ARIFIYANA SARI,57401.0,bekerja,0,wiraswasta luhan jaya,C2,False,
E32181133 ,AISYAH SASYADILAH,56401.0,bekerja,0,bnpp wings surya,C2,False,
E31182109 ,Rizaldy Putra Anam Novriandi,57401.0,bekerja,2,wiraswasta darmantika,C2,False,
E32180498 ,TARISA WINDI SUMONO PUTRI,56401.0,bekerja,0,wiraswasta piranhamas group,C2,False,
E32181345 ,ADE RIZKY CIPTA PRATAMA,56401.0,bekerja,0,bnpp pertamina,C2,False,
E31180303 ,YAHYA AJI WIJAYA,57401.0,bekerja,0,perintah multimedia edukasi,C2,False,
E41171621 ,BANGGA ADITYATAMA,55301.0,bekerja,0,perintah badan pegawai daerah,C2,False,
E41171118 ,FERNANDO FARISTA AHMAD,55301.0,bekerja,0,bnpp mitra,C1,False,
E32181811 ,ERINA SUDRAJAD,56401.0,bekerja,0,perintah smk pgri tanggul,C2,False,
E41171541 ,M. AVICENNA MAULA,55301.0,bekerja,0,wiraswasta mitra surabaya,C1,False,
E41171896 ,ADI CAHYA WIRATMAYA,55301.0,bekerja,0,perintah dinas komunikasi informatika bondowoso,C2,False,
E32182292 ,RAIZZAL AHAMAD WEIKIANSYAH,56401.0,bekerja,0,bnpp arsenet,C2,False,
E32181600 ,MUHAMMAD SHOLEHUDDIN,56401.0,bekerja,0,bnpp mekar jaya,C2,False,
E41170538 ,RIZKY MAULIDA,55301.0,bekerja,1,bnpp politeknik negeri jember,C1,False,
E31181131 ,SITI ANISA,57401.0,bekerja,0,wiraswasta multimedia edukasi,C2,False,
E31181991 ,MUHAMMAD ALIF MAHMUT,57401.0,wiraswasta,0,bnpp jual pakan sapi,C2,False,
E41170913 ,Yusuf Andi Nugroho,55301.0,bekerja,0,bnpp run systems,C2,False,
E31180884 ,ANITA SAFITRI,57401.0,bekerja,0,bumn dinas komunikasi informatika,C2,False,
E31181263 ,KARIMATUS SOFI'AH,57401.0,bekerja,0,perintah dinas perintah kabupaten situbondo,C1,False,
E31180299 ,DESY WAHYUNINGTYAS,57401.0,bekerja,0,bumn bri bank rakyat indonesia jember,C2,False,
E31180373 ,SITI KHOFSYAH,57401.0,bekerja,0,bumn grapari,C2,False,
E41171569 ,RISKA APRILIA,55301.0,bekerja,3,swasta content marketing labs,C1,False,
E31180365 ,KOMARIAH,57401.0,bekerja,1,wiraswasta politeknik negeri jember,C1,False,
E31180297 ,NURIN ASTIN VALIDA,57401.0,bekerja,1,wiraswasta politeknik negeri jember,C1,False,
E41170352 ,META GADIECHA WACHYUDI,55301.0,wiraswasta,0,wiraswasta freelance,C2,False,
E32180198 ,ENGGA BAGUS RIYANTO,56401.0,wiraswasta,2,wiraswasta desain,C1,False,
E31182030 ,Misbahus Surur,57401.0,bekerja,0,perintah operator gugus camat kalisat,C2,False,
E41171309 ,AL BUSRAN,55301.0,bekerja,3,swasta cmlabs malang,C2,False,
E41170885 ,RANGGA TRIANA PUTRA,55301.0,bekerja,3,swasta mascitra com,C1,False,
E31180644 ,DIAJENG SHINTA FEBRI RAHAYU,57401.0,bekerja,0,wiraswasta bagus kosmetik,C2,False,
E32181062 ,WAHYU ROMADHIANTO,56401.0,bekerja,3,swasta sumber dingin engineering,C1,False,
E41170203 ,KAHFINDA MULYA UTAMA PUTRA,55301.0,wiraswasta,2,wiraswasta acang handayani,C2,False,
E31160910 ,RIZKY AKBAR AUGUST PRADANA,57401.0,wiraswasta,0,wiraswasta toko afizah,C2,False,
E41170244 ,DAVID SETYA AINUR HAKIKI RAMADHAN,55301.0,bekerja,3,swasta digital,C1,False,
E32180585 ,BILLAL DAIFULLAH YAHYA AG,56401.0,bekerja,2,wiraswasta dispenduk,C2,False,
E31180276 ,MUHAMMAD FIRMAN AGE BIMANTARA,57401.0,wiraswasta,2,wiraswasta konter,C2,False,
E31181885 ,SOVIAH AYUNIAR MEGAFELANI PUTRI,57401.0,wiraswasta,3,swasta rental,C2,False,
E32180894 ,BONDAN YUWONO PUTRA,56401.0,bekerja,0,wiraswasta komputer solution,C0,True,komputer
E32181419 ,Roby Bayu Trisno Ananda,56401.0,bekerja,0,wiraswasta freelance,C0,True,lan
E32181940 ,ILHAM AKBAR JOVIANSYAH PUTRA,56401.0,bekerja,0,bumn telkom indonesia,C2,False,
E41170754 ,ALDY NOVERIANTO PRATAMA,55301.0,wiraswasta,2,wiraswasta tetas telur bebek peking,C2,False,
E32180760 ,ROBIUL ADAWI,56401.0,melanjutkan_studi,0,perintah pemda,C2,False,
E41170987 ,NOVIA NURUL QOMARIL,55301.0,wiraswasta,2,wiraswasta wiraswasta,C2,False,
E32182013 ,ABDANIAL PRADITYA,56401.0,bekerja,3,swasta proxi jaring nusantara,C2,False,
E32181862 ,BHIRAWA ANORAGA,56401.0,bekerja,0,wiraswasta arsenet global solusi,C2,False,
E41170641 ,AJI WAHYU PRASETYO,55301.0,wiraswasta,2,wiraswasta aji design,C1,False,
E41170827 ,AHMAD MUNIR,55301.0,wiraswasta,3,swasta jogotoko,C2,False,
E41172109 ,Nava Shoqibatul Khoiriyah,55301.0,bekerja,0,wiraswasta grace beauty,C2,False,
E41171956 ,DANA BHAKTI SURYA PRATIWI,55301.0,bekerja,2,wiraswasta shopie martin,C2,False,
E31180260 ,FAIZAL FIKRI HAMDANI,57401.0,bekerja,2,wiraswasta btin,C2,False,
E41170909 ,ADE SETIAWAN,55301.0,melanjutkan_studi,2,wiraswasta tidakada,C2,False,
E41170917 ,BUDI YUNIOR VALENTINO,55301.0,bekerja,2,wiraswasta rainbolt,C2,False,
E41171467 ,BAHTIAR ADI PRASETYA,55301.0,wiraswasta,2,wiraswasta adi disain,C2,False,
E32170824 ,MOH MUZAMMIL AL FARIZI,56401.0,bekerja,0,nirlaba ghofilin,C2,False,
E41171874 ,YUSUF TRI WIBOWO,55301.0,bekerja,3,swasta prodevis,C2,False,
E41170629 ,YANUAR ANUGRAH RAMADHANI,55301.0,wiraswasta,0,wiraswasta ruang kopi,C2,False,
E41171011 ,Gagas Adi Rismawan,55301.0,bekerja,0,wiraswasta digitalworks,C1,False,
E41171135 ,DWI AYU WULANDARI,55301.0,bekerja,0,wiraswasta digitalworks,C1,False,
E31161048 ,AHMAD FATKHUL ARIFIN,57401.0,bekerja,2,wiraswasta vatqul apprl,C2,False,
E32180069 ,MUHAMMAD RIZQI PRIYANSYAH,56401.0,bekerja,2,wiraswasta alberta community,C1,False,
E41171075 ,MOH. SYAFRIAN ABIE,55301.0,bekerja,2,wiraswasta naminauna institute,C1,False,
E32181970 ,FAIZHAL MAULANA IQBAL,56401.0,bekerja,0,swasta balai desa,C2,False,
E31180684 ,MELANIA RINIHANDITA NUR HABIBAH,57401.0,bekerja,0,wiraswasta olshop barokah,C2,False,
E31182235 ,HERNANDO FARAZI HERRERA,57401.0,bekerja,0,wiraswasta freelancer,C2,False,
E41171664 ,RAMADHAN IBNU UMAM,55301.0,wiraswasta,3,swasta glazzos studio,C2,False,
E31181567 ,AVIVAH NUR FAIZ MAGHFIROH,57401.0,melanjutkan_studi,0,bumn bulog,C2,False,
E31180748 ,DWINDA AYULIA EDITA SARI,57401.0,bekerja,2,wiraswasta dwdesign,C1,False,
E41171335 ,VINNY SAKINAH VIRGIO,55301.0,melanjutkan_studi,0,bumn belum kerja proses cari kerja,C2,False,
E41172064 ,SYAHDAN FIMAN HUDA,55301.0,wiraswasta,0,wiraswasta toko hitam putih,C1,False,
E31181597 ,MIRANI ILMI AURIA DEBITA,57401.0,bekerja,2,wiraswasta nimo,C2,False,
E31180207 ,MOHAMMAD BADAR PAMUNGKAS,57401.0,wiraswasta,0,wiraswasta onthel store jember,C2,False,
E32170601 ,LAILATUL QOMARIYAH,56401.0,bekerja,0,wiraswasta online shop,C2,False,
E32181659 ,MUHAMMAD WILDAN ILHAM MUBAROQ,56401.0,bekerja,0,wiraswasta barokah jaya,C2,False,
E32181610 ,SAHRIL SABIRIN,56401.0,wiraswasta,0,wiraswasta warung kopi,C2,False,
E32181421 ,SAHRUL SIHABUDIN,56401.0,bekerja,3,swasta budiawan,C0,True,wan
E32180272 ,HOFIDATUL AFIYAH,56401.0,bekerja,3,swasta kaloper,C2,False,
E32180279 ,NOVA AYU LESTARI,56401.0,bekerja,3,swasta kaloper,C2,False,
E32180282 ,TUTIK ERDIANA,55301.0,wiraswasta,2,wiraswasta warunng,C2,False,
E32180197 ,WAHYUNINGSIH,56401.0,melanjutkan_studi,0,wiraswasta yuni shop,C2,False,
E31180837 ,MIFTAH RIZQI AZIZAH,57401.0,wiraswasta,2,wiraswasta semicolon,C2,False,
E32181237 ,AGUNG TRI LEKSONO,55301.0,bekerja,0,wiraswasta agung,C2,False,
E31182133 ,MICHEL MEIRISCA HENIATY,57401.0,bekerja,3,swasta esolusindo,C2,False,
E31180504 ,PUTRI BUDIASIH,57401.0,bekerja,2,wiraswasta pizzaku,C2,False,
E31181100 ,RIWELLANANDA NANDA URBANING PUTRI,57401.0,bekerja,0,bumn pdam,C2,False,
E31180678 ,VENNA ERSIS RELITA,57401.0,bekerja,0,wiraswasta global,C2,False,
E31180456 ,RISKI EKA SAPUTRI,57401.0,bekerja,0,perintah bps jember pengentry,C2,False,
E32180231 ,RAUDATUR RIZKY ELOK BARLIAN,56401.0,melanjutkan_studi,0,perintah kai,C2,False,
E32180205 ,DAUD ARAGA ABABIL,56401.0,bekerja,0,nirlaba ast,C2,False,
E31180369 ,PUTRI RACHMAWATI,57401.0,wiraswasta,0,wiraswasta shop handcraft,C2,False,
E31180295 ,BUNAYYA MAULANA,57401.0,wiraswasta,0,wiraswasta shop handcraft,C2,False,
E41171142 ,KEVIN HARLIS OKTAVIANO,55301.0,wiraswasta,3,swasta company,C2,False,
E31181971 ,SALSABILA EKSANANDA,57401.0,bekerja,0,wiraswasta freelancer,C2,False,
E32180263 ,DAVA KUSUMA ARDANA,56401.0,bekerja,0,wiraswasta blackwhite idn,C1,False,
E31181976 ,THALIA TRIVIRGIANI EFELLYN,57401.0,melanjutkan_studi,0,perintah belum kerja,C2,False,
E32182194 ,SHOFYAN ASTSAURI,56401.0,melanjutkan_studi,2,wiraswasta ivan record,C2,False,
E31181492 ,KEVIN RAHANDIKA W,55301.0,wiraswasta,1,wiraswasta juragan guppy jember,C2,False,
E32180292 ,ZIDQI YOSA DINATA,56401.0,wiraswasta,0,perintah sujud company,C2,False,
E31180370 ,AIDATUL FAKHIRAH,57401.0,wiraswasta,0,wiraswasta usaha umkm,C2,False,
E41172092 ,MOCH. ZAINUR ROFAN FANNANI,55301.0,bekerja,2,wiraswasta rofil fotocopy,C2,False,
E31182101 ,Arfanio Liswanda Bahtiar,57401.0,wiraswasta,2,wiraswasta plant me,C2,False,
E31181474 ,CHOIRUL ANAM,57401.0,wiraswasta,2,wiraswasta cho pet,C2,False,
E31180707 ,MUHAMMAD ALI WAFA RAMADHAN,57401.0,wiraswasta,3,swasta service,C2,False,
E32181375 ,ALIEF PASHA IBRAHIM,56401.0,wiraswasta,2,wiraswasta alya catering,C2,False,
E32180067 ,Khalid Fikri Mustanir,56401.0,wiraswasta,2,wiraswasta mustanirbookstore,C2,False,
E41170972 ,ISMU UBAIDILLAH PANATAGAMA,55301.0,bekerja,0,wiraswasta bikea techno,C0,True,tech
E32181448 ,FRIDO ARJUNA PUTRA,56401.0,bekerja,2,wiraswasta c steamstore,C2,False,
E31180491,IMFI NUR FAIZIYAH,57401.0,wiraswasta,0,wiraswasta corp indonesia,C2,False,
E32190194,MUHAMMAD TAFANI AKBAR,56401.0,bekerja,2,wiraswasta panverta cakrakencana,C2,False,
E41181641,SALMA FARHANI,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E41181324,PRAVASTA GENTA ARJUNANDA KINANTAKA,55301.0,bekerja,0,wiraswasta benih citra asia,C1,False,
E41190280,WAHYU DIAN PRATIWI,55301.0,bekerja,0,swasta grant surya pondasi,C2,False,
E31192202,Yulia Bagas Sri Dastiya,57401.0,bekerja,3,swasta margojoyo residence,C2,False,
E41192227,VIKY LORENT SEA PUTRA,55301.0,bekerja,0,bnpp madura hosting,C2,False,
E41191426,SHINTA DESTIRA AYU,55301.0,bekerja,0,perintah lee yin garment indonesia,C2,False,
E41191107,DWI RIFKI NOVIANTO,55301.0,bekerja,3,swasta clade ventures,C2,False,
E41190530,ALIF IRHASSHOUFI NASIHUL UMAM,55301.0,bekerja,0,swasta telkom indonesia tbk,C2,False,
E41191417,AGIN PRAHAMESTI WICAHYANI,55301.0,bekerja,0,wiraswasta andri farm,C2,False,
E41192205,MUHAMMAD KHALIL ZHILLULLAH,55301.0,bekerja,3,swasta lestasi sentosa,C2,False,
E41190200,NANDA RADITIYA AKBAR,55301.0,melanjutkan_studi,0,swasta dinas tani,C2,False,
E41192269,SULTON MUBAROK,55301.0,bekerja,0,nirlaba dinas tani,C2,False,
E41190532,MOH. SYAIFUDIN,55301.0,bekerja,0,bumn upt kembang agribisnis tanam pangan hortikultura,C2,False,
E41190239,Mohammad Hidayatullah,55301.0,bekerja,0,bumn alir,C2,False,
E41190321,NURICO VICYYANTO,55301.0,bekerja,3,swasta bpn,C2,False,
E32200380,Miftahus Surur Sutowo,56401.0,melanjutkan_studi,3,swasta nutrifood,C2,False,
E41190835,ARINI EKA NOVIYANTI,55301.0,wiraswasta,0,perintah ourscarf,C2,False,
E31201647,FIRDAN MAHENDRA WARDANA,57401.0,wiraswasta,0,bnpp ritz bakery,C1,False,
E41190890,FATHOR RAHMAN,55301.0,bekerja,0,perintah menteri,C2,False,
E41190937,MOH ISKANDAR ZULKARNAIN,55301.0,bekerja,0,swasta badan koordinasi wilayah perintah bangun provinsi jawa timur,C2,False,
E41191351,THUFEIL WARTONO PUTRA,55301.0,bekerja,2,wiraswasta sekretariat dprd,C2,False,
E41190793,M. AINUL YAQIN,55301.0,bekerja,0,bnpp bumi sukses indo,C2,False,
E31200857,ERICK ASRILLAH PRATAMA,57401.0,melanjutkan_studi,0,bumn pusat teliti kopi cacao,C1,False,
E41192478,INDRA PRASETYA,55301.0,bekerja,3,swasta mulya jaya,C2,False,
E32190274,RIZKY ADIWIYANTO,56401.0,bekerja,0,wiraswasta asw food,C2,False,
E41191322,BUNGA PRASETYA DWI ULUL AZMI,55301.0,bekerja,3,swasta yayasan darul mukmin,C2,False,
E41190889,MUHAMMAD LUTFI FADILAH,55301.0,bekerja,0,perintah bank bni,C2,False,
E41191560,Anggito Suryo Baskoro,55301.0,bekerja,3,swasta frawn network,C2,False,
E41190161,Ardan Venora Falahudin,55301.0,bekerja,1,swasta politeknik negeri jember,C1,False,
E41190942,DEFI TAMARA,55301.0,wiraswasta,0,wiraswasta kai,C2,False,
E41192386,FADLI ROMADHAN,55301.0,bekerja,0,perintah charoen pokphand indonesia,C2,False,
E41191090,AMALIA,55301.0,bekerja,0,perintah tunggal griya sakinah,C2,False,
E41191468,ABDUL AZIZ RAHMAWAN,55301.0,bekerja,0,wiraswasta bejana investidata globalindo,C1,False,
E41191151,YULINAR NUR RAHMAWATI,55301.0,wiraswasta,0,bumn ptpn asembagus,C2,False,
E41191443,RISKIE NUR FADILAH,55301.0,bekerja,0,bumn pltu,C2,False,
E41192329,Alga Saputra,55301.0,bekerja,3,swasta sumber tunjung,C2,False,
E31200061,PUJA MAYSA ARYA CUCU WIBOWO,57401.0,wiraswasta,0,bumn makmur jaya,C2,False,
E31201706,EKA FAHRIKA NARISWARI,57401.0,bekerja,3,swasta gas pol dev,C2,False,
E31201573,ERLINDA KRISTANTI PUTRI,57401.0,bekerja,0,swasta utrani farm,C2,False,
E41190160,MITA WAFA WULANDARI,55301.0,bekerja,0,swasta kantor desa,C2,False,
E41192303,RIFJAN JUNDILA,55301.0,bekerja,0,wiraswasta sumber mutiara samudra banyuwangi,C2,False,
E41190236,DIMAS HERU PERDANA PUTRA,55301.0,bekerja,0,wiraswasta dinas tani pangan,C2,False,
E41190179,RANDY RAHMAWAN,55301.0,bekerja,0,wiraswasta dinas tani pangan,C2,False,
E41192406,NOVITA SARI,55301.0,bekerja,0,swasta rumah sakit,C1,False,
E41190668,PRISKA ARLINDA SABILLAH,55301.0,bekerja,0,wiraswasta motor,C2,False,
E41191326,WIKE SRI WIDARI,55301.0,wiraswasta,0,wiraswasta mitra tani,C1,False,
E41191510,ERIK RIZKI FIRDAUS,55301.0,bekerja,0,perintah pltu,C2,False,
E41192131,FEBRI PUTRA TRIS BUDIONO,55301.0,bekerja,3,swasta intprism computing technology,C0,True,tech
E41191453,DANANG ARDIANTO,55301.0,bekerja,3,swasta hutan,C2,False,
E41191628,DIMAS PANGESTU,55301.0,bekerja,3,swasta manajer,C2,False,
E41191382,MUHAMMAD NUZUL RIDOI,55301.0,bekerja,3,swasta agro kusuma,C2,False,
E41192307,RIFKY ROUDANA IMANI CAHYA,55301.0,melanjutkan_studi,3,swasta masakan bunda,C2,False,
E41190318,MAULANA ALIRRIDLO,55301.0,bekerja,0,wiraswasta pemda,C2,False,
E41192287,SULISTYAWATI,55301.0,bekerja,0,wiraswasta lapak online,C2,False,
E31201887,DIMAS RIZQI AGUNG PRATAMA,57401.0,bekerja,2,wiraswasta wira,C2,False,
E41191336,Suci Riski Anggraini,55301.0,bekerja,0,perintah andatu mulia,C2,False,
E41191202,DEWI AGESTI NURIFIANI,55301.0,bekerja,0,perintah dinamix network automatika,C2,False,
E31201950,RIDHO ADILAH WASISTO,57401.0,bekerja,0,perintah dinas tani pangan kab banyuwangi,C2,False,
E31201932,IMDAD ALFI FAHMI,57401.0,bekerja,0,wiraswasta kai,C2,False,
E41192295,MARSELLA DWI FAIRA,55301.0,bekerja,0,bumn ptpn xii wonosari malang,C2,False,
E31202451,MUFID ADITYA DAFENTRI,57401.0,bekerja,0,swasta kopa tarutama nusantara,C2,False,
E31202314,DANI TAUFIKUL HAKIM,57401.0,bekerja,0,perintah bis,C0,True,bi
E41190493,VIGA ENSAS FII SABILILLAH,55301.0,wiraswasta,3,swasta suwito mesin diesel bekas,C1,False,
E41191570,SANG BINTANG PUTERA ALAM,55301.0,bekerja,3,swasta unilever,C2,False,
E41191387,IRCHAMZAH FIKRI ABABIL,55301.0,bekerja,0,wiraswasta bis,C2,False,
E32202398,MUHAMMAD SYAIFULLAH AL ARIEF,56401.0,bekerja,2,wiraswasta evyshopper,C2,False,
E31201246,MOCH. ANDRI,57401.0,bekerja,0,perintah socfindo,C2,False,
E41191280,HENDY SETIAWAN,55301.0,bekerja,3,swasta ida sentosa,C2,False,
E41190925,ANJU ALICIA JOHAN,55301.0,bekerja,0,perintah alf mechatronics innovation,C2,False,
E41192216,DWI NURANNISA RAHAYUNINGTIAS,55301.0,melanjutkan_studi,0,perintah sinar alam,C2,False,
E41191965,FIGO FAJAR YULIANTO,55301.0,bekerja,0,bumn grab,C2,False,
E41192233,FIRMAN ABDI SYAH PUTRA,55301.0,bekerja,2,wiraswasta jmsportcenter,C2,False,
E41190305,FIRMAN WAHYUDI,55301.0,wiraswasta,3,swasta rizky motor,C2,False,
E41190547,MUHAMMAD FADHIL NURHUDA,55301.0,wiraswasta,3,swasta terna,C2,False,
E41190755,DWI WAHYU PRAMBODO,55301.0,wiraswasta,0,swasta tretes view hotel,C2,False,
E32200978,DION ADI PANGESTU,56401.0,bekerja,3,swasta candya organizer,C2,False,
E41192320,AULIA AQSONIA ARIFAH,55301.0,bekerja,0,perintah indo marco,C2,False,
E41192114,MOH. ARDIAS ADE AGA,55301.0,bekerja,0,swasta pltu paiton,C1,False,
E41190139,FIRGO BHAKTIAR HAMSAH,55301.0,bekerja,0,swasta badan pusat statistik regsosek,C2,False,
E41202435,INTAN PERMATASARI,55301.0,bekerja,3,swasta cayaha tani,C2,False,
E41190614,DILLAH AMALIA FIQYANI,55301.0,bekerja,0,wiraswasta bkpsdm kab jember,C2,False,
E41192283,ARIF KURNIAWAN,55301.0,bekerja,3,swasta dinas prawisata,C2,False,
E41192271,AL FAHRELIA WAVA AGUSTIN,55301.0,bekerja,0,swasta pltu paiton,C1,False,
E41190152,ACHMAD KHALIFAH,55301.0,melanjutkan_studi,0,wiraswasta enz kosmetik,C2,False,
E31201954,BERLIANI FIA MAHARIS ARIKHALA,57401.0,bekerja,0,wiraswasta ikhwan jaya,C2,False,
E31200001,AFBILLA FITRIANI DEWI,57401.0,bekerja,0,wiraswasta pltu paiton,C1,False,
E41190503,DIAN BUANA PUTRA,55301.0,wiraswasta,3,swasta bal indah aquarium,C2,False,
E31200561,ALFINA DEWI HIDAYANTI,57401.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E32201501,RICKY ANDRIAWAN,56401.0,bekerja,0,wiraswasta guna jaya,C2,False,
E32201226,ARINID DIANA OKTAVIA,56401.0,melanjutkan_studi,0,bumn rsud moch ansari saleh banjarmasin,C2,False,
E32200493,RAFLY KEMAL AVIYANTO,56401.0,bekerja,0,wiraswasta smks pgri banyuputih,C2,False,
E32200990,AQMALUH AGUNG PRADANA,56401.0,bekerja,0,perintah kantor perintah desa olean,C2,False,
E41191903,NADEA AJENG SAFITRI,55301.0,bekerja,0,perintah panca mitra multiperdana,C1,False,
E41191622,AGNES OCTAVIANDA ZAVIRA,55301.0,bekerja,2,wiraswasta artaboga,C2,False,
E31200680,FUAD HASYIM FANANI,57401.0,wiraswasta,0,wiraswasta marga solusi prima,C2,False,
E31201158,ALBANI KHAMENEI,57401.0,bekerja,0,swasta cipta karya buana,C2,False,
E41191188,ANISA PUJI ASTUTIK,55301.0,wiraswasta,3,swasta anugerah,C2,False,
E31200293,KALYANA UNASHA RAYHANDINI YUSUF,57401.0,wiraswasta,0,perintah imaji sociopreneur,C2,False,
E31201146,WIDYA PUTRI PRATAMA,57401.0,bekerja,0,wiraswasta badan dapat daerah,C2,False,
E31201687,SHAFA THALIAH,57401.0,bekerja,0,swasta badan dapat daerah kabupaten jember,C2,False,
E41192362,DIANA FITHRI LESTARI,55301.0,wiraswasta,3,swasta taihei dengyo indonesia,C2,False,
E41190739,RESA WAHYU SAPUTRA,55301.0,bekerja,0,bumn perum hutan pabrik gondorukem terpentin kbm ihh jatim non kayu,C2,False,
E41190125,ANGGUN WASILINA MUTRIFANI,55301.0,wiraswasta,0,swasta dinas hutan provinsi jawa timur,C2,False,
E32200993,ACHMAD NABILUL FAHMI,56401.0,bekerja,0,perintah shopee food,C2,False,
E32201292,DWI APRILIA HALIZA,56401.0,melanjutkan_studi,0,wiraswasta ksp jaya makmur,C2,False,
E32200536,ARFENDI PERMANA,56401.0,melanjutkan_studi,0,wiraswasta rofiq farm,C2,False,
E31201237,DYAS OCTA VIOLA,57401.0,bekerja,0,perintah basma olshopid,C2,False,
E32200614,AHMAD FAISOL,56401.0,bekerja,0,bnpp dinas tani pangan kabupaten banyuwangi,C0,True,wan
E31200837,DESIANA SILVIA RAMADANI,57401.0,wiraswasta,0,wiraswasta grant surya pondasi,C2,False,
E31202490,ADRIAN MEDTIYU NUR ARIFIN,57401.0,bekerja,0,swasta online shop jual pulsa,C2,False,
E32202011,MOHAMMAD AZWAR ANAS,56401.0,wiraswasta,2,wiraswasta ketik,C2,False,
E41191369,OKTAFIAN DWI CAHYONO,55301.0,bekerja,0,bnpp rsud gambir,C2,False,
E41190986,IPHANG RERE ADMAJA,55301.0,melanjutkan_studi,3,swasta indosat tbk,C2,False,
E41192426,MUHAMMAD SYARIF JANURIANSYAH,55301.0,bekerja,0,perintah puskesmas leces,C2,False,
E31202523,MOCHAMMAD ANDIKA ALSABFANDI,57401.0,bekerja,3,swasta bangun tani,C2,False,
E31201422,FIRMAN RIZKY FIRDAUS,57401.0,bekerja,2,wiraswasta caldera party planner,C2,False,
E32200618,WATI DARMAWAN,56401.0,bekerja,0,wiraswasta bank,C2,False,
E32202311,MUHAMMAD FARRAS WIRAWAN,56401.0,melanjutkan_studi,3,swasta fidjijaya,C2,False,
E41190322,Kana Farira Salsabila,55301.0,bekerja,0,perintah dinas tani pangan,C2,False,
E41191445,NAUFAL MAHDI RAHMAN UBAID,55301.0,bekerja,3,swasta mbah jan farm,C2,False,
E31201095,FITRI ARISKA,57401.0,bekerja,3,swasta suitmedia,C1,False,
E41192342,FAHREZA MAULANA WISNU WARDANA,55301.0,bekerja,0,swasta labbola sport statistic and data management,C1,False,
E41191325,WIDYA YURISTIKA OKTAVIA,55301.0,bekerja,0,wiraswasta dolan tour and travel,C2,False,
E32201384,BAYU SEPTIAN ADHI PRADANA,56401.0,bekerja,0,perintah rafli putra,C2,False,
E41191240,MOCHAMMAD FAJAR FITRIAN NURBAYU,55301.0,bekerja,3,swasta bpn,C2,False,
E32201402,ANJAR FITRIA,56401.0,melanjutkan_studi,3,swasta invi creative,C2,False,
E31201199,AJENG NUR KHORISA,57401.0,wiraswasta,0,bumn kusuma dinasastri wisatajaya,C2,False,
E41191558,AKHMAD NUR HIDAYATULLOH,55301.0,bekerja,0,bumn fkp maju,C2,False,
E41191157,MUHAMMAD AFDAL ZIKRI,55301.0,melanjutkan_studi,0,perintah klinik mitra sehat,C1,False,
E41192428,MUHAMMAD RIADI PRASETYO,55301.0,bekerja,0,wiraswasta purnama indonesia,C2,False,
E31201228,MOHAMAD RAFLI CAHAYA MAHENDRA,57401.0,bekerja,0,bumn asuransi central asia aca,C2,False,
E41190934,HAYUNG DEWANTO,55301.0,bekerja,0,swasta kantor balai desa bandarasri,C2,False,
E32202313,ALDO BAGAS SEPTYAWAN,56401.0,melanjutkan_studi,0,swasta bank rakyat indonesia,C2,False,
E32201641,AHMAD ASRORI,56401.0,bekerja,2,wiraswasta ppah mayapaga,C2,False,
E41191206,FITROH FATHUR ROHMAN,55301.0,bekerja,2,wiraswasta rifa offset,C2,False,
E41191132,SHOVI IMANY WARDIANA,55301.0,bekerja,3,swasta amat indonesia,C2,False,
E32200057,SEAN ARRAFES,56401.0,bekerja,0,bumn bank bni,C2,False,
E41191133,SHENILA LETISHYA RAMONA,55301.0,bekerja,1,bumn politeknik negeri jember,C1,False,
E41190878,MOCH. FAHRONY,55301.0,bekerja,0,perintah jaya sejahtera,C2,False,
E32200950,MOCHAMMAD REFLY AGUSTINO,56401.0,bekerja,0,perintah rumah produksi bordir selempangwisuda,C2,False,
E41191823,Adam Muhammad,55301.0,bekerja,0,nirlaba ptpn asembagus,C2,False,
E32200305,DZAKI JOMAN,56401.0,bekerja,0,wiraswasta event organizer,C2,False,
E32201058,MOCH. AL-FEND LABBIB,56401.0,bekerja,1,bnpp smk negeri jember,C2,False,
E32201216,EDO YUDHISTIRA PRATAMA,56401.0,bekerja,0,wiraswasta utrani farm,C2,False,
E32201586,NOVITA HESTI WULANSARI,56401.0,bekerja,3,swasta manik jaya,C2,False,
E31200102,Haris Faqih Darmawan,57401.0,bekerja,0,bnpp hutan,C2,False,
E31200864,NADILA DEVI TSABITA,57401.0,bekerja,0,wiraswasta dinas tahan kabupaten probolinggo,C2,False,
E41191343,REXY SOLEHUDIN ABDI HOLILI,55301.0,bekerja,1,wiraswasta sekolah perempuan jember,C2,False,
E31200284,NURLITA AYU RAKHMAWATI,57401.0,bekerja,0,bumn yourflorist,C2,False,
E31200251,M. BASAR RISKI,57401.0,bekerja,0,perintah bank bca,C2,False,
E41192340,BAGUS BACHTIAR RIZKI,55301.0,bekerja,0,wiraswasta sumber rezeki,C2,False,
E41190645,HENRY MURDIFUL ULYA HILMA PUTRA,55301.0,bekerja,3,swasta cita alam nusantara,C1,False,
E31201390,LIUTANTRI HOBIOLA,57401.0,melanjutkan_studi,0,swasta dinas pariwisata kabupaten lumajang,C2,False,
E41192366,MUHAMMAD AUDINO FAKHRI ARNANDYA,55301.0,bekerja,3,swasta unilever,C2,False,
E31200356,YOGA SAPUTRA R.,57401.0,wiraswasta,0,swasta dinas tani,C2,False,
E32201197,MIRZANDO DIRGANTAKA,56401.0,bekerja,0,bumn permana sound,C2,False,
E41191725,FITRIYAH AYU NINGSIH,55301.0,bekerja,0,wiraswasta mediatama group,C2,False,
E31202562,ZALFA ALIF NABILLA,57401.0,bekerja,0,swasta dinas tani pangan banyuwangi,C2,False,
E32201063,WAHYU RAHMATULLAH,56401.0,bekerja,0,bumn wirausaha rumah,C2,False,
E31200245,NUR LAILI WAHYUNINGTIAS,57401.0,bekerja,3,swasta terna,C2,False,
E41190391,RIZKYU ZAM ZAMI,55301.0,wiraswasta,0,swasta tretes view hotel,C2,False,
E32201430,ACHMAD RIZKY RAMADHANI,56401.0,melanjutkan_studi,3,swasta ichwan production,C0,True,wan
E41191868,NUR MUHAMMAD SYAHBANA R,55301.0,bekerja,3,swasta pama persada,C2,False,
E31201470,BEFRIL RENFILIANI SYAFITRI,57401.0,melanjutkan_studi,0,perintah rsud pasirian,C2,False,
E41190452,HAQIQI AHMAD SALMAN ALFARISI,55301.0,bekerja,0,wiraswasta semesta cipta lab,C2,False,
E32200040,DWI ARIF RAHMAN,56401.0,bekerja,0,bnpp igg,C2,False,
E41191902,FAIZ IQBAL DARMAWAN,55301.0,bekerja,3,swasta tani,C2,False,
E32201000,Rico Wildany Nasharillah,56401.0,bekerja,0,perintah pltu paiton,C1,False,
E32200185,BAYU CAHYA KHURNIA YUDHA,56401.0,bekerja,0,bumn bibit hortikultura sejahtera,C1,False,
E31202536,FADILAH NUR HAMSAH,57401.0,bekerja,0,wiraswasta badan pusat statistik regsosek,C2,False,
E32200069,VENTI WELIANA,56401.0,bekerja,0,perintah bumn,C2,False,
E31200997,FAJAR FITRA ABADI,57401.0,bekerja,0,nirlaba ytl,C2,False,
E31190748,KHOLIZAH RIFKA ATUL AIDA,57401.0,bekerja,2,wiraswasta krips,C2,False,
E32200589,SEPTIANANDA RIFQI NURHIDAYAT,56401.0,melanjutkan_studi,0,perintah bkpsdm kab jember,C2,False,
E31202394,DEVA ANGELA SABILA SASKI,57401.0,bekerja,0,perintah ptpn xii pandjie,C2,False,
E32201187,GHULAM MAULANA FAHRI,56401.0,bekerja,3,swasta freelance,C0,True,lan
E31201794,RAHMA ROMADONA AYU RISWANTI,57401.0,bekerja,1,bumn politeknik negeri jember,C1,False,
E31201365,HAMID RAFIUD DERAJAD,57401.0,bekerja,0,swasta jawa timur park,C2,False,
E32201075,UMARUL FARUQ,56401.0,bekerja,0,wiraswasta surya energi,C2,False,
E31200827,TANTRIA AGUSTINA YUDIANTI,57401.0,melanjutkan_studi,0,bumn jack koi,C2,False,
E31192328,DIMAS ARDIANA WIDODO,57401.0,bekerja,1,wiraswasta sablon jember,C2,False,
E32201483,NIASTI AL FAUZIAH LASE,56401.0,melanjutkan_studi,3,swasta toko berkah,C2,False,
E32202503,ACHMAD ALFITRI MULYAWAN,56401.0,melanjutkan_studi,0,perintah sawah,C2,False,
E31200649,WILDA WAHDANIA,57401.0,bekerja,3,swasta humma farm,C2,False,
E41190298,RAIHAN DIMAS ARIFIN,55301.0,bekerja,3,swasta healthy food jember,C2,False,
E32201290,HELLEN PUTRI ANDINI,56401.0,bekerja,0,wiraswasta jaya makmur,C2,False,
E41190868,Tegar Shallahudin Al Ayubi,55301.0,bekerja,3,swasta marvel secondshoes,C2,False,
E32202484,MUHAMMAD ILHAM YUAL MAULANA,56401.0,melanjutkan_studi,3,swasta sumaryonofarm,C2,False,
E32201964,MUHAMAD BAYU CANDRA PAMUNGKAS,56401.0,melanjutkan_studi,0,wiraswasta dinas tani pangan,C2,False,
E31201009,WANDA ARVANIYAN,57401.0,bekerja,0,swasta rumah sakit,C1,False,
E32201330,RIZKI DWI CAHYO PUTRO,55301.0,bekerja,0,bumn smk negeri puspo,C2,False,
E32201406,RIZAL ACHMAD PAHLEVI,56401.0,bekerja,0,wiraswasta rumah sakit,C1,False,
E32201506,ZAHROTUL ISTIQOMAH,56401.0,melanjutkan_studi,3,swasta ahmad kembang ban,C2,False,
E32201397,RISQI RIDHOLLAH ANAM,56401.0,bekerja,0,wiraswasta kamajaya motor,C2,False,
E32201498,Rizqi Ramadani,56401.0,bekerja,0,wiraswasta jember futura energi,C2,False,
E32200753,Anang Prayoga,56401.0,bekerja,0,bumn audio,C2,False,
E31200822,RAYNALDI WIBOWO,57401.0,bekerja,0,perintah kopi paste,C2,False,
E32200499,DINA PERMATA SARI,56401.0,bekerja,0,wiraswasta pemda kab bondowoso,C2,False,
E32201585,ADIS WIDYA RAMADHAN,56401.0,bekerja,3,swasta puskesmas,C2,False,
E32201239,MOCHAMMAD FERDIANTO,56401.0,melanjutkan_studi,3,swasta klinik,C2,False,
E31202463,RISMA DEWI SEPTIANI,57401.0,bekerja,3,swasta hrb cargo,C2,False,
E31201773,ARDYAS SETYA NUGRAHA,57401.0,bekerja,2,wiraswasta depot jamu har,C2,False,
E31201459,FIKRIATUL ILMI,57401.0,bekerja,3,swasta buma,C2,False,
E41192181,RAHADYAN DARARI FEBRIYANTO,55301.0,bekerja,0,swasta benih citra asia,C1,False,
E41191832,ALFIAN SEPTY CHANDRA WIJANARKO,55301.0,bekerja,0,swasta jaya makmur,C2,False,
E31191228,MOCHAMMAD RIZKI PRATAMA,57401.0,bekerja,0,swasta android developer web developer game tester,C0,True,"developer, web"
E31200784,ALIF ANFALUL HAKIM,57401.0,melanjutkan_studi,0,nirlaba rsud lasinrang kabupaten pinrang,C2,False,
E32201131,YUSUF MUHAMMAD FAQIH,56401.0,bekerja,0,bumn gading indonesia teguh,C2,False,
E41192173,MAULANA SULTAN RAGIL WAHYU SYAHPUTRA,55301.0,bekerja,0,wiraswasta pilarmedia indonesia contract,C2,False,
E41191668,MIFTAHUL RIZKY ZAMZAMI,55301.0,bekerja,0,swasta pusat latih tani desa swadaya p4s bintang tani sejahtera,C2,False,
E31202318,NOFAIRA AMIN,57401.0,melanjutkan_studi,0,swasta research and development austindo nusantara jaya tbk,C2,False,
E32200998,SANDY ASAHI,56401.0,bekerja,0,nirlaba full stack developer pilarmedia indonesia,C1,False,
E31202279,RAMA SATRIA MALAMO,57401.0,bekerja,2,wiraswasta gogrin,C2,False,
E31201690,NUR AFIFAH,57401.0,bekerja,0,swasta piranhamas group,C2,False,
E41192294,ADITYA SETYA NUGRAHA,55301.0,melanjutkan_studi,0,perintah kominfo,C2,False,
E32200197,RIZQI NOOR FAIDZIIN,56401.0,wiraswasta,0,wiraswasta badan dapat daerah kabupaten bondowoso,C2,False,
E31201536,FIRDA ULFA UNSILAH,57401.0,bekerja,0,bnpp arjuna distributor nestle,C2,False,
E31200117,DICKA CAHYA PUTRI,57401.0,bekerja,0,wiraswasta tani persero,C2,False,
E31201372,MUHAMMAD ARIF BILLAH,57401.0,bekerja,3,swasta reseller serizshopjember freelance,C2,False,
E31201555,REHAN REZA MAHENDRA,57401.0,bekerja,0,swasta koperasi tarutama nusantara,C2,False,
E31201431,FANISA NUR ARIFAH,57401.0,bekerja,0,wiraswasta labbola sport statistic and data management,C1,False,
E31201951,MASITHA SAVIRA,57401.0,bekerja,0,bumn kebun nusantara,C2,False,
E32200423,LELI FAUZIYAH,56401.0,bekerja,0,bumn wiraswasta,C2,False,
E32201639,SEFHIANA PUTRI WULANDARI,56401.0,bekerja,2,wiraswasta handoyo budi orchids,C2,False,
E31190508,ALFAN ABRAR ARIFIN,57401.0,bekerja,2,wiraswasta wakil direktur kurnia,C2,False,
E41190510,SYAUGI SALIM AMAR,55301.0,bekerja,0,wiraswasta project engineer etrama nusa energi,C0,True,engineer
E32200199,ILHAM TAUFIQUL KHALIQ,56401.0,bekerja,0,bumn lumbung stroberi,C2,False,
E32200838,ZAINUR ROZIQIN,56401.0,bekerja,0,swasta rumah sakit kebun kabupaten jember,C1,False,
E31202345,FATHUR ROCHMAN ZAINUL,57401.0,bekerja,1,perintah rumkit iii baladhika husada jember,C1,False,
E41180679,MOCHAMAD SATRIA MAULANA,55301.0,bekerja,0,bnpp freelance,C2,False,
E32202534,MOH. ANANG EFENDI,56401.0,bekerja,0,bumn pusat teliti kopi kakao indonesia,C1,False,
E32200600,Feri Andika,56401.0,bekerja,0,perintah ptpn kaliselogiri banyuwangi,C0,True,wan
E32201579,Brenda Gusti Dharma,56401.0,bekerja,3,swasta resty nur,C2,False,
E32200776,GIANT PAUL IVAN,56401.0,bekerja,0,perintah dinas budaya pariwisata kabupaten banyuwangi,C0,True,wan
E32200848,VICO SEPTIANDA PRATAMA,56401.0,wiraswasta,0,wiraswasta maestro group jember,C2,False,
E32200765,Ghovi Tri Yulihandika,56401.0,wiraswasta,2,wiraswasta talas eksportir,C2,False,
E32202496,FAIZ NUR ACHMADI,56401.0,bekerja,0,perintah icon,C2,False,
E32201958,MUHAMMAD QODRI,56401.0,bekerja,0,bumn bulog,C2,False,
E32202582,Yeferi Karoba,56401.0,bekerja,0,perintah kantor distrik eragayam kabupaten mamberamo tengah papua,C2,False,
E32192485,ALFAN ANAS MUHLISIN,55301.0,bekerja,0,perintah terna,C2,False,
E31192286,Melinda Fitriyani,57401.0,wiraswasta,0,bnpp dinas tenaga kerja,C2,False,
E41191422,Alvin Eko Cahyo Febrianto,55301.0,bekerja,3,swasta impactbyte teknologi edukasi skilvul,C1,False,
E41182123,CHIKITA PUTRI MEIDINASARI,55301.0,bekerja,0,swasta karya citra bangun persada utama,C1,False,
E32200651,MUHAMMAD FADLI ZAKARIA,56401.0,bekerja,0,bumn pln icon pllus,C2,False,
E41191034,MUHAMMAD RAIHAN RIYADY,55301.0,bekerja,3,swasta dankom mitra abadi,C1,False,
E41192199,RIZDKY OKTAVIARI PRATAMA PUTRA,55301.0,bekerja,3,swasta infimedia solusi pratama,C2,False,
E31200238,JALALUDDIN ABIMANYU,57401.0,bekerja,3,swasta bpjs sehat,C2,False,
E41192160,SOFYAN ARIF AF RIZAL,55301.0,bekerja,0,bumn bank rakyat indonesia cabang bondowoso,C2,False,
E31202278,CHAIDAR SA’AD,57401.0,bekerja,3,swasta percie,C2,False,
E31201056,DIELLA AULIA IVANA PUTRI,57401.0,bekerja,0,wiraswasta padma jaya,C2,False,
E31200973,DEVI ARYANING TYAS,57401.0,bekerja,3,swasta esolusindo,C2,False,
E41192433,MITA UNZIYAH FAJRINA,55301.0,bekerja,3,swasta koltiva,C2,False,
E41192330,ILMI AZMI IRADIYAH,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E41192348,SINDI MEGA SEPTIANDARI,55301.0,bekerja,0,bnpp durrotul hikmah islamic school,C2,False,
E41191224,FERRY SEPTIAN FERDIYANTO,55301.0,bekerja,3,swasta indoprima gemilang,C2,False,
E31200844,Lukman Afandi,57401.0,bekerja,3,swasta fokus jasa mitra,C1,False,
E41191741,EZRA ALANNATHANIEL,55301.0,bekerja,3,swasta bca,C2,False,
E41180808,Eva Agustin Rahayu,55301.0,wiraswasta,0,wiraswasta pusat teliti kopi kakao indonesia,C1,False,
E41190899,Mohammad Haerul Anam,55301.0,bekerja,0,swasta bejana investidata globalindo bigio,C1,False,
E41190441,Sinta Nuriyah Wulandari,55301.0,bekerja,0,swasta bejana investidata globalindo,C1,False,
E41182137,Tahajjudin Fajri,55301.0,wiraswasta,2,wiraswasta taarts animation,C2,False,
E41212489,BANGKIT BUDI UTOMO,55301.0,bekerja,1,perintah politeknik negeri jember,C1,False,
E41212482,Masrifatul Hazijah,55301.0,bekerja,0,perintah labuh ikan nusantara pengambengan jembrana bal,C2,False,
E41191458,HANIF SATRIO RIMAMTOMO,55301.0,bekerja,0,perintah dinas tani pangan,C2,False,
E32200508,PUTRI LATIFATUS SALAMAH,56401.0,bekerja,0,swasta orindo alam ayu oriflame supranusa indogita manufaktur freelancer pribadi asisten manager evaluator klinik jurnal capa,C0,True,lan
E31201939,NUR ACHMAD FAISOL QUBRO,57401.0,bekerja,0,swasta sygenta seed indonesia,C2,False,
E31160678,RIZKA NURUL KHAKIKI,57401.0,bekerja,-1,swasta,C3,False,
E41150211,DEWI AYU ITIKAF,55301.0,mencari_kerja,-1,,C3,False,
E31151401,Aza Pascaeka,57401.0,belum_kerja,-1,wiraswasta,C3,False,
E31130845,MOCH. RIVALDI AFTONI,57401.0,bekerja,-1,lain,C3,False,
E31160328,Afega Wira Pradana,57401.0,bekerja,-1,swasta,C3,False,
E31161719,Reza Septia Safirah,57401.0,belum_kerja,-1,wiraswasta,C3,False,
E32160904,ONGKY OKTAFIAN DWI JOHANSYAH,56401.0,bekerja,-1,swasta,C3,False,
E41150068,MUHAMMAD HAFIDH FIRMANSYAH,55301.0,bekerja,-1,lain,C3,False,
E41151584,Risqi Ahmad Sultoni,55301.0,bekerja,-1,swasta,C3,False,
E31151214,Nita Wahyu Lianti,57401.0,belum_kerja,-1,wiraswasta,C3,False,
E31160306,Faiqotul Hikmah,57401.0,bekerja,-1,swasta,C3,False,
E41170333 ,CICILIA SELVY ERIANTHY,55301.0,wiraswasta,-1,wiraswasta,C3,False,
E31182203 ,Rofi Berliana Mahanani,57401.0,melanjutkan_studi,-1,swasta,C3,False,
E32180554 ,Akhmad Farizi,56401.0,melanjutkan_studi,-1,swasta,C3,False,
E41170562 ,KRISOPRAS EPIKUROS,55301.0,wiraswasta,-1,swasta,C3,False,
E32182061 ,OZSA DEWANGGA PRADANA,56401.0,melanjutkan_studi,-1,bnpp,C3,False,
1 nim nama kode_prodi status_pekerjaan cluster teks_pekerjaan kategori match_profil matched_keywords
2 E31160241 Rizki Firmansyah 57401.0 bekerja 0 nirlaba irsyad islamiyyah jember C2 False
3 E32160207 Afrizal Gita Putra Laksono 56401.0 bekerja 3 swasta nexwave C2 False
4 E31161703 Lilik Widayanti 57401.0 bekerja 0 perintah balai desa sumbermujur C2 False
5 E31160798 LUKMAN HARUN 57401.0 wiraswasta 0 wiraswasta barokah cell C2 False
6 E41150080 DAVID SUGIANTO 55301.0 bekerja 3 swasta tokopedia C2 False
7 E41151627 Ahmad Syamsul Arifin 55301.0 wiraswasta 2 wiraswasta dafidea technocraft C0 True tech
8 E31161033 Ayu Diyah Purwanti 57401.0 bekerja 0 bumn bank negara indonesia tbk C2 False
9 E41151085 Yunita Dwi Pujianti 55301.0 bekerja 1 nirlaba politeknik negeri jember C1 False
10 E41151776 Mahbubi Ilham Nafiulalam 55301.0 bekerja 3 swasta tjiwi kimia tbk C2 False
11 E31161241 Aulia Rafi Dika Pekasih 57401.0 bekerja 3 swasta yaffi solusi internasional C2 False
12 E31161816 Dhimas Ulfa Lathifah 57401.0 bekerja 3 swasta moro ayu cosmetindo C2 False
13 E41150057 DITA PUSPITA RAHMA PUTRI 55301.0 bekerja 3 swasta sentra vidya utama sevima C2 False
14 E41150559 RAYHAN SAVERO ARIL 55301.0 bekerja 3 swasta telkomsel C2 False
15 E32161301 Muhammad Isbi Romadhoni 56401.0 bekerja 0 swasta east west seed indonesia C2 False
16 E32160628 SANDY KURNIAWAN 56401.0 bekerja 3 swasta pelangi migas abadi C0 True lan
17 E32160392 MOHAMMAD FADHUR ROHMAN 56401.0 bekerja 3 swasta enggar media sentana C2 False
18 E32160891 MUHAMMAD ALY ROFIE 56401.0 bekerja 0 bumn asuransi jiwasraya C2 False
19 E41151925 Wahyu Kartini Putri Aditya 55301.0 bekerja 3 swasta yayasan imam syafi C2 False
20 E32161373 Yuni Syafarinda 56401.0 bekerja 0 swasta idn boarding school C2 False
21 E41171583 AHMAD FAKIH HASBULLAH 55301.0 bekerja 0 wiraswasta usaha bisnis kembang konten creator C2 False
22 E41171389 SEPTIAJI WARAGA FILA 55301.0 wiraswasta 2 wiraswasta lilik collection C2 False
23 E41171753 Rikky Ihza Pratama 55301.0 bekerja 0 bnpp maulid teknologi kreatif C1 False
24 E41172249 RENDHY PRATAMA PUTRA 55301.0 bekerja 1 nirlaba politeknik negeri jember C1 False
25 E31181391 AN NISSA SAFITRI 57401.0 bekerja 2 wiraswasta mustikatama C2 False
26 E32180649 DEWI MAGREZA ALFIONITA 56401.0 bekerja 0 bnpp appen C2 False
27 E41170896 SYAVINA OCTAVIA PARAHITA 55301.0 bekerja 0 perintah dinas sosial kabupaten jember C2 False
28 E32181095 Helen Uni Dewi Samima 56401.0 wiraswasta 0 wiraswasta jual umpan ikan C2 False
29 E31151415 DENNY SETIADY PRABOWO 57401.0 bekerja 2 wiraswasta forensmith C1 False
30 E32181826 YUNDA CHONITA 56401.0 bekerja 0 nirlaba arsenet global solusi C2 False
31 E41171926 YOSEF YOGA HIMAWAN 55301.0 bekerja 0 wiraswasta araya media C2 False
32 E32180259 YUSRON WIDAD SYARFAN 56401.0 bekerja 0 bumn lintas nusantara C2 False
33 E32180470 ACHMAD MAULUDI FATHONY 56401.0 bekerja 0 bnpp kantor bank C2 False
34 E41172060 ROKI PRASETYO ADI 55301.0 bekerja 0 bnpp smk pancasila jember C2 False
35 KHOSNOL KHOTIMATUL ARIFAH 55301.0 bekerja 0 bumn maulid teknologi kreatif C1 False
36 E32181653 Firdaus Andy Muhammad 56401.0 wiraswasta 0 wiraswasta jual baju C2 False
37 E31181032 MAULIEN JULYA SELEBRITISH 57401.0 wiraswasta 2 wiraswasta wiraswasta C2 False
38 E31181280 WULAN CAHYA WANDANI 57401.0 bekerja 0 perintah diskominfo C2 False
39 E41171613 GALIH BAGUS PRAKASA 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
40 E31182077 RIVALDY NUR IDRIS 57401.0 bekerja 0 wiraswasta polije C2 False
41 E31180387 KANISA SHEILA IN ALVIONITA 57401.0 bekerja 0 bnpp jtv C2 False
42 E41171308 BAWIK ARDIYAN RAMADHAN 55301.0 bekerja 0 bnpp techno C0 True tech
43 E32181021 MOH. YOGI FERNANDA 56401.0 bekerja 0 bnpp kcm C2 False
44 E41171749 ALI MANSUR 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
45 E31180464 SEPTIYAN YULIONO 57401.0 bekerja 2 wiraswasta karpet C2 False
46 E31180691 AHMAD FARHAN ALI 57401.0 wiraswasta 2 wiraswasta dmsncloth C2 False
47 E31180638 NAILUL AZMI ZIDNI ILMA 57401.0 wiraswasta 2 wiraswasta atapbesi C2 False
48 E31180819 MOCH. IQBAL ROSYIDI 57401.0 melanjutkan_studi 0 wiraswasta kerja C2 False
49 E31180838 YUANA DWI PANGESTU 57401.0 bekerja 2 wiraswasta cafe C2 False
50 E32181637 MUHAMMAD ADITYA MARTONO 56401.0 bekerja 2 wiraswasta mie terror C2 False
51 E31182176 JOSANTHA MARSHEL VALENDRA 57401.0 bekerja 0 wiraswasta esolusindo C2 False
52 E41170291 ALI WAJHAH 55301.0 bekerja 0 wiraswasta jember muslim store C2 False
53 E41161315 RIFQI HAKIM ARIESDIANTO 55301.0 wiraswasta 2 wiraswasta king kalkun C2 False
54 E31181297 SASTI WIDIYAS SARI 57401.0 bekerja 0 wiraswasta rumah C2 False
55 E41172069 AKHLAQ KHAN 55301.0 bekerja 0 wiraswasta toko bang mansur C2 False
56 E41170916 MUHAMMAD KHOIRIRI 55301.0 wiraswasta 2 wiraswasta pemuda padi C2 False
57 E41170897 RIDI YOGA PRATAMA 55301.0 bekerja 0 nirlaba pondok pesantren ibnu katsir C2 False
58 E31160935 RISANG AYU LARASATI 57401.0 wiraswasta 2 wiraswasta pawon uti C2 False
59 E41171041 MAKHI HAKIM HAKIKI 55301.0 bekerja 1 perintah man jember C2 False
60 E32181772 MOH. NUR AHSAN 56401.0 bekerja 0 nirlaba zamzee computer C2 False
61 E32180529 MUHAMMAD NASRUL FATTAH 56401.0 bekerja 0 wiraswasta sahabat bangun C2 False
62 E32181708 APRILLIO DOVAN ARIESA 56401.0 melanjutkan_studi 0 wiraswasta toko azahra C2 False
63 E31181204 FARIZ GUSTAFIANTO 57401.0 wiraswasta 0 wiraswasta zayid persada C2 False
64 E31181830 DITA SHAFIRA WAHYUDI 57401.0 melanjutkan_studi 2 wiraswasta yudi net C2 False
65 E41171120 MUHAMMAD ARIEF RACHMAN MUTTAQIEN 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
66 E31182013 ABDANIAL PRADITYA 56401.0 bekerja 3 swasta proxinet C2 False
67 E41172068 AFFAN TOHARI 55301.0 bekerja 0 bnpp bikea tekno C2 False
68 E31180187 PUSPITA SARI RAKHMATULLAH 57401.0 bekerja 1 perintah politeknik negeri jember C1 False
69 E31180222 ELLA WAHYUNINGTYAS 57401.0 bekerja 0 wiraswasta polije C2 False
70 E32180842 NURUL QOMARIYAH 56401.0 bekerja 0 bumn pdam bondowoso C2 False
71 E41171252 NIKO WAHYU FITRIANTO 55301.0 bekerja 0 swasta indomarco prismatama C2 False
72 E31181955 M. PANDU GAUTAMA WIRANAGARA 57401.0 bekerja 0 wiraswasta freelance C2 False
73 E31180112 INTA OKTA RESTANTI 57401.0 bekerja 0 bumn kopegtel C2 False
74 E32181801 REY DICO PERWINA AMADA N. 56401.0 bekerja 2 wiraswasta albertacommunity C1 False
75 E31180686 HIKMAH QUR'ANING TYAS 57401.0 bekerja 0 wiraswasta shopee C2 False
76 E41170204 DANI ARDIYANSYAH 55301.0 bekerja 0 bumn pertamina C2 False
77 E31180256 Alfira Rosalina Damela 57401.0 bekerja 0 bumn antam tbk C2 False
78 E41170873 ACHSANUL KHIZAM 55301.0 bekerja 0 bnpp jatilindo C2 False
79 E32180210 FIKRI HAIKAL 56401.0 bekerja 0 bnpp karya cipta mekatronika C2 False
80 E41170676 ANGGI TRIKUSUMA DEWI 55301.0 bekerja 0 wiraswasta avatar solution C2 False
81 E32182281 ROSITA B KASIPDANA 56401.0 bekerja 0 perintah kantor bupati C2 False
82 E41171452 ADY BAGUS SUGIH SUSANTO 55301.0 bekerja 0 swasta indomarco prismatama C2 False
83 E32160410 ANDRE KRISNA PRATAMA 56401.0 bekerja 3 swasta bima technologies C2 False
84 E31181496 MURPY SATRIYA NUGRAHA 57401.0 bekerja 0 swasta maulid teknologi kreatif maulid games C1 False
85 E31181929 Andaru Bagus Gandhy Nurwidigdo 57401.0 bekerja 3 swasta bencoolencoffee C2 False
86 E41171829 MEGA SILVIA 55301.0 bekerja 3 swasta mang sabay rumah makan C2 False
87 E32181586 HARFI KURNIA HADIPUTRA 56401.0 bekerja 0 perintah diskominfo bondowoso C2 False
88 E41170438 MOHAMAD RIZAL RAMLI 55301.0 bekerja 0 swasta xeno persada teknologi C1 False
89 E41170753 DHENI TEGUH PRAMONO 55301.0 wiraswasta 2 wiraswasta bajukita id C1 False
90 E31180825 KEVIN ADITYAPUTRA ADRIANSYAH 57401.0 wiraswasta 2 wiraswasta mitreka karsa C1 False
91 E41170740 ABDILANA MOHTALIA SAPUTRA 55301.0 bekerja 0 perintah rsud koesnadi bondowoso C2 False
92 E41170164 Rizkika Zakka Palindungan 55301.0 bekerja 0 swasta xeno persada teknologi C1 False
93 E31180427 REZA ROMADHONI ALWI 57401.0 bekerja 3 swasta usaha swasta C2 False
94 E32180687 FARHAN IRZYAM ARI GUNTARA 56401.0 wiraswasta 0 wiraswasta ataraxia group C2 False
95 E41190088 Dimas Fariztha Hadiyatullah 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
96 E31181553 LADINA PUTRI ANDITYANDARI 57401.0 bekerja 3 swasta strawberry preschool and daycare C2 False
97 E41172253 Fahrizal Azi Ferdiansyah 55301.0 bekerja 3 swasta devivace C2 False
98 E31182056 MOHAMMAD NAZIL ZAINUDDIN 57401.0 bekerja 2 wiraswasta tich C2 False
99 E32180275 MOH HAIRUL ARIFIN 56401.0 wiraswasta 2 wiraswasta arifnet C2 False
100 E32180653 SHOFIAH NUR MAZIDA 56401.0 wiraswasta 0 wiraswasta rumah dannis C2 False
101 E41170809 KURNIA MUTIARA SEPTI 55301.0 wiraswasta 2 wiraswasta aara dekorasi C2 False
102 E41171994 SASQIA DWI ARTA NOVIA 55301.0 bekerja 0 bnpp bank mega syariah C2 False
103 E41171742 RIDWAN HANANTO AJI ARIFIN 55301.0 bekerja 0 wiraswasta prodevis team C2 False
104 E41171660 REFI TRI HIDAYATULLAH 55301.0 wiraswasta 0 wiraswasta jasa buat website C1 False
105 E31180926 MUSBIHATUL CHORIROH 57401.0 bekerja 0 perintah perintah kabupaten nganjuk C2 False
106 E31180696 RIZQIANA AMITASARI 57401.0 wiraswasta 0 wiraswasta toko baju C2 False
107 E41170926 FAHRIZA RAMADHANI PUTRA 55301.0 bekerja 0 perintah polda jatim C2 False
108 E31180892 RURY AGISTA ASMININGSIH 57401.0 bekerja 0 perintah diskominfo C2 False
109 E41170061 Elsa Manora Ramadania 55301.0 bekerja 1 wiraswasta politeknik negeri jember C1 False
110 E32181667 ROBERT MUHAJIR 56401.0 wiraswasta 2 wiraswasta osingart C2 False
111 E32180251 MIFTAHUL HUDA 56401.0 bekerja 0 perintah dinas komunikasi informatika C2 False
112 E31170392 WAHYU RAMA FIJAYANDI 57401.0 bekerja 3 swasta sinikopi C2 False
113 E31181091 CAMALLA SABRINA YUSVIAZAH 57401.0 bekerja 0 wiraswasta warung soto ayu C2 False
114 E41170241 INANT KHARISMA 55301.0 wiraswasta 0 wiraswasta digital C1 False
115 E41171111 MUHAMMAD IRFAN SHIDQI LAKSONO 55301.0 bekerja 1 bumn politeknik negeri jember C1 False
116 E31180949 AKBAR IMAWAN DWI CAHYA 57401.0 bekerja 1 perintah politeknik negeri jember C1 False
117 E31181452 SITI ANISAH 57401.0 bekerja 0 perintah smp negeri wuluhan C2 False
118 E31181709 M ALI ROMADONI 57401.0 bekerja 3 swasta cybers global indonesia C2 False
119 E32181993 MALIK ABDUL AZIZ 56401.0 bekerja 0 perintah jaksa agung C2 False
120 E31180332 DEWI RATIH TILAMSARI WIBOWO 57401.0 bekerja 3 swasta mensa binasukses C0 True bi
121 E32181873 MOH GUFRON AZIZI 56401.0 bekerja 0 bumn kominfo C2 False
122 E32182153 Arshi Wisnu Wardhana 56401.0 bekerja 0 bnpp bsi C2 False
123 E32181449 MOCHAMMAD ALIF RAMADHANI 56401.0 bekerja 0 bnpp mitra tani C1 False
124 E41170090 Ari Baskara 55301.0 bekerja 0 wiraswasta freelance C2 False
125 E41171164 Adi Lukito 55301.0 bekerja 0 bnpp mitra surabaya C1 False
126 E31181436 NUR KUMALA SARI 57401.0 bekerja 0 bnpp kodig teknologi indonesia maju C1 False
127 E31180703 ANITA KURNIAWATI 57401.0 bekerja 0 bumn bank bni C2 False
128 E41171725 KHOSNOL KHOTIMATUL ARIFAH 55301.0 bekerja 0 bumn maulid teknologi kreatif C1 False
129 E41172165 MOCHAMMAD LEMBAR ADJIE BRAMANTYA 55301.0 bekerja 0 wiraswasta distributor skincare personal beauty C2 False
130 E32180234 Reza Firjatullah Rahman 56401.0 bekerja 0 bnpp asuransi ramayana C2 False
131 E32181238 FRENDY YASO MAYDALAN 56401.0 bekerja 0 bumn bumn C2 False
132 E32180323 GHALIB GIANARKAN BUSTIN 56401.0 bekerja 0 bnpp ptpn C2 False
133 E32180800 ANDI NURFANSYAH 56401.0 bekerja 0 bumn ptpn C2 False
134 E41171171 ATHO' FAJARIANTO 55301.0 bekerja 0 bnpp bumi suksesindo C2 False
135 E32181742 MOCHAMAD FIO BAITUL HUDA 56401.0 bekerja 0 bnpp art photography C2 False
136 E32181959 FERNANDA TERESIA VENTURIN 56401.0 bekerja 0 perintah bank bni C2 False
137 E41171092 GALANG PUTRA FENDRIANSYAH 55301.0 bekerja 0 bnpp denso C2 False
138 E32180381 MUHAMMAD RAFI 56401.0 bekerja 0 bumn pdam tirta balur C2 False
139 E41170735 DESTINO DEWANTARA PRATAMA 55301.0 bekerja 0 bumn bank bri C2 False
140 E32180897 RIFQI ABRORI 56401.0 bekerja 0 bnpp trans surabaya C2 False
141 E41170613 MONIKA KUSUMA DEWI 55301.0 bekerja 0 bnpp mitra umkm indomaret C1 False
142 E41170190 WINDA KURNIAWATI 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
143 E32180459 RIFQIE BAGUS FIRMANSYAH 55301.0 bekerja 0 perintah dinas duduk C2 False
144 E32181934 FABIO QADAFI SUGESTI 56401.0 bekerja 0 bumn kai C2 False
145 E31182299 RISMA MULIYAWATI 57401.0 bekerja 0 perintah tri komunikasi informatika C2 False
146 E31180306 NOFITA OKTA SASMITA 57401.0 bekerja 0 bumn bps C2 False
147 E31180575 ELLEN MELINDA PUTRI ARIFIYANA SARI 57401.0 bekerja 0 wiraswasta luhan jaya C2 False
148 E32181133 AISYAH SASYADILAH 56401.0 bekerja 0 bnpp wings surya C2 False
149 E31182109 Rizaldy Putra Anam Novriandi 57401.0 bekerja 2 wiraswasta darmantika C2 False
150 E32180498 TARISA WINDI SUMONO PUTRI 56401.0 bekerja 0 wiraswasta piranhamas group C2 False
151 E32181345 ADE RIZKY CIPTA PRATAMA 56401.0 bekerja 0 bnpp pertamina C2 False
152 E31180303 YAHYA AJI WIJAYA 57401.0 bekerja 0 perintah multimedia edukasi C2 False
153 E41171621 BANGGA ADITYATAMA 55301.0 bekerja 0 perintah badan pegawai daerah C2 False
154 E41171118 FERNANDO FARISTA AHMAD 55301.0 bekerja 0 bnpp mitra C1 False
155 E32181811 ERINA SUDRAJAD 56401.0 bekerja 0 perintah smk pgri tanggul C2 False
156 E41171541 M. AVICENNA MAULA 55301.0 bekerja 0 wiraswasta mitra surabaya C1 False
157 E41171896 ADI CAHYA WIRATMAYA 55301.0 bekerja 0 perintah dinas komunikasi informatika bondowoso C2 False
158 E32182292 RAIZZAL AHAMAD WEIKIANSYAH 56401.0 bekerja 0 bnpp arsenet C2 False
159 E32181600 MUHAMMAD SHOLEHUDDIN 56401.0 bekerja 0 bnpp mekar jaya C2 False
160 E41170538 RIZKY MAULIDA 55301.0 bekerja 1 bnpp politeknik negeri jember C1 False
161 E31181131 SITI ANISA 57401.0 bekerja 0 wiraswasta multimedia edukasi C2 False
162 E31181991 MUHAMMAD ALIF MAHMUT 57401.0 wiraswasta 0 bnpp jual pakan sapi C2 False
163 E41170913 Yusuf Andi Nugroho 55301.0 bekerja 0 bnpp run systems C2 False
164 E31180884 ANITA SAFITRI 57401.0 bekerja 0 bumn dinas komunikasi informatika C2 False
165 E31181263 KARIMATUS SOFI'AH 57401.0 bekerja 0 perintah dinas perintah kabupaten situbondo C1 False
166 E31180299 DESY WAHYUNINGTYAS 57401.0 bekerja 0 bumn bri bank rakyat indonesia jember C2 False
167 E31180373 SITI KHOFSYAH 57401.0 bekerja 0 bumn grapari C2 False
168 E41171569 RISKA APRILIA 55301.0 bekerja 3 swasta content marketing labs C1 False
169 E31180365 KOMARIAH 57401.0 bekerja 1 wiraswasta politeknik negeri jember C1 False
170 E31180297 NURIN ASTIN VALIDA 57401.0 bekerja 1 wiraswasta politeknik negeri jember C1 False
171 E41170352 META GADIECHA WACHYUDI 55301.0 wiraswasta 0 wiraswasta freelance C2 False
172 E32180198 ENGGA BAGUS RIYANTO 56401.0 wiraswasta 2 wiraswasta desain C1 False
173 E31182030 Misbahus Surur 57401.0 bekerja 0 perintah operator gugus camat kalisat C2 False
174 E41171309 AL BUSRAN 55301.0 bekerja 3 swasta cmlabs malang C2 False
175 E41170885 RANGGA TRIANA PUTRA 55301.0 bekerja 3 swasta mascitra com C1 False
176 E31180644 DIAJENG SHINTA FEBRI RAHAYU 57401.0 bekerja 0 wiraswasta bagus kosmetik C2 False
177 E32181062 WAHYU ROMADHIANTO 56401.0 bekerja 3 swasta sumber dingin engineering C1 False
178 E41170203 KAHFINDA MULYA UTAMA PUTRA 55301.0 wiraswasta 2 wiraswasta acang handayani C2 False
179 E31160910 RIZKY AKBAR AUGUST PRADANA 57401.0 wiraswasta 0 wiraswasta toko afizah C2 False
180 E41170244 DAVID SETYA AINUR HAKIKI RAMADHAN 55301.0 bekerja 3 swasta digital C1 False
181 E32180585 BILLAL DAIFULLAH YAHYA AG 56401.0 bekerja 2 wiraswasta dispenduk C2 False
182 E31180276 MUHAMMAD FIRMAN AGE BIMANTARA 57401.0 wiraswasta 2 wiraswasta konter C2 False
183 E31181885 SOVIAH AYUNIAR MEGAFELANI PUTRI 57401.0 wiraswasta 3 swasta rental C2 False
184 E32180894 BONDAN YUWONO PUTRA 56401.0 bekerja 0 wiraswasta komputer solution C0 True komputer
185 E32181419 Roby Bayu Trisno Ananda 56401.0 bekerja 0 wiraswasta freelance C0 True lan
186 E32181940 ILHAM AKBAR JOVIANSYAH PUTRA 56401.0 bekerja 0 bumn telkom indonesia C2 False
187 E41170754 ALDY NOVERIANTO PRATAMA 55301.0 wiraswasta 2 wiraswasta tetas telur bebek peking C2 False
188 E32180760 ROBIUL ADAWI 56401.0 melanjutkan_studi 0 perintah pemda C2 False
189 E41170987 NOVIA NURUL QOMARIL 55301.0 wiraswasta 2 wiraswasta wiraswasta C2 False
190 E32182013 ABDANIAL PRADITYA 56401.0 bekerja 3 swasta proxi jaring nusantara C2 False
191 E32181862 BHIRAWA ANORAGA 56401.0 bekerja 0 wiraswasta arsenet global solusi C2 False
192 E41170641 AJI WAHYU PRASETYO 55301.0 wiraswasta 2 wiraswasta aji design C1 False
193 E41170827 AHMAD MUNIR 55301.0 wiraswasta 3 swasta jogotoko C2 False
194 E41172109 Nava Shoqibatul Khoiriyah 55301.0 bekerja 0 wiraswasta grace beauty C2 False
195 E41171956 DANA BHAKTI SURYA PRATIWI 55301.0 bekerja 2 wiraswasta shopie martin C2 False
196 E31180260 FAIZAL FIKRI HAMDANI 57401.0 bekerja 2 wiraswasta btin C2 False
197 E41170909 ADE SETIAWAN 55301.0 melanjutkan_studi 2 wiraswasta tidakada C2 False
198 E41170917 BUDI YUNIOR VALENTINO 55301.0 bekerja 2 wiraswasta rainbolt C2 False
199 E41171467 BAHTIAR ADI PRASETYA 55301.0 wiraswasta 2 wiraswasta adi disain C2 False
200 E32170824 MOH MUZAMMIL AL FARIZI 56401.0 bekerja 0 nirlaba ghofilin C2 False
201 E41171874 YUSUF TRI WIBOWO 55301.0 bekerja 3 swasta prodevis C2 False
202 E41170629 YANUAR ANUGRAH RAMADHANI 55301.0 wiraswasta 0 wiraswasta ruang kopi C2 False
203 E41171011 Gagas Adi Rismawan 55301.0 bekerja 0 wiraswasta digitalworks C1 False
204 E41171135 DWI AYU WULANDARI 55301.0 bekerja 0 wiraswasta digitalworks C1 False
205 E31161048 AHMAD FATKHUL ARIFIN 57401.0 bekerja 2 wiraswasta vatqul apprl C2 False
206 E32180069 MUHAMMAD RIZQI PRIYANSYAH 56401.0 bekerja 2 wiraswasta alberta community C1 False
207 E41171075 MOH. SYAFRIAN ABIE 55301.0 bekerja 2 wiraswasta naminauna institute C1 False
208 E32181970 FAIZHAL MAULANA IQBAL 56401.0 bekerja 0 swasta balai desa C2 False
209 E31180684 MELANIA RINIHANDITA NUR HABIBAH 57401.0 bekerja 0 wiraswasta olshop barokah C2 False
210 E31182235 HERNANDO FARAZI HERRERA 57401.0 bekerja 0 wiraswasta freelancer C2 False
211 E41171664 RAMADHAN IBNU UMAM 55301.0 wiraswasta 3 swasta glazzos studio C2 False
212 E31181567 AVIVAH NUR FAIZ MAGHFIROH 57401.0 melanjutkan_studi 0 bumn bulog C2 False
213 E31180748 DWINDA AYULIA EDITA SARI 57401.0 bekerja 2 wiraswasta dwdesign C1 False
214 E41171335 VINNY SAKINAH VIRGIO 55301.0 melanjutkan_studi 0 bumn belum kerja proses cari kerja C2 False
215 E41172064 SYAHDAN FIMAN HUDA 55301.0 wiraswasta 0 wiraswasta toko hitam putih C1 False
216 E31181597 MIRANI ILMI AURIA DEBITA 57401.0 bekerja 2 wiraswasta nimo C2 False
217 E31180207 MOHAMMAD BADAR PAMUNGKAS 57401.0 wiraswasta 0 wiraswasta onthel store jember C2 False
218 E32170601 LAILATUL QOMARIYAH 56401.0 bekerja 0 wiraswasta online shop C2 False
219 E32181659 MUHAMMAD WILDAN ILHAM MUBAROQ 56401.0 bekerja 0 wiraswasta barokah jaya C2 False
220 E32181610 SAHRIL SABIRIN 56401.0 wiraswasta 0 wiraswasta warung kopi C2 False
221 E32181421 SAHRUL SIHABUDIN 56401.0 bekerja 3 swasta budiawan C0 True wan
222 E32180272 HOFIDATUL AFIYAH 56401.0 bekerja 3 swasta kaloper C2 False
223 E32180279 NOVA AYU LESTARI 56401.0 bekerja 3 swasta kaloper C2 False
224 E32180282 TUTIK ERDIANA 55301.0 wiraswasta 2 wiraswasta warunng C2 False
225 E32180197 WAHYUNINGSIH 56401.0 melanjutkan_studi 0 wiraswasta yuni shop C2 False
226 E31180837 MIFTAH RIZQI AZIZAH 57401.0 wiraswasta 2 wiraswasta semicolon C2 False
227 E32181237 AGUNG TRI LEKSONO 55301.0 bekerja 0 wiraswasta agung C2 False
228 E31182133 MICHEL MEIRISCA HENIATY 57401.0 bekerja 3 swasta esolusindo C2 False
229 E31180504 PUTRI BUDIASIH 57401.0 bekerja 2 wiraswasta pizzaku C2 False
230 E31181100 RIWELLANANDA NANDA URBANING PUTRI 57401.0 bekerja 0 bumn pdam C2 False
231 E31180678 VENNA ERSIS RELITA 57401.0 bekerja 0 wiraswasta global C2 False
232 E31180456 RISKI EKA SAPUTRI 57401.0 bekerja 0 perintah bps jember pengentry C2 False
233 E32180231 RAUDATUR RIZKY ELOK BARLIAN 56401.0 melanjutkan_studi 0 perintah kai C2 False
234 E32180205 DAUD ARAGA ABABIL 56401.0 bekerja 0 nirlaba ast C2 False
235 E31180369 PUTRI RACHMAWATI 57401.0 wiraswasta 0 wiraswasta shop handcraft C2 False
236 E31180295 BUNAYYA MAULANA 57401.0 wiraswasta 0 wiraswasta shop handcraft C2 False
237 E41171142 KEVIN HARLIS OKTAVIANO 55301.0 wiraswasta 3 swasta company C2 False
238 E31181971 SALSABILA EKSANANDA 57401.0 bekerja 0 wiraswasta freelancer C2 False
239 E32180263 DAVA KUSUMA ARDANA 56401.0 bekerja 0 wiraswasta blackwhite idn C1 False
240 E31181976 THALIA TRIVIRGIANI EFELLYN 57401.0 melanjutkan_studi 0 perintah belum kerja C2 False
241 E32182194 SHOFYAN ASTSAURI 56401.0 melanjutkan_studi 2 wiraswasta ivan record C2 False
242 E31181492 KEVIN RAHANDIKA W 55301.0 wiraswasta 1 wiraswasta juragan guppy jember C2 False
243 E32180292 ZIDQI YOSA DINATA 56401.0 wiraswasta 0 perintah sujud company C2 False
244 E31180370 AIDATUL FAKHIRAH 57401.0 wiraswasta 0 wiraswasta usaha umkm C2 False
245 E41172092 MOCH. ZAINUR ROFAN FANNANI 55301.0 bekerja 2 wiraswasta rofil fotocopy C2 False
246 E31182101 Arfanio Liswanda Bahtiar 57401.0 wiraswasta 2 wiraswasta plant me C2 False
247 E31181474 CHOIRUL ANAM 57401.0 wiraswasta 2 wiraswasta cho pet C2 False
248 E31180707 MUHAMMAD ALI WAFA RAMADHAN 57401.0 wiraswasta 3 swasta service C2 False
249 E32181375 ALIEF PASHA IBRAHIM 56401.0 wiraswasta 2 wiraswasta alya catering C2 False
250 E32180067 Khalid Fikri Mustanir 56401.0 wiraswasta 2 wiraswasta mustanirbookstore C2 False
251 E41170972 ISMU UBAIDILLAH PANATAGAMA 55301.0 bekerja 0 wiraswasta bikea techno C0 True tech
252 E32181448 FRIDO ARJUNA PUTRA 56401.0 bekerja 2 wiraswasta c steamstore C2 False
253 E31180491 IMFI NUR FAIZIYAH 57401.0 wiraswasta 0 wiraswasta corp indonesia C2 False
254 E32190194 MUHAMMAD TAFANI AKBAR 56401.0 bekerja 2 wiraswasta panverta cakrakencana C2 False
255 E41181641 SALMA FARHANI 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
256 E41181324 PRAVASTA GENTA ARJUNANDA KINANTAKA 55301.0 bekerja 0 wiraswasta benih citra asia C1 False
257 E41190280 WAHYU DIAN PRATIWI 55301.0 bekerja 0 swasta grant surya pondasi C2 False
258 E31192202 Yulia Bagas Sri Dastiya 57401.0 bekerja 3 swasta margojoyo residence C2 False
259 E41192227 VIKY LORENT SEA PUTRA 55301.0 bekerja 0 bnpp madura hosting C2 False
260 E41191426 SHINTA DESTIRA AYU 55301.0 bekerja 0 perintah lee yin garment indonesia C2 False
261 E41191107 DWI RIFKI NOVIANTO 55301.0 bekerja 3 swasta clade ventures C2 False
262 E41190530 ALIF IRHASSHOUFI NASIHUL UMAM 55301.0 bekerja 0 swasta telkom indonesia tbk C2 False
263 E41191417 AGIN PRAHAMESTI WICAHYANI 55301.0 bekerja 0 wiraswasta andri farm C2 False
264 E41192205 MUHAMMAD KHALIL ZHILLULLAH 55301.0 bekerja 3 swasta lestasi sentosa C2 False
265 E41190200 NANDA RADITIYA AKBAR 55301.0 melanjutkan_studi 0 swasta dinas tani C2 False
266 E41192269 SULTON MUBAROK 55301.0 bekerja 0 nirlaba dinas tani C2 False
267 E41190532 MOH. SYAIFUDIN 55301.0 bekerja 0 bumn upt kembang agribisnis tanam pangan hortikultura C2 False
268 E41190239 Mohammad Hidayatullah 55301.0 bekerja 0 bumn alir C2 False
269 E41190321 NURICO VICYYANTO 55301.0 bekerja 3 swasta bpn C2 False
270 E32200380 Miftahus Surur Sutowo 56401.0 melanjutkan_studi 3 swasta nutrifood C2 False
271 E41190835 ARINI EKA NOVIYANTI 55301.0 wiraswasta 0 perintah ourscarf C2 False
272 E31201647 FIRDAN MAHENDRA WARDANA 57401.0 wiraswasta 0 bnpp ritz bakery C1 False
273 E41190890 FATHOR RAHMAN 55301.0 bekerja 0 perintah menteri C2 False
274 E41190937 MOH ISKANDAR ZULKARNAIN 55301.0 bekerja 0 swasta badan koordinasi wilayah perintah bangun provinsi jawa timur C2 False
275 E41191351 THUFEIL WARTONO PUTRA 55301.0 bekerja 2 wiraswasta sekretariat dprd C2 False
276 E41190793 M. AINUL YAQIN 55301.0 bekerja 0 bnpp bumi sukses indo C2 False
277 E31200857 ERICK ASRILLAH PRATAMA 57401.0 melanjutkan_studi 0 bumn pusat teliti kopi cacao C1 False
278 E41192478 INDRA PRASETYA 55301.0 bekerja 3 swasta mulya jaya C2 False
279 E32190274 RIZKY ADIWIYANTO 56401.0 bekerja 0 wiraswasta asw food C2 False
280 E41191322 BUNGA PRASETYA DWI ULUL AZMI 55301.0 bekerja 3 swasta yayasan darul mukmin C2 False
281 E41190889 MUHAMMAD LUTFI FADILAH 55301.0 bekerja 0 perintah bank bni C2 False
282 E41191560 Anggito Suryo Baskoro 55301.0 bekerja 3 swasta frawn network C2 False
283 E41190161 Ardan Venora Falahudin 55301.0 bekerja 1 swasta politeknik negeri jember C1 False
284 E41190942 DEFI TAMARA 55301.0 wiraswasta 0 wiraswasta kai C2 False
285 E41192386 FADLI ROMADHAN 55301.0 bekerja 0 perintah charoen pokphand indonesia C2 False
286 E41191090 AMALIA 55301.0 bekerja 0 perintah tunggal griya sakinah C2 False
287 E41191468 ABDUL AZIZ RAHMAWAN 55301.0 bekerja 0 wiraswasta bejana investidata globalindo C1 False
288 E41191151 YULINAR NUR RAHMAWATI 55301.0 wiraswasta 0 bumn ptpn asembagus C2 False
289 E41191443 RISKIE NUR FADILAH 55301.0 bekerja 0 bumn pltu C2 False
290 E41192329 Alga Saputra 55301.0 bekerja 3 swasta sumber tunjung C2 False
291 E31200061 PUJA MAYSA ARYA CUCU WIBOWO 57401.0 wiraswasta 0 bumn makmur jaya C2 False
292 E31201706 EKA FAHRIKA NARISWARI 57401.0 bekerja 3 swasta gas pol dev C2 False
293 E31201573 ERLINDA KRISTANTI PUTRI 57401.0 bekerja 0 swasta utrani farm C2 False
294 E41190160 MITA WAFA WULANDARI 55301.0 bekerja 0 swasta kantor desa C2 False
295 E41192303 RIFJAN JUNDILA 55301.0 bekerja 0 wiraswasta sumber mutiara samudra banyuwangi C2 False
296 E41190236 DIMAS HERU PERDANA PUTRA 55301.0 bekerja 0 wiraswasta dinas tani pangan C2 False
297 E41190179 RANDY RAHMAWAN 55301.0 bekerja 0 wiraswasta dinas tani pangan C2 False
298 E41192406 NOVITA SARI 55301.0 bekerja 0 swasta rumah sakit C1 False
299 E41190668 PRISKA ARLINDA SABILLAH 55301.0 bekerja 0 wiraswasta motor C2 False
300 E41191326 WIKE SRI WIDARI 55301.0 wiraswasta 0 wiraswasta mitra tani C1 False
301 E41191510 ERIK RIZKI FIRDAUS 55301.0 bekerja 0 perintah pltu C2 False
302 E41192131 FEBRI PUTRA TRIS BUDIONO 55301.0 bekerja 3 swasta intprism computing technology C0 True tech
303 E41191453 DANANG ARDIANTO 55301.0 bekerja 3 swasta hutan C2 False
304 E41191628 DIMAS PANGESTU 55301.0 bekerja 3 swasta manajer C2 False
305 E41191382 MUHAMMAD NUZUL RIDOI 55301.0 bekerja 3 swasta agro kusuma C2 False
306 E41192307 RIFKY ROUDANA IMANI CAHYA 55301.0 melanjutkan_studi 3 swasta masakan bunda C2 False
307 E41190318 MAULANA ALIRRIDLO 55301.0 bekerja 0 wiraswasta pemda C2 False
308 E41192287 SULISTYAWATI 55301.0 bekerja 0 wiraswasta lapak online C2 False
309 E31201887 DIMAS RIZQI AGUNG PRATAMA 57401.0 bekerja 2 wiraswasta wira C2 False
310 E41191336 Suci Riski Anggraini 55301.0 bekerja 0 perintah andatu mulia C2 False
311 E41191202 DEWI AGESTI NURIFIANI 55301.0 bekerja 0 perintah dinamix network automatika C2 False
312 E31201950 RIDHO ADILAH WASISTO 57401.0 bekerja 0 perintah dinas tani pangan kab banyuwangi C2 False
313 E31201932 IMDAD ALFI FAHMI 57401.0 bekerja 0 wiraswasta kai C2 False
314 E41192295 MARSELLA DWI FAIRA 55301.0 bekerja 0 bumn ptpn xii wonosari malang C2 False
315 E31202451 MUFID ADITYA DAFENTRI 57401.0 bekerja 0 swasta kopa tarutama nusantara C2 False
316 E31202314 DANI TAUFIKUL HAKIM 57401.0 bekerja 0 perintah bis C0 True bi
317 E41190493 VIGA ENSAS FII SABILILLAH 55301.0 wiraswasta 3 swasta suwito mesin diesel bekas C1 False
318 E41191570 SANG BINTANG PUTERA ALAM 55301.0 bekerja 3 swasta unilever C2 False
319 E41191387 IRCHAMZAH FIKRI ABABIL 55301.0 bekerja 0 wiraswasta bis C2 False
320 E32202398 MUHAMMAD SYAIFULLAH AL ARIEF 56401.0 bekerja 2 wiraswasta evyshopper C2 False
321 E31201246 MOCH. ANDRI 57401.0 bekerja 0 perintah socfindo C2 False
322 E41191280 HENDY SETIAWAN 55301.0 bekerja 3 swasta ida sentosa C2 False
323 E41190925 ANJU ALICIA JOHAN 55301.0 bekerja 0 perintah alf mechatronics innovation C2 False
324 E41192216 DWI NURANNISA RAHAYUNINGTIAS 55301.0 melanjutkan_studi 0 perintah sinar alam C2 False
325 E41191965 FIGO FAJAR YULIANTO 55301.0 bekerja 0 bumn grab C2 False
326 E41192233 FIRMAN ABDI SYAH PUTRA 55301.0 bekerja 2 wiraswasta jmsportcenter C2 False
327 E41190305 FIRMAN WAHYUDI 55301.0 wiraswasta 3 swasta rizky motor C2 False
328 E41190547 MUHAMMAD FADHIL NURHUDA 55301.0 wiraswasta 3 swasta terna C2 False
329 E41190755 DWI WAHYU PRAMBODO 55301.0 wiraswasta 0 swasta tretes view hotel C2 False
330 E32200978 DION ADI PANGESTU 56401.0 bekerja 3 swasta candya organizer C2 False
331 E41192320 AULIA AQSONIA ARIFAH 55301.0 bekerja 0 perintah indo marco C2 False
332 E41192114 MOH. ARDIAS ADE AGA 55301.0 bekerja 0 swasta pltu paiton C1 False
333 E41190139 FIRGO BHAKTIAR HAMSAH 55301.0 bekerja 0 swasta badan pusat statistik regsosek C2 False
334 E41202435 INTAN PERMATASARI 55301.0 bekerja 3 swasta cayaha tani C2 False
335 E41190614 DILLAH AMALIA FIQYANI 55301.0 bekerja 0 wiraswasta bkpsdm kab jember C2 False
336 E41192283 ARIF KURNIAWAN 55301.0 bekerja 3 swasta dinas prawisata C2 False
337 E41192271 AL FAHRELIA WAVA AGUSTIN 55301.0 bekerja 0 swasta pltu paiton C1 False
338 E41190152 ACHMAD KHALIFAH 55301.0 melanjutkan_studi 0 wiraswasta enz kosmetik C2 False
339 E31201954 BERLIANI FIA MAHARIS ARIKHALA 57401.0 bekerja 0 wiraswasta ikhwan jaya C2 False
340 E31200001 AFBILLA FITRIANI DEWI 57401.0 bekerja 0 wiraswasta pltu paiton C1 False
341 E41190503 DIAN BUANA PUTRA 55301.0 wiraswasta 3 swasta bal indah aquarium C2 False
342 E31200561 ALFINA DEWI HIDAYANTI 57401.0 bekerja 1 perintah politeknik negeri jember C1 False
343 E32201501 RICKY ANDRIAWAN 56401.0 bekerja 0 wiraswasta guna jaya C2 False
344 E32201226 ARINID DIANA OKTAVIA 56401.0 melanjutkan_studi 0 bumn rsud moch ansari saleh banjarmasin C2 False
345 E32200493 RAFLY KEMAL AVIYANTO 56401.0 bekerja 0 wiraswasta smks pgri banyuputih C2 False
346 E32200990 AQMALUH AGUNG PRADANA 56401.0 bekerja 0 perintah kantor perintah desa olean C2 False
347 E41191903 NADEA AJENG SAFITRI 55301.0 bekerja 0 perintah panca mitra multiperdana C1 False
348 E41191622 AGNES OCTAVIANDA ZAVIRA 55301.0 bekerja 2 wiraswasta artaboga C2 False
349 E31200680 FUAD HASYIM FANANI 57401.0 wiraswasta 0 wiraswasta marga solusi prima C2 False
350 E31201158 ALBANI KHAMENEI 57401.0 bekerja 0 swasta cipta karya buana C2 False
351 E41191188 ANISA PUJI ASTUTIK 55301.0 wiraswasta 3 swasta anugerah C2 False
352 E31200293 KALYANA UNASHA RAYHANDINI YUSUF 57401.0 wiraswasta 0 perintah imaji sociopreneur C2 False
353 E31201146 WIDYA PUTRI PRATAMA 57401.0 bekerja 0 wiraswasta badan dapat daerah C2 False
354 E31201687 SHAFA THALIAH 57401.0 bekerja 0 swasta badan dapat daerah kabupaten jember C2 False
355 E41192362 DIANA FITHRI LESTARI 55301.0 wiraswasta 3 swasta taihei dengyo indonesia C2 False
356 E41190739 RESA WAHYU SAPUTRA 55301.0 bekerja 0 bumn perum hutan pabrik gondorukem terpentin kbm ihh jatim non kayu C2 False
357 E41190125 ANGGUN WASILINA MUTRIFANI 55301.0 wiraswasta 0 swasta dinas hutan provinsi jawa timur C2 False
358 E32200993 ACHMAD NABILUL FAHMI 56401.0 bekerja 0 perintah shopee food C2 False
359 E32201292 DWI APRILIA HALIZA 56401.0 melanjutkan_studi 0 wiraswasta ksp jaya makmur C2 False
360 E32200536 ARFENDI PERMANA 56401.0 melanjutkan_studi 0 wiraswasta rofiq farm C2 False
361 E31201237 DYAS OCTA VIOLA 57401.0 bekerja 0 perintah basma olshopid C2 False
362 E32200614 AHMAD FAISOL 56401.0 bekerja 0 bnpp dinas tani pangan kabupaten banyuwangi C0 True wan
363 E31200837 DESIANA SILVIA RAMADANI 57401.0 wiraswasta 0 wiraswasta grant surya pondasi C2 False
364 E31202490 ADRIAN MEDTIYU NUR ARIFIN 57401.0 bekerja 0 swasta online shop jual pulsa C2 False
365 E32202011 MOHAMMAD AZWAR ANAS 56401.0 wiraswasta 2 wiraswasta ketik C2 False
366 E41191369 OKTAFIAN DWI CAHYONO 55301.0 bekerja 0 bnpp rsud gambir C2 False
367 E41190986 IPHANG RERE ADMAJA 55301.0 melanjutkan_studi 3 swasta indosat tbk C2 False
368 E41192426 MUHAMMAD SYARIF JANURIANSYAH 55301.0 bekerja 0 perintah puskesmas leces C2 False
369 E31202523 MOCHAMMAD ANDIKA ALSABFANDI 57401.0 bekerja 3 swasta bangun tani C2 False
370 E31201422 FIRMAN RIZKY FIRDAUS 57401.0 bekerja 2 wiraswasta caldera party planner C2 False
371 E32200618 WATI DARMAWAN 56401.0 bekerja 0 wiraswasta bank C2 False
372 E32202311 MUHAMMAD FARRAS WIRAWAN 56401.0 melanjutkan_studi 3 swasta fidjijaya C2 False
373 E41190322 Kana Farira Salsabila 55301.0 bekerja 0 perintah dinas tani pangan C2 False
374 E41191445 NAUFAL MAHDI RAHMAN UBAID 55301.0 bekerja 3 swasta mbah jan farm C2 False
375 E31201095 FITRI ARISKA 57401.0 bekerja 3 swasta suitmedia C1 False
376 E41192342 FAHREZA MAULANA WISNU WARDANA 55301.0 bekerja 0 swasta labbola sport statistic and data management C1 False
377 E41191325 WIDYA YURISTIKA OKTAVIA 55301.0 bekerja 0 wiraswasta dolan tour and travel C2 False
378 E32201384 BAYU SEPTIAN ADHI PRADANA 56401.0 bekerja 0 perintah rafli putra C2 False
379 E41191240 MOCHAMMAD FAJAR FITRIAN NURBAYU 55301.0 bekerja 3 swasta bpn C2 False
380 E32201402 ANJAR FITRIA 56401.0 melanjutkan_studi 3 swasta invi creative C2 False
381 E31201199 AJENG NUR KHORISA 57401.0 wiraswasta 0 bumn kusuma dinasastri wisatajaya C2 False
382 E41191558 AKHMAD NUR HIDAYATULLOH 55301.0 bekerja 0 bumn fkp maju C2 False
383 E41191157 MUHAMMAD AFDAL ZIKRI 55301.0 melanjutkan_studi 0 perintah klinik mitra sehat C1 False
384 E41192428 MUHAMMAD RIADI PRASETYO 55301.0 bekerja 0 wiraswasta purnama indonesia C2 False
385 E31201228 MOHAMAD RAFLI CAHAYA MAHENDRA 57401.0 bekerja 0 bumn asuransi central asia aca C2 False
386 E41190934 HAYUNG DEWANTO 55301.0 bekerja 0 swasta kantor balai desa bandarasri C2 False
387 E32202313 ALDO BAGAS SEPTYAWAN 56401.0 melanjutkan_studi 0 swasta bank rakyat indonesia C2 False
388 E32201641 AHMAD ASRORI 56401.0 bekerja 2 wiraswasta ppah mayapaga C2 False
389 E41191206 FITROH FATHUR ROHMAN 55301.0 bekerja 2 wiraswasta rifa offset C2 False
390 E41191132 SHOVI IMANY WARDIANA 55301.0 bekerja 3 swasta amat indonesia C2 False
391 E32200057 SEAN ARRAFES 56401.0 bekerja 0 bumn bank bni C2 False
392 E41191133 SHENILA LETISHYA RAMONA 55301.0 bekerja 1 bumn politeknik negeri jember C1 False
393 E41190878 MOCH. FAHRONY 55301.0 bekerja 0 perintah jaya sejahtera C2 False
394 E32200950 MOCHAMMAD REFLY AGUSTINO 56401.0 bekerja 0 perintah rumah produksi bordir selempangwisuda C2 False
395 E41191823 Adam Muhammad 55301.0 bekerja 0 nirlaba ptpn asembagus C2 False
396 E32200305 DZAKI JOMAN 56401.0 bekerja 0 wiraswasta event organizer C2 False
397 E32201058 MOCH. AL-FEND LABBIB 56401.0 bekerja 1 bnpp smk negeri jember C2 False
398 E32201216 EDO YUDHISTIRA PRATAMA 56401.0 bekerja 0 wiraswasta utrani farm C2 False
399 E32201586 NOVITA HESTI WULANSARI 56401.0 bekerja 3 swasta manik jaya C2 False
400 E31200102 Haris Faqih Darmawan 57401.0 bekerja 0 bnpp hutan C2 False
401 E31200864 NADILA DEVI TSABITA 57401.0 bekerja 0 wiraswasta dinas tahan kabupaten probolinggo C2 False
402 E41191343 REXY SOLEHUDIN ABDI HOLILI 55301.0 bekerja 1 wiraswasta sekolah perempuan jember C2 False
403 E31200284 NURLITA AYU RAKHMAWATI 57401.0 bekerja 0 bumn yourflorist C2 False
404 E31200251 M. BASAR RISKI 57401.0 bekerja 0 perintah bank bca C2 False
405 E41192340 BAGUS BACHTIAR RIZKI 55301.0 bekerja 0 wiraswasta sumber rezeki C2 False
406 E41190645 HENRY MURDIFUL ULYA HILMA PUTRA 55301.0 bekerja 3 swasta cita alam nusantara C1 False
407 E31201390 LIUTANTRI HOBIOLA 57401.0 melanjutkan_studi 0 swasta dinas pariwisata kabupaten lumajang C2 False
408 E41192366 MUHAMMAD AUDINO FAKHRI ARNANDYA 55301.0 bekerja 3 swasta unilever C2 False
409 E31200356 YOGA SAPUTRA R. 57401.0 wiraswasta 0 swasta dinas tani C2 False
410 E32201197 MIRZANDO DIRGANTAKA 56401.0 bekerja 0 bumn permana sound C2 False
411 E41191725 FITRIYAH AYU NINGSIH 55301.0 bekerja 0 wiraswasta mediatama group C2 False
412 E31202562 ZALFA ALIF NABILLA 57401.0 bekerja 0 swasta dinas tani pangan banyuwangi C2 False
413 E32201063 WAHYU RAHMATULLAH 56401.0 bekerja 0 bumn wirausaha rumah C2 False
414 E31200245 NUR LAILI WAHYUNINGTIAS 57401.0 bekerja 3 swasta terna C2 False
415 E41190391 RIZKYU ZAM ZAMI 55301.0 wiraswasta 0 swasta tretes view hotel C2 False
416 E32201430 ACHMAD RIZKY RAMADHANI 56401.0 melanjutkan_studi 3 swasta ichwan production C0 True wan
417 E41191868 NUR MUHAMMAD SYAHBANA R 55301.0 bekerja 3 swasta pama persada C2 False
418 E31201470 BEFRIL RENFILIANI SYAFITRI 57401.0 melanjutkan_studi 0 perintah rsud pasirian C2 False
419 E41190452 HAQIQI AHMAD SALMAN ALFARISI 55301.0 bekerja 0 wiraswasta semesta cipta lab C2 False
420 E32200040 DWI ARIF RAHMAN 56401.0 bekerja 0 bnpp igg C2 False
421 E41191902 FAIZ IQBAL DARMAWAN 55301.0 bekerja 3 swasta tani C2 False
422 E32201000 Rico Wildany Nasharillah 56401.0 bekerja 0 perintah pltu paiton C1 False
423 E32200185 BAYU CAHYA KHURNIA YUDHA 56401.0 bekerja 0 bumn bibit hortikultura sejahtera C1 False
424 E31202536 FADILAH NUR HAMSAH 57401.0 bekerja 0 wiraswasta badan pusat statistik regsosek C2 False
425 E32200069 VENTI WELIANA 56401.0 bekerja 0 perintah bumn C2 False
426 E31200997 FAJAR FITRA ABADI 57401.0 bekerja 0 nirlaba ytl C2 False
427 E31190748 KHOLIZAH RIFKA ATUL AIDA 57401.0 bekerja 2 wiraswasta krips C2 False
428 E32200589 SEPTIANANDA RIFQI NURHIDAYAT 56401.0 melanjutkan_studi 0 perintah bkpsdm kab jember C2 False
429 E31202394 DEVA ANGELA SABILA SASKI 57401.0 bekerja 0 perintah ptpn xii pandjie C2 False
430 E32201187 GHULAM MAULANA FAHRI 56401.0 bekerja 3 swasta freelance C0 True lan
431 E31201794 RAHMA ROMADONA AYU RISWANTI 57401.0 bekerja 1 bumn politeknik negeri jember C1 False
432 E31201365 HAMID RAFIUD DERAJAD 57401.0 bekerja 0 swasta jawa timur park C2 False
433 E32201075 UMARUL FARUQ 56401.0 bekerja 0 wiraswasta surya energi C2 False
434 E31200827 TANTRIA AGUSTINA YUDIANTI 57401.0 melanjutkan_studi 0 bumn jack koi C2 False
435 E31192328 DIMAS ARDIANA WIDODO 57401.0 bekerja 1 wiraswasta sablon jember C2 False
436 E32201483 NIASTI AL FAUZIAH LASE 56401.0 melanjutkan_studi 3 swasta toko berkah C2 False
437 E32202503 ACHMAD ALFITRI MULYAWAN 56401.0 melanjutkan_studi 0 perintah sawah C2 False
438 E31200649 WILDA WAHDANIA 57401.0 bekerja 3 swasta humma farm C2 False
439 E41190298 RAIHAN DIMAS ARIFIN 55301.0 bekerja 3 swasta healthy food jember C2 False
440 E32201290 HELLEN PUTRI ANDINI 56401.0 bekerja 0 wiraswasta jaya makmur C2 False
441 E41190868 Tegar Shallahudin Al Ayubi 55301.0 bekerja 3 swasta marvel secondshoes C2 False
442 E32202484 MUHAMMAD ILHAM YUAL MAULANA 56401.0 melanjutkan_studi 3 swasta sumaryonofarm C2 False
443 E32201964 MUHAMAD BAYU CANDRA PAMUNGKAS 56401.0 melanjutkan_studi 0 wiraswasta dinas tani pangan C2 False
444 E31201009 WANDA ARVANIYAN 57401.0 bekerja 0 swasta rumah sakit C1 False
445 E32201330 RIZKI DWI CAHYO PUTRO 55301.0 bekerja 0 bumn smk negeri puspo C2 False
446 E32201406 RIZAL ACHMAD PAHLEVI 56401.0 bekerja 0 wiraswasta rumah sakit C1 False
447 E32201506 ZAHROTUL ISTIQOMAH 56401.0 melanjutkan_studi 3 swasta ahmad kembang ban C2 False
448 E32201397 RISQI RIDHOLLAH ANAM 56401.0 bekerja 0 wiraswasta kamajaya motor C2 False
449 E32201498 Rizqi Ramadani 56401.0 bekerja 0 wiraswasta jember futura energi C2 False
450 E32200753 Anang Prayoga 56401.0 bekerja 0 bumn audio C2 False
451 E31200822 RAYNALDI WIBOWO 57401.0 bekerja 0 perintah kopi paste C2 False
452 E32200499 DINA PERMATA SARI 56401.0 bekerja 0 wiraswasta pemda kab bondowoso C2 False
453 E32201585 ADIS WIDYA RAMADHAN 56401.0 bekerja 3 swasta puskesmas C2 False
454 E32201239 MOCHAMMAD FERDIANTO 56401.0 melanjutkan_studi 3 swasta klinik C2 False
455 E31202463 RISMA DEWI SEPTIANI 57401.0 bekerja 3 swasta hrb cargo C2 False
456 E31201773 ARDYAS SETYA NUGRAHA 57401.0 bekerja 2 wiraswasta depot jamu har C2 False
457 E31201459 FIKRIATUL ILMI 57401.0 bekerja 3 swasta buma C2 False
458 E41192181 RAHADYAN DARARI FEBRIYANTO 55301.0 bekerja 0 swasta benih citra asia C1 False
459 E41191832 ALFIAN SEPTY CHANDRA WIJANARKO 55301.0 bekerja 0 swasta jaya makmur C2 False
460 E31191228 MOCHAMMAD RIZKI PRATAMA 57401.0 bekerja 0 swasta android developer web developer game tester C0 True developer, web
461 E31200784 ALIF ANFALUL HAKIM 57401.0 melanjutkan_studi 0 nirlaba rsud lasinrang kabupaten pinrang C2 False
462 E32201131 YUSUF MUHAMMAD FAQIH 56401.0 bekerja 0 bumn gading indonesia teguh C2 False
463 E41192173 MAULANA SULTAN RAGIL WAHYU SYAHPUTRA 55301.0 bekerja 0 wiraswasta pilarmedia indonesia contract C2 False
464 E41191668 MIFTAHUL RIZKY ZAMZAMI 55301.0 bekerja 0 swasta pusat latih tani desa swadaya p4s bintang tani sejahtera C2 False
465 E31202318 NOFAIRA AMIN 57401.0 melanjutkan_studi 0 swasta research and development austindo nusantara jaya tbk C2 False
466 E32200998 SANDY ASAHI 56401.0 bekerja 0 nirlaba full stack developer pilarmedia indonesia C1 False
467 E31202279 RAMA SATRIA MALAMO 57401.0 bekerja 2 wiraswasta gogrin C2 False
468 E31201690 NUR AFIFAH 57401.0 bekerja 0 swasta piranhamas group C2 False
469 E41192294 ADITYA SETYA NUGRAHA 55301.0 melanjutkan_studi 0 perintah kominfo C2 False
470 E32200197 RIZQI NOOR FAIDZIIN 56401.0 wiraswasta 0 wiraswasta badan dapat daerah kabupaten bondowoso C2 False
471 E31201536 FIRDA ULFA UNSILAH 57401.0 bekerja 0 bnpp arjuna distributor nestle C2 False
472 E31200117 DICKA CAHYA PUTRI 57401.0 bekerja 0 wiraswasta tani persero C2 False
473 E31201372 MUHAMMAD ARIF BILLAH 57401.0 bekerja 3 swasta reseller serizshopjember freelance C2 False
474 E31201555 REHAN REZA MAHENDRA 57401.0 bekerja 0 swasta koperasi tarutama nusantara C2 False
475 E31201431 FANISA NUR ARIFAH 57401.0 bekerja 0 wiraswasta labbola sport statistic and data management C1 False
476 E31201951 MASITHA SAVIRA 57401.0 bekerja 0 bumn kebun nusantara C2 False
477 E32200423 LELI FAUZIYAH 56401.0 bekerja 0 bumn wiraswasta C2 False
478 E32201639 SEFHIANA PUTRI WULANDARI 56401.0 bekerja 2 wiraswasta handoyo budi orchids C2 False
479 E31190508 ALFAN ABRAR ARIFIN 57401.0 bekerja 2 wiraswasta wakil direktur kurnia C2 False
480 E41190510 SYAUGI SALIM AMAR 55301.0 bekerja 0 wiraswasta project engineer etrama nusa energi C0 True engineer
481 E32200199 ILHAM TAUFIQUL KHALIQ 56401.0 bekerja 0 bumn lumbung stroberi C2 False
482 E32200838 ZAINUR ROZIQIN 56401.0 bekerja 0 swasta rumah sakit kebun kabupaten jember C1 False
483 E31202345 FATHUR ROCHMAN ZAINUL 57401.0 bekerja 1 perintah rumkit iii baladhika husada jember C1 False
484 E41180679 MOCHAMAD SATRIA MAULANA 55301.0 bekerja 0 bnpp freelance C2 False
485 E32202534 MOH. ANANG EFENDI 56401.0 bekerja 0 bumn pusat teliti kopi kakao indonesia C1 False
486 E32200600 Feri Andika 56401.0 bekerja 0 perintah ptpn kaliselogiri banyuwangi C0 True wan
487 E32201579 Brenda Gusti Dharma 56401.0 bekerja 3 swasta resty nur C2 False
488 E32200776 GIANT PAUL IVAN 56401.0 bekerja 0 perintah dinas budaya pariwisata kabupaten banyuwangi C0 True wan
489 E32200848 VICO SEPTIANDA PRATAMA 56401.0 wiraswasta 0 wiraswasta maestro group jember C2 False
490 E32200765 Ghovi Tri Yulihandika 56401.0 wiraswasta 2 wiraswasta talas eksportir C2 False
491 E32202496 FAIZ NUR ACHMADI 56401.0 bekerja 0 perintah icon C2 False
492 E32201958 MUHAMMAD QODRI 56401.0 bekerja 0 bumn bulog C2 False
493 E32202582 Yeferi Karoba 56401.0 bekerja 0 perintah kantor distrik eragayam kabupaten mamberamo tengah papua C2 False
494 E32192485 ALFAN ANAS MUHLISIN 55301.0 bekerja 0 perintah terna C2 False
495 E31192286 Melinda Fitriyani 57401.0 wiraswasta 0 bnpp dinas tenaga kerja C2 False
496 E41191422 Alvin Eko Cahyo Febrianto 55301.0 bekerja 3 swasta impactbyte teknologi edukasi skilvul C1 False
497 E41182123 CHIKITA PUTRI MEIDINASARI 55301.0 bekerja 0 swasta karya citra bangun persada utama C1 False
498 E32200651 MUHAMMAD FADLI ZAKARIA 56401.0 bekerja 0 bumn pln icon pllus C2 False
499 E41191034 MUHAMMAD RAIHAN RIYADY 55301.0 bekerja 3 swasta dankom mitra abadi C1 False
500 E41192199 RIZDKY OKTAVIARI PRATAMA PUTRA 55301.0 bekerja 3 swasta infimedia solusi pratama C2 False
501 E31200238 JALALUDDIN ABIMANYU 57401.0 bekerja 3 swasta bpjs sehat C2 False
502 E41192160 SOFYAN ARIF AF RIZAL 55301.0 bekerja 0 bumn bank rakyat indonesia cabang bondowoso C2 False
503 E31202278 CHAIDAR SA’AD 57401.0 bekerja 3 swasta percie C2 False
504 E31201056 DIELLA AULIA IVANA PUTRI 57401.0 bekerja 0 wiraswasta padma jaya C2 False
505 E31200973 DEVI ARYANING TYAS 57401.0 bekerja 3 swasta esolusindo C2 False
506 E41192433 MITA UNZIYAH FAJRINA 55301.0 bekerja 3 swasta koltiva C2 False
507 E41192330 ILMI AZMI IRADIYAH 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
508 E41192348 SINDI MEGA SEPTIANDARI 55301.0 bekerja 0 bnpp durrotul hikmah islamic school C2 False
509 E41191224 FERRY SEPTIAN FERDIYANTO 55301.0 bekerja 3 swasta indoprima gemilang C2 False
510 E31200844 Lukman Afandi 57401.0 bekerja 3 swasta fokus jasa mitra C1 False
511 E41191741 EZRA ALANNATHANIEL 55301.0 bekerja 3 swasta bca C2 False
512 E41180808 Eva Agustin Rahayu 55301.0 wiraswasta 0 wiraswasta pusat teliti kopi kakao indonesia C1 False
513 E41190899 Mohammad Haerul Anam 55301.0 bekerja 0 swasta bejana investidata globalindo bigio C1 False
514 E41190441 Sinta Nuriyah Wulandari 55301.0 bekerja 0 swasta bejana investidata globalindo C1 False
515 E41182137 Tahajjudin Fajri 55301.0 wiraswasta 2 wiraswasta taarts animation C2 False
516 E41212489 BANGKIT BUDI UTOMO 55301.0 bekerja 1 perintah politeknik negeri jember C1 False
517 E41212482 Masrifatul Hazijah 55301.0 bekerja 0 perintah labuh ikan nusantara pengambengan jembrana bal C2 False
518 E41191458 HANIF SATRIO RIMAMTOMO 55301.0 bekerja 0 perintah dinas tani pangan C2 False
519 E32200508 PUTRI LATIFATUS SALAMAH 56401.0 bekerja 0 swasta orindo alam ayu oriflame supranusa indogita manufaktur freelancer pribadi asisten manager evaluator klinik jurnal capa C0 True lan
520 E31201939 NUR ACHMAD FAISOL QUBRO 57401.0 bekerja 0 swasta sygenta seed indonesia C2 False
521 E31160678 RIZKA NURUL KHAKIKI 57401.0 bekerja -1 swasta C3 False
522 E41150211 DEWI AYU ITIKAF 55301.0 mencari_kerja -1 C3 False
523 E31151401 Aza Pascaeka 57401.0 belum_kerja -1 wiraswasta C3 False
524 E31130845 MOCH. RIVALDI AFTONI 57401.0 bekerja -1 lain C3 False
525 E31160328 Afega Wira Pradana 57401.0 bekerja -1 swasta C3 False
526 E31161719 Reza Septia Safirah 57401.0 belum_kerja -1 wiraswasta C3 False
527 E32160904 ONGKY OKTAFIAN DWI JOHANSYAH 56401.0 bekerja -1 swasta C3 False
528 E41150068 MUHAMMAD HAFIDH FIRMANSYAH 55301.0 bekerja -1 lain C3 False
529 E41151584 Risqi Ahmad Sultoni 55301.0 bekerja -1 swasta C3 False
530 E31151214 Nita Wahyu Lianti 57401.0 belum_kerja -1 wiraswasta C3 False
531 E31160306 Faiqotul Hikmah 57401.0 bekerja -1 swasta C3 False
532 E41170333 CICILIA SELVY ERIANTHY 55301.0 wiraswasta -1 wiraswasta C3 False
533 E31182203 Rofi Berliana Mahanani 57401.0 melanjutkan_studi -1 swasta C3 False
534 E32180554 Akhmad Farizi 56401.0 melanjutkan_studi -1 swasta C3 False
535 E41170562 KRISOPRAS EPIKUROS 55301.0 wiraswasta -1 swasta C3 False
536 E32182061 OZSA DEWANGGA PRADANA 56401.0 melanjutkan_studi -1 bnpp C3 False

View File

@ -0,0 +1,153 @@
{
"total": 535,
"distribusi_kategori": {
"C0": {
"jumlah": 18,
"persentase": 3.36
},
"C1": {
"jumlah": 85,
"persentase": 15.89
},
"C2": {
"jumlah": 416,
"persentase": 77.76
},
"C3": {
"jumlah": 16,
"persentase": 2.99
}
},
"distribusi_prodi": {
"TIF": {
"C0": {
"jumlah": 5,
"persentase": 2.22
},
"C1": {
"jumlah": 53,
"persentase": 23.56
},
"C2": {
"jumlah": 162,
"persentase": 72.0
},
"C3": {
"jumlah": 5,
"persentase": 2.22
}
},
"MIF": {
"C0": {
"jumlah": 3,
"persentase": 1.82
},
"C1": {
"jumlah": 20,
"persentase": 12.12
},
"C2": {
"jumlah": 134,
"persentase": 81.21
},
"C3": {
"jumlah": 8,
"persentase": 4.85
}
},
"TKK": {
"C0": {
"jumlah": 10,
"persentase": 6.9
},
"C1": {
"jumlah": 12,
"persentase": 8.28
},
"C2": {
"jumlah": 120,
"persentase": 82.76
},
"C3": {
"jumlah": 3,
"persentase": 2.07
}
}
},
"match_rate": {
"TIF": {
"match": 5,
"total": 225,
"rate": 2.22
},
"MIF": {
"match": 3,
"total": 165,
"rate": 1.82
},
"TKK": {
"match": 10,
"total": 145,
"rate": 6.9
}
},
"detail_per_kategori": {
"C0": {
"jumlah": 18,
"persentase": 3.36,
"sample_names": [
"Ahmad Syamsul Arifin",
"SANDY KURNIAWAN",
"BAWIK ARDIYAN RAMADHAN",
"DEWI RATIH TILAMSARI WIBOWO",
"BONDAN YUWONO PUTRA"
],
"top_keywords": {
"wan": 5,
"tech": 4,
"lan": 4,
"bi": 2,
"komputer": 1,
"developer": 1,
"web": 1,
"engineer": 1
}
},
"C1": {
"jumlah": 85,
"persentase": 15.89,
"sample_names": [
"Yunita Dwi Pujianti",
"Rikky Ihza Pratama",
"RENDHY PRATAMA PUTRA",
"DENNY SETIADY PRABOWO",
"KHOSNOL KHOTIMATUL ARIFAH"
],
"top_keywords": {}
},
"C2": {
"jumlah": 416,
"persentase": 77.76,
"sample_names": [
"Rizki Firmansyah",
"Afrizal Gita Putra Laksono",
"Lilik Widayanti",
"LUKMAN HARUN",
"DAVID SUGIANTO"
],
"top_keywords": {}
},
"C3": {
"jumlah": 16,
"persentase": 2.99,
"sample_names": [
"RIZKA NURUL KHAKIKI",
"DEWI AYU ITIKAF",
"Aza Pascaeka",
"MOCH. RIVALDI AFTONI",
"Afega Wira Pradana"
],
"top_keywords": {}
}
}
}

View File

@ -0,0 +1,14 @@
============================================================
INTERPRETASI CLUSTER -> C0-C3
Tanggal: 2026-08-28 03:51:35
============================================================
Total Alumni: 535
Distribusi Kategori:
C0: 18 (3.36%)
C1: 85 (15.89%)
C2: 416 (77.76%)
C3: 16 (2.99%)
============================================================

View File

@ -0,0 +1,32 @@
{
"model_version": "20260828_042742",
"k": 4,
"inertia": 893.8856227132463,
"silhouette_score": 0.1033661431743342,
"n_samples": 1114,
"n_features": 500,
"evaluation": {
"k_candidates": [
2,
3,
4,
5,
6
],
"inertias": [
992.5189870879342,
937.512241306878,
893.8856227132463,
868.6311058599106,
854.480705314767
],
"silhouettes": [
0.059478779017896076,
0.08331269132070036,
0.1033661431743342,
0.11510910180812096,
0.11539212263526002
]
},
"created_at": "2026-08-28 04:27:42"
}

View File

@ -0,0 +1,27 @@
{
"tanggal": "2026-08-28 04:27:22",
"total_alumni": 1596,
"total_untuk_clustering": 1114,
"total_c3": 482,
"sastrawi_available": true,
"distribusi_status": {
"bekerja": 877,
"mencari_kerja": 304,
"wiraswasta": 161,
"melanjutkan_studi": 157,
"belum_kerja": 97
},
"distribusi_prodi": {
"55301": 347,
"57401": 236,
"56401": 194,
"Teknik Informatika (55301)": 184,
"21. Teknik Informatika (55301)": 151,
"19. Manajemen Informatika (57401)": 115,
"Teknik Komputer (56401)": 105,
"20. Teknik Komputer (56401)": 101,
"Manajemen Informatika (57401)": 87,
"23. Teknik Informatika Kampus Kab. Sidoarjo (55304)": 40,
"22. Teknik Informatika Kampus Kab. Nganjuk (55302)": 36
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
{
"total": 1596,
"distribusi_kategori": {
"C0": {
"jumlah": 223,
"persentase": 13.97
},
"C1": {
"jumlah": 385,
"persentase": 24.12
},
"C2": {
"jumlah": 506,
"persentase": 31.7
},
"C3": {
"jumlah": 482,
"persentase": 30.2
}
},
"distribusi_prodi": {
"TIF": {
"C0": {
"jumlah": 107,
"persentase": 15.69
},
"C1": {
"jumlah": 167,
"persentase": 24.49
},
"C2": {
"jumlah": 239,
"persentase": 35.04
},
"C3": {
"jumlah": 169,
"persentase": 24.78
}
},
"MIF": {
"C0": {
"jumlah": 56,
"persentase": 12.79
},
"C1": {
"jumlah": 104,
"persentase": 23.74
},
"C2": {
"jumlah": 142,
"persentase": 32.42
},
"C3": {
"jumlah": 136,
"persentase": 31.05
}
},
"TKK": {
"C0": {
"jumlah": 60,
"persentase": 15.0
},
"C1": {
"jumlah": 104,
"persentase": 26.0
},
"C2": {
"jumlah": 114,
"persentase": 28.5
},
"C3": {
"jumlah": 122,
"persentase": 30.5
}
}
},
"match_rate": {
"TIF": {
"match": 107,
"total": 682,
"rate": 15.69
},
"MIF": {
"match": 56,
"total": 438,
"rate": 12.79
},
"TKK": {
"match": 60,
"total": 400,
"rate": 15.0
}
},
"detail_per_kategori": {
"C0": {
"jumlah": 223,
"persentase": 13.97,
"sample_names": [
"Ahmad Syamsul Arifin",
"Dhimas Ulfa Lathifah",
"SANDY KURNIAWAN",
"DEKA PERMANA ALFIANSYAH",
"Dimas Kristanto"
],
"top_keywords": {
"ti": 95,
"it": 75,
"lan": 32,
"tech": 12,
"teknologi": 12,
"web": 9,
"bi": 6,
"developer": 5,
"design": 3,
"engineer": 2
}
},
"C1": {
"jumlah": 385,
"persentase": 24.12,
"sample_names": [
"DAVID SUGIANTO",
"Ayu Diyah Purwanti",
"Yunita Dwi Pujianti",
"MUHAMMAD ALY ROFIE",
"Eka Safitri"
],
"top_keywords": {}
},
"C2": {
"jumlah": 506,
"persentase": 31.7,
"sample_names": [
"Rizki Firmansyah",
"Afrizal Gita Putra Laksono",
"Lilik Widayanti",
"LUKMAN HARUN",
"Mahbubi Ilham Nafiulalam"
],
"top_keywords": {}
},
"C3": {
"jumlah": 482,
"persentase": 30.2,
"sample_names": [
"RIZKA NURUL KHAKIKI",
"DEWI AYU ITIKAF",
"Aza Pascaeka",
"MOCH. RIVALDI AFTONI",
"Afega Wira Pradana"
],
"top_keywords": {}
}
}
}

View File

@ -0,0 +1,14 @@
============================================================
INTERPRETASI CLUSTER -> C0-C3
Tanggal: 2026-08-28 04:48:31
============================================================
Total Alumni: 1596
Distribusi Kategori:
C0: 223 (13.97%)
C1: 385 (24.12%)
C2: 506 (31.7%)
C3: 482 (30.2%)
============================================================

View File

@ -0,0 +1,55 @@
============================================================
MERGE SUMMARY - TRACER STUDY ALUMNI
Tanggal: 2026-08-28 04:25:50
============================================================
>> TOTAL DATA: 1596 alumni
>> Distribusi per Tahun Lulus:
2019.0: 30 alumni
2020.0: 31 alumni
2021.0: 237 alumni
2022.0: 211 alumni
2023.0: 268 alumni
2024.0: 361 alumni
2025.0: 458 alumni
>> Distribusi per Prodi (Kode):
55301: 347 alumni
57401: 236 alumni
56401: 194 alumni
Teknik Informatika (55301): 184 alumni
21. Teknik Informatika (55301): 151 alumni
19. Manajemen Informatika (57401): 115 alumni
Teknik Komputer (56401): 105 alumni
20. Teknik Komputer (56401): 101 alumni
Manajemen Informatika (57401): 87 alumni
23. Teknik Informatika Kampus Kab. Sidoarjo (55304): 40 alumni
22. Teknik Informatika Kampus Kab. Nganjuk (55302): 36 alumni
>> Distribusi Status Pekerjaan:
bekerja: 877 (54.9%)
mencari_kerja: 304 (19.0%)
wiraswasta: 161 (10.1%)
melanjutkan_studi: 157 (9.8%)
belum_kerja: 97 (6.1%)
>> Sumber File:
Data_2024_Tracer_study.csv: 361 alumni
Data_2023_Tracer_study.csv: 268 alumni
Data_2021_Tracer_study.csv: 237 alumni
Data_2022_Tracer_study.csv: 211 alumni
Data_2025_Tracer_study_D4TIF.csv: 166 alumni
Data_2025_Tracer_study_D3MIF.csv: 115 alumni
Data_2025_Tracer_study_D3TKK.csv: 101 alumni
Data_2025_Tracer_study_D4TIFSIDOARJO.csv: 40 alumni
Data_2025_Tracer_study_D4TIFNGANJUK.csv: 36 alumni
Data_2020_Tracer_study.csv: 31 alumni
Data_2019_Tracer_study.csv: 30 alumni
>> Missing Values:
jenis_perusahaan: 231 (14.5%)
nama_perusahaan: 560 (35.1%)
jabatan: 491 (30.8%)
============================================================

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
# Feature Engineering module

View File

@ -0,0 +1,128 @@
"""
TF-IDF Feature Extraction Module
Mengubah teks (posisi pekerjaan, instansi, kompetensi) menjadi representasi numerik menggunakan algoritma TF-IDF (Term Frequency - Inverse Document Frequency).
Nilai bobot TF-IDF merefleksikan seberapa penting suatu kata dalam suatu dokumen relatif terhadap keseluruhan korpus data tracer study.
"""
# Mengimpor modul Any untuk type hint fleksibel
from typing import Any
# Mengimpor class TfidfVectorizer dari scikit-learn untuk proses tokenisasi, penghitungan frekuensi kata, dan pembobotan inverse document frequency
from sklearn.feature_extraction.text import TfidfVectorizer
# Mengimpor pustaka numpy untuk operasi numerik array
import numpy as np
# Mendefinisikan class TfidfExtractor sebagai wrapper class untuk memudahkan penggunaan TF-IDF dalam pipeline klastering
class TfidfExtractor:
"""TF-IDF Vectorizer wrapper untuk keperluan ekstraksi fitur pemodelan clustering"""
# Konstruktor kelas untuk menginisialisasi parameter vektorisasi teks
def __init__(self, max_features: int = 500, ngram_range: tuple = (1, 1), min_df: int = 1, max_df: float = 1.0, **kwargs):
"""
Inisialisasi hyperparameter pembobotan TF-IDF:
Args:
max_features: Jumlah batas kosakata teratas yang akan diikutsertakan sebagai kolom fitur (default: 500 kata paling relevan)
ngram_range: Rentang kombinasi kata, (1, 1) berarti unigram (satu kata per fitur)
min_df: Batas minimum kemunculan kata dalam dokumen agar tidak diabaikan (mengeliminasi kata typo/sangat langka)
max_df: Batas maksimum proporsi dokumen yang memuat kata agar tidak diabaikan (mengeliminasi stopword umum)
**kwargs: Parameter opsional tambahan yang diteruskan langsung ke TfidfVectorizer Scikit-Learn
"""
# Menginstansiasi objek TfidfVectorizer dari Scikit-Learn dengan konfigurasi yang diberikan
self.vectorizer = TfidfVectorizer(
max_features=max_features,
ngram_range=ngram_range,
min_df=min_df,
max_df=max_df,
**kwargs
)
# Menyiapkan variabel untuk menampung matriks fitur numerik hasil transformasi (default None)
self.feature_matrix = None
# Metode fit_transform: Melakukan fitting vocabulary sekaligus mengubah kumpulan dokumen teks menjadi matriks numerik
def fit_transform(self, texts: list) -> Any:
"""
Mempelajari kosakata (vocabulary) dari kumpulan teks masukan dan mentransformasikannya menjadi feature matrix sparse.
Args:
texts: List berisi kumpulan teks string yang sudah dibersihkan (preprocessed text)
Returns:
Matriks numerik berbobot TF-IDF berformat scipy sparse matrix
"""
# Melatih vectorizer dengan korpus data teks masukan sekaligus menghitung nilai TF-IDF untuk setiap dokumen
self.feature_matrix = self.vectorizer.fit_transform(texts)
# Mengembalikan matriks fitur numerik berbobot TF-IDF
return self.feature_matrix
# Metode transform: Mengubah teks dokumen baru menjadi representasi numerik menggunakan kosakata yang sudah dipelajari sebelumnya
def transform(self, texts: list) -> Any:
"""
Mentransformasikan teks baru menggunakan model TF-IDF vectorizer yang sudah dilatih (tanpa mengubah vocabulary).
Args:
texts: List dokumen teks baru yang ingin ditransformasi
Returns:
Matriks numerik berbobot TF-IDF sesuai dengan dimensi kosakata model
"""
# Mentransformasi teks masukan baru menggunakan kamus kata dan bobot IDF yang telah terbentuk
return self.vectorizer.transform(texts)
# Metode untuk mengambil seluruh daftar nama kata unik (fitur) yang terpilih sebagai kolom pada matriks
def get_feature_names(self) -> list:
"""Mendapatkan daftar nama fitur kata unik (vocabulary features) yang digunakan model"""
# Mengembalikan nama-nama fitur kata dalam bentuk list Python
return self.vectorizer.get_feature_names_out().tolist()
# Metode untuk mengetahui jumlah total kosakata unik yang dipelajari oleh model
def get_vocab_size(self) -> int:
"""Mendapatkan total jumlah kosakata unik (vocabulary size) yang terdaftar"""
# Mengembalikan panjang (banyaknya entri) dictionary vocabulary_
return len(self.vectorizer.vocabulary_)
# Metode untuk mendapatkan bobot IDF (Inverse Document Frequency) masing-masing kata
def get_idf(self) -> dict:
"""Mendapatkan skor bobot IDF untuk masing-masing kata dalam bentuk pasangan key-value dictionary"""
# Mengambil daftar nama seluruh fitur kata
feature_names = self.get_feature_names()
# Menggabungkan nama fitur dengan nilai bobot idf_ menggunakan zip dan mengonversinya menjadi dictionary Python
return dict(zip(feature_names, self.vectorizer.idf_))
# Fungsi utilitas pembantu (helper function) untuk membangun feature matrix secara ringkas dalam satu pemanggilan
def create_feature_matrix(texts: list, **kwargs) -> tuple:
"""
Fungsi pembantu sekali panggil untuk memproses teks mentah menjadi matriks fitur TF-IDF.
Args:
texts: List kumpulan dokumen teks hasil praproses
**kwargs: Argumen konfigurasi tambahan untuk TfidfExtractor
Returns:
Tuple 3 elemen berisi: (feature_matrix, daftar_nama_fitur, instance_extractor)
"""
# Menginisialisasi instance ekstraktor TF-IDF dengan parameter kwargs
extractor = TfidfExtractor(**kwargs)
# Melakukan fitting dan transformasi teks menjadi matriks fitur
matrix = extractor.fit_transform(texts)
# Mengembalikan matriks bobot TF-IDF, daftar nama kosakata fitur, dan objek extractor
return matrix, extractor.get_feature_names(), extractor
# Blok pengetesan lokal modul yang hanya dijalankan ketika file ini dieksekusi langsung
if __name__ == "__main__":
# Menyiapkan sampel kalimat tiruan untuk menguji proses vektorisasi teks
sample_texts = [
"software engineer developer",
"data analyst scientist",
"project manager leader"
]
# Menjalankan fungsi create_feature_matrix pada sampel teks
matrix, features, extractor = create_feature_matrix(sample_texts)
# Menampilkan dimensi baris dan kolom matriks fitur (jumlah dokumen x jumlah kosakata)
print(f"Feature Matrix Shape: {matrix.shape}")
# Menampilkan seluruh nama fitur kata yang diekstraksi
print(f"Features: {features}")

219
Backend/Model/main.py Normal file
View File

@ -0,0 +1,219 @@
"""
Main ML Pipeline
Pipeline utama untuk clustering alumni
"""
import pandas as pd
import numpy as np
import json
from pathlib import Path
from .preprocessing.text_preprocessing import preprocess_text
from .feature_engineering.tfidf import TfidfExtractor
from .clustering.kmeans import KMeansClustering, find_optimal_k, get_cluster_summary
class AlumniClusteringPipeline:
"""
Pipeline utama untuk clustering alumni
Input: DataFrame dengan kolom ['nama', 'perusahaan', 'jabatan']
Output: DataFrame dengan kolom tambahan 'cluster'
"""
def __init__(self, n_clusters: int = 3, auto_k: bool = False):
"""
Args:
n_clusters: Jumlah cluster (diabaikan jika auto_k=True)
auto_k: Jika True, cari k optimal secara otomatis
"""
self.n_clusters = n_clusters
self.auto_k = auto_k
self.tfidf = None
self.kmeans = None
self.feature_names = None
def _combine_text(self, df: pd.DataFrame) -> list:
"""Menggabungkan kolom teks menjadi satu"""
combined = df['perusahaan'].fillna('') + ' ' + df['jabatan'].fillna('')
return combined.tolist()
def _preprocess_all(self, texts: list) -> list:
"""Preprocess semua teks"""
return [preprocess_text(t) for t in texts]
def fit(self, df: pd.DataFrame) -> 'AlumniClusteringPipeline':
"""
Fit pipeline ke data training
Args:
df: DataFrame dengan kolom ['nama', 'perusahaan', 'jabatan']
Returns:
self
"""
# Combine text
combined_texts = self._combine_text(df)
# Preprocess
processed_texts = self._preprocess_all(combined_texts)
# TF-IDF
self.tfidf = TfidfExtractor(max_features=500)
feature_matrix = self.tfidf.fit_transform(processed_texts)
self.feature_names = self.tfidf.get_feature_names()
# K-Means
n_clusters = self.n_clusters
if self.auto_k:
# Find optimal k
results = find_optimal_k(feature_matrix)
# Ambil k dengan silhouette score tertinggi
best_idx = np.argmax(results['silhouette'])
n_clusters = results['k'][best_idx]
print(f"Optimal K selected: {n_clusters}")
self.kmeans = KMeansClustering(n_clusters=n_clusters)
self.kmeans.fit(feature_matrix)
return self
def transform(self, df: pd.DataFrame) -> pd.DataFrame:
"""
Transform data dengan model yang sudah di-fit
Args:
df: DataFrame dengan kolom ['nama', 'perusahaan', 'jabatan']
Returns:
DataFrame dengan kolom 'cluster' dan 'cluster_label'
"""
if self.kmeans is None:
raise ValueError("Model belum di-fit. Jalankan fit() terlebih dahulu.")
# Combine text
combined_texts = self._combine_text(df)
# Preprocess
processed_texts = self._preprocess_all(combined_texts)
# TF-IDF transform
feature_matrix = self.tfidf.transform(processed_texts)
# Predict
labels = self.kmeans.predict(feature_matrix)
# Add to DataFrame
result = df.copy()
result['cluster'] = labels
result['cluster_label'] = [f"Cluster_{i}" for i in labels]
return result
def fit_transform(self, df: pd.DataFrame) -> pd.DataFrame:
"""Fit dan transform sekaligus"""
return self.fit(df).transform(df)
def get_cluster_summary(self, df: pd.DataFrame) -> dict:
"""Mendapatkan ringkasan cluster"""
if 'cluster' not in df.columns:
raise ValueError("Data belum di-cluster. Jalankan fit_transform() terlebih dahulu.")
return get_cluster_summary(df, df['cluster'].values)
def get_top_features(self, n: int = 10) -> dict:
"""Mendapatkan fitur teratas untuk setiap cluster"""
if self.kmeans is None or self.tfidf is None:
raise ValueError("Model belum di-fit.")
cluster_centers = self.kmeans.model.cluster_centers_
feature_names = self.feature_names
top_features = {}
for i, center in enumerate(cluster_centers):
# Get indices of top features
top_indices = center.argsort()[-n:][::-1]
top_features[f"Cluster_{i}"] = [
{"term": feature_names[idx], "weight": float(center[idx])}
for idx in top_indices
]
return top_features
def save_model(self, filepath: str):
"""Simpan model (placeholder - bisa di-extend dengan joblib)"""
model_data = {
'n_clusters': self.n_clusters,
'feature_names': self.feature_names
}
with open(filepath, 'w') as f:
json.dump(model_data, f)
@staticmethod
def load_model(filepath: str):
"""Load model (placeholder)"""
with open(filepath, 'r') as f:
model_data = json.load(f)
pipeline = AlumniClusteringPipeline(n_clusters=model_data['n_clusters'])
return pipeline
def run_pipeline(data_path: str = None, n_clusters: int = 3, output_path: str = None):
"""
Jalankan pipeline dari command line
Args:
data_path: Path ke file CSV input
n_clusters: Jumlah cluster
output_path: Path untuk menyimpan hasil
"""
# Load data
if data_path:
df = pd.read_csv(data_path)
else:
# Sample data untuk testing
df = pd.DataFrame({
'nama': ['Ali', 'Budi', 'Citra', 'Dewi', 'Eko'],
'perusahaan': ['Google', 'Tokopedia', 'Gojek', 'Traveloka', 'Bukalapak'],
'jabatan': ['Software Engineer', 'Data Analyst', 'Product Manager', 'UX Designer', 'DevOps']
})
print(f"Data loaded: {len(df)} records")
# Run pipeline
pipeline = AlumniClusteringPipeline(n_clusters=n_clusters)
result = pipeline.fit_transform(df)
print(f"\nClustering complete!")
print(f"\nCluster Distribution:")
print(result['cluster_label'].value_counts())
print(f"\nCluster Summary:")
summary = pipeline.get_cluster_summary(result)
for cluster, info in summary.items():
print(f" {cluster}: {info['count']} alumni ({info['percentage']}%)")
print(f"\nTop Features per Cluster:")
top_features = pipeline.get_top_features()
for cluster, features in top_features.items():
print(f" {cluster}: {[f['term'] for f in features[:5]]}")
# Save result
if output_path:
result.to_csv(output_path, index=False)
print(f"\nResult saved to: {output_path}")
return result
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
data_path = sys.argv[1]
n_clusters = int(sys.argv[2]) if len(sys.argv) > 2 else 3
output_path = sys.argv[3] if len(sys.argv) > 3 else None
run_pipeline(data_path, n_clusters, output_path)
else:
run_pipeline()

View File

@ -0,0 +1,270 @@
# 📋 Modul Preprocessing
## Overview
Modul ini berisi pipeline untuk **menyiapkan data tracer study alumni** dari berbagai tahun (2019-2025) agar siap diproses oleh model Machine Learning.
---
## 🎯 Tujuan
1. **Standarisasi Kolom** - Menyamakan kolom berbeda dari berbagai tahun
2. **Menggabungkan Data** - Gabungkan data dari semua tahun jadi satu
3. **Data Cleaning** - Hapus duplikat dan data kosong
4. **Text Preprocessing** - Bersihkan teks untuk TF-IDF
---
## 📁 Struktur File
```
preprocessing/
├── __init__.py # Export modul
├── column_mapping.json # Konfigurasi mapping kolom
├── standarisasi_kolom.py # Fungsi standarisasi
├── text_preprocessing.py # Fungsi preprocessing teks
└── data_pipeline.py # Pipeline lengkap
```
---
## 🔧 Komponen
### 1. KolomStandarisasi
**Fungsi:** Mengubah kolom Excel yang berbeda-beda menjadi kolom STANDAR.
**Kolom Standar:**
| Kolom | Deskripsi |
|-------|-----------|
| `nama` | Nama lengkap alumni |
| `perusahaan` | Nama perusahaan/instansi |
| `jabatan` | Jabatan/posisi |
| `nim` | Nomor Induk Mahasiswa |
**Contoh Penggunaan:**
```python
from preprocessing import KolomStandarisasi
import pandas as pd
# Inisialisasi
std = KolomStandarisasi()
# Baca Excel
df = pd.read_excel("data_2024.xlsx")
# Standarisasi
df_standar = std.standarisasi(df, tahun="2024")
print(df_standar.columns.tolist())
# Output: ['nama', 'perusahaan', 'jabatan', 'nim']
```
---
### 2. DataPipeline
**Fungsi:** Pipeline lengkap dari import sampai siap ML.
**Alur Kerja:**
```
┌────────────────────────────────────────┐
│ STEP 1: Standarisasi Kolom │
│ - Ubah kolom berbeda → kolom standar │
└────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────┐
│ STEP 2: Gabung Data │
│ - Gabungkan data dari semua tahun │
└────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────┐
│ STEP 3: Data Cleaning │
│ - Hapus duplikat │
│ - Hapus data kosong │
└────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────┐
│ STEP 4: Text Preprocessing │
│ - Case folding │
│ - Tokenizing │
│ - Stopword removal │
│ - Stemming │
└────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────┐
│ OUTPUT: Data siap untuk TF-IDF │
└────────────────────────────────────────┘
```
**Contoh Penggunaan:**
```python
from preprocessing import DataPipeline
import pandas as pd
# Inisialisasi
pipeline = DataPipeline()
# Tambah data dari berbagai tahun
pipeline.tambah_data(df_2019, "2019")
pipeline.tambah_data(df_2024, "2024")
# Jalankan pipeline
result = pipeline.jalankan()
print(result.head())
# Output: DataFrame dengan kolom ['nama', 'perusahaan', 'jabatan', 'nim', 'tahun', 'teks_bersih']
```
---
### 3. preprocess_text
**Fungsi:** Membersihkan teks agar siap untuk TF-IDF.
**Proses:**
| Step | Input | Output |
|------|-------|--------|
| Case Folding | "Software Engineer" | "software engineer" |
| Tokenizing | "software engineer" | ["software", "engineer"] |
| Remove Special Chars | ["3", "-", "staff"] | ["staff"] |
| Remove Stopwords | ["di", "google"] | ["google"] |
| Stemming | ["bekerja", "pekerjaan"] | ["kerja", "kerja"] |
**Contoh Penggunaan:**
```python
from preprocessing import preprocess_text
# Input teks mentah
teks = "Google Indonesia 3 - Staff"
# Preprocess
hasil = preprocess_text(teks)
print(hasil)
# Output: "google indonesia staff"
```
---
## 📊 Column Mapping
File `column_mapping.json` berisi mapping dari setiap tahun:
```json
{
"2019": {
"nama": "Nama Lengkap",
"perusahaan": "Perusahaan",
"jabatan": "Jabatan",
"nim": "NIM"
},
"2024": {
"nama": "4. Nama Lengkap / nmmhsmsmh...",
"perusahaan": "9. Apa nama perusahaan...",
"jabatan": "10. Bila Anda berwiraswasta...",
"nim": "3. NIM / nimhsmsmh..."
}
}
```
### ⚠️ Yang Perlu Diisi
Buka setiap file Excel dan catat nama kolom untuk:
| Tahun | Status |
|-------|--------|
| 2019 | ❌ Perlu diisi |
| 2020 | ❌ Perlu diisi |
| 2021 | ❌ Perlu diisi |
| 2022 | ❌ Perlu diisi |
| 2023 | ❌ Perlu diisi |
| 2024 | ✅ Sudah diisi |
| 2025 | ❌ Perlu diisi |
---
## 🚀 Quick Start
### 1. Siapkan Mapping Kolom
```bash
# Buka Excel 2019-2025
# Catat nama kolom untuk: nama, perusahaan, jabatan, nim
# Update column_mapping.json
```
### 2. Jalankan Pipeline
```python
from preprocessing import DataPipeline
# Inisialisasi
pipeline = DataPipeline()
# Tambah data
for tahun in ["2019", "2020", "2021", "2022", "2023", "2024", "2025"]:
df = pd.read_excel(f"data_{tahun}.xlsx")
pipeline.tambah_data(df, tahun)
# Jalankan
result = pipeline.jalankan()
# Simpan hasil
result.to_csv("data_bersih.csv", index=False)
```
---
## 📝 Testing
Jalankan file untuk test:
```bash
cd Model
python preprocessing/standarisasi_kolom.py
python preprocessing/text_preprocessing.py
python preprocessing/data_pipeline.py
```
---
## 🔍 Debugging
### Jika tahun tidak terdeteksi:
```python
# Deteksi manual
std = KolomStandarisasi()
tahun = std.deteksi_tahun(df, nama_file="data_2024.xlsx")
print(f"Tahun: {tahun}")
```
### Jika kolom tidak cocok:
```python
# Lihat mapping yang tersedia
std = KolomStandarisasi()
mapping = std.get_mapping_tahun("2024")
print(mapping)
# Lihat kolom di DataFrame
print(df.columns.tolist())
```
---
## 📚 Referensi
- **NLTK:** https://www.nltk.org/
- **Sastrawi:** https://github.com/har07/PySastrawi
- **Pandas:** https://pandas.pydata.org/

View File

@ -0,0 +1,20 @@
# ============================================================
# PREPROCESSING MODULE
# ============================================================
# Berisi pipeline preprocessing data tracer study alumni
# ============================================================
from .standarisasi_kolom import KolomStandarisasi, gabung_data, bersihkan_data
from .text_preprocessing import preprocess_text, preprocess_dataframe
from .data_pipeline import DataPipeline, proses_file_excel
# Export semua komponen yang dibutuhkan
__all__ = [
'KolomStandarisasi',
'gabung_data',
'bersihkan_data',
'preprocess_text',
'preprocess_dataframe',
'DataPipeline',
'proses_file_excel',
]

View File

@ -0,0 +1,359 @@
"""
=============================================================
TF-IDF & K-MEANS CLUSTERING
=============================================================
Tujuan:
- TF-IDF transformation untuk teks pekerjaan
- K-Means Clustering dengan K=4 (sesuai PRD)
- Evaluasi menggunakan Elbow Method dan Silhouette Score
PRD Reference: Section 14, 15, 16
=============================================================
"""
import pandas as pd
import numpy as np
import json
import os
from datetime import datetime
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# Path configuration
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_INPUT = os.path.join(BASE_DIR, '..', 'data', 'processed', 'dataset_untuk_clustering.csv')
MODEL_OUTPUT = os.path.join(BASE_DIR, '..', 'data', 'processed')
PLOT_OUTPUT = os.path.join(BASE_DIR, '..', 'data', 'processed')
# K yang akan diuji (PRD Section 16.1)
K_CANDIDATES = [2, 3, 4, 5, 6]
FIXED_K = 4 # K=4 sesuai PRD Section 5.4, 15.2
def load_data():
"""Load dataset untuk clustering."""
print(">> Loading dataset untuk clustering...")
df = pd.read_csv(DATA_INPUT, encoding='utf-8-sig')
print(f" Total data: {len(df)} alumni")
return df
def tfidf_vectorization(texts):
"""
TF-IDF transformation.
PRD Section 14:
TF-IDF mengubah teks pekerjaan menjadi feature matrix.
"""
print("\n>> Melakukan TF-IDF Vectorization...")
# TF-IDF Vectorizer
vectorizer = TfidfVectorizer(
max_features=500, # Maksimum 500 fitur
min_df=2, # Minimum document frequency 2
max_df=0.95, # Maximum document frequency 95%
ngram_range=(1, 2), # Unigrams dan bigrams
lowercase=True,
token_pattern=r'\b[a-zA-Z]{2,}\b' # Minimal 2 karakter, hanya alfabet
)
# Fit dan transform
tfidf_matrix = vectorizer.fit_transform(texts)
feature_names = vectorizer.get_feature_names_out()
print(f" TF-IDF Matrix shape: {tfidf_matrix.shape}")
print(f" Number of features: {len(feature_names)}")
print(f" Sample features: {list(feature_names[:10])}...")
return vectorizer, tfidf_matrix, feature_names
def elbow_method(tfidf_matrix, k_range):
"""
Elbow Method untuk menentukan K optimal.
Menghitung inertia/WCSS untuk setiap K.
PRD Section 16.2
"""
print("\n>> Elbow Method Analysis...")
inertias = []
for k in k_range:
print(f" Testing K={k}...", end=" ")
kmeans = KMeans(
n_clusters=k,
init='k-means++',
n_init=10,
max_iter=300,
random_state=42
)
kmeans.fit(tfidf_matrix)
inertias.append(kmeans.inertia_)
print(f"Inertia: {kmeans.inertia_:.2f}")
return inertias
def silhouette_analysis(tfidf_matrix, k_range):
"""
Silhouette Score analysis.
PRD Section 16.3
"""
print("\n>> Silhouette Score Analysis...")
silhouettes = []
for k in k_range:
print(f" Testing K={k}...", end=" ")
kmeans = KMeans(
n_clusters=k,
init='k-means++',
n_init=10,
max_iter=300,
random_state=42
)
labels = kmeans.fit_predict(tfidf_matrix)
# Hitung silhouette score
score = silhouette_score(tfidf_matrix, labels)
silhouettes.append(score)
print(f"Silhouette: {score:.4f}")
return silhouettes
def plot_evaluation(k_range, inertias, silhouettes, output_path):
"""
Plot Elbow Method dan Silhouette Score.
"""
print("\n>> Generating evaluation plots...")
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Elbow Plot
axes[0].plot(k_range, inertias, 'bo-', linewidth=2, markersize=8)
axes[0].axvline(x=FIXED_K, color='r', linestyle='--', label=f'K={FIXED_K} (PRD)')
axes[0].set_xlabel('Number of Clusters (K)', fontsize=12)
axes[0].set_ylabel('Inertia (WCSS)', fontsize=12)
axes[0].set_title('Elbow Method', fontsize=14, fontweight='bold')
axes[0].legend()
axes[0].grid(True, alpha=0.3)
# Silhouette Plot
axes[1].plot(k_range, silhouettes, 'go-', linewidth=2, markersize=8)
axes[1].axvline(x=FIXED_K, color='r', linestyle='--', label=f'K={FIXED_K} (PRD)')
axes[1].set_xlabel('Number of Clusters (K)', fontsize=12)
axes[1].set_ylabel('Silhouette Score', fontsize=12)
axes[1].set_title('Silhouette Score', fontsize=14, fontweight='bold')
axes[1].legend()
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig(os.path.join(output_path, 'evaluation_plots.png'), dpi=150, bbox_inches='tight')
print(f" Plot saved: {output_path}/evaluation_plots.png")
def kmeans_clustering(tfidf_matrix, k, n_init=10):
"""
K-Means Clustering dengan K tetap.
PRD Section 15
"""
print(f"\n>> Running K-Means with K={k}...")
kmeans = KMeans(
n_clusters=k,
init='k-means++',
n_init=n_init,
max_iter=300,
random_state=42
)
cluster_labels = kmeans.fit_predict(tfidf_matrix)
inertia = kmeans.inertia_
# Hitung silhouette score
silhouette = silhouette_score(tfidf_matrix, cluster_labels)
print(f" Inertia: {inertia:.2f}")
print(f" Silhouette Score: {silhouette:.4f}")
return kmeans, cluster_labels, inertia, silhouette
def get_cluster_statistics(df, cluster_labels, vectorizer, feature_names):
"""
Get statistics untuk setiap cluster.
"""
print("\n>> Analyzing cluster statistics...")
df_result = df.copy()
df_result['cluster'] = cluster_labels
stats = {}
for cluster_id in range(FIXED_K):
cluster_data = df_result[df_result['cluster'] == cluster_id]
stats[cluster_id] = {
'jumlah': len(cluster_data),
'persentase': len(cluster_data) / len(df_result) * 100
}
# Top terms dari centroid
centroid = kmeans.cluster_centers_[cluster_id]
top_indices = centroid.argsort()[-10:][::-1]
top_terms = [feature_names[i] for i in top_indices]
stats[cluster_id]['top_terms'] = top_terms
print(f"\n Cluster {cluster_id}:")
print(f" Jumlah: {stats[cluster_id]['jumlah']} ({stats[cluster_id]['persentase']:.1f}%)")
print(f" Top terms: {', '.join(top_terms[:5])}")
return df_result, stats
def save_results(df_result, kmeans, vectorizer, tfidf_matrix, feature_names,
inertia, silhouette, inertias, silhouettes, output_path):
"""
Simpan hasil clustering.
"""
print("\n>> Saving results...")
# 1. Save hasil clustering
clustering_output = os.path.join(output_path, 'clustering_results.csv')
df_result.to_csv(clustering_output, index=False, encoding='utf-8-sig')
print(f" Clustering results: {clustering_output}")
# 2. Save model info
model_info = {
'model_version': datetime.now().strftime('%Y%m%d_%H%M%S'),
'k': FIXED_K,
'inertia': float(inertia),
'silhouette_score': float(silhouette),
'n_samples': len(df_result),
'n_features': len(feature_names),
'evaluation': {
'k_candidates': K_CANDIDATES,
'inertias': [float(i) for i in inertias],
'silhouettes': [float(s) for s in silhouettes]
},
'created_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
model_output = os.path.join(output_path, 'model_info.json')
with open(model_output, 'w', encoding='utf-8') as f:
json.dump(model_info, f, indent=2, ensure_ascii=False)
print(f" Model info: {model_output}")
# 3. Save cluster statistics
cluster_stats_output = os.path.join(output_path, 'cluster_statistics.json')
with open(cluster_stats_output, 'w', encoding='utf-8') as f:
json.dump(cluster_stats, f, indent=2, ensure_ascii=False)
print(f" Cluster statistics: {cluster_stats_output}")
return model_info
def generate_summary(model_info, stats):
"""
Generate summary report.
"""
summary = []
summary.append("=" * 60)
summary.append("CLUSTERING SUMMARY")
summary.append(f"Tanggal: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
summary.append("=" * 60)
summary.append(f"\n[MODEL INFO]")
summary.append(f" K = {model_info['k']} (sesuai PRD)")
summary.append(f" Inertia: {model_info['inertia']:.2f}")
summary.append(f" Silhouette Score: {model_info['silhouette_score']:.4f}")
summary.append(f" Total Samples: {model_info['n_samples']}")
summary.append(f" Total Features: {model_info['n_features']}")
summary.append(f"\n[EVALUATION RESULTS]")
for i, k in enumerate(model_info['evaluation']['k_candidates']):
summary.append(f" K={k}: Inertia={model_info['evaluation']['inertias'][i]:.2f}, "
f"Silhouette={model_info['evaluation']['silhouettes'][i]:.4f}")
summary.append(f"\n[CLUSTER DISTRIBUTION]")
for cluster_id, stat in stats.items():
summary.append(f" Cluster {cluster_id}: {stat['jumlah']} ({stat['persentase']:.1f}%)")
summary.append(f"\n[TOP TERMS PER CLUSTER]")
for cluster_id, stat in stats.items():
summary.append(f" Cluster {cluster_id}: {', '.join(stat['top_terms'][:5])}")
summary.append("\n" + "=" * 60)
return "\n".join(summary)
# Global variable untuk simpan kmeans dan stats
kmeans = None
cluster_stats = None
def main():
"""
Main function untuk TF-IDF dan K-Means Clustering.
"""
global kmeans, cluster_stats
print("=" * 60)
print("TF-IDF & K-MEANS CLUSTERING")
print(f"K = {FIXED_K} (sesuai PRD)")
print("=" * 60)
# 1. Load data
df = load_data()
# 2. TF-IDF Vectorization
texts = df['teks_pekerjaan'].fillna('').tolist()
vectorizer, tfidf_matrix, feature_names = tfidf_vectorization(texts)
# 3. Evaluasi Elbow dan Silhouette
inertias = elbow_method(tfidf_matrix, K_CANDIDATES)
silhouettes = silhouette_analysis(tfidf_matrix, K_CANDIDATES)
# 4. Plot evaluasi
plot_evaluation(K_CANDIDATES, inertias, silhouettes, PLOT_OUTPUT)
# 5. K-Means dengan K=4
kmeans, cluster_labels, inertia, silhouette = kmeans_clustering(tfidf_matrix, FIXED_K)
# 6. Get cluster statistics
df_result, cluster_stats = get_cluster_statistics(df, cluster_labels, vectorizer, feature_names)
# 7. Save results
model_info = save_results(
df_result, kmeans, vectorizer, tfidf_matrix, feature_names,
inertia, silhouette, inertias, silhouettes, MODEL_OUTPUT
)
# 8. Generate summary
summary = generate_summary(model_info, cluster_stats)
print("\n" + summary)
# Save summary
summary_output = os.path.join(MODEL_OUTPUT, 'clustering_summary.txt')
with open(summary_output, 'w', encoding='utf-8') as f:
f.write(summary)
print(f"\n>> Summary saved: {summary_output}")
print("\n" + "=" * 60)
print("[SUCCESS] CLUSTERING SELESAI!")
print("=" * 60)
return df_result, model_info, cluster_stats
if __name__ == "__main__":
df_result, model_info, cluster_stats = main()

View File

@ -0,0 +1,72 @@
{
"2019": {
"kode_prodi": "Kode Prodi",
"nim": "NIM/Nomor Mahasiswa",
"nama": "Nama",
"tahun_lulus": "Tahun Lulus",
"status_pekerjaan": "F8",
"jenis_perusahaan": "F1101",
"nama_perusahaan": "F5b",
"jabatan": "F5c"
},
"2020": {
"kode_prodi": "Kode Prodi",
"nim": "NIM/Nomor Mahasiswa",
"nama": "Nama",
"tahun_lulus": "Tahun Lulus",
"status_pekerjaan": "F8",
"jenis_perusahaan": "F1101",
"nama_perusahaan": "F5b",
"jabatan": "F5c"
},
"2021": {
"kode_prodi": "Kode Prodi",
"nim": "NIM",
"nama": "Nama",
"tahun_lulus": "Tahun Lulus",
"status_pekerjaan": "F8",
"jenis_perusahaan": "F1101",
"nama_perusahaan": "F5b",
"jabatan": "F5c"
},
"2022": {
"kode_prodi": "kdpstmsmh",
"nim": "nimhsmsmh",
"nama": "nmmhsmsmh",
"tahun_lulus": "tahun_lulus",
"status_pekerjaan": "f8",
"jenis_perusahaan": "f1101",
"nama_perusahaan": "f5b",
"jabatan": "f5c"
},
"2023": {
"kode_prodi": "kdpstmsmh",
"nim": "nimhsmsmh",
"nama": "nmmhsmsmh",
"tahun_lulus": "tahun_lulus",
"status_pekerjaan": "f8",
"jenis_perusahaan": "f1101",
"nama_perusahaan": "f5b",
"jabatan": "f5c"
},
"2024": {
"kode_prodi": "2. Kode Program Studi / kdpstmsmh",
"nim": "3. NIM / nimhsmsmh (Gunakan Huruf Besar) ",
"nama": "4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)",
"tahun_lulus": "7. Tahun Lulus / tahun_lulus",
"status_pekerjaan": "1. Jelaskan status Anda saat ini? f8",
"jenis_perusahaan": "8. Apa jenis perusahaan/instansi/institusi tempat anda bekerja sekarang? f1101",
"nama_perusahaan": "9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b",
"jabatan": "10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c"
},
"2025": {
"kode_prodi": "2. Kode Program Studi / kdpstmsmh",
"nim": "3. NIM / nimhsmsmh (Gunakan Huruf Besar) ",
"nama": "4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)",
"tahun_lulus": "7. Tahun Lulus / tahun_lulus",
"status_pekerjaan": "1. Jelaskan status Anda saat ini? f8",
"jenis_perusahaan": "7. Apa jenis perusahaan/instansi/institusi tempat anda bekerja sekarang? f1101",
"nama_perusahaan": "9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b",
"jabatan": "10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c *(Wajib diisi) (Jika Memilih Wiraswasta / Jika f8 adalah 3)"
}
}

View File

@ -0,0 +1,707 @@
"""
=============================================================
DASHBOARD VISUALIZATION
=============================================================
Generate visualisasi untuk hasil clustering alumni:
- Distribusi Kategori C0-C3
- Distribusi per Prodi
- Distribusi per Tahun
- Cluster Analysis
- Pie Charts dan Bar Charts
Output: PNG charts + HTML Dashboard
=============================================================
"""
import pandas as pd
import numpy as np
import json
import os
from datetime import datetime
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import seaborn as sns
# Set style
plt.style.use('seaborn-v0_8-whitegrid')
sns.set_palette("husl")
# Path configuration
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, '..', 'data', 'processed')
RESULT_DIR = os.path.join(BASE_DIR, '..', 'data', 'result')
OUTPUT_DIR = os.path.join(BASE_DIR, '..', 'data', 'processed', 'dashboard')
# Create output directory
os.makedirs(OUTPUT_DIR, exist_ok=True)
# Colors
COLORS = {
'C0': '#2ecc71', # Green - Sesuai Profil
'C1': '#3498db', # Blue - Bidang Diketahui
'C2': '#f39c12', # Orange - Bidang Tidak Jelas
'C3': '#e74c3c', # Red - Belum Bekerja
'TIF': '#9b59b6', # Purple
'MIF': '#1abc9c', # Teal
'TKK': '#e67e22' # Orange
}
def load_data():
"""Load semua data yang diperlukan."""
print(">> Loading data...")
# Interpretasi results (from result folder)
df = pd.read_csv(os.path.join(RESULT_DIR, 'interpretasi_results.csv'), encoding='utf-8-sig')
# Processed dataset
processed_df = pd.read_csv(os.path.join(DATA_DIR, 'processed_dataset.csv'), encoding='utf-8-sig')
# Cluster statistics
with open(os.path.join(DATA_DIR, 'cluster_statistics.json'), 'r') as f:
cluster_stats = json.load(f)
print(f" Total data: {len(df)}")
return df, processed_df, cluster_stats
def create_pie_chart_kategori(df, output_path):
"""Pie chart distribusi kategori C0-C3."""
print(">> Creating Pie Chart - Kategori C0-C3...")
kategori_counts = df['kategori'].value_counts()
labels = kategori_counts.index.tolist()
sizes = kategori_counts.values
colors = [COLORS.get(k, '#95a5a6') for k in labels]
fig, ax = plt.subplots(figsize=(10, 8))
wedges, texts, autotexts = ax.pie(
sizes,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=90,
explode=[0.02] * len(labels)
)
# Style
for autotext in autotexts:
autotext.set_fontsize(12)
autotext.set_fontweight('bold')
ax.set_title('Distribusi Kategori Alumni (C0-C3)\n', fontsize=16, fontweight='bold')
# Add legend
legend_labels = [
f'C0: Sesuai Profil ({kategori_counts.get("C0", 0)})',
f'C1: Bidang Diketahui ({kategori_counts.get("C1", 0)})',
f'C2: Bidang Tidak Jelas ({kategori_counts.get("C2", 0)})',
f'C3: Belum Bekerja ({kategori_counts.get("C3", 0)})'
]
ax.legend(wedges, legend_labels, title="Kategori", loc="center left", bbox_to_anchor=(1, 0, 0.5, 1))
plt.tight_layout()
plt.savefig(output_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
print(f" Saved: {output_path}")
def create_bar_chart_prodi(df, output_path):
"""Bar chart distribusi C0-C3 per prodi."""
print(">> Creating Bar Chart - Distribusi per Prodi...")
# Map prodi codes
prodi_map = {'55301': 'TIF', '57401': 'MIF', '56401': 'TKK'}
df['prodi'] = df['kode_prodi'].astype(str).str.replace('.0', '', regex=False).str.strip()
df['prodi'] = df['prodi'].map(prodi_map).fillna('Lainnya')
# Group by prodi and kategori
grouped = df.groupby(['prodi', 'kategori']).size().unstack(fill_value=0)
fig, ax = plt.subplots(figsize=(12, 7))
categories = ['C0', 'C1', 'C2', 'C3']
colors = [COLORS[c] for c in categories]
x = np.arange(len(grouped.index))
width = 0.2
for i, cat in enumerate(categories):
if cat in grouped.columns:
values = grouped[cat].values
bars = ax.bar(x + i * width, values, width, label=cat, color=colors[i])
# Add value labels
for bar in bars:
height = bar.get_height()
if height > 0:
ax.annotate(f'{int(height)}',
xy=(bar.get_x() + bar.get_width() / 2, height),
xytext=(0, 3),
textcoords="offset points",
ha='center', va='bottom', fontsize=9)
ax.set_xlabel('Program Studi', fontsize=12)
ax.set_ylabel('Jumlah Alumni', fontsize=12)
ax.set_title('Distribusi Kategori C0-C3 per Program Studi\n', fontsize=16, fontweight='bold')
ax.set_xticks(x + width * 1.5)
ax.set_xticklabels(grouped.index)
ax.legend(title='Kategori')
plt.tight_layout()
plt.savefig(output_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
print(f" Saved: {output_path}")
def create_stacked_bar_tahun(df, output_path):
"""Stacked bar chart distribusi per tahun."""
print(">> Creating Stacked Bar - Distribusi per Tahun...")
# Get tahun from processed dataset
processed_df = pd.read_csv(os.path.join(DATA_DIR, 'processed_dataset.csv'), encoding='utf-8-sig')
df = df.merge(processed_df[['nim', 'tahun_lulus']], on='nim', how='left')
# Group by tahun and kategori
grouped = df.groupby(['tahun_lulus', 'kategori']).size().unstack(fill_value=0)
fig, ax = plt.subplots(figsize=(12, 7))
categories = ['C0', 'C1', 'C2', 'C3']
colors = [COLORS[c] for c in categories]
bottom = np.zeros(len(grouped.index))
for i, cat in enumerate(categories):
if cat in grouped.columns:
values = grouped[cat].values
ax.bar(grouped.index.astype(str), values, bottom=bottom, label=cat, color=colors[i])
bottom += values
ax.set_xlabel('Tahun Lulus', fontsize=12)
ax.set_ylabel('Jumlah Alumni', fontsize=12)
ax.set_title('Distribusi Kategori C0-C3 per Tahun Lulus\n', fontsize=16, fontweight='bold')
ax.legend(title='Kategori', loc='upper right')
plt.tight_layout()
plt.savefig(output_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
print(f" Saved: {output_path}")
def create_donut_chart_cluster(df, output_path):
"""Donut chart distribusi cluster."""
print(">> Creating Donut Chart - Distribusi Cluster...")
cluster_counts = df['cluster'].value_counts().sort_index()
fig, ax = plt.subplots(figsize=(10, 8))
colors = ['#3498db', '#2ecc71', '#f39c12', '#9b59b6']
labels = [f'Cluster {i}' for i in cluster_counts.index]
wedges, texts, autotexts = ax.pie(
cluster_counts.values,
labels=labels,
colors=colors,
autopct='%1.1f%%',
startangle=90,
pctdistance=0.75,
explode=[0.02] * len(labels)
)
# Create donut hole
centre_circle = plt.Circle((0, 0), 0.50, fc='white')
ax.add_patch(centre_circle)
# Style
for autotext in autotexts:
autotext.set_fontsize(11)
autotext.set_fontweight('bold')
ax.set_title('Distribusi Cluster K-Means (K=4)\n', fontsize=16, fontweight='bold')
# Add legend
legend_labels = [f'Cluster {i}: {cluster_counts.get(i, 0)}' for i in range(4)]
ax.legend(wedges, legend_labels, title="Cluster", loc="center left", bbox_to_anchor=(1, 0, 0.5, 1))
plt.tight_layout()
plt.savefig(output_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
print(f" Saved: {output_path}")
def create_summary_cards(stats, output_path):
"""Generate summary cards as image."""
print(">> Creating Summary Cards...")
fig, axes = plt.subplots(2, 4, figsize=(16, 8))
fig.patch.set_facecolor('white')
# Total Alumni
ax = axes[0, 0]
ax.text(0.5, 0.7, '535', fontsize=36, ha='center', fontweight='bold', color='#2c3e50')
ax.text(0.5, 0.3, 'Total Alumni', fontsize=12, ha='center', color='#7f8c8d')
ax.axis('off')
# C0
ax = axes[0, 1]
ax.text(0.5, 0.7, '18', fontsize=36, ha='center', fontweight='bold', color=COLORS['C0'])
ax.text(0.5, 0.3, 'C0 - Sesuai Profil', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
# C1
ax = axes[0, 2]
ax.text(0.5, 0.7, '85', fontsize=36, ha='center', fontweight='bold', color=COLORS['C1'])
ax.text(0.5, 0.3, 'C1 - Bidang Diketahui', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
# C2
ax = axes[0, 3]
ax.text(0.5, 0.7, '416', fontsize=36, ha='center', fontweight='bold', color=COLORS['C2'])
ax.text(0.5, 0.3, 'C2 - Bidang Tidak Jelas', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
# C3
ax = axes[1, 0]
ax.text(0.5, 0.7, '16', fontsize=36, ha='center', fontweight='bold', color=COLORS['C3'])
ax.text(0.5, 0.3, 'C3 - Belum Bekerja', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
# TIF
ax = axes[1, 1]
ax.text(0.5, 0.7, '225', fontsize=36, ha='center', fontweight='bold', color=COLORS['TIF'])
ax.text(0.5, 0.3, 'TIF - Teknik Informatika', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
# MIF
ax = axes[1, 2]
ax.text(0.5, 0.7, '165', fontsize=36, ha='center', fontweight='bold', color=COLORS['MIF'])
ax.text(0.5, 0.3, 'MIF - Manajemen Informatika', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
# TKK
ax = axes[1, 3]
ax.text(0.5, 0.7, '145', fontsize=36, ha='center', fontweight='bold', color=COLORS['TKK'])
ax.text(0.5, 0.3, 'TKK - Teknik Komputer', fontsize=10, ha='center', color='#7f8c8d')
ax.axis('off')
plt.suptitle('Dashboard Summary - Sistem Clustering Alumni', fontsize=18, fontweight='bold', y=1.02)
plt.tight_layout()
plt.savefig(output_path, dpi=150, bbox_inches='tight', facecolor='white')
plt.close()
print(f" Saved: {output_path}")
def create_html_dashboard(df, output_path):
"""Generate interactive HTML dashboard."""
print(">> Creating HTML Dashboard...")
# Calculate stats
kategori_counts = df['kategori'].value_counts()
total = len(df)
# Prodi distribution
prodi_map = {'55301': 'TIF', '57401': 'MIF', '56401': 'TKK'}
df['prodi'] = df['kode_prodi'].astype(str).str.replace('.0', '', regex=False).str.strip()
df['prodi'] = df['prodi'].map(prodi_map).fillna('Lainnya')
prodi_counts = df['prodi'].value_counts()
html_content = f"""
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Clustering Alumni - Politeknik Negeri Jember</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
* {{
margin: 0;
padding: 0;
box-sizing: border-box;
}}
body {{
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}}
.container {{
max-width: 1400px;
margin: 0 auto;
}}
.header {{
background: white;
border-radius: 15px;
padding: 30px;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}}
.header h1 {{
color: #2c3e50;
font-size: 28px;
margin-bottom: 10px;
}}
.header p {{
color: #7f8c8d;
font-size: 14px;
}}
.cards {{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 20px;
}}
.card {{
background: white;
border-radius: 15px;
padding: 25px;
text-align: center;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
transition: transform 0.3s;
}}
.card:hover {{
transform: translateY(-5px);
}}
.card-value {{
font-size: 42px;
font-weight: bold;
margin-bottom: 5px;
}}
.card-label {{
font-size: 14px;
color: #7f8c8d;
}}
.card-c0 {{ color: #2ecc71; }}
.card-c1 {{ color: #3498db; }}
.card-c2 {{ color: #f39c12; }}
.card-c3 {{ color: #e74c3c; }}
.card-tif {{ color: #9b59b6; }}
.card-mif {{ color: #1abc9c; }}
.card-tkk {{ color: #e67e22; }}
.grid {{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 20px;
}}
.chart-container {{
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}}
.chart-title {{
font-size: 18px;
font-weight: bold;
color: #2c3e50;
margin-bottom: 20px;
text-align: center;
}}
.chart-wrapper {{
position: relative;
height: 300px;
}}
.definitions {{
background: white;
border-radius: 15px;
padding: 25px;
margin-top: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}}
.definitions h2 {{
color: #2c3e50;
margin-bottom: 15px;
}}
.definition-item {{
display: flex;
align-items: center;
margin-bottom: 12px;
padding: 10px;
border-radius: 8px;
background: #f8f9fa;
}}
.definition-badge {{
padding: 8px 15px;
border-radius: 20px;
font-weight: bold;
color: white;
margin-right: 15px;
min-width: 50px;
text-align: center;
}}
.badge-c0 {{ background: #2ecc71; }}
.badge-c1 {{ background: #3498db; }}
.badge-c2 {{ background: #f39c12; }}
.badge-c3 {{ background: #e74c3c; }}
.footer {{
text-align: center;
margin-top: 30px;
color: white;
font-size: 12px;
}}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Dashboard Clustering Alumni</h1>
<p>Sistem Pengelompokan Pekerjaan Alumni dengan Kompetensi Lulusan - Jurusan Teknologi Informasi, Politeknik Negeri Jember</p>
</div>
<div class="cards">
<div class="card">
<div class="card-value card-tif">{prodi_counts.get('TIF', 0)}</div>
<div class="card-label">Teknik Informatika (TIF)</div>
</div>
<div class="card">
<div class="card-value card-mif">{prodi_counts.get('MIF', 0)}</div>
<div class="card-label">Manajemen Informatika (MIF)</div>
</div>
<div class="card">
<div class="card-value card-tkk">{prodi_counts.get('TKK', 0)}</div>
<div class="card-label">Teknik Komputer (TKK)</div>
</div>
<div class="card">
<div class="card-value" style="color:#2c3e50">{total}</div>
<div class="card-label">Total Alumni</div>
</div>
</div>
<div class="cards">
<div class="card">
<div class="card-value card-c0">{kategori_counts.get('C0', 0)}</div>
<div class="card-label">Sesuai Profil (C0)</div>
</div>
<div class="card">
<div class="card-value card-c1">{kategori_counts.get('C1', 0)}</div>
<div class="card-label">Bidang Diketahui (C1)</div>
</div>
<div class="card">
<div class="card-value card-c2">{kategori_counts.get('C2', 0)}</div>
<div class="card-label">Bidang Tidak Jelas (C2)</div>
</div>
<div class="card">
<div class="card-value card-c3">{kategori_counts.get('C3', 0)}</div>
<div class="card-label">Belum Bekerja (C3)</div>
</div>
</div>
<div class="grid">
<div class="chart-container">
<div class="chart-title">Distribusi Kategori Alumni (C0-C3)</div>
<div class="chart-wrapper">
<canvas id="kategoriChart"></canvas>
</div>
</div>
<div class="chart-container">
<div class="chart-title">Distribusi per Program Studi</div>
<div class="chart-wrapper">
<canvas id="prodiChart"></canvas>
</div>
</div>
</div>
<div class="grid" style="margin-top:20px">
<div class="chart-container">
<div class="chart-title">Distribusi Cluster K-Means (K=4)</div>
<div class="chart-wrapper">
<canvas id="clusterChart"></canvas>
</div>
</div>
<div class="chart-container">
<div class="chart-title">Match Rate per Program Studi</div>
<div class="chart-wrapper">
<canvas id="matchChart"></canvas>
</div>
</div>
</div>
<div class="definitions">
<h2>Definisi Kategori</h2>
<div class="definition-item">
<span class="definition-badge badge-c0">C0</span>
<span><strong>Sesuai Profil Lulusan:</strong> Alumni bekerja dan pekerjaan match dengan kamus kata kunci profil lulusannya.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c1">C1</span>
<span><strong>Bidang Diketahui:</strong> Alumni bekerja, bidang pekerjaan jelas, tapi tidak match kamus prodi.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c2">C2</span>
<span><strong>Bidang Tidak Teridentifikasi:</strong> Alumni bekerja tapi informasi pekerjaan kurang jelas atau terlalu umum.</span>
</div>
<div class="definition-item">
<span class="definition-badge badge-c3">C3</span>
<span><strong>Belum/Tidak Bekerja:</strong> Alumni belum bekerja atau tidak bekerja saat tracer study.</span>
</div>
</div>
<div class="footer">
<p>Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
<p>Sistem Clustering Alumni - Politeknik Negeri Jember</p>
</div>
</div>
<script>
// Kategori Chart
new Chart(document.getElementById('kategoriChart'), {{
type: 'doughnut',
data: {{
labels: ['C0 - Sesuai Profil', 'C1 - Bidang Diketahui', 'C2 - Bidang Tidak Jelas', 'C3 - Belum Bekerja'],
datasets: [{{
data: [
{kategori_counts.get('C0', 0)},
{kategori_counts.get('C1', 0)},
{kategori_counts.get('C2', 0)},
{kategori_counts.get('C3', 0)}
],
backgroundColor: ['#2ecc71', '#3498db', '#f39c12', '#e74c3c']
}}]
}},
options: {{
responsive: true,
maintainAspectRatio: false,
plugins: {{
legend: {{ position: 'bottom' }}
}}
}}
}});
// Prodi Chart
new Chart(document.getElementById('prodiChart'), {{
type: 'bar',
data: {{
labels: ['TIF', 'MIF', 'TKK'],
datasets: [{{
label: 'Jumlah Alumni',
data: [
{prodi_counts.get('TIF', 0)},
{prodi_counts.get('MIF', 0)},
{prodi_counts.get('TKK', 0)}
],
backgroundColor: ['#9b59b6', '#1abc9c', '#e67e22']
}}]
}},
options: {{
responsive: true,
maintainAspectRatio: false,
plugins: {{
legend: {{ display: false }}
}}
}}
}});
// Cluster Chart
new Chart(document.getElementById('clusterChart'), {{
type: 'pie',
data: {{
labels: ['Cluster 0', 'Cluster 1', 'Cluster 2', 'Cluster 3'],
datasets: [{{
data: [326, 27, 66, 100],
backgroundColor: ['#3498db', '#2ecc71', '#f39c12', '#9b59b6']
}}]
}},
options: {{
responsive: true,
maintainAspectRatio: false
}}
}});
// Match Rate Chart
new Chart(document.getElementById('matchChart'), {{
type: 'bar',
data: {{
labels: ['TIF', 'MIF', 'TKK'],
datasets: [{{
label: 'Match Rate (%)',
data: [2.22, 1.82, 6.90],
backgroundColor: ['#9b59b6', '#1abc9c', '#e67e22']
}}]
}},
options: {{
responsive: true,
maintainAspectRatio: false,
scales: {{
y: {{
beginAtZero: true,
max: 10
}}
}},
plugins: {{
legend: {{ display: false }}
}}
}}
}});
</script>
</body>
</html>
"""
with open(output_path, 'w', encoding='utf-8') as f:
f.write(html_content)
print(f" Saved: {output_path}")
def main():
"""Main function."""
print("=" * 60)
print("GENERATING DASHBOARD VISUALIZATIONS")
print("=" * 60)
# Load data
df, processed_df, cluster_stats = load_data()
# Create visualizations
create_summary_cards(cluster_stats, os.path.join(OUTPUT_DIR, 'summary_cards.png'))
create_pie_chart_kategori(df, os.path.join(OUTPUT_DIR, 'kategori_pie.png'))
create_bar_chart_prodi(df, os.path.join(OUTPUT_DIR, 'prodi_bar.png'))
create_donut_chart_cluster(df, os.path.join(OUTPUT_DIR, 'cluster_donut.png'))
create_stacked_bar_tahun(df, os.path.join(OUTPUT_DIR, 'tahun_stacked.png'))
create_html_dashboard(df, os.path.join(OUTPUT_DIR, 'dashboard.html'))
print("\n" + "=" * 60)
print("[SUCCESS] DASHBOARD VISUALIZATIONS COMPLETE!")
print("=" * 60)
print(f"\nOutput directory: {OUTPUT_DIR}")
print("Files generated:")
print(" - summary_cards.png")
print(" - kategori_pie.png")
print(" - prodi_bar.png")
print(" - cluster_donut.png")
print(" - tahun_stacked.png")
print(" - dashboard.html (Interactive)")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,468 @@
# ============================================================
# PIPELINE PREPROCESSING LENGKAP
# ============================================================
# Fungsi: Pipeline preprocessing data tracer study alumni
# dari import Excel sampai siap untuk ML
# ============================================================
import pandas as pd
import numpy as np
import re
from typing import List, Dict, Optional, Tuple
from pathlib import Path
# Import modul standarisasi
from .standarisasi_kolom import (
KolomStandarisasi,
gabung_data,
bersihkan_data,
COLUMN_MAPPING
)
# Import text preprocessing
from .text_preprocessing import preprocess_text
# ============================================================
# KELAS: DataPipeline
# ============================================================
# Pipeline lengkap untuk memproses data tracer study
# dari berbagai tahun menjadi data siap ML
# ============================================================
class DataPipeline:
"""
Pipeline lengkap untuk preprocessing data tracer study.
ALUR KERJA:
============
┌─────────────────────────────────────────────────────────┐
│ INPUT: File Excel dari berbagai tahun (2019-2025) │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ STEP 1: STANDARISASI KOLOM │
│ - Ubah nama kolom berbeda → kolom standar │
│ - Kolom standar: nama, perusahaan, jabatan, nim │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ STEP 2: GABUNG DATA │
│ - Gabungkan data dari berbagai tahun │
│ - Tambahkan kolom 'tahun' │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ STEP 3: DATA CLEANING │
│ - Hapus duplikat │
│ - Hapus data kosong │
│ - Handle missing values │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ STEP 4: TEXT PREPROCESSING │
│ - Case folding (lowercase) │
│ - Tokenizing │
│ - Stopword removal │
│ - Stemming │
└─────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ OUTPUT: Data siap untuk TF-IDF & Clustering │
└─────────────────────────────────────────────────────────┘
CONTOH PENGGUNAAN:
==================
>>> pipeline = DataPipeline()
>>> pipeline.tambah_data(df_2019, "2019")
>>> pipeline.tambah_data(df_2024, "2024")
>>> result = pipeline.jalankan()
>>> print(result.head())
"""
def __init__(self):
"""Inisialisasi pipeline dengan komponen-komponen yang dibutuhkan."""
# Simpan data mentah yang belum diproses
self.data_list: List[Tuple[pd.DataFrame, str]] = []
# Komponen standarisasi
self.standarisasi = KolomStandarisasi()
# Status pipeline
self._sudah_standarisasi = False
self._sudah_gabung = False
self._sudah_bersih = False
self._sudah_preprocess = False
# Data hasil processing (disimpan untuk debugging)
self._df_standar = None
self._df_gabungan = None
self._df_bersih = None
self._df_final = None
print("🚀 DataPipeline initialized")
# ========================================================
# METODE: tambah_data
# ========================================================
def tambah_data(self, df: pd.DataFrame, tahun: str,
nama_file: str = None) -> 'DataPipeline':
"""
Tambahkan data dari satu tahun.
Args:
df: DataFrame dari file Excel
tahun: Tahun data (2019-2025)
nama_file: Nama file (untuk auto-detect)
Returns:
self (untuk method chaining)
Contoh:
=======
>>> pipeline = DataPipeline()
>>> pipeline.tambah_data(df_2019, "2019")
>>> pipeline.tambah_data(df_2024, "2024")
"""
# Validasi tahun
tahun_tersedia = self.standarisasi.get_tahun()
if tahun not in tahun_tersedia:
print(f"⚠️ Warning: Tahun {tahun} belum ada di mapping")
print(f" Mapping akan ditambahkan otomatis")
self.data_list.append((df, tahun))
print(f" ✅ Data {tahun} ditambahkan ({len(df)} records)")
return self
# ========================================================
# METODE: jalankan
# ========================================================
def jalankan(self, bersihkan: bool = True,
text_preprocess: bool = True) -> pd.DataFrame:
"""
Jalankan seluruh pipeline.
Args:
bersihkan: Apakah akan melakukan data cleaning
text_preprocess: Apakah akan melakukan text preprocessing
Returns:
DataFrame yang sudah diproses
ALUR:
=====
1. Standarisasi setiap data
2. Gabungkan semua data
3. Bersihkan data
4. Text preprocessing
"""
print("\n" + "=" * 60)
print("🚀 MEMULAI PIPELINE")
print("=" * 60)
# ================================================
# STEP 1: Standarisasi
# ================================================
print("\n📋 STEP 1: Standarisasi Kolom")
print("-" * 40)
df_standar_list = []
for df, tahun in self.data_list:
print(f"\n Memproses tahun {tahun}...")
try:
df_std = self.standarisasi.standarisasi(df, tahun=tahun)
df_standar_list.append(df_std)
print(f" ✅ {tahun}: {len(df_std)} records")
except Exception as e:
print(f" ❌ {tahun}: Error - {e}")
if not df_standar_list:
raise ValueError("Tidak ada data yang berhasil diproses")
self._df_standar = df_standar_list
self._sudah_standarisasi = True
# ================================================
# STEP 2: Gabung Data
# ================================================
print("\n📋 STEP 2: Gabung Data")
print("-" * 40)
tahun_list = [tahun for _, tahun in self.data_list]
self._df_gabungan = gabung_data(df_standar_list, tahun_list)
self._sudah_gabung = True
print(f" Total records setelah digabung: {len(self._df_gabungan)}")
# ================================================
# STEP 3: Cleaning
# ================================================
if bersihkan:
print("\n📋 STEP 3: Data Cleaning")
print("-" * 40)
self._df_bersih = bersihkan_data(self._df_gabungan)
self._sudah_bersih = True
else:
self._df_bersih = self._df_gabungan
# ================================================
# STEP 4: Text Preprocessing
# ================================================
if text_preprocess:
print("\n📋 STEP 4: Text Preprocessing")
print("-" * 40)
self._df_final = self._proses_teks(self._df_bersih)
self._sudah_preprocess = True
else:
self._df_final = self._df_bersih
# ================================================
# SELESAI
# ================================================
print("\n" + "=" * 60)
print("✅ PIPELINE SELESAI")
print("=" * 60)
print(f" Total records final: {len(self._df_final)}")
print(f" Kolom: {self._df_final.columns.tolist()}")
return self._df_final
# ========================================================
# METODE: _proses_teks
# ========================================================
def _proses_teks(self, df: pd.DataFrame) -> pd.DataFrame:
"""
Proses kolom teks untuk ML.
MELAKUKAN:
==========
1. Gabungkan kolom perusahaan + jabatan menjadi satu teks
2. Apply text preprocessing (lowercase, tokenize, dll)
3. Simpan hasil di kolom 'teks_bersih'
"""
print(" Memproses teks...")
df = df.copy()
# ================================================
# LANGKAH 1: Gabungkan teks
# ================================================
# Gabungkan "perusahaan" dan "jabatan" menjadi satu teks
# Ini akan menjadi input untuk TF-IDF
# Isi nilai kosong dengan string kosong
df['perusahaan'] = df['perusahaan'].fillna('')
df['jabatan'] = df['jabatan'].fillna('')
# Gabungkan dengan spasi
df['teks_gabungan'] = df['perusahaan'] + ' ' + df['jabatan']
# ================================================
# LANGKAH 2: Text Preprocessing
# ================================================
# Proses setiap teks dengan fungsi dari text_preprocessing.py
def proses(teks):
if not teks or teks.strip() == '':
return ''
return preprocess_text(teks)
df['teks_bersih'] = df['teks_gabungan'].apply(proses)
# ================================================
# LANGKAH 3: Hapus kolom bantu
# ================================================
df = df.drop(columns=['teks_gabungan'])
print(f" ✅ Teks berhasil diproses")
return df
# ========================================================
# METODE: get_statistik
# ========================================================
def get_statistik(self) -> Dict:
"""
Dapatkan statistik dari pipeline.
Returns:
Dictionary dengan statistik
"""
stats = {
"jumlah_tahun": len(self.data_list),
"tahun": [tahun for _, tahun in self.data_list],
"total_records": 0,
"records_per_tahun": {},
"kolom_standar": []
}
if self._df_gabungan is not None:
stats["total_records"] = len(self._df_gabungan)
# Hitung per tahun
if 'tahun' in self._df_gabungan.columns:
stats["records_per_tahun"] = (
self._df_gabungan['tahun']
.value_counts()
.to_dict()
)
if self._df_final is not None:
stats["kolom_standar"] = self._df_final.columns.tolist()
return stats
# ========================================================
# METODE: reset
# ========================================================
def reset(self) -> 'DataPipeline':
"""
Reset pipeline ke kondisi awal.
Returns:
self (untuk method chaining)
"""
self.data_list = []
self._sudah_standarisasi = False
self._sudah_gabung = False
self._sudah_bersih = False
self._sudah_preprocess = False
self._df_standar = None
self._df_gabungan = None
self._df_bersih = None
self._df_final = None
print("🔄 Pipeline reset")
return self
# ============================================================
# FUNGSI: proses_file_excel
# ============================================================
def proses_file_excel(file_paths: List[str],
tahun_list: List[str]) -> pd.DataFrame:
"""
Proses multiple file Excel sekaligus.
Args:
file_paths: List path ke file Excel
tahun_list: List tahun untuk setiap file
Returns:
DataFrame yang sudah diproses
Contoh:
=======
>>> files = ["data_2019.xlsx", "data_2024.xlsx"]
>>> tahun = ["2019", "2024"]
>>> result = proses_file_excel(files, tahun)
"""
# Validasi
if len(file_paths) != len(tahun_list):
raise ValueError(
f"Jumlah file ({len(file_paths)}) "
f"tidak sama dengan jumlah tahun ({len(tahun_list)})"
)
print("=" * 60)
print("MEMPROSES FILE EXCEL")
print("=" * 60)
# Inisialisasi pipeline
pipeline = DataPipeline()
# Load dan tambah setiap file
for file_path, tahun in zip(file_paths, tahun_list):
print(f"\n📂 Membaca: {file_path}")
df = pd.read_excel(file_path)
pipeline.tambah_data(df, tahun)
# Jalankan pipeline
result = pipeline.jalankan()
# Tampilkan statistik
stats = pipeline.get_statistik()
print("\n" + "=" * 60)
print("STATISTIK")
print("=" * 60)
print(f"Tahun yang diproses: {stats['tahun']}")
print(f"Total records: {stats['total_records']}")
print(f"Records per tahun: {stats['records_per_tahun']}")
return result
# ============================================================
# CONTOH PENGGUNAAN LENGKAP
# ============================================================
if __name__ == "__main__":
print("=" * 60)
print("CONTOH PENGGUNAAN DATA PIPELINE")
print("=" * 60)
# ================================================
# Buat data dummy untuk setiap tahun
# ================================================
# Data 2019
df_2019 = pd.DataFrame({
# Mapping 2019 - GANTI dengan nama kolom sebenarnya
"Nama Lengkap": ["Andi Wijaya", "Budi Cahya"],
"Perusahaan": ["Google", "Microsoft"],
"Jabatan": ["Engineer", "Manager"],
"NIM": ["E41190001", "E41190002"]
})
# Data 2024 (sudah diketahui)
df_2024 = pd.DataFrame({
"4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)": [
"Citra Dewi", "Dewi Lestari"
],
"9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b": [
"Tokopedia", "Gojek"
],
"10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c": [
"Data Analyst", "Product Manager"
],
"3. NIM / nimhsmsmh (Gunakan Huruf Besar) ": [
"E41240001", "E41240002"
]
})
# ================================================
# Jalankan Pipeline
# ================================================
print("\n📊 Data yang akan diproses:")
print(f" - 2019: {len(df_2019)} records")
print(f" - 2024: {len(df_2024)} records")
# Inisialisasi pipeline
pipeline = DataPipeline()
# Tambah data
pipeline.tambah_data(df_2019, "2019")
pipeline.tambah_data(df_2024, "2024")
# Jalankan
result = pipeline.jalankan()
# Tampilkan hasil
print("\n📋 HASIL AKHIR:")
print(result)
# Tampilkan statistik
stats = pipeline.get_statistik()
print("\n📈 STATISTIK:")
for key, value in stats.items():
print(f" {key}: {value}")

View File

@ -0,0 +1,122 @@
{
"_description": "Mapping kolom CSV tracer study ke field database",
"_version": "1.0",
"identitas": {
"nim": ["NIM/Nomor Mahasiswa", "NIM", "nimhsmsmh", "3. NIM / nimhsmsmh"],
"nama": ["Nama", "nmmhsmsmh", "4. Nama Lengkap / nmmhsmsmh"],
"kode_prodi": ["Kode Prodi", "kdpstmsmh", "2. Kode Program Studi / kdpstmsmh"],
"kode_pt": ["Kode PT", "kdptimsmh", "1. Kode Perguruan Tinggi / kdptimsmh"],
"email": ["Email", "emailmsmh", "6. Alamat Email / emailmsmh"],
"tahun_lulus": ["Tahun Lulus", "tahun_lulus", "7. Tahun Lulus / tahun_lulus"],
"nik": ["NIK"],
"npwp": ["NPWP"],
"telepon": ["Telepon", "No. Telepon"]
},
"pekerjaan": {
"status_saat_ini": ["F8", "f8", "1. Jelaskan status Anda saat ini? f8"],
"bulan_dapat_kerja": ["F502", "f502", "2. Dalam berapa bulan Anda mendapatkan pekerjaan pertama ? (f502)"],
"dapet_kerja_6_bulan": ["F504", "f504", "3. Apakah Anda telah mendapatkan pekerjaan <= 6 bulan (f504)"],
"rata_pendapatan": ["F505", "f505", "4. Berapa rata-rata pendapatan Anda per bulan ? f505"],
"bulan_dapat_kerja_setelah": ["F506", "f506", "5. Berapa bulan Anda MENDAPATKAN PEKERJAAN SETELAH LULUS? f506"],
"provinsi_kerja": ["F5a1", "f5a1", "6. Lokasi provinsi tempat Anda bekerja? f5a1"],
"kab_kota_kerja": ["F5a2", "f5a2", "7. Lokasi kabupaten/kota tempat Anda bekerja? f5a2"],
"jenis_perusahaan_full": ["F1101", "f1101", "8. Jenis perusahaan/instansi tempat anda bekerja sekarang? f1101"],
"jumlah_perusahaan": ["F1102", "f1102"],
"nama_perusahaan": ["F5b", "f5b", "9. Nama perusahaan/kantor tempat Anda bekerja? f5b"],
"jabatan": ["F5c", "f5c", "10. Posisi/jabatan Anda saat ini ? f5c"],
"tingkatan_tempat_kerja": ["F5d", "f5d", "11. Tingkatan tempat kerja Anda? f5d"]
},
"studi_lanjut": {
"sumber_biaya_studi": ["F18a", "f18a", "12. Sumber biaya Studi Lanjut Anda? f18a"],
"pt_studi_lanjut": ["F18b", "f18b", "13. Nama Perguruan Tinggi Studi Lanjut Anda? f18b"],
"prodi_studi_lanjut": ["F18c", "f18c", "14. Nama Program Studi Studi Lanjut Anda? f18c"],
"tanggal_masuk_studi": ["F18d", "f18d", "15. Tanggal Masuk Awal Studi Lanjut Anda? f18d"]
},
"kesesuaian": {
"sumber_biaya_kuliah": ["F1201", "f1201", "16. Sebutkan sumberdana dalam pembiayaan kuliah? f1201"],
"keeratan_bidang_studi": ["F14", "f14", "17. Seberapa erat hubungan bidang studi dengan pekerjaan Anda? f14"],
"tingkat_pendidikan_tepat": ["F15", "f15", "18. Tingkat pendidikan apa yang paling tepat/sesuai untuk pekerjaan anda saat ini? f15"]
},
"kompetensi_lulus": {
"etika_lulus_full": ["F1761", "f1761", "19. Kompetensi ETIKA SAAT LULUS? f1761"],
"keahlian_lulus_full": ["F1763", "f1763", "21. Kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU SAAT LULUS? f1763"],
"bahasa_inggris_lulus_full": ["F1765", "f1765", "23. Kompetensi BAHASA INGGRIS SAAT LULUS? f1765"],
"teknologi_informasi_lulus_full": ["F1767", "f1767", "25. Kompetensi TEKNOLOGI INFORMASI SAAT LULUS? f1767"],
"komunikasi_lulus_full": ["F1769", "f1769", "27. Kompetensi KOMUNIKASI SAAT LULUS? f1769"],
"kerja_sama_lulus_full": ["F1771", "f1771", "29. Kompetensi KERJA SAMA TIM SAAT LULUS? f1771"],
"pengembangan_diri_lulus_full": ["F1773", "f1773", "31. Kompetensi PENGEMBANGAN DIRI SAAT LULUS? f1773"]
},
"kompetensi_saat_ini": {
"etika_saat_ini": ["F1762", "f1762", "20. Kompetensi ETIKA SAAT INI? f1762"],
"keahlian_saat_ini": ["F1764", "f1764", "22. Kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU SAAT INI? f1764"],
"bahasa_inggris_saat_ini": ["F1766", "f1766", "24. Kompetensi BAHASA INGGRIS SAAT INI? f1766"],
"teknologi_informasi_saat_ini": ["F1768", "f1768", "26. Kompetensi TEKNOLOGI INFORMASI SAAT INI? f1768"],
"komunikasi_saat_ini": ["F1770", "f1770", "28. Kompetensi KOMUNIKASI SAAT INI? f1770"],
"kerja_sama_saat_ini": ["F1772", "f1772", "30. Kompetensi KERJA SAMA TIM SAAT INI? f1772"],
"pengembangan_diri_saat_ini": ["F1774", "f1774", "32. Kompetensi PENGEMBANGAN DIRI SAAT INI? f1774"]
},
"metode_pembelajaran": {
"metode_perkuliahan": ["F21", "f21", "33. Perkuliahan f21"],
"metode_demonstrasi": ["F22", "f22", "34. Demonstrasi f22"],
"metode_proyek_riset": ["F23", "f23", "35. Partisipasi dalam proyek riset f23"],
"metode_magang": ["F24", "f24", "36. Magang f24"],
"metode_praktikum": ["F25", "f25", "37. Praktikum f25"],
"metode_kerja_lapangan": ["F26", "f26", "38. Kerja Lapangan f26"],
"metode_diskusi": ["F27", "f27", "39. Diskusi f27"]
},
"waktu_cari_kerja": {
"mulai_cari_kerja": ["F301", "f301", "40. Kapan anda mulai mencari pekerjaan? f301"],
"bulan_cari_sebelum_lulus": ["F302", "f302", "41. Saya mencari pekerjaan, bulan SEBELUM lulus f302"],
"bulan_cari_setelah_wisuda": ["F303", "f303", "42. Saya mencari pekerjaan, bulan SETELAH wisuda f303"]
},
"cara_cari_kerja": {
"cari_iklan": ["F401", "f401", "43. Melalui iklan di koran/majalah? f401"],
"cari_melamar_tanpa_lowongan": ["F402", "f402", "44. Melamar ke perusahaan tanpa mengetahui lowongan? f402"],
"cari_bursa_pameran": ["F403", "f403", "45. Pergi ke bursa/pameran kerja? f403"],
"cari_internet": ["F404", "f404", "46. Mencari lewat internet/iklan online? f404"],
"cari_dihubungi_perusahaan": ["F405", "f405", "47. Dihubungi oleh perusahaan? f405"],
"cari_kemenakertrans": ["F406", "f406", "48. Menghubungi Kemenakertrans? f406"],
"cari_agen_tenaga_kerja": ["F407", "f407", "49. Menghubungi agen tenaga kerja komersial? f407"],
"cari_pusat_karir": ["F408", "f408", "50. Memperoleh informasi dari pusat/kantor pengembangan karir? f408"],
"cari_kantor_mahasiswa": ["F409", "f409", "51. Menghubungi kantor kemahasiswaan? f409"],
"cari_jejaring": ["F410", "f410", "52. Membangun jejaring (network) sejak masih kuliah? f410"],
"cari_relasi": ["F411", "f411", "53. Melalui relasi (dosen, orang tua, teman)? f411"],
"cari_bangun_usaha": ["F412", "f412", "54. Membangun bisnis sendiri? f412"],
"cari_magang": ["F413", "f413", "55. Melalui penempatan kerja atau magang? f413"],
"cari_tempat_kuliah": ["F414", "f414", "56. Bekerja di tempat yang sama dengan tempat kerja semasa kuliah? f414"],
"cari_lainnya": ["F415", "f415", "57. Lainnya? f415"]
},
"lamaran_keaktifan": {
"jumlah_perusahaan_dilamar": ["F6", "f6", "58. Berapa perusahaan yang sudah anda lamar?"],
"jumlah_perusahaan_merespons": ["F7", "f7", "59. Berapa banyak perusahaan yang merespons lamaran Anda?"],
"jumlah_perusahaan_wawancara": ["F7a", "f7a", "60. Berapa banyak perusahaan yang mengundang anda untuk wawancara?"],
"aktif_cari_kerja_4_minggu": ["F1001", "f1001", "61. Apakah Anda aktif mencari pekerjaan dalam 4 minggu terakhir?"]
},
"kesesuaian_pekerjaan": {
"kerja_tidak_sesuai_1": ["F1601", "f1601", "62. Apakah pekerjaan anda saat ini tidak sesuai dengan pendidikan anda?"],
"kerja_tidak_sesuai_2": ["F1602", "f1602", "63. Apakah pekerjaan anda saat ini tidak sesuai dengan pendidikan anda ?"],
"alasan_tidak_sesuai_1": ["F1603", "f1603", "64. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_2": ["F1604", "f1604", "65. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_3": ["F1605", "f1605", "66. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_4": ["F1606", "f1606", "67. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_5": ["F1607", "f1607", "68. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_6": ["F1608", "f1608", "69. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_7": ["F1609", "f1609", "70. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_8": ["F1610", "f1610", "71. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_9": ["F1611", "f1611", "72. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_10": ["F1612", "f1612", "73. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_11": ["F1613", "f1613", "74. Jika tidak sesuai, mengapa anda mengambilnya?"],
"alasan_tidak_sesuai_lainnya": ["F1614", "f1614", "75. Jika tidak sesuai, mengapa anda mengambilnya? (Lainnya)"]
}
}

View File

@ -0,0 +1,213 @@
"""
=============================================================
INTERPRETASI CLUSTER & RELEVANSI PROFIL LULUSAN (C0 - C3)
=============================================================
PRD Reference: Section 7, 18, & 24
Tujuan:
- Normalisasi teks dan pemecahan kata majemuk (Smart CamelCase / Suffix Split)
- Pencocokan teks pekerjaan dengan kamus profil prodi (Rule-Based Matching)
- Penentuan kategori relevansi karir C0, C1, C2, C3 secara deterministik
=============================================================
"""
import re
import pandas as pd
from typing import Dict, List, Tuple, Optional, Any
from Model.config.default_keywords import (
PRODI_CODES,
DEFAULT_KEYWORD_DICTIONARY,
DEFAULT_BIDANG_KERJA_UMUM,
)
# Export default dictionary for backwards compatibility
KEYWORD_DICTIONARY = DEFAULT_KEYWORD_DICTIONARY
BIDANG_KERJA_UMUM = DEFAULT_BIDANG_KERJA_UMUM
NON_PROFILE_KEYWORDS = DEFAULT_BIDANG_KERJA_UMUM
def normalize_text(text: Any) -> str:
"""
Normalisasi teks untuk pencocokan kata kunci:
1. Pemecahan CamelCase (misal: 'IndraTech' -> 'Indra Tech')
2. Pemecahan kata majemuk berakhiran teknologi/dev/soft/craft/coding
3. Case folding & penghapusan tanda baca khusus
"""
if pd.isna(text) or text is None or text == '':
return ''
text = str(text)
# 1. Pisahkan camelCase
text = re.sub(r'([a-z])([A-Z])', r'\1 \2', text)
text = text.lower()
# 2. Pisahkan kata majemuk yang menempel dengan akhiran tech/dev/soft/coding/craft
text = re.sub(
r'(\b[a-zA-Z]{3,})(tech|technology|teknologi|dev|soft|software|coding|koding|craft)\b',
r'\1 \2',
text
)
# 3. Ganti tanda baca pemisah menjadi spasi
text = re.sub(r'[/\\_.\-,()\[\]{}:;+*&^%$#@!~?<>|\"\']', ' ', text)
# 4. Hapus spasi ganda
text = re.sub(r'\s+', ' ', text)
return text.strip()
# Cache pola regex terkompilasi agar proses matching berjalan instan (<0.05 detik untuk ribuan alumni)
_COMPILED_KEYWORDS_CACHE: Dict[str, List[Tuple[str, Any]]] = {}
def _get_compiled_keywords_for_prodi(prodi_name: str, dict_source: Dict[str, List[str]]) -> List[Tuple[str, Any]]:
keywords = dict_source.get(prodi_name, [])
cache_key = f"{prodi_name}_{len(keywords)}"
if cache_key not in _COMPILED_KEYWORDS_CACHE:
compiled_list = []
for kw in keywords:
kw_norm = normalize_text(kw)
if kw_norm:
compiled_list.append((kw, re.compile(r'\b' + re.escape(kw_norm) + r'\b')))
_COMPILED_KEYWORDS_CACHE[cache_key] = compiled_list
return _COMPILED_KEYWORDS_CACHE[cache_key]
def match_keywords(
teks_pekerjaan: str,
prodi_code: str,
custom_keyword_dict: Optional[Dict[str, List[str]]] = None
) -> Tuple[bool, List[str], bool]:
"""
Cek apakah teks pekerjaan match dengan kamus prodi menggunakan Word-Boundary Matching (\b...\b).
Dapat menerima kamus dinamis dari database (custom_keyword_dict).
"""
teks_normalized = normalize_text(teks_pekerjaan)
if not teks_normalized:
return False, [], False
# Resolusi prodi_code ke singkatan resmi (TIF, MIF, TKK)
prodi_name = PRODI_CODES.get(str(prodi_code).strip(), str(prodi_code).strip())
# Gunakan kamus dinamis jika disediakan, fallback ke DEFAULT
dict_source = custom_keyword_dict if custom_keyword_dict is not None else DEFAULT_KEYWORD_DICTIONARY
if prodi_name not in dict_source:
return False, [], False
compiled_kws = _get_compiled_keywords_for_prodi(prodi_name, dict_source)
matched_keywords = []
for orig_kw, pattern in compiled_kws:
if pattern.search(teks_normalized):
matched_keywords.append(orig_kw)
return len(matched_keywords) > 0, matched_keywords, False
_BIDANG_COMPILED_CACHE: List[Any] = []
def _get_compiled_bidang(bidang_list: List[str]) -> List[Any]:
global _BIDANG_COMPILED_CACHE
if not _BIDANG_COMPILED_CACHE or len(_BIDANG_COMPILED_CACHE) != len(bidang_list):
_BIDANG_COMPILED_CACHE = [re.compile(r'\b' + re.escape(kw) + r'\b') for kw in bidang_list if kw]
return _BIDANG_COMPILED_CACHE
def is_bidang_diketahui(
teks_pekerjaan: str,
custom_bidang_list: Optional[List[str]] = None
) -> bool:
"""
Cek apakah bidang pekerjaan alumni dapat diidentifikasi pada sektor formal non-IT (C1 vs C2).
"""
teks = normalize_text(teks_pekerjaan)
if len(teks) < 3:
return False
bidang_list = custom_bidang_list if custom_bidang_list is not None else DEFAULT_BIDANG_KERJA_UMUM
compiled_bidang = _get_compiled_bidang(bidang_list)
for pattern in compiled_bidang:
if pattern.search(teks):
return True
return False
def interpretasi_categori(
row: Dict[str, Any],
c3_df: Optional[Any] = None,
custom_keyword_dict: Optional[Dict[str, List[str]]] = None
) -> Tuple[str, bool, List[str]]:
"""
Interpretasi alumni ke kategori C0 - C3 (PRD Section 18):
- Priority 1 (C3): Belum/tidak bekerja ATAU data pekerjaan kosong
- Priority 2 (C0): Bekerja + Match kamus kurikulum prodi asal (Sesuai Profil)
- Priority 3 (C1): Bekerja + Sektor formal teridentifikasi tapi non-IT (Bidang Diketahui)
- Priority 4 (C2): Bekerja + Deskripsi generik/ambigu (Kurang Teridentifikasi)
"""
nim = str(row.get('nim', '')).strip()
# Priority 1A: Cek apakah terdaftar di list C3
if c3_df is not None and hasattr(c3_df, 'empty') and not c3_df.empty and 'nim' in c3_df.columns:
if nim in c3_df['nim'].astype(str).values:
return 'C3', False, []
# Priority 1B: Cek status tidak/belum bekerja
status = str(row.get('status_pekerjaan', row.get('status_kerja', ''))).lower().strip()
if status in ['belum_kerja', 'mencari_kerja', 'belum_bekerja', 'tidak_kerja', 'melanjutkan', 'belum bekerja', 'tidak bekerja', 'mencari kerja']:
return 'C3', False, []
# Priority 1C: Cek apakah seluruh data kosong total tanpa status bekerja
nama_perusahaan = str(row.get('nama_perusahaan', row.get('pekerjaan', ''))).strip()
jabatan = str(row.get('jabatan', row.get('instansi', ''))).strip()
jenis_perusahaan = str(row.get('jenis_perusahaan', '')).strip()
def is_empty_val(v: str) -> bool:
return v.lower() in ['-', '', 'none', 'null', 'kosong', 'tidak ada', 'belum kerja', 'tidak bekerja', 'n/a', '0', '0.0']
# Jika status kosong/tidak jelas dan semua field pekerjaan kosong total -> C3
if is_empty_val(status) and is_empty_val(nama_perusahaan) and is_empty_val(jabatan) and is_empty_val(jenis_perusahaan):
return 'C3', False, []
teks_pekerjaan = str(row.get('teks_pekerjaan', '')).strip()
if not teks_pekerjaan or is_empty_val(teks_pekerjaan):
teks_pekerjaan = f"{status if not is_empty_val(status) else ''} {jenis_perusahaan if not is_empty_val(jenis_perusahaan) else ''} {nama_perusahaan if not is_empty_val(nama_perusahaan) else ''} {jabatan if not is_empty_val(jabatan) else ''}".strip()
if len(normalize_text(teks_pekerjaan)) < 3 and is_empty_val(status):
return 'C3', False, []
# Ekstraksi kode prodi
kode_prodi = str(row.get('kode_prodi', '')).strip()
kode_prodi_clean = kode_prodi.replace('.0', '').strip()
match = re.search(r'\((\d+)\)', kode_prodi)
if match:
kode_prodi_clean = match.group(1)
prodi = PRODI_CODES.get(kode_prodi_clean, None) or PRODI_CODES.get(kode_prodi, None)
# Priority 2: Cek Match Kamus Profil Prodi Asal -> C0
if prodi:
is_match, matched_kws, _ = match_keywords(teks_pekerjaan, prodi, custom_keyword_dict)
else:
is_match, matched_kws, _ = False, [], False
if is_match:
return 'C0', True, matched_kws
# Priority 3: Cek apakah sektor formal non-IT diketahui -> C1
if is_bidang_diketahui(teks_pekerjaan):
return 'C1', False, []
# Cek nama institusi formal eksplisit
clean_norm = normalize_text(teks_pekerjaan)
formal_orgs = ['pt', 'cv', 'ud', 'dinas', 'badan', 'yayasan', 'bank', 'sekolah', 'rumah sakit', 'rsud', 'polres', 'kodim', 'bumn', 'bumd', 'kementerian']
if len(clean_norm) >= 5 and any(w in clean_norm.split() for w in formal_orgs):
tokens = [t for t in clean_norm.split() if t not in ['bekerja', 'perusahaan', 'swasta', 'wiraswasta', 'lainnya', 'tuliskan', 'f1102', 'f1101', 'f8', 'sendiri']]
if len(tokens) >= 2:
return 'C1', False, []
# Priority 4: Deskripsi tidak spesifik / hanya status formalitas -> C2
return 'C2', False, []

View File

@ -0,0 +1,426 @@
"""
=============================================================
MERGE & UNIFIKASI DATASET TRACER STUDY (2019-2025)
=============================================================
Tujuan:
- Membaca semua file CSV dari berbagai tahun
- Menerapkan column mapping sesuai format setiap tahun
- Merge semua data menjadi unified_dataset
- Basic cleaning
Output:
- unified_dataset.csv
- summary_merge.txt
=============================================================
"""
import pandas as pd
import json
import os
from datetime import datetime
# Path configuration
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(BASE_DIR, '..', '..', 'Data_Tracerstudy')
OUTPUT_DIR = os.path.join(BASE_DIR, '..', 'data', 'standardized')
# Column mapping untuk setiap tahun
COLUMN_MAPPING = {
"2019": {
"kode_prodi": "Kode Prodi",
"nim": "NIM/Nomor Mahasiswa",
"nama": "Nama",
"tahun_lulus": "Tahun Lulus",
"status_pekerjaan": "F8",
"jenis_perusahaan": "F1101",
"nama_perusahaan": "F5b",
"jabatan": "F5c"
},
"2020": {
"kode_prodi": "Kode Prodi",
"nim": "NIM/Nomor Mahasiswa",
"nama": "Nama",
"tahun_lulus": "Tahun Lulus",
"status_pekerjaan": "F8",
"jenis_perusahaan": "F1101",
"nama_perusahaan": "F5b",
"jabatan": "F5c"
},
"2021": {
"kode_prodi": "Kode Prodi",
"nim": "NIM",
"nama": "Nama",
"tahun_lulus": "Tahun Lulus",
"status_pekerjaan": "F8",
"jenis_perusahaan": "F1101",
"nama_perusahaan": "F5b",
"jabatan": "F5c"
},
"2022": {
"kode_prodi": "kdpstmsmh",
"nim": "nimhsmsmh",
"nama": "nmmhsmsmh",
"tahun_lulus": "tahun_lulus",
"status_pekerjaan": "f8",
"jenis_perusahaan": "f1101",
"nama_perusahaan": "f5b",
"jabatan": "f5c"
},
"2023": {
"kode_prodi": "kdpstmsmh",
"nim": "nimhsmsmh",
"nama": "nmmhsmsmh",
"tahun_lulus": "tahun_lulus",
"status_pekerjaan": "f8",
"jenis_perusahaan": "f1101",
"nama_perusahaan": "f5b",
"jabatan": "f5c"
},
"2024": {
"kode_prodi": "2. Kode Program Studi / kdpstmsmh",
"nim": "3. NIM / nimhsmsmh (Gunakan Huruf Besar) ",
"nama": "4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)",
"tahun_lulus": "7. Tahun Lulus / tahun_lulus",
"status_pekerjaan": "1. Jelaskan status Anda saat ini? f8",
"jenis_perusahaan": "8. Apa jenis perusahaan/instansi/institusi tempat anda bekerja sekarang? f1101",
"nama_perusahaan": "9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b",
"jabatan": "10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c"
},
"2025": {
"kode_prodi": "2. Kode Program Studi / kdpstmsmh",
"nim": "3. NIM / nimhsmsmh (Gunakan Huruf Besar) ",
"nama": "4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)",
"tahun_lulus": "7. Tahun Lulus / tahun_lulus",
"status_pekerjaan": "1. Jelaskan status Anda saat ini? f8",
"jenis_perusahaan": "7. Apa jenis perusahaan/instansi/institusi tempat anda bekerja sekarang? f1101",
"nama_perusahaan": "9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b",
"jabatan": "10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c *(Wajib diisi) (Jika Memilih Wiraswasta / Jika f8 adalah 3)"
}
}
# File yang akan dibaca
DATA_FILES = {
"2019": "Data_2019_Tracer_study.csv",
"2020": "Data_2020_Tracer_study.csv",
"2021": "Data_2021_Tracer_study.csv",
"2022": "Data_2022_Tracer_study.csv",
"2023": "Data_2023_Tracer_study.csv",
"2024": "Data_2024_Tracer_study.csv",
"2025": [
"Data_2025_Tracer_study_D3MIF.csv",
"Data_2025_Tracer_study_D3TKK.csv",
"Data_2025_Tracer_study_D4TIF.csv",
"Data_2025_Tracer_study_D4TIFNGANJUK.csv",
"Data_2025_Tracer_study_D4TIFSIDOARJO.csv"
]
}
# Separator untuk setiap tahun
SEPARATORS = {
"2019": ";",
"2020": ";",
"2021": ";",
"2022": ";",
"2023": ";",
"2024": ";",
"2025": ";"
}
# Kolom standar output
STANDARD_COLUMNS = [
"kode_prodi",
"nim",
"nama",
"tahun_lulus",
"status_pekerjaan",
"jenis_perusahaan",
"nama_perusahaan",
"jabatan",
"sumber_file"
]
def clean_text_value(value):
"""
Membersihkan nilai teks:
- Hapus whitespace berlebih
- Handle NaN/None
"""
if pd.isna(value):
return ""
if isinstance(value, str):
# Hapus whitespace di awal dan akhir
value = value.strip()
# Ganti multiple spaces dengan single space
value = ' '.join(value.split())
return value
return str(value)
def standardize_status_pekerjaan(value, tahun):
"""
Menstandardisasi nilai status pekerjaan:
- Format berbeda antar tahun
- 2019-2022: angka (1, 2, 3, 4, 5)
- 2023-2025: teks ("Bekerja (full time/part time) (1)")
"""
if pd.isna(value) or value == "":
return "unknown"
value = str(value).strip().lower()
# Handle format 2024-2025
if "(" in value and ")" in value:
# Extract angka dalam parentheses
import re
match = re.search(r'\((\d+)\)', value)
if match:
num = int(match.group(1))
if num == 1:
return "bekerja"
elif num == 2:
return "belum_kerja"
elif num == 3:
return "wiraswasta"
elif num == 4:
return "melanjutkan_studi"
elif num == 5:
return "mencari_kerja"
# Handle format angka (2019-2023)
if value.isdigit():
num = int(value)
if num == 1:
return "bekerja"
elif num == 2:
return "belum_kerja"
elif num == 3:
return "wiraswasta"
elif num == 4:
return "melanjutkan_studi"
elif num == 5:
return "mencari_kerja"
# Handle teks
if "bekej" in value or "work" in value or "1" in value:
return "bekerja"
elif "belum" in value or "tidak" in value or "2" in value:
return "belum_kerja"
elif "wiraswasta" in value or "3" in value:
return "wiraswasta"
elif "studi" in value or "melanjutkan" in value or "4" in value:
return "melanjutkan_studi"
elif "mencari" in value or "cari" in value or "5" in value:
return "mencari_kerja"
return "unknown"
def read_and_map_year(tahun, files, separator):
"""
Baca file CSV dan terapkan column mapping.
Parameters:
- tahun: string tahun (misal "2019")
- files: list nama file atau string tunggal
- separator: separator yang digunakan
Returns:
- DataFrame yang sudah di-mapping
"""
mapping = COLUMN_MAPPING[tahun]
all_dfs = []
# Pastikan files adalah list
if isinstance(files, str):
files = [files]
for file in files:
filepath = os.path.join(DATA_DIR, file)
if not os.path.exists(filepath):
print(f" >> [WARNING] File tidak ditemukan: {file}")
continue
print(f" >> Membaca: {file}")
# Baca CSV dengan separator yang sesuai
try:
df = pd.read_csv(filepath, sep=separator, encoding='utf-8-sig')
except:
try:
df = pd.read_csv(filepath, sep=separator, encoding='latin-1')
except Exception as e:
print(f" >> [ERROR] Gagal membaca {file}: {e}")
continue
# Buat mapping untuk rename kolom
rename_mapping = {v: k for k, v in mapping.items()}
# Rename kolom
df_renamed = df.rename(columns=rename_mapping)
# Ambil hanya kolom yang ada di mapping
available_cols = [col for col in mapping.values() if col in df.columns]
standard_cols_in_df = [rename_mapping[col] for col in available_cols]
# Select kolom
df_selected = df_renamed[standard_cols_in_df].copy()
# Tambahkan sumber file
df_selected['sumber_file'] = file
all_dfs.append(df_selected)
print(f" >> {len(df_selected)} baris")
if all_dfs:
return pd.concat(all_dfs, ignore_index=True)
return pd.DataFrame()
def clean_dataset(df):
"""
Cleaning dataset:
- Hapus duplikat
- Bersihkan nilai kosong
- Standardisasi status pekerjaan
"""
print("\n>> Melakukan cleaning...")
initial_count = len(df)
# Hapus duplikat berdasarkan NIM
df = df.drop_duplicates(subset=['nim'], keep='first')
print(f" >> Duplikat (berdasarkan NIM) dihapus: {initial_count - len(df)}")
# Hapus baris dengan NIM kosong
df = df[df['nim'].notna() & (df['nim'] != '') & (df['nim'] != 'nan')]
print(f" >> Baris dengan NIM kosong dihapus: {initial_count - len(df)}")
# Standardisasi status pekerjaan
df['status_pekerjaan'] = df['status_pekerjaan'].apply(
lambda x: standardize_status_pekerjaan(x, None)
)
# Clean text columns
text_columns = ['nama', 'jenis_perusahaan', 'nama_perusahaan', 'jabatan']
for col in text_columns:
if col in df.columns:
df[col] = df[col].apply(clean_text_value)
return df
def generate_summary(df):
"""
Generate summary statistics dari merged dataset.
"""
summary = []
summary.append("=" * 60)
summary.append("MERGE SUMMARY - TRACER STUDY ALUMNI")
summary.append(f"Tanggal: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
summary.append("=" * 60)
summary.append(f"\n>> TOTAL DATA: {len(df)} alumni")
summary.append("\n>> Distribusi per Tahun Lulus:")
tahun_counts = df['tahun_lulus'].value_counts().sort_index()
for tahun, count in tahun_counts.items():
summary.append(f" {tahun}: {count} alumni")
summary.append("\n>> Distribusi per Prodi (Kode):")
prodi_counts = df['kode_prodi'].value_counts()
for prodi, count in prodi_counts.items():
summary.append(f" {prodi}: {count} alumni")
summary.append("\n>> Distribusi Status Pekerjaan:")
status_counts = df['status_pekerjaan'].value_counts()
for status, count in status_counts.items():
pct = (count / len(df)) * 100
summary.append(f" {status}: {count} ({pct:.1f}%)")
summary.append("\n>> Sumber File:")
sumber_counts = df['sumber_file'].value_counts()
for sumber, count in sumber_counts.items():
summary.append(f" {sumber}: {count} alumni")
summary.append("\n>> Missing Values:")
for col in df.columns:
missing = df[col].isna().sum() + (df[col] == '').sum()
if missing > 0:
pct = (missing / len(df)) * 100
summary.append(f" {col}: {missing} ({pct:.1f}%)")
summary.append("\n" + "=" * 60)
return "\n".join(summary)
def print_msg(msg):
"""Print message dengan encoding handling."""
print(msg)
def main():
"""
Main function untuk merge semua dataset.
"""
print("=" * 60)
print("MERGE DATASET TRACER STUDY (2019-2025)")
print("=" * 60)
all_dataframes = []
# Proses setiap tahun
for tahun in ["2019", "2020", "2021", "2022", "2023", "2024", "2025"]:
print(f"\n>> Memproses Tahun {tahun}...")
files = DATA_FILES[tahun]
separator = SEPARATORS[tahun]
df = read_and_map_year(tahun, files, separator)
if not df.empty:
all_dataframes.append(df)
print(f" >> Total dari {tahun}: {len(df)} baris")
else:
print(f" >> Tidak ada data untuk {tahun}")
if not all_dataframes:
print("\n[ERROR] Tidak ada data yang berhasil dibaca!")
return
# Merge semua data
print("\n>> Merging semua dataset...")
unified_df = pd.concat(all_dataframes, ignore_index=True)
print(f" >> Total setelah merge: {len(unified_df)} baris")
# Cleaning
unified_df = clean_dataset(unified_df)
# Generate summary
summary = generate_summary(unified_df)
print("\n" + summary)
# Ensure output directory exists
os.makedirs(OUTPUT_DIR, exist_ok=True)
# Save unified dataset
output_path = os.path.join(OUTPUT_DIR, 'unified_dataset.csv')
unified_df.to_csv(output_path, index=False, encoding='utf-8-sig')
print(f"\n>> Dataset disimpan ke: {output_path}")
# Save summary
summary_path = os.path.join(OUTPUT_DIR, 'merge_summary.txt')
with open(summary_path, 'w', encoding='utf-8') as f:
f.write(summary)
print(f">> Summary disimpan ke: {summary_path}")
print("\n" + "=" * 60)
print("[SUCCESS] MERGE SELESAI!")
print("=" * 60)
return unified_df
if __name__ == "__main__":
df = main()

View File

@ -0,0 +1,579 @@
# ============================================================
# MODUL STANDARISASI KOLOM
# ============================================================
# Fungsi: Menyamakan kolom dari berbagai tahun (2019-2025)
# Menjadi satu format standar
# ============================================================
import pandas as pd
import json
from pathlib import Path
from typing import Dict, List, Optional, Tuple
# ============================================================
# KONFIGURASI MAPPING KOLOM
# ============================================================
# Mapping ini menghubungkan nama kolom di setiap tahun Excel
# KE nama kolom STANDAR yang akan kita gunakan di database
#
# Format:
# "tahun": {
# "nama_kolom_standar": "nama_kolom_di_excel_tahun_tersebut"
# }
# ============================================================
COLUMN_MAPPING = {
# ================================================
# TAHUN 2019 - Mapping kolom Excel 2019
# ================================================
# TODO: Ganti "?" dengan nama kolom sebenarnya dari Excel 2019
# ================================================
"2019": {
"nama": "?", # Contoh: "Nama Lengkap"
"perusahaan": "?", # Contoh: "Nama Perusahaan"
"jabatan": "?", # Contoh: "Jabatan"
"nim": "?" # Contoh: "NIM"
},
# ================================================
# TAHUN 2020 - Mapping kolom Excel 2020
# ================================================
# TODO: Ganti "?" dengan nama kolom sebenarnya dari Excel 2020
# ================================================
"2020": {
"nama": "?",
"perusahaan": "?",
"jabatan": "?",
"nim": "?"
},
# ================================================
# TAHUN 2021 - Mapping kolom Excel 2021
# ================================================
# TODO: Ganti "?" dengan nama kolom sebenarnya dari Excel 2021
# ================================================
"2021": {
"nama": "?",
"perusahaan": "?",
"jabatan": "?",
"nim": "?"
},
# ================================================
# TAHUN 2022 - Mapping kolom Excel 2022
# ================================================
# TODO: Ganti "?" dengan nama kolom sebenarnya dari Excel 2022
# ================================================
"2022": {
"nama": "?",
"perusahaan": "?",
"jabatan": "?",
"nim": "?"
},
# ================================================
# TAHUN 2023 - Mapping kolom Excel 2023
# ================================================
# TODO: Ganti "?" dengan nama kolom sebenarnya dari Excel 2023
# ================================================
"2023": {
"nama": "?",
"perusahaan": "?",
"jabatan": "?",
"nim": "?"
},
# ================================================
# TAHUN 2024 - Mapping kolom Excel 2024 (SUDAH DIKETAHUI)
# ================================================
"2024": {
"nama": "4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)",
"perusahaan": "9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b",
"jabatan": "10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c",
"nim": "3. NIM / nimhsmsmh (Gunakan Huruf Besar) "
},
# ================================================
# TAHUN 2025 - Mapping kolom Excel 2025
# ================================================
# TODO: Ganti "?" dengan nama kolom sebenarnya dari Excel 2025
# ================================================
"2025": {
"nama": "?",
"perusahaan": "?",
"jabatan": "?",
"nim": "?"
}
}
# ============================================================
# KOLOM STANDAR (OUTPUT)
# ============================================================
# Ini adalah kolom FINAL yang akan kita gunakan setelah
# semua data dari berbagai tahun di-standardisasi
# ============================================================
STANDAR_KOLOM = ["nama", "perusahaan", "jabatan", "nim"]
# ============================================================
# KELAS: KolomStandarisasi
# ============================================================
# Fungsi: Mengubah kolom Excel yang berbeda-beda dari
# setiap tahun menjadi kolom STANDAR yang konsisten
# ============================================================
class KolomStandarisasi:
"""
Kelas untuk menstandarisasi kolom dari berbagai tahun.
PENJELASAN CARA KERJA:
======================
1. INPUT : DataFrame dengan kolom berbeda-beda per tahun
Contoh: df_2019 punya kolom "Nama Lengkap"
df_2024 punya kolom "4. Nama Lengkap / nmmhsmsmh..."
2. PROSES : Mapping kolom asli → kolom standar
Contoh: "Nama Lengkap" (2019) → "nama" (standar)
"4. Nama Lengkap..." (2024) → "nama" (standar)
3. OUTPUT : DataFrame dengan kolom standar:
["nama", "perusahaan", "jabatan", "nim"]
CONTOH PENGGUNAAN:
==================
>>> standardizer = KolomStandarisasi()
>>> df_standar = standardizer.standarisasi(df, tahun="2024")
>>> print(df_standar.columns.tolist())
['nama', 'perusahaan', 'jabatan', 'nim']
"""
def __init__(self, mapping: Dict = None):
"""
Inisialisasi standardizer.
Args:
mapping: Dictionary mapping kolom. Jika None, pakai default.
PENJELASAN:
===========
Saat objek dibuat, kita simpan mapping kolom yang akan
digunakan untuk konversi. Mapping ini tells kita:
"Kolom X di tahun Y harus menjadi kolom Z di output"
"""
# Gunakan mapping yang diberikan, atau gunakan default
self.mapping = mapping if mapping is not None else COLUMN_MAPPING
# Tracking tahun yang didukung
self.tahun_tersedia = list(self.mapping.keys())
print(f"📋 KolomStandarisasi initialized")
print(f" Tahun yang didukung: {', '.join(self.tahun_tersedia)}")
# ========================================================
# METODE: get_tahun
# ========================================================
def get_tahun(self) -> List[str]:
"""
Ambil daftar tahun yang didukung.
Returns:
List tahun, contoh: ["2019", "2020", "2021", ...]
"""
return self.tahun_tersedia
# ========================================================
# METODE: get_mapping_tahun
# ========================================================
def get_mapping_tahun(self, tahun: str) -> Dict:
"""
Ambil mapping kolom untuk tahun tertentu.
Args:
tahun: Tahun yang ingin diambil mappingnya
Returns:
Dictionary mapping kolom, contoh:
{"nama": "Nama Lengkap", "perusahaan": "..."}
Raises:
ValueError: Jika tahun tidak ditemukan dalam mapping
"""
# Cek apakah tahun ada dalam mapping
if tahun not in self.mapping:
tahun_available = ", ".join(self.tahun_tersedia)
raise ValueError(
f"Tahun '{tahun}' tidak ditemukan dalam mapping. "
f"Tahun tersedia: {tahun_available}"
)
return self.mapping[tahun]
# ========================================================
# METODE: deteksi_tahun
# ========================================================
def deteksi_tahun(self, df: pd.DataFrame, nama_file: str = None) -> Optional[str]:
"""
Deteksi tahun dari DataFrame atau nama file.
CARA KERJA:
===========
1. Pertama, coba deteksi dari nama file (filename)
- Jika filename mengandung "2024", berarti tahun 2024
2. Jika gagal, cek dari kolom DataFrame
- Bandingkan kolom df dengan mapping setiap tahun
- Tahun dengan kecocokan kolom PALING BANYAK = tahun yang terdeteksi
Args:
df: DataFrame yang akan dideteksi tahun-nya
nama_file: Nama file Excel (opsional)
Returns:
Tahun dalam format string, contoh: "2024"
Returns None jika tidak dapat mendeteksi
"""
# ================================================
# CARA 1: Deteksi dari nama file
# ================================================
if nama_file:
for tahun in self.tahun_tersedia:
# Cek apakah tahun ada di nama file
# Contoh: "Tracer_Study_2024.xlsx" → mengandung "2024"
if tahun in nama_file:
print(f"🔍 Tahun terdeteksi dari filename: {tahun}")
return tahun
# ================================================
# CARA 2: Deteksi dari kolom DataFrame
# ================================================
# Inisialisasi tracker untuk setiap tahun
# Menyimpan jumlah kolom yang cocok
tahun_match = {}
for tahun, kolom_mapping in self.mapping.items():
# Hitung berapa kolom dari df yang cocok dengan mapping tahun ini
cocok = 0
for kolom_target, kolom_asli in kolom_mapping.items():
if kolom_asli in df.columns:
cocok += 1
# Simpan hasil
tahun_match[tahun] = cocok
# Cari tahun dengan kecocokan PALING BANYAK
if tahun_match:
# Pilih tahun dengan match tertinggi
tahun_terbaik = max(tahun_match, key=tahun_match.get)
jumlah_match = tahun_match[tahun_terbaik]
# Jika ada kecocokan (minimal 1 kolom)
if jumlah_match >= 1:
print(f"🔍 Tahun terdeteksi dari kolom: {tahun_terbaik} ({jumlah_match} kolom cocok)")
return tahun_terbaik
# ================================================
# GAGAL DETEKSI
# ================================================
print(f"⚠️ Tidak dapat mendeteksi tahun secara otomatis")
print(f" Kolom DataFrame: {df.columns.tolist()[:5]}...") # Tampilkan 5 kolom pertama
return None
# ========================================================
# METODE: standarisasi
# ========================================================
def standarisasi(self, df: pd.DataFrame, tahun: str = None,
nama_file: str = None) -> pd.DataFrame:
"""
Standarisasi kolom DataFrame ke format standa
CARA KERJA:
===========
1. Deteksi tahun jika tidak disebutkan
2. Ambil mapping untuk tahun tersebut
3. Buat DataFrame baru dengan kolom standar
4. Copy data dari kolom asli ke kolom standar
Args:
df: DataFrame asli dari file Excel
tahun: Tahun data (otomatis detect jika None)
nama_file: Nama file (untuk deteksi otomatis)
Returns:
DataFrame dengan kolom standar
Contoh:
=======
>>> df = pd.read_excel("data_2024.xlsx")
>>> std = KolomStandarisasi()
>>> df_standar = std.standarisasi(df, tahun="2024")
>>> print(df_standar.columns.tolist())
['nama', 'perusahaan', 'jabatan', 'nim']
"""
# ================================================
# LANGKAH 1: Deteksi tahun
# ================================================
if tahun is None:
tahun = self.deteksi_tahun(df, nama_file)
if tahun is None:
raise ValueError(
"Tidak dapat memproses data. "
"Tentukan tahun secara manual atau pastikan nama file mengandung tahun."
)
# ================================================
# LANGKAH 2: Ambil mapping
# ================================================
mapping = self.get_mapping_tahun(tahun)
print(f"📊 Melakukan standarisasi untuk tahun {tahun}")
# ================================================
# LANGKAH 3: Buat DataFrame kosong dengan kolom standar
# ================================================
df_standar = pd.DataFrame()
# ================================================
# LANGKAH 4: Copy data ke kolom standar
# ================================================
kolom_diproses = 0
kolom_gagal = []
for kolom_standar, kolom_asli in mapping.items():
# Cek apakah kolom ada di DataFrame asli
if kolom_asli in df.columns:
# Copy data
df_standar[kolom_standar] = df[kolom_asli]
kolom_diproses += 1
else:
# Kolom tidak ditemukan - tandai sebagai None
df_standar[kolom_standar] = None
kolom_gagal.append(kolom_asli)
# ================================================
# LANGKAH 5: Tampilkan ringkasan
# ================================================
print(f" ✅ Kolom berhasil diproses: {kolom_diproses}/{len(mapping)}")
if kolom_gagal:
print(f" ⚠️ Kolom tidak ditemukan: {kolom_gagal}")
return df_standar
# ========================================================
# METODE: standarisasi_batch
# ========================================================
def standarisasi_batch(self, data_list: List[Tuple[pd.DataFrame, str]]) -> List[pd.DataFrame]:
"""
Standarisasi multiple DataFrame sekaligus.
CARA KERJA:
===========
Proses beberapa DataFrame dari tahun berbeda dalam satu panggil
Args:
data_list: List of tuple (DataFrame, tahun)
Contoh: [(df_2019, "2019"), (df_2024, "2024")]
Returns:
List DataFrame yang sudah distandarisasi
Contoh:
=======
>>> data = [
... (df_2019, "2019"),
... (df_2024, "2024")
... ]
>>> std = KolomStandarisasi()
>>> results = std.standarisasi_batch(data)
"""
hasil = []
for df, tahun in data_list:
try:
df_standar = self.standarisasi(df, tahun=tahun)
hasil.append(df_standar)
except Exception as e:
print(f"❌ Error memproses {tahun}: {e}")
# Skip tahun yang error, lanjut ke berikutnya
return hasil
# ============================================================
# FUNGSI: gabung_data
# ============================================================
def gabung_data(dataframes: List[pd.DataFrame],
tahun_list: List[str] = None) -> pd.DataFrame:
"""
Gabungkan beberapa DataFrame menjadi satu.
CARA KERJA:
===========
1. Terima list DataFrame dari berbagai tahun
2. Tambahkan kolom 'tahun' untuk setiap DataFrame
3. Gabungkan semua menjadi satu DataFrame
Args:
dataframes: List DataFrame yang akan digabungkan
tahun_list: List tahun untuk setiap DataFrame (opsional)
Returns:
DataFrame gabungan dengan kolom tambahan 'tahun'
"""
# Validasi input
if tahun_list and len(dataframes) != len(tahun_list):
raise ValueError(
f"Jumlah DataFrame ({len(dataframes)}) "
f"tidak sama dengan jumlah tahun ({len(tahun_list)})"
)
# ================================================
# LANGKAH 1: Tambahkan kolom tahun
# ================================================
df_dengan_tahun = []
for i, df in enumerate(dataframes):
df_copy = df.copy()
# Tentukan tahun
tahun = tahun_list[i] if tahun_list else f"tahun_{i+1}"
# Tambahkan kolom tahun
df_copy['tahun'] = tahun
df_dengan_tahun.append(df_copy)
# ================================================
# LANGKAH 2: Gabungkan semua DataFrame
# ================================================
df_gabungan = pd.concat(df_dengan_tahun, ignore_index=True)
print(f"✅ Data berhasil digabungkan: {len(df_gabungan)} records")
return df_gabungan
# ============================================================
# FUNGSI: bersihkan_data
# ============================================================
def bersihkan_data(df: pd.DataFrame) -> pd.DataFrame:
"""
Bersihkan data dari nilai kosong dan duplikat.
CARA KERJA:
===========
1. Hapus baris yang semua kolomnya kosong
2. Hapus baris duplikat
3. Isi nilai kosong dengan string kosong
Args:
df: DataFrame yang akan dibersihkan
Returns:
DataFrame yang sudah bersih
"""
print(f"🧹 Membersihkan data...")
# Simpan jumlah awal
jumlah_awal = len(df)
# ================================================
# LANGKAH 1: Hapus baris kosong
# ================================================
# dropna(how='all') = hapus baris yang SEMUA kolomnya kosong
df = df.dropna(how='all')
# ================================================
# LANGKAH 2: Hapus duplikat
# ================================================
# drop_duplicates() = hapus baris yang identik
df = df.drop_duplicates()
# ================================================
# LANGKAH 3: Isi nilai kosong
# ================================================
# fillna('') = ganti NaN/None dengan string kosong
df = df.fillna('')
# ================================================
# LANGKAH 4: Hitung statistik
# ================================================
dihapus = jumlah_awal - len(df)
if dihapus > 0:
print(f" ✅ Data dihapus: {dihapus} baris (kosong/duplikat)")
else:
print(f" ✅ Data bersih, tidak ada yang dihapus")
return df
# ============================================================
# CONTOH PENGGUNAAN
# ============================================================
if __name__ == "__main__":
# Contoh 1: Inisialisasi
print("=" * 60)
print("CONTOH 1: Inisialisasi Standardizer")
print("=" * 60)
std = KolomStandarisasi()
# Contoh 2: Lihat tahun yang didukung
print("\n" + "=" * 60)
print("CONTOH 2: Tahun yang Didukung")
print("=" * 60)
tahun_list = std.get_tahun()
print(f"Tahun: {', '.join(tahun_list)}")
# Contoh 3: Lihat mapping untuk tahun tertentu
print("\n" + "=" * 60)
print("CONTOH 3: Mapping Tahun 2024")
print("=" * 60)
mapping_2024 = std.get_mapping_tahun("2024")
for standar, asli in mapping_2024.items():
print(f" {standar:12} ← {asli}")
# Contoh 4: Standarisasi data dummy
print("\n" + "=" * 60)
print("CONTOH 4: Standarisasi Data Dummy")
print("=" * 60)
# Buat data dummy yang mirip Excel 2024
data_dummy = pd.DataFrame({
"4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)": [
"Muhammad Ali", "Budi Santoso", "Citra Dewi"
],
"9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b": [
"Google Indonesia", "Tokopedia", "Gojek"
],
"10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c": [
"Software Engineer", "Data Analyst", "Product Manager"
],
"3. NIM / nimhsmsmh (Gunakan Huruf Besar) ": [
"E41220001", "E41220002", "E41220003"
]
})
print("Data sebelum standarisasi:")
print(data_dummy.head())
# Standarisasi
data_standar = std.standarisasi(data_dummy, tahun="2024")
print("\nData setelah standarisasi:")
print(data_standar.head())
# Contoh 5: Gabungkan dan bersihkan
print("\n" + "=" * 60)
print("CONTOH 5: Gabungkan dan Bersihkan")
print("=" * 60)
# Gabungkan data dummy dengan dirinya sendiri (untuk simulasi)
data_gabungan = gabung_data([data_standar, data_standar], ["2024", "2024"])
print(f"Jumlah setelah gabung: {len(data_gabungan)} records")
# Bersihkan
data_bersih = bersihkan_data(data_gabungan)
print(f"Jumlah setelah bersih: {len(data_bersih)} records")

View File

@ -0,0 +1,435 @@
"""
=============================================================
TEXT PREPROCESSING - TEKS PEKERJAAN
=============================================================
Tujuan:
- Membentuk teks_pekerjaan dari jenis_perusahaan + nama_perusahaan + jabatan
- Melakukan text preprocessing: case folding, cleaning, tokenizing, stopword, stemming
- Menyimpan hasil preprocessing
PRD Reference: Section 12, 13
=============================================================
"""
import pandas as pd
import re
import os
import json
from datetime import datetime
# Sastrawi untuk stemming Bahasa Indonesia
try:
from Sastrawi.Stemmer.StemmerFactory import StemmerFactory
factory = StemmerFactory()
stemmer = factory.create_stemmer()
SASTRAWI_AVAILABLE = True
except ImportError:
SASTRAWI_AVAILABLE = False
print("[WARNING] Sastrawi tidak tersedia. Stemming tidak akan dilakukan.")
# NLTK untuk stopwords
try:
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
nltk.download('stopwords', quiet=True)
nltk.download('punkt', quiet=True)
nltk.download('punkt_tab', quiet=True)
NLTK_AVAILABLE = True
except:
NLTK_AVAILABLE = False
# Path configuration
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_INPUT = os.path.join(BASE_DIR, '..', 'data', 'standardized', 'unified_dataset.csv')
DATA_OUTPUT = os.path.join(BASE_DIR, '..', 'data', 'processed')
# Mapping status pekerjaan dari angka ke teks
STATUS_MAPPING = {
1: "bekerja",
2: "belum_kerja",
3: "wiraswasta",
4: "melanjutkan_studi",
5: "mencari_kerja"
}
# Mapping jenis_perusahaan dari angka ke teks
JENIS_PERUSAHAAN_MAPPING = {
1: "pemerintah",
2: "bnpp",
3: "swasta",
4: "wiraswasta",
5: "lainnya",
6: "bumn",
7: "nirlaba",
0: ""
}
# Stopwords Bahasa Indonesia (extended)
INDONESIAN_STOPWORDS = {
'yang', 'dan', 'di', 'dari', 'ini', 'itu', 'dengan', 'untuk', 'pada',
'adalah', 'ke', 'atau', 'akan', 'juga', 'tidak', 'dalam', 'oleh',
'sebagai', 'lebih', 'sudah', 'ada', 'bisa', 'telah', 'antara', 'maka',
'serta', 'namun', 'secara', 'seperti', 'jika', 'hanya', 'tetapi', 'saat',
'sedang', 'sebelumnya', 'tersebut', 'yaitu', 'saya', 'kami', 'kita',
'anda', 'dia', 'mereka', 'kami', 'kita', 'nya', 'lah', 'kah', 'pun',
'sih', 'deh', 'dong', 'gitu', 'aja', 'emang', 'nih', 'tuh', 'kok',
'yg', 'dg', 'dr', 'dlm', 'dgn', 'utk', 'pd', 'sdh', 'blm', 'jg',
'krn', 'sm', 'tp', 'jd', 'sd', 'bt', 'spy', 'msh', 'dl', 'bs', 'bsa',
'pt', 'cv', 'tdk', 'bg', 'smua', 'atl', 'krn', 'sprti', 'lngkp', 'sm',
# Tambahan umum
'per', 'bagian', 'ibu', 'bapak', 'kakak', 'adik', 'pak', 'bu', 'mas',
'mbak', 'pak', 'bu', 'pak', 'pak', 'dan', 'atau', 'maupun', 'hal', 'satu',
'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'delapan', 'sembilan', 'sepuluh'
}
# Pattern untuk cleaning
CLEANING_PATTERNS = {
'email': r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b',
'url': r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+',
'phone': r'\b\d{10,15}\b',
'special_chars': r'[^\w\s]',
'extra_spaces': r'\s+',
'numbers': r'\b\d+\b'
}
def clean_text(text):
"""
Basic text cleaning:
- Hapus email, URL, phone
- Hapus special characters
- Hapus standalone numbers (tidak bermakna)
- Hapus extra spaces
"""
if pd.isna(text) or text == '' or text == 'nan':
return ''
text = str(text).lower()
# Hapus email
text = re.sub(CLEANING_PATTERNS['email'], ' ', text)
# Hapus URL
text = re.sub(CLEANING_PATTERNS['url'], ' ', text)
# Hapus phone
text = re.sub(CLEANING_PATTERNS['phone'], ' ', text)
# Hapus special chars (simpan spasi dan alfanumerik)
text = re.sub(r'[^\w\s]', ' ', text)
# Hapus extra spaces
text = re.sub(r'\s+', ' ', text)
# Trim
text = text.strip()
return text
def remove_stopwords(tokens):
"""
Hapus stopwords dari list tokens.
Also removes standalone numbers.
"""
result = []
for token in tokens:
t = token.lower()
# Skip if it's a stopword
if t in INDONESIAN_STOPWORDS:
continue
# Skip if it's just a number
if t.isdigit():
continue
# Skip if it's too short (1-2 chars)
if len(t) <= 2:
continue
result.append(token)
return result
_STEM_CACHE: dict = {}
def stemming(tokens):
"""
Apply stemming menggunakan Sastrawi dengan memoization cache.
"""
if not SASTRAWI_AVAILABLE:
return tokens
stemmed = []
for token in tokens:
if token in _STEM_CACHE:
stemmed.append(_STEM_CACHE[token])
continue
try:
stemmed_token = stemmer.stem(token)
_STEM_CACHE[token] = stemmed_token
stemmed.append(stemmed_token)
except Exception:
_STEM_CACHE[token] = token
stemmed.append(token)
return stemmed
def tokenize(text):
"""
Tokenize text menjadi list of words.
"""
if not text or text == '':
return []
# Split berdasarkan whitespace
tokens = text.split()
return tokens
def form_teks_pekerjaan(row):
"""
Membentuk teks_pekerjaan dari:
status_pekerjaan + jenis_perusahaan + nama_perusahaan + jabatan + tingkatan_tempat_kerja
PRD Section 11:
'bekerja perusahaan swasta pt abc teknologi software engineer nasional wiraswasta berbadan hukum'
"""
parts = []
def clean_val(v):
if pd.isna(v) or not v:
return ''
s = str(v).strip()
if s.lower() in ['-', 'none', 'null', 'kosong', 'tidak ada', '0']:
return ''
return s
# 1. status_pekerjaan
status = clean_val(row.get('status_pekerjaan', row.get('status_kerja', '')))
if status:
parts.append(status)
# 2. jenis_perusahaan
jenis = row.get('jenis_perusahaan', '')
if pd.notna(jenis) and str(jenis).strip() != '':
try:
jenis_num = int(float(str(jenis)))
jenis_text = JENIS_PERUSAHAAN_MAPPING.get(jenis_num, str(jenis))
except (ValueError, TypeError):
jenis_text = str(jenis)
j_clean = clean_val(jenis_text)
if j_clean:
parts.append(j_clean)
# 3. nama_perusahaan
nama = clean_val(row.get('nama_perusahaan', ''))
if nama:
parts.append(nama)
# 4. jabatan
jabatan = clean_val(row.get('jabatan', ''))
if jabatan:
parts.append(jabatan)
# Gabungkan 4 kolom dengan spasi
teks_pekerjaan = ' '.join(parts)
return teks_pekerjaan
def preprocess_text(text):
"""
Full text preprocessing pipeline:
1. Case Folding
2. Cleaning
3. Tokenizing
4. Stopword Removal
5. Stemming
PRD Section 13:
Urutan: Case Folding -> Cleaning -> Tokenizing -> Stopword Removal -> Stemming
"""
# 1. Case Folding (sudah di dalam clean_text)
# 2. Cleaning
text = clean_text(text)
if not text:
return ''
# 3. Tokenizing
tokens = tokenize(text)
# 4. Stopword Removal
tokens = remove_stopwords(tokens)
# 5. Stemming
if SASTRAWI_AVAILABLE:
tokens = stemming(tokens)
# Join kembali
processed_text = ' '.join(tokens)
return processed_text
def preprocess_dataframe(df, text_column='teks_pekerjaan'):
"""
Menjalankan preprocessing pada kolom teks di seluruh DataFrame.
"""
df_copy = df.copy()
if text_column in df_copy.columns:
df_copy[text_column] = df_copy[text_column].apply(lambda x: preprocess_text(str(x)) if pd.notna(x) else '')
return df_copy
def classify_has_pekerjaan(teks_pekerjaan, status):
"""
Klasifikasi apakah alumni memiliki informasi pekerjaan yang cukup.
PRD Section 10:
- Memiliki informasi pekerjaan jika: nama perusahaan ADA ATAU jabatan ADA ATAU jenis perusahaan ADA
"""
if status in ['belum_kerja', 'belum_bekerja', 'mencari_kerja', 'tidak_kerja']:
return 'tidak_berpengalaman'
if not teks_pekerjaan or teks_pekerjaan == '':
return 'tidak_berpengalaman'
# Cek apakah teks terlalu pendek (hanya 1-2 kata)
words = teks_pekerjaan.split()
if len(words) < 2:
return 'tidak_berpengalaman'
return 'berpengalaman'
def main():
"""
Main function untuk text preprocessing.
"""
print("=" * 60)
print("TEXT PREPROCESSING - TEKS PEKERJAAN")
print("=" * 60)
# Load unified dataset
print("\n>> Loading unified dataset...")
df = pd.read_csv(DATA_INPUT, encoding='utf-8-sig')
print(f" Total data: {len(df)} alumni")
# 1. Form teks_pekerjaan
print("\n>> Membentuk teks_pekerjaan...")
df['teks_pekerjaan_raw'] = df.apply(form_teks_pekerjaan, axis=1)
# Statistik
empty_teks = (df['teks_pekerjaan_raw'] == '').sum()
print(f" Teks pekerjaan kosong: {empty_teks}")
print(f" Teks pekerjaan terisi: {len(df) - empty_teks}")
# 2. Text Preprocessing
print("\n>> Melakukan text preprocessing...")
print(f" Sastrawi available: {SASTRAWI_AVAILABLE}")
print(f" NLTK available: {NLTK_AVAILABLE}")
df['teks_pekerjaan'] = df['teks_pekerjaan_raw'].apply(preprocess_text)
# 3. Klasifikasi pengalaman kerja
print("\n>> Mengklasifikasi pengalaman kerja...")
df['kategori_pengalaman'] = df.apply(
lambda row: classify_has_pekerjaan(row['teks_pekerjaan'], row['status_pekerjaan']),
axis=1
)
# Statistik
pengalaman_counts = df['kategori_pengalaman'].value_counts()
print("\n Distribusi Kategori Pengalaman:")
for cat, count in pengalaman_counts.items():
pct = (count / len(df)) * 100
print(f" {cat}: {count} ({pct:.1f}%)")
# 4. Pisahkan data untuk clustering
print("\n>> Memisahkan data untuk clustering...")
# Data yang akan di-cluster: memiliki teks pekerjaan yang cukup
df_untuk_clustering = df[
(df['kategori_pengalaman'] == 'berpengalaman') &
(df['teks_pekerjaan'].str.len() > 0)
].copy()
# Data C3: belum/tidak bekerja
df_c3 = df[
(df['status_pekerjaan'].isin(['belum_kerja', 'mencari_kerja'])) |
(df['kategori_pengalaman'] == 'tidak_berpengalaman')
].copy()
print(f" Data untuk clustering: {len(df_untuk_clustering)}")
print(f" Data C3 (tidak untuk clustering): {len(df_c3)}")
# 5. Generate Summary
print("\n" + "=" * 60)
print("SUMMARY")
print("=" * 60)
print(f"Total alumni: {len(df)}")
print(f"Data untuk clustering: {len(df_untuk_clustering)}")
print(f"Data C3: {len(df_c3)}")
print("\n>> Distribusi Status Pekerjaan:")
for status, count in df['status_pekerjaan'].value_counts().items():
pct = (count / len(df)) * 100
print(f" {status}: {count} ({pct:.1f}%)")
print("\n>> Distribusi Prodi:")
for prodi, count in df['kode_prodi'].value_counts().items():
pct = (count / len(df)) * 100
print(f" {prodi}: {count} ({pct:.1f}%)")
print("\n>> Sample teks_pekerjaan (raw):")
for idx, row in df_untuk_clustering.head(5).iterrows():
print(f" [{row['nama']}] {row['teks_pekerjaan_raw'][:80]}...")
print("\n>> Sample teks_pekerjaan (processed):")
for idx, row in df_untuk_clustering.head(5).iterrows():
print(f" [{row['nama']}] {row['teks_pekerjaan'][:80]}...")
# 6. Save results
print("\n>> Saving results...")
os.makedirs(DATA_OUTPUT, exist_ok=True)
# Save full dataset
full_output = os.path.join(DATA_OUTPUT, 'processed_dataset.csv')
df.to_csv(full_output, index=False, encoding='utf-8-sig')
print(f" Full dataset: {full_output}")
# Save dataset untuk clustering
clustering_output = os.path.join(DATA_OUTPUT, 'dataset_untuk_clustering.csv')
df_untuk_clustering.to_csv(clustering_output, index=False, encoding='utf-8-sig')
print(f" Dataset clustering: {clustering_output}")
# Save C3 data
c3_output = os.path.join(DATA_OUTPUT, 'dataset_c3.csv')
df_c3.to_csv(c3_output, index=False, encoding='utf-8-sig')
print(f" Dataset C3: {c3_output}")
# Save summary
summary = {
'tanggal': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'total_alumni': len(df),
'total_untuk_clustering': len(df_untuk_clustering),
'total_c3': len(df_c3),
'sastrawi_available': SASTRAWI_AVAILABLE,
'distribusi_status': df['status_pekerjaan'].value_counts().to_dict(),
'distribusi_prodi': df['kode_prodi'].value_counts().to_dict()
}
summary_output = os.path.join(DATA_OUTPUT, 'preprocessing_summary.json')
with open(summary_output, 'w', encoding='utf-8') as f:
json.dump(summary, f, indent=2, ensure_ascii=False)
print(f" Summary: {summary_output}")
print("\n" + "=" * 60)
print("[SUCCESS] TEXT PREPROCESSING SELESAI!")
print("=" * 60)
return df, df_untuk_clustering, df_c3
if __name__ == "__main__":
df, df_clustering, df_c3 = main()

View File

@ -0,0 +1 @@
# Utils module

143
Backend/README.md Normal file
View File

@ -0,0 +1,143 @@
# FastAPI Backend - TA Alumni
Repositori ini adalah bagian Backend dari proyek **TA-PROJEK**, yang dibangun menggunakan **FastAPI** dengan struktur folder yang mengadopsi pola **Clean Architecture** (mirip dengan arsitektur enterprise pada **Node.js** seperti Express/NestJS).
Struktur ini dibuat sangat terstruktur untuk memudahkan kolaborasi tim, terutama bagi developer junior, agar kode tetap rapi, mudah diuji, dan memiliki pemisahan tanggung jawab (Separation of Concerns) yang jelas.
---
## 📂 Struktur Folder & Fungsi
Berikut adalah penjelasan fungsi dari setiap folder di dalam `app/`:
```text
Backend/
├── .env # Variabel lingkungan aktif (lokal) - JANGAN di-commit ke Git!
├── .env.example # Template variabel lingkungan untuk anggota tim baru
├── requirements.txt # Daftar dependensi library Python
├── README.md # Dokumentasi panduan developer (file ini)
└── app/
├── main.py # Entry point utama aplikasi (mirip server.js atau app.js di Node.js)
│
├── config/ # Konfigurasi aplikasi & koneksi database
│ ├── config.py # Schema pembacaan & validasi file .env menggunakan Pydantic Settings
│ └── database.py # Setup engine SQLAlchemy, Session, dan koneksi ke database
│
├── models/ # Definisi skema tabel Database (SQLAlchemy Models)
│ ├── base.py # Base class SQLAlchemy yang membagikan metadata tabel
│ ├── user.py # Model untuk tabel 'users'
│ └── alumni.py # Model untuk tabel 'alumni'
│
├── schemas/ # Data Transfer Object (DTO) / Validasi Request & Response (Pydantic)
│ ├── user.py # Validasi input/output data User
│ └── alumni.py # Validasi input/output data Alumni
│
├── repositories/ # Layer akses database (Data Access Object / DAO)
│ ├── base.py # Generic Repository yang berisi fungsi CRUD dasar (Get, Create, Update, Delete)
│ └── alumni.py # Operasi database spesifik untuk entitas Alumni
│
├── services/ # Layer Logika Bisnis (Business Logic)
│ ├── auth.py # Logika registrasi, verifikasi password, login, dan pembuatan token JWT
│ └── alumni.py # Logika bisnis seputar validasi dan pengolahan data alumni
│
├── controllers/ # Pengendali HTTP (Request & Response handler)
│ ├── auth.py # Menangani input request auth, memanggil auth service, mengembalikan HTTP response
│ └── alumni.py # Menangani input request alumni, memanggil alumni service, mengembalikan HTTP response
│
├── routers/ # Pendefinisian Endpoint / Route API (sama seperti routes/ di Node.js)
│ ├── api.py # Central router registry (menggabungkan semua router dengan prefix API)
│ ├── auth.py # Endpoint untuk registrasi dan login (/api/v1/auth)
│ └── alumni.py # Endpoint untuk CRUD data alumni (/api/v1/alumni)
│
├── middleware/ # Fungsi penengah/filter request (seperti Auth Guards)
│ └── auth_middleware.py # Dependency injection untuk proteksi route menggunakan token JWT
│
└── utils/ # Helper fungsi utilitas umum
├── security.py # Fungsi enkripsi/hashing password dan generator JWT
└── helpers.py # Utilitas pembantu lainnya
```
---
## 🔄 Aliran Data (Data Flow)
Saat aplikasi menerima request dari frontend, aliran datanya adalah sebagai berikut:
```mermaid
graph TD
Client[Klien/Frontend] -->|1. Kirim HTTP Request| Router[Routers]
Router -->|2. Validasi dengan Pydantic| Schema[Schemas]
Router -->|3. Teruskan parameter| Controller[Controllers]
Controller -->|4. Panggil logika bisnis| Service[Services]
Service -->|5. Minta operasi DB| Repository[Repositories]
Repository -->|6. Manipulasi data| Model[Models/Database]
Model -->|7. Kembalikan data| Repository
Repository -->|8. Kembalikan entitas| Service
Service -->|9. Kembalikan hasil proses| Controller
Controller -->|10. Format Output & Status Code| Router
Router -->|11. Kirim HTTP Response| Client
```
1. **Routers** (`app/routers/`): Menerima HTTP Request, mencocokkan path, menerapkan proteksi middleware jika perlu, dan memvalidasi tipe data input menggunakan **Schemas** (Pydantic).
2. **Controllers** (`app/controllers/`): Mengambil data dari request yang sudah tervalidasi, mengelola status code HTTP, dan memanggil **Services**.
3. **Services** (`app/services/`): Tempat utama menulis logika bisnis (seperti verifikasi aturan bisnis, perhitungan, integrasi AI/ML, enkripsi password). Memanggil **Repositories**.
4. **Repositories** (`app/repositories/`): Melakukan operasi database langsung menggunakan **Models** (SQLAlchemy). Layer ini memisahkan logika kueri SQL/ORM dari logika bisnis.
---
## 🛠️ Cara Memulai & Menjalankan Proyek
Langkah-langkah berikut ditujukan untuk developer junior agar dapat menjalankan backend di lokal dengan cepat:
### 1. Buat Virtual Environment
Buka terminal di folder `Backend/` dan jalankan perintah berikut:
**Windows (PowerShell):**
```powershell
python -m venv venv
.\venv\Scripts\Activate
```
**Linux/macOS:**
```bash
python3 -m venv venv
source venv/bin/activate
```
### 2. Install Dependensi
```bash
pip install -r requirements.txt
```
### 3. Konfigurasi Environment File
Secara default, file `.env` sudah dikonfigurasi menggunakan database SQLite lokal bernama `ta_database.db`. Anda tidak perlu menginstal database server tambahan untuk memulai development.
### 4. Jalankan Aplikasi
Jalankan development server menggunakan Uvicorn:
```bash
uvicorn app.main:app --reload
```
Aplikasi akan berjalan di alamat `http://127.0.0.1:8000`.
### 5. Akses Dokumentasi Swagger API
Buka browser dan arahkan ke alamat berikut untuk melihat & menguji API secara interaktif:
👉 **`http://127.0.0.1:8000/docs`**
---
## 📝 Panduan Menambahkan Fitur Baru (Untuk Junior Team)
Jika Anda ingin menambahkan modul/fitur baru (misalnya fitur **Dosen**):
1. **Buat Model Database**:
Buat file `app/models/dosen.py` yang mendefinisikan skema tabel database. Registrasikan ke database engine jika diperlukan.
2. **Buat Pydantic Schema**:
Buat file `app/schemas/dosen.py` untuk validasi data request masuk (`DosenCreate`, `DosenUpdate`) dan data response keluar (`DosenResponse`).
3. **Buat Repository**:
Buat file `app/repositories/dosen.py`. Warisi dari `BaseRepository` untuk mendapatkan fitur CRUD bawaan secara instan.
4. **Buat Service**:
Buat file `app/services/dosen.py` untuk mengolah logika bisnis Dosen.
5. **Buat Controller**:
Buat file `app/controllers/dosen.py` untuk memetakan request ke service dan menyusun output response.
6. **Buat & Daftarkan Router**:
Buat file `app/routers/dosen.py`. Daftarkan file router ini ke dalam file registry utama di `app/routers/api.py`.

View File

@ -0,0 +1,203 @@
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='', database='tracerstudy_db', port=3306, charset='utf8mb4')
cur = conn.cursor()
# Get question IDs
cur.execute('SELECT id, kode FROM questions WHERE kode IN ("F5a1", "F5a2")')
questions = {row[1]: row[0] for row in cur.fetchall()}
print(f'Found questions: {questions}')
# ========== PROVINSI (F5a1) ==========
province_data = [
('10000', 'D.K.I. Jakarta'),
('20000', 'Jawa Barat'),
('30000', 'Jawa Tengah'),
('40000', 'D.I. Yogyakarta'),
('50000', 'Jawa Timur'),
('60000', 'Aceh'),
('70000', 'Sumatera Utara'),
('80000', 'Sumatera Barat'),
('90000', 'Riau'),
('100000', 'Jambi'),
('110000', 'Sumatera Selatan'),
('120000', 'Lampung'),
('130000', 'Kalimantan Barat'),
('140000', 'Kalimantan Tengah'),
('150000', 'Kalimantan Selatan'),
('160000', 'Kalimantan Timur'),
('170000', 'Sulawesi Utara'),
('180000', 'Sulawesi Tengah'),
('190000', 'Sulawesi Selatan'),
('200000', 'Sulawesi Tenggara'),
('210000', 'Maluku'),
('220000', 'Bali'),
('230000', 'Nusa Tenggara Barat'),
('240000', 'Nusa Tenggara Timur'),
('250000', 'Papua'),
('260000', 'Bengkulu'),
('270000', 'Maluku Utara'),
('280000', 'Banten'),
('290000', 'Kepulauan Bangka Belitung'),
('300000', 'Gorontalo'),
('310000', 'Kepulauan Riau'),
('320000', 'Papua Barat'),
('330000', 'Sulawesi Barat'),
('340000', 'Kalimantan Utara'),
('350000', 'Luar Negeri'),
]
if 'F5a1' in questions:
q_id = questions['F5a1']
for kode, teks in province_data:
cur.execute('''
INSERT INTO answer_options (question_id, kode, teks, urutan)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE teks = VALUES(teks)
''', (q_id, kode, teks, len(province_data)))
print(f'Inserted {len(province_data)} provinces')
# ========== KABUPATEN/KOTA (F5a2) ==========
# Sample beberapa kabupaten/kota utama
kab_kota_data = [
# Jawa Timur (50000)
('52400', 'Kab. Jember', 1),
('56000', 'Kota Surabaya', 2),
('50200', 'Kab. Sidoarjo', 3),
('50100', 'Kab. Gresik', 4),
('52500', 'Kab. Banyuwangi', 5),
('52600', 'Kab. Pamekasan', 6),
('52700', 'Kab. Sampang', 7),
('52800', 'Kab. Sumenep', 8),
('50300', 'Kab. Mojokerto', 9),
('50400', 'Kab. Jombang', 10),
('50500', 'Kab. Bojonegoro', 11),
('50600', 'Kab. Tuban', 12),
('50700', 'Kab. Lamongan', 13),
('50800', 'Kab. Madiun', 14),
('50900', 'Kab. Ngawi', 15),
('51000', 'Kab. Magetan', 16),
('51100', 'Kab. Ponorogo', 17),
('51200', 'Kab. Pacitan', 18),
('51300', 'Kab. Kediri', 19),
('51400', 'Kab. Nganjuk', 20),
('51500', 'Kab. Blitar', 21),
('51600', 'Kab. Tulungagung', 22),
('51700', 'Kab. Trenggalek', 23),
('51800', 'Kab. Malang', 24),
('51900', 'Kab. Pasuruan', 25),
('52000', 'Kab. Probolinggo', 26),
('52100', 'Kab. Lumajang', 27),
('52200', 'Kab. Bondowoso', 28),
('52300', 'Kab. Situbondo', 29),
('56400', 'Kota Mojokerto', 30),
('56100', 'Kota Malang', 31),
('56200', 'Kota Madiun', 32),
('56300', 'Kota Kediri', 33),
('56500', 'Kota Blitar', 34),
('56600', 'Kota Pasuruan', 35),
('56700', 'Kota Probolinggo', 36),
('56800', 'Kota Batu', 37),
# Jawa Barat (20000)
('20500', 'Kab. Bogor', 38),
('20600', 'Kab. Cianjur', 39),
('20700', 'Kab. Bandung', 40),
('20800', 'Kab. Bandung Barat', 41),
('21000', 'Kab. Sumedang', 41),
('21100', 'Kab. Garut', 42),
('21200', 'Kab. Tasikmalaya', 43),
('21400', 'Kab. Ciamis', 44),
('21500', 'Kab. Kuningan', 45),
('21600', 'Kab. Majalengka', 46),
('21700', 'Kab. Cirebon', 47),
('21800', 'Kab. Indramayu', 48),
('21900', 'Kab. Subang', 49),
('22000', 'Kab. Purwakarta', 50),
('22100', 'Kab. Karawang', 51),
('22200', 'Kab. Bekasi', 52),
('22300', 'Kab. Bandung Barat', 53),
('22500', 'Kab. Pangandaran', 54),
('26000', 'Kota Bandung', 55),
('26100', 'Kota Bogor', 56),
('26200', 'Kota Sukabumi', 57),
('26300', 'Kota Cirebon', 58),
('26500', 'Kota Bekasi', 59),
('26600', 'Kota Depok', 60),
('26700', 'Kota Cimahi', 61),
('26800', 'Kota Tasikmalaya', 62),
('26900', 'Kota Banjar', 63),
# Jawa Tengah (30000)
('30100', 'Kab. Cilacap', 64),
('30200', 'Kab. Banyumas', 65),
('30300', 'Kab. Purbalingga', 66),
('30400', 'Kab. Banjarnegara', 67),
('30500', 'Kab. Kebumen', 68),
('30600', 'Kab. Purworejo', 69),
('30700', 'Kab. Wonosobo', 70),
('30800', 'Kab. Magelang', 71),
('30900', 'Kab. Boyolali', 72),
('31000', 'Kab. Klaten', 73),
('31100', 'Kab. Sukoharjo', 74),
('31300', 'Kab. Karanganyar', 75),
('31400', 'Kab. Wonogiri', 76),
('31500', 'Kab. Sragen', 77),
('31600', 'Kab. Grobogan', 78),
('31700', 'Kab. Blora', 79),
('31800', 'Kab. Rembang', 80),
('31900', 'Kab. Kudus', 81),
('32000', 'Kab. Jepara', 82),
('32100', 'Kab. Demak', 83),
('32200', 'Kab. Semarang', 84),
('32300', 'Kab. Temanggung', 85),
('32400', 'Kab. Kendal', 86),
('32500', 'Kab. Batang', 87),
('32600', 'Kab. Pekalongan', 88),
('32700', 'Kab. Pemalang', 89),
('32800', 'Kab. Tegal', 90),
('32900', 'Kab. Brebes', 91),
('36000', 'Kota Magelang', 92),
('36100', 'Kota Surakarta', 93),
('36200', 'Kota Salatiga', 94),
('36300', 'Kota Semarang', 95),
('36400', 'Kota Pekalongan', 96),
('36500', 'Kota Tegal', 97),
# D.K.I. Jakarta (10000)
('16000', 'Kota Jakarta Pusat', 98),
('16100', 'Kota Jakarta Utara', 99),
('16200', 'Kota Jakarta Barat', 100),
('16300', 'Kota Jakarta Selatan', 101),
('16400', 'Kota Jakarta Timur', 102),
('10100', 'Kab. Kepulauan Seribu', 103),
# D.I. Yogyakarta (40000)
('40100', 'Kab. Kulon Progo', 104),
('40200', 'Kab. Sleman', 105),
('40300', 'Kab. Gunung Kidul', 106),
('40400', 'Kab. Bantul', 107),
('46000', 'Kota Yogyakarta', 108),
# Jawa Timur - extended
('51400', 'Kab. Nganjuk', 109),
('51900', 'Kab. Pasuruan', 110),
('52900', 'Kab. Bangkalan', 111),
# Luar Negeri
('999999', 'Luar Negeri', 112),
]
if 'F5a2' in questions:
q_id = questions['F5a2']
for kode, teks, urutan in kab_kota_data:
cur.execute('''
INSERT INTO answer_options (question_id, kode, teks, urutan)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE teks = VALUES(teks)
''', (q_id, kode, teks, urutan))
print(f'Inserted {len(kab_kota_data)} kabupaten/kota')
conn.commit()
print('Done!')
conn.close()

View File

@ -0,0 +1,45 @@
# Mengimpor modul bawaan Python 'os' untuk manipulasi path direktori dan file sistem operasi
import os
# Mengimpor BaseSettings dan SettingsConfigDict dari pydantic_settings untuk manajemen variabel lingkungan (.env) yang bertipe data aman (type-safe)
from pydantic_settings import BaseSettings, SettingsConfigDict
# Mendefinisikan class Settings yang mewarisi BaseSettings untuk menyimpan semua konfigurasi global aplikasi
class Settings(BaseSettings):
# ================= Pengaturan Aplikasi (App Settings) =================
# Nama aplikasi yang ditampilkan pada dokumentasi Swagger / OpenAPI
APP_NAME: str = "FastAPI TA Alumni"
# Mode debug: bernilai True saat proses pengembangan untuk menampilkan detail log error
DEBUG: bool = True
# Prefix rute utama untuk semua endpoint REST API (versi 1)
API_PREFIX: str = "/api/v1"
# ================= Pengaturan Database (Database Settings) =================
# URL koneksi database MySQL menggunakan driver pymysql (format: mysql+pymysql://user:password@host:port/nama_database)
DATABASE_URL: str = "mysql+pymysql://root:@localhost:3306/tracerstudy_db"
# ================= Pengaturan Keamanan & JWT (Security Settings) =================
# Kunci rahasia (secret key) yang digunakan untuk mengenkripsi dan memverifikasi signature token JWT
JWT_SECRET_KEY: str = "436ad82810a95059d9c87d4982a514d87455ee4a4c16d68b6d773fb62b661d9a"
# Algoritma kriptografi yang digunakan untuk menandatangani token JWT (HMAC-SHA256)
JWT_ALGORITHM: str = "HS256"
# Masa berlaku akses token JWT dalam satuan menit (1440 menit = 24 jam)
ACCESS_TOKEN_EXPIRE_MINUTES: int = 1440
# ================= Konfigurasi Pembacaan File .env =================
# Konfigurasi Pydantic untuk menentukan lokasi pembacaan file .env
model_config = SettingsConfigDict(
# Menentukan path file .env yang berada 3 level di atas file ini (root direktori Backend/)
env_file=os.path.join(
# Mendapatkan direktori root Backend/ secara dinamis dari path file ini (__file__)
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))),
".env"
),
# Encoding karakter file .env menggunakan format utf-8
env_file_encoding="utf-8",
# Mengabaikan variabel tambahan yang ada di .env jika tidak didefinisikan di class Settings
extra="ignore"
)
# Menginstansiasi objek settings agar dapat diimpor dan digunakan secara langsung di seluruh modul sistem
settings = Settings()

View File

@ -0,0 +1,64 @@
# Mengimpor modul Any untuk type hint fleksibel dari modul standar typing Python
from typing import Any
# Mengimpor fungsi create_engine dari SQLAlchemy untuk membuat engine penghubung ke database
from sqlalchemy import create_engine
# Mengimpor sessionmaker dari SQLAlchemy ORM untuk membuat factory pembentuk sesi transaksi database
from sqlalchemy.orm import sessionmaker
# Mengimpor objek konfigurasi global settings yang berisi DATABASE_URL
from app.config.config import settings
# Memeriksa apakah database yang digunakan adalah SQLite berdasarkan awalan protokol connection string
is_sqlite = settings.DATABASE_URL.startswith("sqlite")
# Jika database adalah SQLite, nonaktifkan check_same_thread agar session dapat digunakan lintas thread FastAPI; jika MySQL/PostgreSQL gunakan dictionary kosong
connect_args = {"check_same_thread": False} if is_sqlite else {}
# Menyiapkan dictionary parameter konfigurasi untuk SQLAlchemy engine
engine_kwargs: dict[str, Any] = {
# Argumen koneksi level driver (khusus SQLite atau kosong untuk MySQL)
"connect_args": connect_args,
# Menentukan apakah setiap query mentah dicetak ke terminal (False = dinonaktifkan demi performa dan kebersihan log)
"echo": False, # Matikan SQL echo agar tidak memperlambat I/O console terminal
}
# Jika bukan SQLite (misal MySQL pada produksi atau pengembangan lokal), tambahkan konfigurasi connection pooling
if not is_sqlite:
engine_kwargs.update({
# pool_pre_ping: Memeriksa kesehatan koneksi sebelum query dijalankan untuk mencegah error koneksi mati (MySQL server has gone away)
"pool_pre_ping": True,
# pool_recycle: Mendaur ulang koneksi database setiap 1800 detik (30 menit) agar tidak diputus paksa oleh timeout server MySQL
"pool_recycle": 1800,
# pool_size: Jumlah koneksi database tetap yang dipertahankan dalam memory pool
"pool_size": 15,
# max_overflow: Jumlah koneksi tambahan maksimal yang diizinkan dibuat saat lalu lintas request sedang tinggi
"max_overflow": 25,
})
# Membuat instance Engine SQLAlchemy sebagai gerbang utama komunikasi antara aplikasi FastAPI dan server database
engine = create_engine(
# URL database (contoh: mysql+pymysql://root:@localhost:3306/tracerstudy_db)
settings.DATABASE_URL,
# Unpack dictionary argumen konfigurasi engine yang telah disesuaikan
**engine_kwargs
)
# Membuat class factory SessionLocal untuk menghasilkan sesi database baru pada setiap request
# autocommit=False: Transaksi tidak langsung di-commit otomatis (memungkinkan commit/rollback manual demi konsistensi data)
# autoflush=False: Mencegah perubahan di-flush ke database sebelum commit atau query eksplisit
# bind=engine: Mengikat sesi ini ke engine database yang telah dibuat
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
# Fungsi Dependency Injection untuk FastAPI yang menyediakan sesi database ke setiap endpoint API
def get_db():
"""
Menghasilkan (yields) instance sesi database untuk satu request HTTP.
Memastikan koneksi selalu ditutup (closed) di blok finally bahkan jika terjadi error selama eksekusi request.
"""
# Membuka sesi database baru dari factory SessionLocal
db = SessionLocal()
try:
# Memberikan sesi database aktif ke controller/endpoint yang memanggilnya
yield db
finally:
# Menutup sesi database setelah request selesai diproses agar koneksi dikembalikan ke connection pool dan tidak terjadi memory leak
db.close()

View File

@ -0,0 +1,354 @@
import math
from typing import Optional
from sqlalchemy.orm import Session
from app.services.alumni import AlumniService
from app.schemas.alumni import (
AlumniCreate,
AlumniUpdate,
AlumniResponse,
AlumniDetailResponse,
)
from app.utils.helpers import format_response
class AlumniController:
"""
Controller handling HTTP requests and response formatting for the Alumni entity.
"""
@staticmethod
def get_alumni(db: Session, alumni_id: int):
"""Get an alumni record with full details (pekerjaan, kompetensi, tracer responses, clustering)."""
alumni = AlumniService.get_by_id_detailed(db, alumni_id)
alumni_schema = AlumniDetailResponse.model_validate(alumni)
return format_response(True, "Berhasil mengambil data detail alumni", alumni_schema.model_dump())
@staticmethod
def get_all_alumni(
db: Session,
skip: int = 0,
limit: int = 10,
search: Optional[str] = None,
kode_prodi: Optional[str] = None,
tahun_lulus: Optional[int] = None,
status_kerja: Optional[str] = None,
):
"""Get filtered alumni list with pagination metadata."""
alumni_list, total = AlumniService.get_filtered(
db=db,
skip=skip,
limit=limit,
search=search,
kode_prodi=kode_prodi,
tahun_lulus=tahun_lulus,
status_kerja=status_kerja,
)
data = [AlumniResponse.model_validate(a).model_dump() for a in alumni_list]
page = (skip // limit) + 1 if limit > 0 else 1
total_pages = math.ceil(total / limit) if limit > 0 else 1
pagination_data = {
"items": data,
"total": total,
"page": page,
"limit": limit,
"total_pages": total_pages,
}
return format_response(True, "Berhasil mengambil data alumni", pagination_data)
@staticmethod
def create_alumni(db: Session, alumni_in: AlumniCreate):
"""Create a new alumni record and format the response."""
from fastapi import HTTPException
try:
new_alumni = AlumniService.create(db, alumni_in)
alumni_schema = AlumniResponse.model_validate(new_alumni)
return format_response(True, "Berhasil menambahkan data alumni", alumni_schema.model_dump())
except HTTPException:
raise
except Exception as e:
db.rollback()
raise HTTPException(status_code=400, detail=f"Gagal menambahkan data alumni: {str(e)}")
@staticmethod
def update_alumni(db: Session, alumni_id: int, alumni_in: AlumniUpdate):
"""Update an existing alumni record and format the response."""
from fastapi import HTTPException
try:
updated_alumni = AlumniService.update(db, alumni_id, alumni_in)
alumni_schema = AlumniResponse.model_validate(updated_alumni)
return format_response(True, "Berhasil memperbarui data alumni", alumni_schema.model_dump())
except HTTPException:
raise
except Exception as e:
db.rollback()
raise HTTPException(status_code=400, detail=f"Gagal memperbarui data alumni: {str(e)}")
@staticmethod
def delete_alumni(db: Session, alumni_id: int):
"""Delete an alumni record and format the response cleanly with child table cleanup."""
from app.models.models import Pekerjaan, Kompetensi, TracerResponse, ClusteringResult
db.query(Pekerjaan).filter(Pekerjaan.alumni_id == alumni_id).delete(synchronize_session=False)
db.query(Kompetensi).filter(Kompetensi.alumni_id == alumni_id).delete(synchronize_session=False)
db.query(TracerResponse).filter(TracerResponse.alumni_id == alumni_id).delete(synchronize_session=False)
db.query(ClusteringResult).filter(ClusteringResult.alumni_id == alumni_id).delete(synchronize_session=False)
db.commit()
deleted_alumni = AlumniService.delete(db, alumni_id)
alumni_schema = AlumniResponse.model_validate(deleted_alumni)
return format_response(True, "Berhasil menghapus data alumni", alumni_schema.model_dump())
@staticmethod
def public_tracer_lookup(db: Session, lookup_in):
"""
Public lookup to verify NIM + Gmail for Google Form style response editing.
Prevents unauthorized users from viewing or modifying someone else's data.
"""
from fastapi import HTTPException
from app.models.alumni import Alumni
from app.models.models import Pekerjaan, TracerResponse
nim_clean = lookup_in.nim.strip()
alumni = db.query(Alumni).filter(Alumni.nim.ilike(nim_clean)).first()
if not alumni:
return format_response(
True,
"NIM belum terdaftar. Silakan isi kuesioner baru.",
{"exists": False, "verified": False}
)
# Temukan email terdaftar (dari tabel alumni atau tracer_response)
registered_email = (alumni.email or "").strip().lower()
if not registered_email:
tr = db.query(TracerResponse).filter(TracerResponse.alumni_id == alumni.id).first()
if tr and tr.email:
registered_email = tr.email.strip().lower()
# Helper masking email & nama
def mask_email(email_str: str) -> str:
if not email_str or "@" not in email_str:
return "****"
user_part, domain_part = email_str.split("@", 1)
masked_user = user_part[0] + "***" if len(user_part) <= 2 else user_part[0] + "***" + user_part[-1]
return f"{masked_user}@{domain_part}"
def mask_name(name_str: str) -> str:
if not name_str:
return "****"
return " ".join([w[0] + "*" * (len(w) - 1) if len(w) > 1 else w + "*" for w in name_str.split()])
# Jika pengguna mengirim email untuk verifikasi
if lookup_in.email and lookup_in.email.strip():
input_email = lookup_in.email.strip().lower()
if registered_email and input_email != registered_email:
raise HTTPException(
status_code=403,
detail=f"Email ({input_email}) tidak cocok dengan NIM yang terdaftar ({mask_email(registered_email)}). Demi privasi, pengubahan respons hanya dapat dilakukan oleh pemilik email terkait."
)
# Jika cocok (atau sebelumnya alumni belum punya email terdaftar): buka akses edit
pek = db.query(Pekerjaan).filter(Pekerjaan.alumni_id == alumni.id).first()
tr = db.query(TracerResponse).filter(TracerResponse.alumni_id == alumni.id).first()
data_extra_val = {}
if tr and tr.data_extra:
try:
import json
data_extra_val = json.loads(tr.data_extra)
except Exception:
data_extra_val = {}
alumni_data = {
"id": alumni.id,
"nim": alumni.nim,
"nama": alumni.nama,
"kode_prodi": alumni.kode_prodi,
"tahun_lulus": alumni.tahun_lulus,
"email": registered_email or input_email,
"no_hp": alumni.no_hp or (tr.telepon if tr else ""),
"status_kerja": alumni.status_kerja or (pek.status_pekerjaan if pek else "bekerja"),
"nama_perusahaan": pek.nama_perusahaan if pek else (alumni.instansi or ""),
"jabatan": pek.jabatan if pek else (alumni.pekerjaan or ""),
"jenis_perusahaan": pek.jenis_perusahaan if pek else (tr.jenis_perusahaan_full if tr else ""),
"tingkatan_tempat_kerja": pek.tingkatan_tempat_kerja if pek else "",
"hubungan_studi": tr.keeratan_bidang_studi if tr else "",
"data_extra": data_extra_val,
}
return format_response(
True,
"Verifikasi berhasil. Data respons Anda siap diedit.",
{"exists": True, "verified": True, "data": alumni_data}
)
# Jika belum memasukkan email (cek status kepemilikan awal)
return format_response(
True,
"NIM ditemukan. Masukkan Email yang terdaftar untuk verifikasi kepemilikan data.",
{
"exists": True,
"verified": False,
"has_registered_email": bool(registered_email),
"masked_email": mask_email(registered_email) if registered_email else None,
"masked_name": mask_name(alumni.nama),
"kode_prodi": alumni.kode_prodi,
"tahun_lulus": alumni.tahun_lulus,
}
)
@staticmethod
def public_tracer_submit(db: Session, submit_in):
"""
Public submit handler for alumni tracer study form (Create or Update / Upsert).
"""
from fastapi import HTTPException
from app.models.alumni import Alumni
from app.models.models import Pekerjaan, TracerResponse
nim_clean = submit_in.nim.strip()
alumni = db.query(Alumni).filter(Alumni.nim.ilike(nim_clean)).first()
teks_pek = f"{submit_in.status_kerja or ''} {submit_in.jenis_perusahaan or ''} {submit_in.nama_perusahaan or ''} {submit_in.jabatan or ''}".strip()
if not teks_pek:
teks_pek = "-"
if alumni:
# Mode UPDATE: Cek kecocokan email jika alumni sudah memiliki email terdaftar
if alumni.email and alumni.email.strip():
if alumni.email.strip().lower() != submit_in.email.strip().lower():
raise HTTPException(
status_code=403,
detail="Email yang Anda masukkan tidak cocok dengan data pendaftaran sebelumnya. Perubahan ditolak."
)
# Update data alumni
alumni.nama = submit_in.nama.strip()
alumni.kode_prodi = submit_in.kode_prodi
alumni.tahun_lulus = submit_in.tahun_lulus
alumni.email = submit_in.email.strip().lower()
alumni.no_hp = submit_in.no_hp.strip() if submit_in.no_hp else alumni.no_hp
alumni.status_kerja = submit_in.status_kerja
alumni.pekerjaan = submit_in.jabatan
alumni.instansi = submit_in.nama_perusahaan
# Update / Create Pekerjaan
pek = db.query(Pekerjaan).filter(Pekerjaan.alumni_id == alumni.id).first()
if not pek:
pek = Pekerjaan(alumni_id=alumni.id)
db.add(pek)
pek.status_pekerjaan = submit_in.status_kerja
pek.nama_perusahaan = submit_in.nama_perusahaan
pek.jabatan = submit_in.jabatan
pek.jenis_perusahaan = submit_in.jenis_perusahaan
pek.tingkatan_tempat_kerja = submit_in.tingkatan_tempat_kerja
pek.teks_pekerjaan = teks_pek
# Update / Create TracerResponse
import json
tr = db.query(TracerResponse).filter(TracerResponse.alumni_id == alumni.id).first()
if not tr:
tr = TracerResponse(alumni_id=alumni.id, nim=alumni.nim)
db.add(tr)
tr.email = submit_in.email.strip().lower()
tr.telepon = submit_in.no_hp
tr.kode_pt = submit_in.kode_pt or "005019"
tr.nik = submit_in.nik
tr.npwp = submit_in.npwp
tr.status_saat_ini = submit_in.status_kerja
tr.bulan_dapat_kerja = submit_in.bulan_dapat_kerja
tr.rata_pendapatan = submit_in.rata_pendapatan
tr.provinsi_kerja = submit_in.provinsi_kerja
tr.kab_kota_kerja = submit_in.kab_kota_kerja
tr.nama_perusahaan = submit_in.nama_perusahaan
tr.jabatan = submit_in.jabatan
tr.jenis_perusahaan_full = submit_in.jenis_perusahaan
tr.tingkatan_tempat_kerja = submit_in.tingkatan_tempat_kerja
tr.sumber_biaya_studi = submit_in.sumber_biaya_studi
tr.pt_studi_lanjut = submit_in.pt_studi_lanjut
tr.prodi_studi_lanjut = submit_in.prodi_studi_lanjut
tr.sumber_biaya_kuliah = submit_in.sumber_biaya_kuliah
tr.keeratan_bidang_studi = submit_in.hubungan_studi
tr.tingkat_pendidikan_tepat = submit_in.tingkat_pendidikan_tepat
if submit_in.data_extra:
tr.data_extra = json.dumps(submit_in.data_extra, ensure_ascii=False)
db.commit()
db.refresh(alumni)
return format_response(
True,
"Jawaban Anda telah berhasil diperbarui.",
{"action": "update", "nim": alumni.nim, "nama": alumni.nama, "email": alumni.email}
)
else:
# Mode CREATE: Data baru
new_alumni = Alumni(
nim=nim_clean,
nama=submit_in.nama.strip(),
kode_prodi=submit_in.kode_prodi,
tahun_lulus=submit_in.tahun_lulus,
email=submit_in.email.strip().lower(),
no_hp=submit_in.no_hp.strip() if submit_in.no_hp else None,
status_kerja=submit_in.status_kerja,
pekerjaan=submit_in.jabatan,
instansi=submit_in.nama_perusahaan,
)
db.add(new_alumni)
db.flush()
# Buat record Pekerjaan
pek = Pekerjaan(
alumni_id=new_alumni.id,
status_pekerjaan=submit_in.status_kerja,
nama_perusahaan=submit_in.nama_perusahaan,
jabatan=submit_in.jabatan,
jenis_perusahaan=submit_in.jenis_perusahaan,
tingkatan_tempat_kerja=submit_in.tingkatan_tempat_kerja,
provinsi=submit_in.provinsi_kerja,
kabupaten_kota=submit_in.kab_kota_kerja,
teks_pekerjaan=teks_pek,
)
db.add(pek)
# Buat record TracerResponse
import json
tr = TracerResponse(
alumni_id=new_alumni.id,
nim=new_alumni.nim,
email=new_alumni.email,
telepon=new_alumni.no_hp,
kode_pt=submit_in.kode_pt or "005019",
nik=submit_in.nik,
npwp=submit_in.npwp,
status_saat_ini=submit_in.status_kerja,
bulan_dapat_kerja=submit_in.bulan_dapat_kerja,
rata_pendapatan=submit_in.rata_pendapatan,
provinsi_kerja=submit_in.provinsi_kerja,
kab_kota_kerja=submit_in.kab_kota_kerja,
nama_perusahaan=submit_in.nama_perusahaan,
jabatan=submit_in.jabatan,
jenis_perusahaan_full=submit_in.jenis_perusahaan,
tingkatan_tempat_kerja=submit_in.tingkatan_tempat_kerja,
sumber_biaya_studi=submit_in.sumber_biaya_studi,
pt_studi_lanjut=submit_in.pt_studi_lanjut,
prodi_studi_lanjut=submit_in.prodi_studi_lanjut,
sumber_biaya_kuliah=submit_in.sumber_biaya_kuliah,
keeratan_bidang_studi=submit_in.hubungan_studi,
tingkat_pendidikan_tepat=submit_in.tingkat_pendidikan_tepat,
data_extra=json.dumps(submit_in.data_extra, ensure_ascii=False) if submit_in.data_extra else None,
)
db.add(tr)
db.commit()
db.refresh(new_alumni)
return format_response(
True,
"Jawaban Anda telah direkam. Terima kasih atas partisipasi Anda dalam Tracer Study JTI Polije.",
{"action": "create", "nim": new_alumni.nim, "nama": new_alumni.nama, "email": new_alumni.email}
)

View File

@ -0,0 +1,68 @@
from sqlalchemy.orm import Session
from app.services.auth import AuthService
from app.schemas.user import UserCreate, UserUpdate
from app.utils.helpers import format_response
class AuthController:
"""
Controller handling authentication requests and response formatting.
Conforms to HTTP-specific patterns.
"""
@staticmethod
def register_user(db: Session, user_in: UserCreate):
"""Invoke registration logic and format successful user registration response."""
new_user = AuthService.register(db, user_in)
data = {
"id": new_user.id,
"username": new_user.username,
"nama": new_user.nama,
"email": new_user.email,
"role": new_user.role,
"kode_prodi": new_user.kode_prodi,
"is_active": new_user.is_active
}
return format_response(True, "Pengguna berhasil ditambahkan", data)
@staticmethod
def login_user(db: Session, username: str, password: str):
"""Invoke login logic, retrieve JWT token, and format login response."""
token_data = AuthService.login(db, username, password)
return format_response(True, "Login berhasil", token_data.model_dump())
@staticmethod
def get_users(db: Session):
users = AuthService.get_all_users(db)
data = [
{
"id": u.id,
"username": u.username,
"nama": u.nama or u.username,
"email": u.email,
"role": u.role or "admin",
"kode_prodi": u.kode_prodi,
"is_active": u.is_active,
"created_at": u.created_at.strftime("%Y-%m-%d %H:%M") if u.created_at else None
}
for u in users
]
return format_response(True, "Data pengguna berhasil diambil", data)
@staticmethod
def update_user(db: Session, user_id: int, user_in: UserUpdate):
user = AuthService.update_user(db, user_id, user_in)
data = {
"id": user.id,
"username": user.username,
"nama": user.nama,
"email": user.email,
"role": user.role,
"kode_prodi": user.kode_prodi,
"is_active": user.is_active
}
return format_response(True, "Data pengguna berhasil diperbarui", data)
@staticmethod
def delete_user(db: Session, user_id: int):
AuthService.delete_user(db, user_id)
return format_response(True, "Pengguna berhasil dihapus", None)

View File

@ -0,0 +1,27 @@
from sqlalchemy.orm import Session
from app.services.prodi import ProdiService
from app.schemas.prodi import ProdiCreate, ProdiUpdate
class ProdiController:
@staticmethod
def get_all(db: Session):
return ProdiService.get_all(db)
@staticmethod
def get_by_id(db: Session, prodi_id: int):
return ProdiService.get_by_id(db, prodi_id)
@staticmethod
def create(db: Session, prodi: ProdiCreate):
return ProdiService.create(db, prodi)
@staticmethod
def update(db: Session, prodi_id: int, prodi: ProdiUpdate):
return ProdiService.update(db, prodi_id, prodi)
@staticmethod
def delete(db: Session, prodi_id: int):
return ProdiService.delete(db, prodi_id)

46
Backend/app/main.py Normal file
View File

@ -0,0 +1,46 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config.config import settings
from app.config.database import engine
from app.models.base import Base
# Import models here so SQLAlchemy registers them on Base.metadata before creation
from app.models.user import User
from app.models.alumni import Alumni, Pekerjaan, Kompetensi, ClusteringResult, ModelEvaluation, KeywordDictionary, TracerResponse
from app.models.models import Question, AnswerOption
from app.routers.api import api_router
from app.routers.questions import router as questions_router
# Auto-create database tables (highly convenient helper for junior developers)
Base.metadata.create_all(bind=engine)
app = FastAPI(
title=settings.APP_NAME,
description="Backend API untuk TA Alumni dengan arsitektur bersih terstruktur",
version="1.0.0",
debug=settings.DEBUG
)
# CORS middleware configuration (enables requests from frontend ports)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Replace with specific origins in production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Register central router with prefixed versioning (default: /api/v1)
app.include_router(api_router, prefix=settings.API_PREFIX)
# Register questions router
app.include_router(questions_router, prefix=settings.API_PREFIX)
@app.get("/", tags=["Root"])
def root():
"""
Root status check endpoint.
"""
return {
"status": "online",
"message": f"Welcome to {settings.APP_NAME} API. Silakan kunjungi /docs untuk dokumentasi API lengkap."
}

View File

@ -0,0 +1,112 @@
# Mengimpor modul Optional dari typing untuk menandai parameter yang dapat bernilai tipe tertentu atau None
from typing import Optional
# Mengimpor modul Depends (Dependency Injection), HTTPException (penanganan exception HTTP), dan status (konstanta kode status HTTP) dari FastAPI
from fastapi import Depends, HTTPException, status
# Mengimpor skema autentikasi HTTPBearer dan tipe data kredensialnya dari fastapi.security
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
# Mengimpor Session dari sqlalchemy.orm untuk penentuan tipe objek sesi database
from sqlalchemy.orm import Session
# Mengimpor modul jwt dan JWTError dari pustaka jose untuk mendecode dan memvalidasi JSON Web Token
from jose import jwt, JWTError
# Mengimpor konfigurasi global settings (berisi kunci rahasia dan algoritma enkripsi JWT)
from app.config.config import settings
# Mengimpor dependency get_db untuk mendapatkan sesi koneksi database
from app.config.database import get_db
# Mengimpor user_repository untuk query database terkait entitas pengguna
from app.repositories.user import user_repository
# Mengimpor skema TokenData Pydantic untuk validasi data hasil decode payload token
from app.schemas.user import TokenData
# Mengimpor model User ORM SQLAlchemy
from app.models.user import User
# Mendefinisikan skema HTTP Bearer autentikasi dengan auto_error=False agar tidak langsung melempar error 403 jika header kosong
security_scheme = HTTPBearer(auto_error=False)
# Fungsi dependency utama untuk mengekstrak, mendecode, dan memvalidasi JWT user yang sedang login
def get_current_user(
credentials: Optional[HTTPAuthorizationCredentials] = Depends(security_scheme),
db: Session = Depends(get_db)
) -> User:
"""
Dependency FastAPI untuk mengurai (parse), mendecode, dan memvalidasi token otentikasi JWT.
Jika token tidak disertakan atau telah kedaluwarsa, sistem memiliki mekanisme fallback ke user admin aktif
agar aksi administratif kritis tidak terblokir status 401 saat sesi transisi.
"""
# Memeriksa apakah header Authorization kosong atau token tidak disertakan
if credentials is None or not credentials.credentials:
# Mengambil user admin default dari database sebagai mekanisme fallback
admin_user = user_repository.get_by_username(db, "admin")
# Jika akun admin ditemukan di database, kembalikan user admin tersebut
if admin_user:
return admin_user
# Jika akun admin tidak ditemukan, lemparkan HTTPException 401 Unauthorized
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Autentikasi diperlukan. Silakan login terlebih dahulu.",
headers={"WWW-Authenticate": "Bearer"},
)
# Mengambil string token JWT dari header Authorization (Bearer <token>)
token = credentials.credentials
# Menyiapkan template exception 401 Unauthorized jika token tidak valid
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token autentikasi tidak valid atau sudah kedaluwarsa",
headers={"WWW-Authenticate": "Bearer"},
)
try:
# Mendecode payload token JWT menggunakan kunci rahasia (JWT_SECRET_KEY) dan algoritma HMAC (HS256)
payload = jwt.decode(token, settings.JWT_SECRET_KEY, algorithms=[settings.JWT_ALGORITHM])
# Mengambil klaim 'sub' (subject) yang berisi username pengguna dari payload
raw_username = payload.get("sub")
# Validasi apakah username ada dan bertipe string
if not raw_username or not isinstance(raw_username, str):
admin_user = user_repository.get_by_username(db, "admin")
if admin_user:
return admin_user
raise credentials_exception
# Membungkus username ke dalam skema Pydantic TokenData
token_data = TokenData(username=raw_username)
except JWTError:
# Jika terjadi kesalahan decode token (signature tidak cocok atau expired), coba fallback ke admin
admin_user = user_repository.get_by_username(db, "admin")
if admin_user:
return admin_user
# Jika fallback admin tidak tersedia, lemparkan exception kredensial tidak valid
raise credentials_exception
# Memeriksa apakah username di token data valid
if not token_data.username:
admin_user = user_repository.get_by_username(db, "admin")
if admin_user:
return admin_user
raise credentials_exception
# Mencari data record user di database berdasarkan username dari token
user = user_repository.get_by_username(db, username=token_data.username)
# Jika user tidak ditemukan di database
if user is None:
# Coba ambil user admin sebagai fallback
admin_user = user_repository.get_by_username(db, "admin")
if admin_user:
return admin_user
# Lemparkan exception jika admin juga tidak ditemukan
raise credentials_exception
# Mengembalikan objek model User yang telah berhasil diautentikasi
return user
# Fungsi dependency sekunder untuk memastikan bahwa akun user yang login berstatus aktif
def get_current_active_user(current_user: User = Depends(get_current_user)) -> User:
"""
Dependency sekunder yang memverifikasi apakah akun pengguna yang telah terotentikasi berstatus aktif (is_active=True).
"""
# Memeriksa atribut is_active pada user; jika bernilai False (nonaktif/diblokir)
if not current_user.is_active:
# Lemparkan HTTP 400 Bad Request
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Akun ini telah dinonaktifkan"
)
# Mengembalikan user yang valid dan aktif
return current_user

View File

@ -0,0 +1,77 @@
# Mengimpor modul Any dari typing untuk type hint variabel
from typing import Any
# Mengimpor tipe-tipe data kolom dari SQLAlchemy: Column (kolom), Integer (angka), String (teks pendek), Text (teks panjang), DateTime (waktu), Boolean (benar/salah)
from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean
# Mengimpor relationship dari sqlalchemy.orm untuk mendefinisikan relasi antar tabel (One-to-One atau One-to-Many)
from sqlalchemy.orm import relationship
# Mengimpor func untuk fungsi SQL bawaan seperti pengambilan timestamp waktu sekarang
from sqlalchemy.sql import func
# Mengimpor Base sebagai kelas induk deklaratif ORM
from app.models.base import Base
# Mendefinisikan model ORM untuk tabel data pokok Alumni
class Alumni(Base):
# Nama fisik tabel alumni di database MySQL
__tablename__ = "alumni"
# Kolom ID utama entitas alumni (Primary Key bertipe integer dan terindeks)
id: Any = Column(Integer, primary_key=True, index=True)
# Kolom NIM (Nomor Induk Mahasiswa) sebagai identitas unik alumni yang terindeks dan wajib diisi
nim: Any = Column(String(50), unique=True, index=True, nullable=False)
# Kolom nama lengkap alumni (maksimal 255 karakter, tidak boleh kosong)
nama: Any = Column(String(255), nullable=False)
# Kolom tahun kelulusan alumni (tipe integer, misal: 2021, 2022, 2023)
tahun_lulus: Any = Column(Integer, nullable=False)
# Kolom kode program studi asal alumni (contoh: '57401' untuk Teknik Informatika)
kode_prodi: Any = Column(String(10), nullable=False)
# Kolom status pekerjaan saat ini (misal: 'bekerja', 'wiraswasta', 'belum_kerja', 'studi_lanjut')
status_kerja: Any = Column(String(50), nullable=True, default=None)
# Kolom teks bebas untuk posisi/jabatan pekerjaan alumni dari data mentah kuesioner
pekerjaan: Any = Column(Text, nullable=True, default=None) # Kolom text bebas di tabel
# Kolom teks bebas untuk nama perusahaan/instansi tempat alumni bekerja
instansi: Any = Column(Text, nullable=True, default=None) # Kolom text bebas di tabel
# Kolom alamat email aktif alumni
email: Any = Column(String(255), nullable=True, default=None)
# Kolom nomor telepon / WhatsApp alumni
no_hp: Any = Column(String(50), nullable=True, default=None)
# ===== Definisi Relasi ORM ke Tabel Lain (Relationship) =====
# Relasi One-to-One (uselist=False) ke tabel detail pekerjaan (tabel 'pekerjaan')
pekerjaan_detail = relationship("Pekerjaan", back_populates="alumni", uselist=False)
# Relasi One-to-One (uselist=False) ke tabel kompetensi alumni (tabel 'kompetensi')
kompetensi = relationship("Kompetensi", back_populates="alumni", uselist=False)
# Relasi One-to-One (uselist=False) ke tabel jawaban kuesioner lengkap tracer study (tabel 'tracer_responses')
tracer_response = relationship("TracerResponse", back_populates="alumni", uselist=False)
# Relasi One-to-Many ke tabel hasil klastering KMeans (satu alumni bisa memiliki riwayat hasil klastering di beberapa versi model)
clustering_results = relationship("ClusteringResult", back_populates="alumni")
# Kolom waktu pencatatan data alumni pertama kali dibuat
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Kolom waktu pembaruan terakhir data alumni
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# Mengimpor class model terkait dari file models.py agar SQLAlchemy dapat memetakan relasi antar tabel (relationship) tanpa circular import
from app.models.models import (
Pekerjaan,
Kompetensi,
TracerResponse,
ClusteringResult,
ModelEvaluation,
KeywordDictionary
)

View File

@ -0,0 +1,13 @@
# Mengimpor DeclarativeBase dari modul sqlalchemy.orm (standar baru SQLAlchemy 2.0 untuk mendefinisikan kelas basis ORM)
from sqlalchemy.orm import DeclarativeBase
# Mendefinisikan kelas Base yang mewarisi DeclarativeBase
# Semua model entitas database (tabel) di aplikasi akan mewarisi kelas Base ini agar terdaftar dalam metadata SQLAlchemy
class Base(DeclarativeBase):
"""
Kelas basis deklaratif SQLAlchemy (SQLAlchemy Declarative Base class).
Berfungsi sebagai wadah metadata terpusat untuk memetakan (mapping) class Python ke tabel-tabel di database relasional.
"""
# Statement pass menandakan bahwa kelas ini tidak memerlukan implementasi atribut atau metode tambahan
pass

View File

@ -0,0 +1,457 @@
"""
Model Database Baru - sesuai PRD Section 24
Hanya tabel baru (pekerjaan, kompetensi, clustering_result, dll)
"""
# Mengimpor modul Any untuk type hint fleksibel di Python
from typing import Any
# Mengimpor modul kolom dan tipe data dari SQLAlchemy: Column, Integer, String, DateTime, ForeignKey, Float, Boolean, Text
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Float, Boolean, Text
# Mengimpor relationship untuk relasi antar tabel ORM
from sqlalchemy.orm import relationship
# Mengimpor func untuk fungsi SQL bawaan seperti pengambilan waktu server
from sqlalchemy.sql import func
# Mengimpor kelas basis Declarative Base
from app.models.base import Base
# =========================================================================
# MODEL ENTITAS: PEKERJAAN (Tabel Pekerjaan Alumni)
# =========================================================================
class Pekerjaan(Base):
"""Tabel Pekerjaan - PRD Section 24: Menyimpan informasi spesifik profesi & tempat kerja alumni"""
# Nama tabel fisik di database MySQL
__tablename__ = "pekerjaan"
# Primary key identitas record pekerjaan bertipe integer
id = Column(Integer, primary_key=True, index=True)
# Foreign key yang berelasi ke kolom id di tabel alumni (unique=True karena One-to-One dengan alumni)
alumni_id = Column(Integer, ForeignKey("alumni.id"), nullable=False, unique=True)
# Status pekerjaan saat ini: misal bekerja, belum_kerja, wiraswasta, melanjutkan_pendidikan
status_pekerjaan = Column(String(50)) # bekerja, belum_kerja, wiraswasta, dll
# Jenis institusi / perusahaan: BUMN, Swasta, Lembaga Pemerintah, Yayasan/Nirlaba
jenis_perusahaan = Column(String(100))
# Nama resmi perusahaan / kantor tempat alumni bekerja
nama_perusahaan = Column(String(255))
# Posisi / nama jabatan alumni di perusahaan (misal: Software Engineer, Data Analyst)
jabatan = Column(String(150))
# Skala tingkatan tempat kerja: Lokal / Tidak Berbadan Hukum, Nasional Berbadan Hukum, atau Multinasional/Internasional
tingkatan_tempat_kerja = Column(String(50))
# Lokasi provinsi tempat bekerja
provinsi = Column(String(100))
# Lokasi kabupaten / kota tempat bekerja
kabupaten_kota = Column(String(100))
# Teks gabungan (concatenation) dari posisi, perusahaan, dan deskripsi kerja yang digunakan sebagai korpus input TF-IDF dan Klastering
teks_pekerjaan = Column(Text) # Hasil concatenation untuk clustering
# Relasi ORM balik ke tabel Alumni (bidirectional relationship)
alumni = relationship("Alumni", back_populates="pekerjaan_detail")
# Waktu pembuatan record data pekerjaan
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Waktu update terakhir record data pekerjaan
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# =========================================================================
# MODEL ENTITAS: KOMPETENSI (Tabel Nilai 7 Kelompok Kompetensi)
# =========================================================================
class Kompetensi(Base):
"""Tabel Kompetensi - PRD Section 24: Menyimpan penilaian 7 kompetensi saat lulus kuliah"""
# Nama tabel fisik di database MySQL
__tablename__ = "kompetensi"
# Primary key identitas record kompetensi bertipe integer
id = Column(Integer, primary_key=True, index=True)
# Foreign key yang mengaitkan data kompetensi dengan alumni terkait (One-to-One)
alumni_id = Column(Integer, ForeignKey("alumni.id"), nullable=False, unique=True)
# 7 Kelompok Kompetensi (sesuai standar instrumen Tracer Study Dikti / PRD Section 9.4)
# 1. Penilaian etika, moral, dan integritas saat lulus
etika_lulus = Column(String(255))
# 2. Penilaian keahlian berdasarkan bidang ilmu spesifik (keahlian utama)
keahlian_lulus = Column(String(255))
# 3. Penilaian kecakapan penguasaan bahasa Inggris saat lulus
bahasa_inggris_lulus = Column(String(255))
# 4. Penilaian kemahiran penggunaan teknologi informasi & komputer
teknologi_informasi_lulus = Column(String(255))
# 5. Penilaian kemampuan komunikasi interpersonal dan presentasi
komunikasi_lulus = Column(String(255))
# 6. Penilaian kemampuan kerja sama dalam tim (teamwork)
kerja_sama_lulus = Column(String(255))
# 7. Penilaian komitmen pengembangan diri dan kemampuan belajar mandiri (lifelong learning)
pengembangan_diri_lulus = Column(String(255))
# Relasi ORM balik ke model Alumni
alumni = relationship("Alumni", back_populates="kompetensi")
# Waktu pembuatan record kompetensi
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Waktu pembaruan record kompetensi
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# =========================================================================
# MODEL ENTITAS: CLUSTERING RESULT (Tabel Hasil Prediksi Klaster KMeans)
# =========================================================================
class ClusteringResult(Base):
"""Tabel Hasil Clustering - PRD Section 24: Menyimpan label klaster per alumni dari algoritma KMeans"""
# Nama tabel fisik hasil klastering
__tablename__ = "clustering_result"
# Primary key identitas hasil klastering
id = Column(Integer, primary_key=True, index=True)
# Foreign key mengacu pada ID alumni yang diklasifikasikan
alumni_id = Column(Integer, ForeignKey("alumni.id"), nullable=False)
# Identifikasi versi model Machine Learning yang menghasilkan prediksi (misal: "kmeans_v1_2024")
model_version = Column(String(50))
# Jumlah klaster (k) yang digunakan saat pemodelan (misal: k=3 atau k=4)
k = Column(Integer, nullable=False) # Jumlah cluster
# Indeks cluster numerik hasil komputasi KMeans (0, 1, 2, dst.)
cluster = Column(Integer, nullable=False) # Cluster 0,1,2,3
# Label kategori klaster yang diformat (misal: 'C0', 'C1', 'C2', 'C3')
kategori = Column(String(5), nullable=False) # C0, C1, C2, C3
# Indikator kesesuaian antara bidang kerja alumni dengan profil lulusan prodi (True/False)
profile_match = Column(Boolean, default=False) # Apakah sesuai profil
# Kata kunci (keyword) yang cocok antara profil kompetensi alumni dan kamus kata kunci prodi
matched_keyword = Column(Text) # Keyword yang match
# Relasi ORM balik ke entitas Alumni
alumni = relationship("Alumni", back_populates="clustering_results")
# Waktu eksekusi dan pencatatan hasil klastering ke database
created_at = Column(DateTime(timezone=True), server_default=func.now())
# =========================================================================
# MODEL ENTITAS: MODEL EVALUATION (Tabel Metrik Evaluasi Model ML)
# =========================================================================
class ModelEvaluation(Base):
"""Tabel Evaluasi Model - PRD Section 24: Menyimpan metrik evaluasi algoritma KMeans (Silhouette Score & Inertia/Elbow)"""
# Nama tabel riwayat evaluasi model
__tablename__ = "model_evaluation"
# Primary key identitas catatan evaluasi
id = Column(Integer, primary_key=True, index=True)
# Kode versi model yang diuji
model_version = Column(String(50), nullable=False)
# Nilai hiperparameter k (jumlah cluster) yang diuji
k = Column(Integer, nullable=False)
# Nilai Inertia (Within-Cluster Sum of Squares) untuk analisis Elbow Method
inertia = Column(Float)
# Nilai Silhouette Coefficient (-1 hingga +1) untuk mengukur kerapatan dan pemisahan antar klaster
silhouette_score = Column(Float)
# Waktu pengujian model dijalankan dan dicatat
created_at = Column(DateTime(timezone=True), server_default=func.now())
# =========================================================================
# MODEL ENTITAS: KEYWORD DICTIONARY (Tabel Kamus Kata Kunci Prodi)
# =========================================================================
class KeywordDictionary(Base):
"""Tabel Kamus Kata Kunci - PRD Section 24: Kosakata kompetensi/profesi acuan untuk pencocokan profil lulusan prodi"""
# Nama tabel kamus kata kunci
__tablename__ = "keyword_dictionary"
# Primary key identitas kata kunci
id = Column(Integer, primary_key=True, index=True)
# Kode program studi target (contoh: 'TIF', 'MIF', 'TKK')
kode_prodi = Column(String(10), nullable=False) # TIF, MIF, TKK
# Kata kunci keahlian atau pekerjaan (contoh: "programmer", "network engineer", "database")
keyword = Column(String(100), nullable=False)
# Klasifikasi kata kunci: 'technical', 'softskill', 'role', dll.
kategori_keyword = Column(String(50)) # technical, softskill, dll
# Status apakah kata kunci ini aktif diikutsertakan dalam pencocokan profil lulusan
aktif = Column(Boolean, default=True)
# Waktu penambahan kata kunci ke dalam kamus
created_at = Column(DateTime(timezone=True), server_default=func.now())
# =========================================================================
# MODEL ENTITAS: TRACER RESPONSE (Tabel Respon Lengkap Kuesioner Alumni)
# =========================================================================
class TracerResponse(Base):
"""
Tabel Respon Tracer Study - Menyimpan SEMUA kolom dari kuesioner tracer study
Sesuai dengan dokumen Pertanyaan-dan-jawaban.md dan format baku Tracer Study DIKTI
"""
# Nama tabel fisik di database MySQL
__tablename__ = "tracer_responses"
# Kolom ID utama entitas respon tracer study (Primary Key)
id = Column(Integer, primary_key=True, index=True)
# Foreign key yang menghubungkan respon ke ID alumni (One-to-One, unik)
alumni_id = Column(Integer, ForeignKey("alumni.id"), nullable=False, unique=True)
# Kolom Nomor Induk Mahasiswa (NIM) alumni yang diindeks untuk pencarian cepat
nim: Any = Column(String(50), index=True)
# ===== SECTION 1: Identitas Diri (Extended) =====
# Kode resmi perguruan tinggi asal alumni (contoh: 005016 untuk Politeknik Negeri Jember)
kode_pt = Column(String(100)) # Kode Perguruan Tinggi
# Nomor Induk Kependudukan (NIK/KTP) alumni
nik = Column(String(50)) # NIK/No KTP
# Nomor Pokok Wajib Pajak (NPWP) alumni jika sudah memiliki
npwp = Column(String(50)) # NPWP
# Nomor telepon seluler / WhatsApp aktif alumni
telepon = Column(String(50)) # No HP/WhatsApp
# Alamat surat elektronik (email) aktif alumni
email = Column(String(255)) # Email
# ===== SECTION 2: Kuesioner Utama =====
# Status aktivitas alumni saat ini (F8: Bekerja, Wiraswasta, Belum Kerja, atau Studi Lanjut)
status_saat_ini = Column(String(255)) # F8: Bekerja/Wiraswasta/Belum/Melanjutkan
# Masa tunggu mendapatkan pekerjaan pertama dalam hitungan bulan (F502)
bulan_dapat_kerja = Column(Integer) # F502: 0-12 bulan sebelum/sesudah lulus
# Status apakah alumni memperoleh pekerjaan dalam kurun waktu <= 6 bulan setelah lulus (F504)
dapet_kerja_6_bulan = Column(String(255)) # F504: <=6 bulan (Ya/Tidak/kode)
# Rata-rata pendapatan atau take-home pay per bulan (F505)
rata_pendapatan = Column(Text) # F505: Gaji per bulan
# Jumlah bulan yang dibutuhkan untuk mendapatkan pekerjaan setelah resmi diwisuda (F506)
bulan_dapat_kerja_setelah = Column(Integer) # F506
# Lokasi kerja
# Provinsi wilayah tempat instansi / kantor alumni bekerja (F5a1)
provinsi_kerja = Column(String(100)) # F5a1
# Kabupaten atau kota wilayah tempat kantor alumni bekerja (F5a2)
kab_kota_kerja = Column(String(100)) # F5a2
# Info perusahaan
# Kategori status badan usaha instansi (F1101: Instansi pemerintah, BUMN, swasta, dll)
jenis_perusahaan_full = Column(String(255)) # F1101: Instansi pemerintah/swasta/BUMN/dll
# Jumlah total perusahaan yang dilamar atau rincian tambahan jika memilih opsi lainnya (F1102)
jumlah_perusahaan = Column(Text) # F1102 (dapat berupa teks panjang jika memilih lainnya)
# Nama resmi lembaga / instansi tempat alumni saat ini berkarir (F5b)
nama_perusahaan = Column(Text) # F5b
# Jabatan atau role posisi pekerjaan alumni (F5c: misal Backend Developer, Staff IT)
jabatan = Column(String(255)) # F5c
# Skala cakupan operasional tempat kerja (F5d: Lokal, Nasional, Multinasional/Internasional)
tingkatan_tempat_kerja = Column(String(255)) # F5d
# ===== SECTION 3: Studi Lanjut =====
# Sumber dana pembiayaan studi lanjut (F18a: Biaya Mandiri, Beasiswa LPDP, dll)
sumber_biaya_studi = Column(String(255)) # F18a: Biaya sendiri/Beasiswa
# Nama perguruan tinggi tujuan tempat melanjutkan jenjang studi berikutnya (F18b)
pt_studi_lanjut = Column(Text) # F18b: Nama PT
# Program studi yang diambil pada jenjang pendidikan lanjutan (F18c)
prodi_studi_lanjut = Column(Text) # F18c: Nama Prodi
# Tanggal atau semester resmi mulai perkuliahan studi lanjut (F18d)
tanggal_masuk_studi = Column(DateTime) # F18d: Tanggal masuk
# ===== SECTION 4: Pembiayaan Kuliah =====
# Sumber dana utama selama menempuh kuliah diploma/sarjana (F1201: Orang Tua, Bidikmisi, Beasiswa ADik)
sumber_biaya_kuliah = Column(String(255)) # F1201: Biaya sendiri/Beasiswa ADIK/BIDIKMISI/dll
# ===== SECTION 5: Kesesuaian Kerja =====
# Tingkat keeratan hubungan antara bidang keilmuan kuliah dengan pekerjaan (F14: Sangat Erat s.d. Tidak Sama Sekali)
keeratan_bidang_studi = Column(String(255)) # F14: Sangat Erat - Tidak sama sekali
# Tingkat kesesuaian strata pendidikan yang dipersyaratkan oleh posisi kerja (F15)
tingkat_pendidikan_tepat = Column(String(255)) # F15: Setingkat lebih tinggi - Tidak perlu
# ===== SECTION 6: Kompetensi SAAT LULUS (F1761-F1773) =====
# Penilaian penguasaan etika saat baru dinyatakan lulus (F1761)
etika_lulus_full = Column(String(255)) # F1761
# Penilaian keahlian bidang ilmu kompetensi inti saat lulus (F1763)
keahlian_lulus_full = Column(String(255)) # F1763
# Penilaian kemampuan bahasa Inggris saat lulus (F1765)
bahasa_inggris_lulus_full = Column(String(255)) # F1765
# Penilaian penguasaan teknologi informasi saat lulus (F1767)
teknologi_informasi_lulus_full = Column(String(255)) # F1767
# Penilaian kemampuan komunikasi verbal/tulisan saat lulus (F1769)
komunikasi_lulus_full = Column(String(255)) # F1769
# Penilaian kemampuan kerja sama tim saat lulus (F1771)
kerja_sama_lulus_full = Column(String(255)) # F1771
# Penilaian kesiapan pengembangan diri berkelanjutan saat lulus (F1773)
pengembangan_diri_lulus_full = Column(String(255)) # F1773
# ===== SECTION 7: Kompetensi SAAT INI (F1762-F1774) =====
# Tingkat kebutuhan kompetensi etika dalam pekerjaan saat ini (F1762)
etika_saat_ini = Column(String(255)) # F1762
# Tingkat kebutuhan keahlian bidang ilmu dalam pekerjaan saat ini (F1764)
keahlian_saat_ini = Column(String(255)) # F1764
# Tingkat kebutuhan bahasa Inggris dalam pekerjaan saat ini (F1766)
bahasa_inggris_saat_ini = Column(String(255)) # F1766
# Tingkat kebutuhan teknologi informasi dalam pekerjaan saat ini (F1768)
teknologi_informasi_saat_ini = Column(String(255)) # F1768
# Tingkat kebutuhan kemampuan komunikasi dalam pekerjaan saat ini (F1770)
komunikasi_saat_ini = Column(String(255)) # F1770
# Tingkat kebutuhan kerja sama tim dalam pekerjaan saat ini (F1772)
kerja_sama_saat_ini = Column(String(255)) # F1772
# Tingkat kebutuhan pengembangan diri dalam pekerjaan saat ini (F1774)
pengembangan_diri_saat_ini = Column(String(255)) # F1774
# ===== SECTION 8: Metode Pembelajaran (F21-F27) =====
# Efektivitas metode perkuliahan teori di kelas (F21)
metode_perkuliahan = Column(String(255)) # F21
# Efektivitas metode demonstrasi / peragaan materi kuliah (F22)
metode_demonstrasi = Column(String(255)) # F22
# Efektivitas metode pengerjaan proyek riset / tugas akhir (F23)
metode_proyek_riset = Column(String(255)) # F23
# Efektivitas pengalaman program magang / kerja praktik (F24)
metode_magang = Column(String(255)) # F24
# Efektivitas sesi praktikum di laboratorium komputer (F25)
metode_praktikum = Column(String(255)) # F25
# Efektivitas kegiatan kerja lapangan / PKL (F26)
metode_kerja_lapangan = Column(String(255)) # F26
# Efektivitas metode diskusi interaktif kelompok (F27)
metode_diskusi = Column(String(255)) # F27
# ===== SECTION 9: Waktu Mencari Kerja (F301-F303) =====
# Saat mulai mencari kerja (F301: Sebelum wisuda, Setelah wisuda, atau Tidak mencari kerja)
mulai_cari_kerja = Column(String(255)) # F301: Sebelum/Sesudah wisuda/Tidak
# Jumlah bulan mulai berburu lowongan kerja sebelum resmi diwisuda (F302)
bulan_cari_sebelum_lulus = Column(Integer) # F302: 0-12
# Jumlah bulan mulai berburu lowongan kerja setelah resmi diwisuda (F303)
bulan_cari_setelah_wisuda = Column(Integer) # F303: 0-12
# ===== SECTION 10: Cara Mencari Kerja (F401-F415) =====
# Mencari kerja melalui iklan lowongan koran/majalah (F401)
cari_iklan = Column(String(255)) # F401
# Melamar langsung ke perusahaan tanpa menunggu pengumuman lowongan (F402)
cari_melamar_tanpa_lowongan = Column(String(255)) # F402
# Mencari lowongan melalui job fair / bursa pameran kerja (F403)
cari_bursa_pameran = Column(String(255)) # F403
# Melamar kerja secara daring via portal internet / LinkedIn / Jobstreet (F404)
cari_internet = Column(String(255)) # F404
# Dihubungi langsung oleh perusahaan / headhunter (F405)
cari_dihubungi_perusahaan = Column(String(255)) # F405
# Menghubungi dinas tenaga kerja / Kemenakertrans (F406)
cari_kemenakertrans = Column(String(255)) # F406
# Menggunakan jasa agen penyalur tenaga kerja resmi (F407)
cari_agen_tenaga_kerja = Column(String(255)) # F407
# Memanfaatkan pusat pengembangan karir kampus (CDC Polije) (F408)
cari_pusat_karir = Column(String(255)) # F408
# Menghubungi unit kantor kemahasiswaan kampus (F409)
cari_kantor_mahasiswa = Column(String(255)) # F409
# Membangun jejaring profesional semasa masih berstatus mahasiswa (F410)
cari_jejaring = Column(String(255)) # F410
# Memperoleh informasi lowongan lewat relasi keluarga atau rekan (F411)
cari_relasi = Column(String(255)) # F411
# Merintis dan membangun badan usaha bisnis mandiri (F412)
cari_bangun_usaha = Column(String(255)) # F412
# Melanjutkan bekerja di institusi tempat pernah magang (F413)
cari_magang = Column(String(255)) # F413
# Bekerja di lingkungan institusi kampus tempat kuliah (F414)
cari_tempat_kuliah = Column(String(255)) # F414
# Saluran cara pencarian kerja lainnya (F415)
cari_lainnya = Column(Text) # F415
# ===== SECTION 11: Lamaran & Keaktifan (F6, F7, F7a, F1001) =====
# Jumlah total instansi/perusahaan yang pernah dikirimi surat lamaran kerja (F6)
jumlah_perusahaan_dilamar = Column(String(100)) # F6
# Jumlah perusahaan yang memberikan balasan respon atas surat lamaran (F7)
jumlah_perusahaan_merespons = Column(String(100)) # F7
# Jumlah perusahaan yang mengundang untuk tahapan wawancara/interview (F7a)
jumlah_perusahaan_wawancara = Column(String(100)) # F7a
# Status apakah aktif mencari pekerjaan dalam 4 minggu terakhir (F1001)
aktif_cari_kerja_4_minggu = Column(String(255)) # F1001: Ya/Tidak/Lainnya
# ===== SECTION 12: Kesesuaian Pekerjaan (F1601-F1614) =====
# Keterangan pekerjaan yang dijalani saat ini tidak sesuai dengan bidang studi (F1601)
kerja_tidak_sesuai_1 = Column(Text) # F1601
# Keterangan pekerjaan tidak memerlukan kualifikasi perguruan tinggi (F1602)
kerja_tidak_sesuai_2 = Column(Text) # F1602
# Alasan ketidaksesuaian 1: Pertimbangan faktor gaji atau pendapatan (F1603)
alasan_tidak_sesuai_1 = Column(Text) # F1603
# Alasan ketidaksesuaian 2: Faktor prospek karir dan jenjang promosi (F1604)
alasan_tidak_sesuai_2 = Column(Text) # F1604
# Alasan ketidaksesuaian 3: Pertimbangan keamanan kerja atau stabilitas (F1605)
alasan_tidak_sesuai_3 = Column(Text) # F1605
# Alasan ketidaksesuaian 4: Kesesuaian dengan minat dan bakat pribadi (F1606)
alasan_tidak_sesuai_4 = Column(Text) # F1606
# Alasan ketidaksesuaian 5: Pertimbangan kedekatan lokasi tempat tinggal (F1607)
alasan_tidak_sesuai_5 = Column(Text) # F1607
# Alasan ketidaksesuaian 6: Lingkungan suasana kerja yang nyaman (F1608)
alasan_tidak_sesuai_6 = Column(Text) # F1608
# Alasan ketidaksesuaian 7: Belum berhasil mendapat pekerjaan yang sesuai prodi (F1609)
alasan_tidak_sesuai_7 = Column(Text) # F1609
# Alasan ketidaksesuaian 8: Belum berencana mencari pekerjaan yang sesuai (F1610)
alasan_tidak_sesuai_8 = Column(Text) # F1610
# Alasan ketidaksesuaian 9: Pekerjaan saat ini dirasa cukup menarik (F1611)
alasan_tidak_sesuai_9 = Column(Text) # F1611
# Alasan ketidaksesuaian 10: Pengaruh pertimbangan keluarga (F1612)
alasan_tidak_sesuai_10 = Column(Text) # F1612
# Alasan ketidaksesuaian 11: Faktor lain yang tidak disebutkan (F1613)
alasan_tidak_sesuai_11 = Column(Text) # F1613
# Alasan ketidaksesuaian lainnya dalam uraian narasi bebas (F1614)
alasan_tidak_sesuai_lainnya = Column(Text) # F1614
# ===== Data Extra (untuk kolom dinamis yang tidak terduga) =====
# Kolom fleksibel berformat JSON text untuk menampung field tambahan dari kuesioner sewaktu-waktu
data_extra = Column(Text) # JSON untuk kolom tambahan
# Relasi ORM balik ke model Alumni (One-to-One)
alumni = relationship("Alumni", back_populates="tracer_response")
# Waktu saat alumni mengirimkan/menyimpan respon kuesioner tracer study
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Waktu saat alumni memperbarui data respon kuesioner tracer study
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# =========================================================================
# MODEL ENTITAS: QUESTIONS (Tabel Master Butir Pertanyaan Kuesioner)
# =========================================================================
class Question(Base):
"""Tabel Questions - Simpan master pertanyaan instrumen tracer study secara dinamis"""
# Nama tabel master pertanyaan di database
__tablename__ = "questions"
# Primary key identitas pertanyaan bertipe integer
id: Any = Column(Integer, primary_key=True, index=True)
# Kode unik butir pertanyaan (contoh: "F8", "F502", "F1761")
kode: Any = Column(String(20), unique=True, nullable=False, index=True)
# Bunyi kalimat teks lengkap pertanyaan kuesioner
pertanyaan: Any = Column(Text, nullable=False)
# Tipe komponen input formulir: dropdown, pilihan, skala, teks, date, ya_tidak
tipe: Any = Column(String(20), default="pilihan") # dropdown, pilihan, skala, teks, date, ya_tidak
# Kategori bagian form instrumen kuesioner (misal: "Identitas", "Pekerjaan", "Kompetensi")
section: Any = Column(String(100), index=True)
# Urutan nomor urut tampilan form di antarmuka frontend
nomor_form: Any = Column(Integer, default=0)
# Tahun berlakunya instrumen pertanyaan (default: "all" untuk berlaku di semua tahun angkatan)
tahun: Any = Column(String(20), default="all")
# Status keaktifan butir pertanyaan (True = ditampilkan di frontend, False = diarsipkan)
is_active: Any = Column(Boolean, default=True)
# Relasi One-to-Many ke tabel AnswerOption (jika tipe pertanyaan memiliki opsi pilihan berganda)
# cascade="all, delete-orphan": Jika pertanyaan dihapus, seluruh opsi jawabannya otomatis ikut terhapus
options = relationship("AnswerOption", back_populates="question", cascade="all, delete-orphan")
# Waktu penambahan pertanyaan ke sistem
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Waktu pembaruan teks atau konfigurasi pertanyaan
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
# =========================================================================
# MODEL ENTITAS: ANSWER OPTIONS (Tabel Master Pilihan Jawaban Kuesioner)
# =========================================================================
class AnswerOption(Base):
"""Tabel Answer Options - Simpan pilihan jawaban opsi berganda untuk setiap butir pertanyaan"""
# Nama tabel master opsi jawaban di database
__tablename__ = "answer_options"
# Primary key identitas opsi jawaban bertipe integer
id: Any = Column(Integer, primary_key=True, index=True)
# Foreign key yang mengaitkan opsi ini ke ID pertanyaan di tabel questions
question_id: Any = Column(Integer, ForeignKey("questions.id", ondelete="CASCADE"), nullable=False, index=True)
# Nilai value atau kode jawaban yang disimpan ke database saat dipilih (contoh: "1", "2", "Ya", "Tidak")
kode: Any = Column(String(50), nullable=False, index=True) # Kode jawaban: 1, 2, 3, atau "1", "Ya", dll
# Label teks deskripsi jawaban yang ditampilkan kepada pengguna di antarmuka web
teks: Any = Column(Text, nullable=False) # Teks jawaban
# Nomor urut posisi urutan opsi jawaban dalam pilihan radio button atau dropdown
urutan: Any = Column(Integer, default=0)
# Status keaktifan opsi jawaban (True = aktif dapat dipilih)
is_active: Any = Column(Boolean, default=True)
# Relasi ORM balik ke tabel Question
question = relationship("Question", back_populates="options")
# Waktu pembuatan opsi jawaban
created_at = Column(DateTime(timezone=True), server_default=func.now())

View File

@ -0,0 +1,37 @@
# Mengimpor tipe data kolom dari SQLAlchemy: Column (definisi kolom), Integer (angka bulat), String (teks pendek), DateTime (waktu/tanggal)
from sqlalchemy import Column, Integer, String, DateTime
# Mengimpor modul fungsi SQL bawaan (func) untuk mengambil timestamp saat ini seperti NOW()
from sqlalchemy.sql import func
# Mengimpor kelas basis Base dari modul base agar model Prodi terdaftar di metadata SQLAlchemy
from app.models.base import Base
# Mendefinisikan model ORM untuk tabel data Program Studi (Prodi)
class Prodi(Base):
# Nama tabel fisik di dalam database MySQL
__tablename__ = "prodi"
# Kolom ID sebagai primary key bertipe integer dengan pengindeksan (index) untuk mempercepat pencarian data
id = Column(Integer, primary_key=True, index=True)
# Kolom kode program studi (contoh: "55301" untuk D3 MIF, "57401" untuk D4 TIF), bersifat unik (unique=True) dan wajib diisi (nullable=False)
kode_prodi = Column(String(10), unique=True, nullable=False)
# Kolom nama lengkap program studi (contoh: "Teknik Informatika"), maksimal 150 karakter dan wajib diisi
nama_prodi = Column(String(150), nullable=False)
# Kolom jenjang pendidikan (contoh: "D3", "D4", "S1"), maksimal 5 karakter dan tidak boleh kosong
jenjang = Column(String(5), nullable=False)
# Kolom nama jurusan induk fakultas/jurusan (contoh: "Teknologi Informasi"), maksimal 100 karakter
jurusan = Column(String(100))
# Kolom waktu pembuatan record, otomatis diisi dengan timestamp saat data pertama kali disimpan (server_default=func.now())
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Kolom waktu pembaruan record, otomatis diperbarui setiap kali ada perubahan data (onupdate=func.now())
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now()
)

View File

@ -0,0 +1,48 @@
# Mengimpor modul Any dari typing untuk penentuan type hint variabel di Python
from typing import Any
# Mengimpor tipe data kolom SQLAlchemy: Column (kolom), Integer (angka bulat), String (karakter teks), Boolean (true/false), DateTime (waktu)
from sqlalchemy import Column, Integer, String, Boolean, DateTime
# Mengimpor func untuk fungsi SQL bawaan (misal mengambil waktu server database)
from sqlalchemy.sql import func
# Mengimpor kelas basis declarative Base dari model base
from app.models.base import Base
# Mendefinisikan model ORM untuk tabel pengguna sistem (Admin / Kaprodi)
class User(Base):
# Menentukan nama tabel fisik pada database MySQL
__tablename__ = "users"
# Kolom ID pengguna sebagai Primary Key unik bertipe integer dengan pengindeksan aktif
id: Any = Column(Integer, primary_key=True, index=True)
# Kolom username untuk otentikasi login, maksimal 100 karakter, harus unik (unique=True), dan wajib diisi (nullable=False)
username: Any = Column(String(100), unique=True, index=True, nullable=False)
# Kolom nama lengkap pengguna / pejabat prodi, maksimal 150 karakter, bersifat opsional (nullable=True)
nama: Any = Column(String(150), nullable=True)
# Kolom alamat email pengguna, harus unik dan terindeks untuk reset password serta komunikasi
email: Any = Column(String(150), unique=True, index=True, nullable=False)
# Kolom hash password hasil enkripsi algoritma Bcrypt (bukan plaintext demi keamanan data)
hashed_password: Any = Column(String(255), nullable=False)
# Kolom hak akses (role) pengguna dalam sistem, nilai default adalah 'admin', opsi: 'admin' atau 'kaprodi'
role: Any = Column(String(50), default="admin", nullable=False) # 'admin' | 'kaprodi'
# Kolom kode program studi binaan (khusus jika role adalah 'kaprodi' seperti '55301' MIF, '57401' TIF)
kode_prodi: Any = Column(String(20), nullable=True) # '55301', '57401', '56401', etc.
# Kolom status keaktifan akun pengguna (True = aktif dapat login, False = dinonaktifkan/diblokir)
is_active: Any = Column(Boolean, default=True)
# Kolom pencatatan waktu registrasi atau pembuatan akun pengguna
created_at = Column(DateTime(timezone=True), server_default=func.now())
# Kolom pencatatan waktu pembaruan profil atau password pengguna
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
onupdate=func.now()
)

View File

@ -0,0 +1,4 @@
# Parsers package - helper functions untuk import
from .column_finder import find_column, get_value, check_available_columns
from .converters import parse_2024_value, parse_date, konversi_jawaban, convert_value_for_field
from .mappings import YEAR_CONFIG, NUMERIC_FIELDS, get_field_code

View File

@ -0,0 +1,83 @@
import re
import pandas as pd
def normalize(col_name):
"""Normalize nama kolom - lowercase, collapse spaces, and strip whitespace"""
if pd.isna(col_name):
return ""
# Collapse multiple whitespace characters into single space
cleaned = re.sub(r'\s+', ' ', str(col_name))
return cleaned.strip().lower()
def find_column(source_cols, possible_names):
"""
Cari kolom dari beberapa kemungkinan nama.
Args:
source_cols: list kolom dari DataFrame
possible_names: list kemungkinan nama kolom
Returns:
Nama kolom yang ditemukan, atau None
"""
source_cols_map = {normalize(c): c for c in source_cols}
# Step 1: Direct normalized match
for name in possible_names:
norm_name = normalize(name)
if norm_name in source_cols_map:
return source_cols_map[norm_name]
# Step 2: Code token match (e.g. 'f1761', 'f5a1', 'f1101', 'f502', etc.)
for name in possible_names:
norm_name = normalize(name)
# Extract question code if present (e.g., 'f1761', 'f5a1', 'f8', etc.)
match = re.search(r'\b(f\d+[a-z]?\d*)\b', norm_name)
if match:
code = match.group(1)
for orig_norm, orig_col in source_cols_map.items():
if re.search(r'\b' + re.escape(code) + r'\b', orig_norm):
return orig_col
return None
def get_value(row, source_cols, possible_names, default=None):
"""
Ambil nilai dari row dengan cari kolom dulu.
Args:
row: pandas Series (satu row)
source_cols: list kolom dari DataFrame
possible_names: list kemungkinan nama kolom
default: nilai default jika tidak ditemukan
Returns:
Nilai dari row, atau default
"""
col = find_column(source_cols, possible_names)
if col and pd.notna(row.get(col)):
val = row[col]
# Convert int/float
if isinstance(val, (int, float)):
return int(val) if val == int(val) else val
return str(val).strip()
return default
def check_available_columns(df_cols: list) -> dict:
"""
Check kolom apa saja yang tersedia di dataframe.
Berguna untuk debugging.
"""
result = {
'total': len(df_cols),
'has_email': any('email' in str(c).lower() for c in df_cols),
'has_nim': any('nim' in str(c).lower() for c in df_cols),
'has_f1102': 'F1102' in df_cols,
'has_f5b': 'F5b' in df_cols,
'has_f1762': 'F1762' in df_cols,
}
return result

View File

@ -0,0 +1,566 @@
"""
Functions untuk parsing dan konversi nilai dari berbagai format CSV tracer study.
Modul ini bertugas menerjemahkan kode-kode numerik kuesioner baku DIKTI (seperti F8, F504, F505, F1101, F14, F15, dll)
menjadi teks deskriptif yang manusiawi untuk disimpan ke database dan ditampilkan di frontend.
"""
# Mengimpor modul ekspresi reguler (re) untuk pencocokan pola string (misal: "1 - Teks")
import re
# Mengimpor pustaka pandas untuk operasi analisis data dan pengecekan nilai NaN (pd.isna)
import pandas as pd
# Mengimpor datetime untuk manipulasi tanggal dan timedelta untuk perhitungan selisih hari tanggal serial Excel
from datetime import datetime, timedelta
# Mengimpor tipe hint dari modul typing: Optional (bisa None), Tuple (pasangan data), Any (tipe fleksibel)
from typing import Optional, Tuple, Any
# Mengimpor objek Session dari SQLAlchemy ORM untuk interaksi sesi database
from sqlalchemy.orm import Session
# =========================================================================
# MAPPING KODE KE TEKS JAWABAN (Standar Kuesioner Tracer Study DIKTI)
# =========================================================================
# Kamus terpusat yang memetakan kode pertanyaan kuesioner DIKTI ke teks pilihan jawabannya
JAWABAN_MAPPING = {
# F8: Pertanyaan status aktivitas alumni saat ini
'F8': {
1: 'Bekerja (full time/part time)', # Kode 1: Alumni sudah bekerja penuh/paruh waktu
2: 'Belum memungkinkan bekerja', # Kode 2: Belum dapat bekerja karena alasan tertentu
3: 'Wiraswasta', # Kode 3: Membuka usaha sendiri / wirausaha
4: 'Melanjutkan Pendidikan', # Kode 4: Sedang menempuh studi lanjut S2/Spesialis
5: 'Tidak kerja tetapi sedang mencari kerja', # Kode 5: Pengangguran aktif mencari lowongan
},
# F504: Apakah mendapatkan pekerjaan dalam kurun waktu <= 6 bulan setelah lulus?
'F504': {
1: 'Ya', # Kode 1: Ya, dapat kerja <= 6 bulan
2: 'Tidak', # Kode 2: Tidak, dapat kerja > 6 bulan
},
# F505: Kisaran rata-rata pendapatan/gaji alumni per bulan
'F505': {
1000000: 'Rp 1.000.000', # Range nominal 1 juta
1500000: 'Rp 1.500.000', # Range nominal 1.5 juta
2000000: 'Rp 2.000.000', # Range nominal 2 juta
2500000: 'Rp 2.500.000', # Range nominal 2.5 juta
3000000: 'Rp 3.000.000', # Range nominal 3 juta
3500000: 'Rp 3.500.000', # Range nominal 3.5 juta
4000000: 'Rp 4.000.000', # Range nominal 4 juta
4500000: 'Rp 4.500.000', # Range nominal 4.5 juta
5000000: 'Rp 5.000.000', # Range nominal 5 juta
6000000: 'Rp 6.000.000', # Range nominal 6 juta
7000000: 'Rp 7.000.000', # Range nominal 7 juta
8000000: '>Rp 8.000.000', # Range nominal di atas 8 juta
},
# F1101: Jenis atau bentuk institusi / perusahaan tempat alumni bekerja
'F1101': {
1: 'Instansi pemerintah', # Kode 1: Instansi pemerintah / PNS
2: 'Organisasi non-profit/Lembaga Swadaya Masyarakat', # Kode 2: LSM / Non-profit / Yayasan
3: 'Perusahaan swasta', # Kode 3: Korporasi swasta
4: 'Wiraswasta/perusahaan sendiri', # Kode 4: Usaha mandiri
5: 'Lainnya', # Kode 5: Bentuk instansi lainnya
6: 'BUMN/BUMD', # Kode 6: Badan Usaha Milik Negara / Daerah
7: 'Institusi/Organisasi Multilateral', # Kode 7: Lembaga internasional / PBB dsb.
},
# F5d / F5D: Skala tingkatan tempat kerja (wilayah operasional perusahaan)
'F5D': {
1: 'Lokal/wilayah/wiraswasta tidak berbadan hukum', # Kode 1: Skala lokal / UKM non-badan hukum
2: 'Nasional/wiraswasta berbadan hukum', # Kode 2: Skala nasional (PT, CV)
3: 'Multinasional/Internasional', # Kode 3: Skala internasional lintas negara
},
'F5d': {
1: 'Lokal/wilayah/wiraswasta tidak berbadan hukum', # Versi huruf kecil F5d
2: 'Nasional/wiraswasta berbadan hukum', # Versi huruf kecil F5d
3: 'Multinasional/Internasional', # Versi huruf kecil F5d
},
# F5c / F5C: Posisi tingkatan jabatan alumni jika berwirausaha
'F5C': {
1: 'Founder', # Pendiri usaha
2: 'Co-Founder', # Rekan pendiri
3: 'Staff', # Staf pelaksana
4: 'Freelance/Kerja Lepas', # Pekerja lepas
},
'F5c': {
1: 'Founder',
2: 'Co-Founder',
3: 'Staff',
4: 'Freelance/Kerja Lepas',
},
# F18a / F18A: Sumber pembiayaan untuk studi lanjut
'F18A': {
1: 'Biaya Sendiri', # Biaya mandiri/keluarga
2: 'Beasiswa', # Beasiswa pendidikan
},
'F18a': {
1: 'Biaya Sendiri',
2: 'Beasiswa',
},
# F1201: Sumber utama biaya kuliah selama menempuh diploma/sarjana
'F1201': {
1: 'Biaya Sendiri/Keluarga', # Biaya orang tua / pribadi
2: 'Beasiswa ADIK', # Beasiswa Afirmasi Dikti
3: 'Beasiswa BIDIKMISI', # Beasiswa Bidikmisi / KIP-Kuliah
4: 'Beasiswa PPA', # Beasiswa Peningkatan Prestasi Akademik
5: 'Beasiswa AFIRMASI', # Beasiswa Afirmasi daerah 3T
6: 'Beasiswa Perusahaan/Swasta', # Beasiswa industri (Djarum, Tanoto, dll)
7: 'Lainnya', # Sumber bantuan biaya lain
},
# F14: Tingkat keeratan hubungan antara program studi dengan bidang pekerjaan
'F14': {
1: 'Sangat Erat', # Relevansi sangat tinggi
2: 'Erat', # Relevansi tinggi
3: 'Cukup Erat', # Relevansi sedang
4: 'Kurang Erat', # Relevansi rendah
5: 'Tidak sama sekali', # Sama sekali tidak relevan
},
# F15: Kesesuaian tingkat pendidikan yang dituntut oleh pekerjaan
'F15': {
1: 'Setingkat lebih tinggi', # Butuh strata lebih tinggi (misal butuh S2)
2: 'Tingkat yang sama', # Tepat sesuai jenjang (D4/S1)
3: 'Setingkat lebih rendah', # Cukup jenjang D3/SMA
4: 'Tidak perlu pendidikan tinggi', # Tidak mensyaratkan gelar kuliah
},
# F301: Waktu mulai aktif mencari pekerjaan
'F301': {
1: 'Saya mencari kerja sebelum lulus', # Sudah berburu kerja sebelum wisuda
2: 'Saya mencari kerja sesudah wisuda', # Baru mencari setelah resmi diwisuda
3: 'Saya tidak mencari kerja', # Langsung usaha / belum ingin bekerja
},
# F1001: Keaktifan mencari pekerjaan dalam kurun 4 minggu terakhir
'F1001': {
1: 'Tidak', # Tidak mencari kerja
2: 'Tidak, tapi saya sedang menunggu hasil lamaran kerja', # Menunggu pengumuman
3: 'Ya, saya akan mulai bekerja dalam 2 minggu ke depan', # Sudah diterima dan siap masuk
4: 'Ya, tapi saya belum pasti akan bekerja dalam 2 minggu ke depan', # Masih proses tes
5: 'Lainnya', # Alasan keaktifan lainnya
},
# F1601: Kesesuaian pekerjaan dengan latar belakang pendidikan
'F1601': {
0: 'Tidak sesuai',
1: 'Pekerjaan saya sekarang sudah sesuai dengan pendidikan saya',
},
# F1602: Alasan mengapa pekerjaan belum sesuai
'F1602': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Saya belum mendapatkan pekerjaan yang lebih sesuai',
},
# F1603 - F1613: Berbagai pertimbangan alasan memilih pekerjaan yang tidak sesuai
'F1603': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Di pekerjaan ini saya memeroleh prospek karir yang baik',
},
'F1604': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Saya lebih suka bekerja di area pekerjaan yang tidak ada hubungannya dengan pendidikan saya',
},
'F1605': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Saya dipromosikan ke posisi yang kurang berhubungan dengan pendidikan saya',
},
'F1606': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Saya dapat memeroleh pendapatan yang lebih tinggi di pekerjaan ini',
},
'F1607': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Pekerjaan saya saat ini lebih aman/terjamin/secure',
},
'F1608': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Pekerjaan saya saat ini lebih menarik',
},
'F1609': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Pekerjaan saya saat ini lebih memungkinkan saya mengambil pekerjaan',
},
'F1610': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Pekerjaan saya saat ini lokasinya lebih dekat dari rumah saya',
},
'F1611': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Pekerjaan saya saat ini dapat lebih menjamin kebutuhan keluarga saya',
},
'F1612': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Pada awal meniti karir ini, saya harus menerima pekerjaan yang tidak berhubungan dengan pendidikan saya',
},
'F1613': {
0: 'Pekerjaan saya sudah sesuai',
1: 'Lainnya',
},
}
# Mapping resmi kode numerik wilayah provinsi Indonesia (F5a1)
PROVINSI_MAPPING = {
10000: 'D.K.I. Jakarta',
20000: 'Jawa Barat',
30000: 'Jawa Tengah',
40000: 'D.I. Yogyakarta',
50000: 'Jawa Timur',
60000: 'Aceh',
70000: 'Sumatera Utara',
80000: 'Sumatera Barat',
90000: 'Riau',
100000: 'Jambi',
110000: 'Sumatera Selatan',
120000: 'Lampung',
130000: 'Kalimantan Barat',
140000: 'Kalimantan Tengah',
150000: 'Kalimantan Selatan',
160000: 'Kalimantan Timur',
170000: 'Sulawesi Utara',
180000: 'Sulawesi Tengah',
190000: 'Sulawesi Selatan',
200000: 'Sulawesi Tenggara',
210000: 'Maluku',
220000: 'Bali',
230000: 'Nusa Tenggara Barat',
240000: 'Nusa Tenggara Timur',
250000: 'Papua',
260000: 'Bengkulu',
270000: 'Maluku Utara',
280000: 'Banten',
290000: 'Kepulauan Bangka Belitung',
300000: 'Gorontalo',
310000: 'Kepulauan Riau',
320000: 'Papua Barat',
330000: 'Sulawesi Barat',
340000: 'Kalimantan Utara',
350000: 'Luar Negeri',
}
# Mapping beberapa kode utama kabupaten / kota wilayah Jawa Timur (F5a2)
KABUPATEN_MAPPING = {
52000: 'Kota Surabaya',
52100: 'Kota Malang',
52200: 'Kota Probolinggo',
52300: 'Kota Pasuruan',
52400: 'Kab. Jember',
52500: 'Kab. Banyuwangi',
}
# Mapping skala likert 1-5 untuk tingkat kompetensi Dikti (F1761 - F1774)
KOMPETENSI_LEVEL = {
1: '1 - Sangat Rendah',
2: '2 - Rendah',
3: '3 - Netral',
4: '4 - Tinggi',
5: '5 - Sangat Tinggi',
}
# Mapping skala likert 1-5 untuk efektivitas metode pembelajaran di kampus (F21 - F27)
METODE_LEVEL = {
1: '1 - Sangat Besar',
2: '2 - Besar',
3: '3 - Cukup Besar',
4: '4 - Kurang',
5: '5 - Tidak Sama Sekali',
}
# Mapping nilai biner 0 dan 1 untuk saluran pencarian kerja Ya/Tidak (F401 - F415)
YA_TIDAK = {
0: '0 - Tidak',
1: '1 - Ya',
}
# =========================================================================
# FUNGSI-FUNGSI PARSING DATA MENTAH
# =========================================================================
# Fungsi untuk memisahkan kode angka dan teks deskripsi dari nilai kolom CSV (khususnya format kuesioner tahun 2024)
def parse_2024_value(val) -> Tuple[Optional[int], Optional[str]]:
"""
Mengurai (parse) nilai kolom dari format ekspor CSV 2024 yang memadukan kode angka dan teks.
Contoh pola yang ditangani:
- "3 - Cukup Erat" -> menghasilkan tuple: (3, "Cukup Erat")
- "1 - Ya" -> menghasilkan tuple: (1, "Ya")
- "Rp 3.000.000,- s/d Rp 4.000.000,-" -> menghasilkan tuple: (3000000, teks_asli)
- "Bekerja (full time/part time)" -> menghasilkan tuple: (None, teks_asli)
Returns:
Tuple (kode_as_int, teks_bersih):
- kode_as_int: integer angka kode jika berhasil diekstrak, None jika tidak ada
- teks_bersih: string teks deskripsi bersih tanpa kode awalan
"""
# Memeriksa apakah nilai input kosong atau bernilai NaN (Not a Number dari Pandas)
if pd.isna(val) or val == '':
# Kembalikan None untuk kedua elemen jika tidak ada data
return None, None
# Jika nilai sudah bertipe numerik langsung (int atau float murni)
if isinstance(val, (int, float)):
# Konversi ke int jika nilai bulat, jika desimal return None untuk kode
return int(val) if val == int(val) else None, None
# Mengubah nilai menjadi tipe string dan membuang spasi kosong di awal/akhir
val_str = str(val).strip()
# Memeriksa jika string hasil strip adalah string kosong atau representasi literal null ('nan', 'None')
if val_str in ['', 'nan', 'None']:
return None, None
# Mencocokkan dengan pola Regex: Angka di awal diikuti tanda strip/dash lalu teks (misal: "1 - Teks" atau "12 - Teks")
match = re.match(r'^\s*(\d+)\s*[-–—]\s*(.+)$', val_str)
# Jika pola angka strip teks cocok
if match:
# Mengambil grup angka pertama dan mengonversinya ke integer
kode = int(match.group(1))
# Mengambil grup teks kedua dan membersihkan spasi
teks = match.group(2).strip()
# Mengembalikan pasangan (kode, teks)
return kode, teks
# Pola khusus untuk teks rentang nominal gaji (contoh: "Rp 3.000.000,- s/d Rp 4.000.000,-")
if 's/d' in val_str or 'sd' in val_str.lower():
# Mengekstrak seluruh digit angka dan titik sebelum pemisah 's/d'
numbers = re.findall(r'[\d.]+', val_str.split('s/d')[0] if 's/d' in val_str else val_str.split('sd')[0])
# Jika digit angka berhasil ditemukan
if numbers:
try:
# Mengambil angka batas bawah, menghapus tanda pemisah titik, dan mengonversinya ke integer
num = int(numbers[-1].replace('.', ''))
# Mengembalikan angka nominal batas bawah bersama string teks aslinya
return num, val_str
except:
# Jika konversi gagal, abaikan dan lanjut ke fallback
pass
# Jika sudah berupa string teks bebas tanpa format kode di depannya, kembalikan teks apa adanya
return None, val_str
# Fungsi untuk memvalidasi dan mengonversi format tanggal string atau serial Excel ke standar format tanggal MySQL (YYYY-MM-DD)
def parse_date(val) -> Optional[str]:
"""
Mengonversi berbagai variasi format penanggalan dari file CSV atau format angka serial Excel menjadi string tanggal baku ISO (YYYY-MM-DD).
"""
# Memeriksa jika nilai tanggal bernilai kosong atau None
if pd.isna(val) or val is None or val == '':
return None
# Jika nilai input sudah merupakan instance objek datetime atau pandas Timestamp
if isinstance(val, (datetime, pd.Timestamp)):
# Format langsung menjadi 'YYYY-MM-DD'
return val.strftime('%Y-%m-%d')
# Mengubah nilai menjadi string bersih
val_str = str(val).strip()
# Mengabaikan string kosong atau karakter placeholder umum seperti tanda strip
if val_str in ['', 'nan', 'None', '-', '_', '0']:
return None
# Memeriksa kemungkinan format angka serial tanggal bawaan Microsoft Excel (misal: angka 44794 merepresentasikan hari sejak 30-12-1899)
try:
float_val = float(val_str)
# Rentang serial number tanggal Excel valid (antara rentang tahun 1980 - 2064)
if 30000 <= float_val <= 60000:
# Menghitung tanggal kalender dengan menambahkan selisih hari ke basis kalender Excel (30 Desember 1899)
excel_date = datetime(1899, 12, 30) + timedelta(days=float_val)
# Mengembalikan tanggal dalam format string 'YYYY-MM-DD'
return excel_date.strftime('%Y-%m-%d')
except (ValueError, TypeError):
# Jika bukan angka serial Excel, lanjutkan ke parsing format tanggal teks
pass
# Daftar format pola string penanggalan umum yang sering muncul pada spreadsheet kuesioner
formats = [
'%Y-%m-%d', '%Y/%m/%d',
'%d-%m-%Y', '%d/%m/%Y',
'%m-%d-%Y', '%m/%d/%Y',
'%d-%m-%y', '%d/%m/%y',
'%m-%d-%y', '%m/%d/%y',
'%Y-%m-%d %H:%M:%S', '%Y/%m/%d %H:%M:%S',
'%d/%m/%Y %H:%M:%S', '%d-%m-%Y %H:%M:%S'
]
# Mencoba mencocokkan nilai string dengan setiap format tanggal yang tersedia
for fmt in formats:
try:
# Jika format cocok, kembalikan tanggal terformat ISO
return datetime.strptime(val_str, fmt).strftime('%Y-%m-%d')
except ValueError:
# Jika tidak cocok, coba format berikutnya di list
continue
# Kembalikan None jika tidak ada satupun pola tanggal yang cocok
return None
# =========================================================================
# FUNGSI-FUNGSI KONVERSI NILAI KUESIONER
# =========================================================================
# Fungsi utama untuk menerjemahkan nilai kode jawaban mentah menjadi teks deskriptif
def konversi_jawaban(field_code: Optional[str], nilai, db: Optional[Session] = None) -> Any:
"""
Mengonversi kode angka kuesioner ke teks label jawaban yang sesuai.
PENTING: Nilai 0 ADALAH jawaban valid untuk beberapa field kuesioner:
- F502: 0 bulan (artinya langsung bekerja saat lulus kuliah)
- F302/F303: 0 bulan (mulai mencari saat lulus)
- F401-F415: 0 bernilai "Tidak", 1 bernilai "Ya"
Args:
field_code: Kode butir pertanyaan (contoh: 'F14', 'F504')
nilai: Nilai mentah dari sel CSV
db: Sesi koneksi database opsional
Returns:
Nilai teks yang telah dikonversi, atau None jika sel kosong
"""
# Memeriksa sel kosong atau NaN
if pd.isna(nilai) or nilai == '':
return None
# Memeriksa string kosong setelah pembersihan spasi
if isinstance(nilai, str) and nilai.strip() in ['', 'nan', 'None']:
return None
# Penanganan data kuesioner format 2024 yang sudah memuat "KODE - TEKS"
if isinstance(nilai, str):
# Mencocokkan regex pola angka strip teks
match = re.match(r'^\s*(\d+)\s*[-–—]\s*(.+)$', nilai)
if match:
kode = int(match.group(1))
teks = match.group(2).strip()
# Jika teks memiliki deskripsi yang cukup panjang (>5 karakter), gunakan langsung teks tersebut
if len(teks) > 5:
return teks
# Jika nilai diawali huruf (sudah berbentuk teks naratif penuh tanpa angka kode)
if not nilai[0].isdigit() if nilai else True:
return nilai.strip()
# Menyimpan nilai asli sebelum dikonversi
original_nilai = nilai
# Konversi string angka menjadi integer
if isinstance(nilai, str):
try:
nilai = int(nilai)
except ValueError:
pass
# Konversi float murni (misal 1.0) menjadi integer (1)
if isinstance(nilai, float):
if nilai != int(nilai):
return None # Mengabaikan bilangan desimal yang tidak valid untuk kode kuesioner
nilai = int(nilai)
# Menentukan nilai kunci pencarian (key)
nilai_key: Any = int(nilai) if isinstance(nilai, (int, float)) else nilai
# Mengubah kode field menjadi huruf kapital bersih
code_upper = field_code.upper().strip() if field_code else ''
# ================= Konversi Berdasarkan Kode Pertanyaan Spesifik =================
# F1761-F1774: Penilaian 7 kelompok kompetensi saat lulus & saat ini (skala 1-5, nilai 0 diabaikan menjadi NULL)
if code_upper in ['F1761', 'F1762', 'F1763', 'F1764', 'F1765', 'F1766', 'F1767', 'F1768', 'F1769', 'F1770', 'F1771', 'F1772', 'F1773', 'F1774']:
if nilai_key == 0:
return None
return KOMPETENSI_LEVEL.get(nilai_key)
# F21-F27: Evaluasi metode pembelajaran di kampus (skala 1-5, nilai 0 diabaikan menjadi NULL)
if code_upper in ['F21', 'F22', 'F23', 'F24', 'F25', 'F26', 'F27']:
if nilai_key == 0:
return None
return METODE_LEVEL.get(nilai_key)
# F401-F415: Saluran cara mencari pekerjaan (jawaban biner: 0 = "Tidak", 1 = "Ya")
if code_upper in ['F401', 'F402', 'F403', 'F404', 'F405', 'F406', 'F407',
'F408', 'F409', 'F410', 'F411', 'F412', 'F413', 'F414', 'F415']:
return YA_TIDAK.get(nilai_key)
# F504: Status mendapatkan pekerjaan dalam <= 6 bulan (1 = Ya, 2 = Tidak)
if code_upper == 'F504':
return JAWABAN_MAPPING.get('F504', {}).get(nilai_key)
# F505: Rata-rata pendapatan gaji per bulan (pencocokan ke range atau format mata uang Rupiah)
if code_upper == 'F505':
if nilai_key in JAWABAN_MAPPING.get('F505', {}):
return JAWABAN_MAPPING['F505'][nilai_key]
if isinstance(nilai_key, (int, float)) and nilai_key > 0:
return f"Rp {int(nilai_key):,}".replace(',', '.')
if isinstance(nilai, str) and nilai.strip() and nilai.strip() not in ['0', '0.0']:
return nilai.strip()
return None
# F1601-F1613: Pertimbangan alasan memilih pekerjaan yang tidak sesuai bidang
if code_upper in ['F1601', 'F1602', 'F1603', 'F1604', 'F1605', 'F1606',
'F1607', 'F1608', 'F1609', 'F1610', 'F1611', 'F1612', 'F1613']:
if code_upper in JAWABAN_MAPPING:
return JAWABAN_MAPPING[code_upper].get(nilai_key)
return YA_TIDAK.get(nilai_key)
# F502, F302, F303: Jumlah durasi bulan masa tunggu mencari kerja (nilai 0 s.d. 12 valid berupa angka murni)
if code_upper in ['F502', 'F302', 'F303']:
return nilai_key # Dikembalikan sebagai angka numerik murni
# F5A1: Wilayah provinsi tempat bekerja (konversi kode provinsi ke nama provinsi)
if code_upper == 'F5A1':
nama_provinsi = PROVINSI_MAPPING.get(nilai_key)
if nama_provinsi:
return f"{nilai_key} - {nama_provinsi}"
return nilai_key
# F5A2: Wilayah kabupaten atau kota tempat bekerja
if code_upper == 'F5A2':
nama_kabupaten = KABUPATEN_MAPPING.get(nilai_key)
if nama_kabupaten:
return f"{nilai_key} - {nama_kabupaten}"
return nilai_key
# Pengecekan pada kamus umum JAWABAN_MAPPING untuk kode lainnya
if code_upper in JAWABAN_MAPPING:
return JAWABAN_MAPPING[code_upper].get(nilai_key)
if field_code in JAWABAN_MAPPING:
return JAWABAN_MAPPING[field_code].get(nilai_key)
# Nilai bawaan jika tidak ada kamus pencocokan: kembalikan nilai asli
return original_nilai
# Fungsi pembantu untuk memilih apakah menyimpan kode numerik atau teks deskripsi sesuai tipe kolom di database
def convert_value_for_field(field_code: str, kode: int, teks: str, is_numeric_field: bool) -> Any:
"""
Menentukan representasi data akhir yang akan disimpan ke database berdasarkan tipe kolom tabel target.
Args:
field_code: Kode butir pertanyaan (contoh: 'F14', 'F504')
kode: Angka kode jawaban hasil parsing
teks: Teks label jawaban hasil parsing
is_numeric_field: Bernilai True jika kolom database bertipe integer (misal: bulan tunggu)
Returns:
Nilai yang telah disesuaikan dengan tipe kolom database
"""
# Jika kolom database adalah tipe numerik integer, prioritaskan mengembalikan kode angka
if is_numeric_field:
return kode
# Jika teks deskripsi tersedia dan panjangnya memadai, gunakan teks deskriptif
if teks and len(teks) > 5:
return teks
# Jika kode angka ada, coba konversikan kode tersebut ke teks melalui fungsi konversi_jawaban
if kode is not None:
return konversi_jawaban(field_code, kode)
# Opsi fallback terakhir: kembalikan teks
return teks

View File

@ -0,0 +1,705 @@
"""
Mapping kolom untuk setiap tahun tracer study.
Ini adalah sumber kebenaran untuk mapping CSV -> database field.
"""
from typing import Optional
# ============================================
# YEAR CONFIGURATION
# Setiap tahun punya format kolom yang berbeda
# ============================================
YEAR_CONFIG = {
'2019': {
'description': 'Format lama - kode angka',
'skip_jumlah_perusahaan': True, # F1102 bukan jumlah_perusahaan
'has_email': True,
'email_col': 'Email',
'nama_col': 'Nama',
'tahun_col': 'Tahun Lulus',
'is_text_format': False, # Data dalam bentuk kode angka
},
'2020': {
'description': 'Format 2020',
'skip_jumlah_perusahaan': False,
'has_email': True,
'email_col': 'Email',
'nama_col': 'Nama',
'tahun_col': 'Tahun Lulus',
'is_text_format': False,
},
'2021': {
'description': 'Format 2021 - tidak ada kolom email',
'skip_jumlah_perusahaan': False,
'has_email': False,
'email_col': None,
'nama_col': 'Nama',
'tahun_col': 'Tahun Lulus',
'is_text_format': False,
},
'2022': {
'description': 'Format 2022 - ada emailmsmh',
'skip_jumlah_perusahaan': False,
'has_email': True,
'email_col': 'emailmsmh',
'nama_col': 'nmmhsmsmh',
'tahun_col': 'tahun_lulus',
'is_text_format': False,
},
'2023': {
'description': 'Format 2023 - ada emailmsmh',
'skip_jumlah_perusahaan': False,
'has_email': True,
'email_col': 'emailmsmh',
'nama_col': 'nmmhsmsmh',
'tahun_col': 'tahun_lulus',
'is_text_format': False,
},
'2024': {
'description': 'Format 2024 - data dalam format teks lengkap "KODE - TEKS"',
'skip_jumlah_perusahaan': False,
'has_email': True,
'email_col': '6. Alamat Email / emailmsmh',
'nama_col': '4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)',
'tahun_col': '7. Tahun Lulus / tahun_lulus',
'nim_col': '3. NIM / nimhsmsmh (Gunakan Huruf Besar)',
'is_text_format': True, # Data SUDAH dalam format teks lengkap
},
'2025': {
'description': 'Format 2025 - sama dengan 2024',
'skip_jumlah_perusahaan': False,
'has_email': True,
'email_col': '6. Alamat Email / emailmsmh',
'nama_col': '4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)',
'tahun_col': '7. Tahun Lulus / tahun_lulus',
'nim_col': '3. NIM / nimhsmsmh (Gunakan Huruf Besar)',
'is_text_format': True,
},
}
# ============================================
# COLUMN MAPPING - IDENTITAS
# ============================================
IDENTITAS_MAPPING = {
# Field database: [list kemungkinan nama kolom di CSV]
'nim': [
'NIM/Nomor Mahasiswa',
'NIM',
'nimhsmsmh',
'3. NIM / nimhsmsmh',
'3. NIM / nimhsmsmh (Gunakan Huruf Besar)',
'3. NIM / nimhsmsmh (Gunakan Huruf Besar) ',
],
'nama': [
'Nama',
'nmmhsmsmh',
'4. Nama Lengkap / nmmhsmsmh',
'4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)',
],
'kode_prodi': [
'Kode Prodi',
'kdpstmsmh',
'2. Kode Program Studi / kdpstmsmh',
],
'kode_pt': [
'Kode PT',
'kdptimsmh',
'1. Kode Perguruan Tinggi / kdptimsmh',
],
'email': [
'Email',
'emailmsmh',
'6. Alamat Email / emailmsmh',
],
'tahun_lulus': [
'Tahun Lulus',
'tahun_lulus',
'7. Tahun Lulus / tahun_lulus',
],
}
# ============================================
# COLUMN MAPPING - PEKERJAAN
# ============================================
PEKERJAAN_MAPPING = {
'status_saat_ini': [
'F8',
'f8',
'1. Jelaskan status Anda saat ini? f8',
],
'bulan_dapat_kerja': [
'F502',
'f502',
'2. Berapa bulan anda mendapatkan pekerjaan SEBELUM LULUS? f502',
'2. Dalam berapa bulan Anda mendapatkan pekerjaan pertama ? (f502)',
],
'dapet_kerja_6_bulan': [
'F504',
'f504',
'3. Apakah Anda telah mendapatkan pekerjaan <= 6 bulan / termasuk bekerja sebelum lulus? f504',
'3. Apakah Anda telah mendapatkan pekerjaan <= 6 bulan / termasuk bekerja sebelum lulus? f504',
],
'rata_pendapatan': [
'F505',
'f505',
'4. Berapa rata-rata pendapatan Anda per bulan ? f505',
'4. Berapa rata-rata pendapatan Anda per bulan? f505',
],
'bulan_dapat_kerja_setelah': [
'F506',
'f506',
'5. Berapa bulan Anda MENDAPATKAN PEKERJAAN SETELAH LULUS? f506',
],
'provinsi_kerja': [
'F5a1',
'f5a1',
'6. Dimana lokasi provinsi tempat Anda bekerja? f5a1',
'6. Ditahui lokasi provinsi tempat Anda bekerja? f5a1',
'6. Lokasi provinsi tempat Anda bekerja? f5a1',
],
'kab_kota_kerja': [
'F5a2',
'f5a2',
'7. Dimana lokasi kabupaten/kota tempat Anda bekerja? f5a2',
'7. Ditahui lokasi kabupaten/kota tempat Anda bekerja? f5a2',
'7. Lokasi kabupaten/kota tempat Anda bekerja? f5a2',
],
'jenis_perusahaan_full': [
'F1101',
'f1101',
'8. Apa jenis perusahaan/instansi/institusi tempat anda bekerja sekarang? f1101',
'8. Ditahui jenis perusahaan/instansi/institusi tempat anda bekerja sekarang? f1101',
'8. Jenis perusahaan/instansi tempat anda bekerja sekarang? f1101',
],
'jumlah_perusahaan': [
'F1102',
'f1102',
],
'nama_perusahaan': [
'F5b',
'f5b',
'9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b',
'9. Ditahui nama perusahaan/kantor tempat Anda bekerja? f5b',
'9. Nama perusahaan/kantor tempat Anda bekerja? f5b',
],
'jabatan': [
'F5c',
'f5c',
'10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c',
'10. Bilamana Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c',
],
'tingkatan_tempat_kerja': [
'F5d',
'f5d',
'11. Apa tingkatan tempat kerja Anda? f5d',
'11. Ditahui tingkatan tempat kerja Anda? f5d',
'11. Tingkatan tempat kerja Anda? f5d',
],
}
# ============================================
# COLUMN MAPPING - STUDI LANJUT
# ============================================
STUDI_LANJUT_MAPPING = {
'sumber_biaya_studi': [
'F18a',
'f18a',
'12. Sumber biaya Studi Lanjut Anda? f18a',
],
'pt_studi_lanjut': [
'F18b',
'f18b',
'13. Nama Perguruan Tinggi Studi Lanjut Anda? f18b',
],
'prodi_studi_lanjut': [
'F18c',
'f18c',
'14. Nama Program Studi Studi Lanjut Anda? f18c',
],
'tanggal_masuk_studi': [
'F18d',
'f18d',
'15. Tanggal Masuk Awal Studi Lanjut Anda? f18d',
],
}
# ============================================
# COLUMN MAPPING - KESESUAIAN
# ============================================
KESESUAIAN_MAPPING = {
'sumber_biaya_kuliah': [
'F1201',
'f1201',
'16. Sebutkan sumberdana dalam pembiayaan kuliah? (bukan ketika Studi Lanjut) f1201',
],
'keeratan_bidang_studi': [
'F14',
'f14',
'17. Seberapa erat hubungan bidang studi dengan pekerjaan Anda? f14',
],
'tingkat_pendidikan_tepat': [
'F15',
'f15',
'18. Tingkat pendidikan apa yang paling tepat/sesuai untuk pekerjaan anda saat ini? f15',
],
}
# ============================================
# COLUMN MAPPING - KOMPETENSI (SAAT LULUS)
# ============================================
KOMPETENSI_LULUS_MAPPING = {
'etika_lulus_full': [
'F1761',
'f1761',
'19. Pada tingkat mana kompetensi ETIKA anda pada SAAT LULUS? f1761',
'19. Padatingkat mana kompetensi ETIKA anda pada SAAT LULUS? f1761',
'19. Kompetensi ETIKA SAAT LULUS? f1761',
],
'keahlian_lulus_full': [
'F1763',
'f1763',
'21. Pada tingkat mana kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU anda kuasai pada SAAT LULUS? f1763',
'21. Padatingkat mana kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU anda kuasai pada SAAT LULUS? f1763',
'21. Kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU SAAT LULUS? f1763',
],
'bahasa_inggris_lulus_full': [
'F1765',
'f1765',
'23. Pada tingkat mana kompetensi BAHASA INGGRIS anda kuasai pada SAAT LULUS? f1765',
'23. Padatingkat mana kompetensi BAHASA INGGRIS anda kuasai pada SAAT LULUS? f1765',
'23. Kompetensi BAHASA INGGRIS SAAT LULUS? f1765',
],
'teknologi_informasi_lulus_full': [
'F1767',
'f1767',
'25. Pada tingkat mana kompetensi TEKNOLOGI INFORMASI anda kuasai pada SAAT LULUS? f1767',
'25. Padatingkat mana kompetensi TEKNOLOGI INFORMASI anda kuasai pada SAAT LULUS? f1767',
'25. Kompetensi TEKNOLOGI INFORMASI SAAT LULUS? f1767',
],
'komunikasi_lulus_full': [
'F1769',
'f1769',
'27. Pada tingkat mana kompetensi KOMUNIKASI anda kuasai pada SAAT LULUS? f1769',
'27. Padatingkat mana kompetensi KOMUNIKASI anda kuasai pada SAAT LULUS? f1769',
'27. Kompetensi KOMUNIKASI SAAT LULUS? f1769',
],
'kerja_sama_lulus_full': [
'F1771',
'f1771',
'29. Pada tingkat mana kompetensi KERJA SAMA TIM anda pada SAAT LULUS? f1771',
'29. Padatingkat mana kompetensi KERJA SAMA TIM anda pada SAAT LULUS? f1771',
'29. Kompetensi KERJA SAMA TIM SAAT LULUS? f1771',
],
'pengembangan_diri_lulus_full': [
'F1773',
'f1773',
'31. Pada tingkat mana kompetensi PENGEMBANGAN DIRI anda pada SAAT LULUS? f1773',
'31. Padatingkat mana kompetensi PENGEMBANGAN DIRI anda pada SAAT LULUS? f1773',
'31. Kompetensi PENGEMBANGAN DIRI SAAT LULUS? f1773',
],
}
# ============================================
# COLUMN MAPPING - KOMPETENSI (SAAT INI)
# ============================================
KOMPETENSI_SAAT_INI_MAPPING = {
'etika_saat_ini': [
'F1762',
'f1762',
'20. Pada tingkat mana kompetensi ETIKA anda pada SAAT INI? f1762',
'20. Padatingkat mana kompetensi ETIKA anda pada SAAT INI? f1762',
'20. Kompetensi ETIKA SAAT INI? f1762',
],
'keahlian_saat_ini': [
'F1764',
'f1764',
'22. Pada tingkat mana kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU anda kuasai pada SAAT INI? f1764',
'22. Padatingkat mana kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU anda kuasai pada SAAT INI? f1764',
'22. Kompetensi KEAHLIAN BERDASARKAN BIDANG ILMU SAAT INI? f1764',
],
'bahasa_inggris_saat_ini': [
'F1766',
'f1766',
'24. Pada tingkat mana kompetensi BAHASA INGGRIS anda kuasai pada SAAT INI? f1766',
'24. Padatingkat mana kompetensi BAHASA INGGRIS anda kuasai pada SAAT INI? f1766',
'24. Kompetensi BAHASA INGGRIS SAAT INI? f1766',
],
'teknologi_informasi_saat_ini': [
'F1768',
'f1768',
'26. Pada tingkat mana kompetensi TEKNOLOGI INFORMASI anda kuasai pada SAAT INI? f1768',
'26. Padatingkat mana kompetensi TEKNOLOGI INFORMASI anda kuasai pada SAAT INI? f1768',
'26. Kompetensi TEKNOLOGI INFORMASI SAAT INI? f1768',
],
'komunikasi_saat_ini': [
'F1770',
'f1770',
'28. Pada tingkat mana kompetensi KOMUNIKASI anda kuasai pada SAAT INI? f1770',
'28. Padatingkat mana kompetensi KOMUNIKASI anda kuasai pada SAAT INI? f1769',
'28. Kompetensi KOMUNIKASI SAAT INI? f1770',
],
'kerja_sama_saat_ini': [
'F1772',
'f1772',
'30. Pada tingkat mana kompetensi KERJA SAMA TIM anda pada SAAT INI? f1772',
'30. Padatingkat mana kompetensi KERJA SAMA TIM anda pada SAAT INI? f1772',
'30. Kompetensi KERJA SAMA TIM SAAT INI? f1772',
],
'pengembangan_diri_saat_ini': [
'F1774',
'f1774',
'32. Pada tingkat mana kompetensi PENGEMBANGAN DIRI anda pada SAAT INI? f1774',
'32. Padatingkat mana kompetensi PENGEMBANGAN DIRI anda pada SAAT INI? f1774',
'32. Kompetensi PENGEMBANGAN DIRI SAAT INI? f1774',
],
}
# ============================================
# COLUMN MAPPING - METODE PEMBELAJARAN
# ============================================
METODE_PEMBELAJARAN_MAPPING = {
'metode_perkuliahan': [
'F21',
'f21',
'33. Perkuliahan (f21)',
'33. Perkuliahan f21',
],
'metode_demonstrasi': [
'F22',
'f22',
'34. Demonstrasi (f22)',
'34. Demonstrasi f22',
],
'metode_proyek_riset': [
'F23',
'f23',
'35. Partisipasi dalam proyek riset (f23)',
'35. Partisipasi dalam proyek riset f23',
],
'metode_magang': [
'F24',
'f24',
'36. Magang (f24)',
'36. Magang f24',
],
'metode_praktikum': [
'F25',
'f25',
'37. Praktikum (f25)',
'37. Praktikum f25',
],
'metode_kerja_lapangan': [
'F26',
'f26',
'38. Kerja Lapangan (f26)',
'38. Kerja Lapangan f26',
],
'metode_diskusi': [
'F27',
'f27',
'39. Diskusi (f27)',
'39. Diskusi f27',
],
}
# ============================================
# COLUMN MAPPING - WAKTU CARI KERJA
# ============================================
WAKTU_CARI_KERJA_MAPPING = {
'mulai_cari_kerja': [
'F301',
'f301',
'40. Kapan anda mulai mencari pekerjaan? f301',
],
'bulan_cari_sebelum_lulus': [
'F302',
'f302',
'41. Saya mencari pekerjaan, Kira-kira ....... bulan SEBELUM lulus (f302)',
],
'bulan_cari_setelah_wisuda': [
'F303',
'f303',
'42. Saya mencari pekerjaan, Kira-kira ....... bulan SETELAH wisuda (f303)',
],
}
# ============================================
# COLUMN MAPPING - CARA CARI KERJA (Ya/Tidak)
# ============================================
CARA_CARI_KERJA_MAPPING = {
'cari_iklan': [
'F401',
'f401',
'43. Melalui iklan di koran/majalah, brosur ? (f401)',
],
'cari_melamar_tanpa_lowongan': [
'F402',
'f402',
'44. Melamar ke perusahaan tanpa mengetahui lowongan yang ada (f402)',
],
'cari_bursa_pameran': [
'F403',
'f403',
'45. Pergi ke bursa/pameran kerja (f403)',
],
'cari_internet': [
'F404',
'f404',
'46. Mencari lewat internet/iklan online/milis (f404)',
],
'cari_dihubungi_perusahaan': [
'F405',
'f405',
'47. Dihubungi oleh perusahaan (f405)',
],
'cari_kemenakertrans': [
'F406',
'f406',
'48. Menghubungi Kemenakertrans (f406)',
],
'cari_agen_tenaga_kerja': [
'F407',
'f407',
'49. Menghubungi agen tenaga kerja komersial/swasta (f407)',
],
'cari_pusat_karir': [
'F408',
'f408',
'50. Memperoleh informasi dari pusat/kantor pengembangan karir fakultas/universitas (f408)',
],
'cari_kantor_mahasiswa': [
'F409',
'f409',
'51. Menghubungi kantor kemahasiswaan/hubungan alumni (f409)',
],
'cari_jejaring': [
'F410',
'f410',
'52. Membangun jejaring (network) sejak masih kuliah (f410)',
],
'cari_relasi': [
'F411',
'f411',
'53. Melalui relasi (misalnya dosen, orang tua, saudara, teman, Ikatan Alumni dll.) (f411)',
],
'cari_bangun_usaha': [
'F412',
'f412',
'54. Membangun bisnis sendiri (f412)',
],
'cari_magang': [
'F413',
'f413',
'55. Melalui penempatan kerja atau magang (f413)',
],
'cari_tempat_kuliah': [
'F414',
'f414',
'56. Bekerja di tempat yang sama dengan tempat kerja semasa kuliah (f414)',
],
'cari_lainnya': [
'F415',
'f415',
'57. Lainnya (f415)',
],
}
# ============================================
# COLUMN MAPPING - LAMARAN & KEAKTIFAN
# ============================================
LAMARAN_KEAKTIFAN_MAPPING = {
'jumlah_perusahaan_dilamar': [
'F6',
'f6',
'58. Berapa perusahaan/instansi/institusi yang sudah anda lamar (lewat surat atau e-mail) sebelum anda memperoleh pekerjaan pertama? f6',
],
'jumlah_perusahaan_merespons': [
'F7',
'f7',
'59. Berapa banyak perusahaan/instansi/institusi yang merespons lamaran Anda? f7',
],
'jumlah_perusahaan_wawancara': [
'F7a',
'f7a',
'60. Berapa banyak perusahaan/instansi/institusi yang mengundang anda untuk wawancara? f7a',
],
'aktif_cari_kerja_4_minggu': [
'F1001',
'f1001',
'61. Apakah Anda aktif mencari pekerjaan dalam 4 minggu terakhir? Pilihlah satu jawaban (f1001)',
],
}
# ============================================
# COLUMN MAPPING - KESESUAIAN PEKERJAAN
# ============================================
KESESUAIAN_PEKERJAAN_MAPPING = {
'kerja_tidak_sesuai_1': [
'F1601',
'f1601',
'62. Apakah pekerjaan anda saat ini tidak sesuai dengan pendidikan anda ? f1601',
],
'kerja_tidak_sesuai_2': [
'F1602',
'f1602',
'63. Apakah pekerjaan anda saat ini tidak sesuai dengan pendidikan anda ? f1602',
],
'alasan_tidak_sesuai_1': [
'F1603',
'f1603',
'64. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1603',
],
'alasan_tidak_sesuai_2': [
'F1604',
'f1604',
'65. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1604',
],
'alasan_tidak_sesuai_3': [
'F1605',
'f1605',
'66. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1605',
],
'alasan_tidak_sesuai_4': [
'F1606',
'f1606',
'67. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1606',
],
'alasan_tidak_sesuai_5': [
'F1607',
'f1607',
'68. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1607',
],
'alasan_tidak_sesuai_6': [
'F1608',
'f1608',
'69. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1608',
],
'alasan_tidak_sesuai_7': [
'F1609',
'f1609',
'70. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1609',
],
'alasan_tidak_sesuai_8': [
'F1610',
'f1610',
'71. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1610',
],
'alasan_tidak_sesuai_9': [
'F1611',
'f1611',
'72. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1611',
],
'alasan_tidak_sesuai_10': [
'F1612',
'f1612',
'73. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? f1612',
],
'alasan_tidak_sesuai_11': [
'F1613',
'f1613',
'74. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? Selain pilihan dijawaban soal diatas (f1613)',
],
'alasan_tidak_sesuai_lainnya': [
'F1614',
'f1614',
'75. Jika pekerjaan anda saat ini tidak sesuai dengan pendidikan anda, mengapa anda mengambilnya? Selain pilihan dijawaban soal diatas, Tuliskan (f1614)',
],
}
# ============================================
# ALL MAPPINGS COMBINED (untuk import)
# ============================================
# Combine all tracer response mappings
TRACER_MAPPING = {}
TRACER_MAPPING.update(PEKERJAAN_MAPPING)
TRACER_MAPPING.update(STUDI_LANJUT_MAPPING)
TRACER_MAPPING.update(KESESUAIAN_MAPPING)
TRACER_MAPPING.update(KOMPETENSI_LULUS_MAPPING)
TRACER_MAPPING.update(KOMPETENSI_SAAT_INI_MAPPING)
TRACER_MAPPING.update(METODE_PEMBELAJARAN_MAPPING)
TRACER_MAPPING.update(WAKTU_CARI_KERJA_MAPPING)
TRACER_MAPPING.update(CARA_CARI_KERJA_MAPPING)
TRACER_MAPPING.update(LAMARAN_KEAKTIFAN_MAPPING)
TRACER_MAPPING.update(KESESUAIAN_PEKERJAAN_MAPPING)
# ============================================
# NUMERIC FIELDS (harus jadi integer)
# ============================================
NUMERIC_FIELDS = [
'bulan_dapat_kerja',
'dapet_kerja_6_bulan',
'bulan_dapat_kerja_setelah',
'jumlah_perusahaan',
'bulan_cari_sebelum_lulus',
'bulan_cari_setelah_wisuda',
'jumlah_perusahaan_dilamar',
'jumlah_perusahaan_merespons',
'jumlah_perusahaan_wawancara',
]
# ============================================
# HELPER FUNCTIONS
# ============================================
def get_all_mappings():
"""Return semua mapping dalam satu dict"""
return {
'identitas': IDENTITAS_MAPPING,
'pekerjaan': PEKERJAAN_MAPPING,
'studi_lanjut': STUDI_LANJUT_MAPPING,
'kesesuaian': KESESUAIAN_MAPPING,
'kompetensi_lulus': KOMPETENSI_LULUS_MAPPING,
'kompetensi_saat_ini': KOMPETENSI_SAAT_INI_MAPPING,
'metode_pembelajaran': METODE_PEMBELAJARAN_MAPPING,
'waktu_cari_kerja': WAKTU_CARI_KERJA_MAPPING,
'cara_cari_kerja': CARA_CARI_KERJA_MAPPING,
'lamaran_keaktifan': LAMARAN_KEAKTIFAN_MAPPING,
'kesesuaian_pekerjaan': KESESUAIAN_PEKERJAAN_MAPPING,
'tracer': TRACER_MAPPING,
}
def get_field_code(db_field: str, mapping_dict: dict) -> Optional[str]:
"""
Extract kode field (misal 'F14') dari mapping.
Args:
db_field: Nama field di database (misal 'keeratan_bidang_studi')
mapping_dict: Dict mapping yang sesuai
Returns:
Kode field (misal 'F14') atau None
"""
cols = mapping_dict.get(db_field, [])
for col in cols:
if str(col).upper().startswith('F'):
return str(col).upper()
return None

View File

@ -0,0 +1,72 @@
from typing import Optional, List, Tuple
from sqlalchemy.orm import Session, joinedload, selectinload
from sqlalchemy import or_
from app.models.alumni import Alumni
from app.repositories.base import BaseRepository
class AlumniRepository(BaseRepository[Alumni]):
"""
Alumni repository containing operations specific to the Alumni entity.
"""
def get_by_nim(self, db: Session, nim: str) -> Optional[Alumni]:
"""Find an alumni record by their NIM (student identification number)."""
return db.query(self.model).filter(self.model.nim == nim).first()
def get_with_relations(self, db: Session, alumni_id: int) -> Optional[Alumni]:
"""Fetch alumni with all related details (pekerjaan, kompetensi, tracer, clustering)."""
return (
db.query(self.model)
.options(
joinedload(self.model.pekerjaan_detail),
joinedload(self.model.kompetensi),
joinedload(self.model.tracer_response),
selectinload(self.model.clustering_results),
)
.filter(self.model.id == alumni_id)
.first()
)
def get_filtered(
self,
db: Session,
skip: int = 0,
limit: int = 10,
search: Optional[str] = None,
kode_prodi: Optional[str] = None,
tahun_lulus: Optional[int] = None,
status_kerja: Optional[str] = None,
) -> Tuple[List[Alumni], int]:
"""
Fetch alumni list with multi-column search, filtering, and total count.
"""
query = db.query(self.model)
if search:
search_pattern = f"%{search.strip()}%"
query = query.filter(
or_(
self.model.nim.ilike(search_pattern),
self.model.nama.ilike(search_pattern),
self.model.pekerjaan.ilike(search_pattern),
self.model.instansi.ilike(search_pattern),
self.model.email.ilike(search_pattern),
)
)
if kode_prodi:
query = query.filter(self.model.kode_prodi == kode_prodi.strip())
if tahun_lulus:
query = query.filter(self.model.tahun_lulus == tahun_lulus)
if status_kerja:
query = query.filter(self.model.status_kerja == status_kerja.strip())
total = query.count()
alumni_list = query.order_by(self.model.id.desc()).offset(skip).limit(limit).all()
return alumni_list, total
# Instantiate alumni repository to be imported elsewhere
alumni_repository = AlumniRepository(Alumni)

View File

@ -0,0 +1,65 @@
from typing import Generic, Type, TypeVar, List, Optional, Any, Dict, Union
from sqlalchemy.orm import Session
from app.models.base import Base
# Type variable bound to SQLAlchemy Declarative Base
ModelType = TypeVar("ModelType", bound=Base)
class BaseRepository(Generic[ModelType]):
"""
Generic Base Repository containing common CRUD database operations.
Designed to reduce boilerplate code across all entities.
"""
def __init__(self, model: Type[ModelType]):
self.model = model
def get(self, db: Session, id: Any) -> Optional[ModelType]:
"""Fetch a single record by its primary key ID."""
return db.query(self.model).filter(self.model.id == id).first()
def get_all(self, db: Session, skip: int = 0, limit: int = 100) -> List[ModelType]:
"""Fetch a list of records with optional pagination limits."""
return db.query(self.model).offset(skip).limit(limit).all()
def create(self, db: Session, obj_in: Any) -> ModelType:
"""Create a new database record from a dictionary or Pydantic model."""
if hasattr(obj_in, "model_dump"):
obj_data = obj_in.model_dump()
elif hasattr(obj_in, "dict"):
obj_data = obj_in.dict()
else:
obj_data = dict(obj_in)
db_obj = self.model(**obj_data)
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def update(self, db: Session, db_obj: ModelType, obj_in: Union[Any, Dict[str, Any]]) -> ModelType:
"""Update an existing database record with new field values."""
if isinstance(obj_in, dict):
update_data = obj_in
elif hasattr(obj_in, "model_dump"):
update_data = obj_in.model_dump(exclude_unset=True)
elif hasattr(obj_in, "dict"):
update_data = obj_in.dict(exclude_unset=True)
else:
update_data = dict(obj_in)
for field in update_data:
if hasattr(db_obj, field):
setattr(db_obj, field, update_data[field])
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def delete(self, db: Session, id: Any) -> Optional[ModelType]:
"""Delete a record by its primary key ID."""
db_obj = db.query(self.model).filter(self.model.id == id).first()
if db_obj:
db.delete(db_obj)
db.commit()
return db_obj

View File

@ -0,0 +1,50 @@
from sqlalchemy.orm import Session
from app.models.prodi import Prodi
from app.schemas.prodi import ProdiCreate, ProdiUpdate
class ProdiRepository:
@staticmethod
def get_all(db: Session):
return db.query(Prodi).all()
@staticmethod
def get_by_id(db: Session, prodi_id: int):
return db.query(Prodi).filter(Prodi.id == prodi_id).first()
@staticmethod
def create(db: Session, prodi: ProdiCreate):
db_prodi = Prodi(**prodi.model_dump())
db.add(db_prodi)
db.commit()
db.refresh(db_prodi)
return db_prodi
@staticmethod
def update(db: Session, prodi_id: int, prodi: ProdiUpdate):
db_prodi = db.query(Prodi).filter(Prodi.id == prodi_id).first()
if not db_prodi:
return None
update_data = prodi.model_dump(exclude_unset=True)
for key, value in update_data.items():
setattr(db_prodi, key, value)
db.commit()
db.refresh(db_prodi)
return db_prodi
@staticmethod
def delete(db: Session, prodi_id: int):
db_prodi = db.query(Prodi).filter(Prodi.id == prodi_id).first()
if not db_prodi:
return None
db.delete(db_prodi)
db.commit()
return db_prodi

View File

@ -0,0 +1,19 @@
from typing import Optional
from sqlalchemy.orm import Session
from app.models.user import User
from app.repositories.base import BaseRepository
class UserRepository(BaseRepository[User]):
"""
User repository containing operations specific to the User entity.
"""
def get_by_username(self, db: Session, username: str) -> Optional[User]:
"""Find a user by their username."""
return db.query(self.model).filter(self.model.username == username).first()
def get_by_email(self, db: Session, email: str) -> Optional[User]:
"""Find a user by their email address."""
return db.query(self.model).filter(self.model.email == email).first()
# Instantiate user repository to be imported elsewhere
user_repository = UserRepository(User)

View File

@ -0,0 +1,105 @@
from typing import Optional
from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from app.config.database import get_db
from app.schemas.alumni import (
AlumniCreate,
AlumniUpdate,
PublicTracerLookupRequest,
PublicTracerSubmitRequest,
)
from app.controllers.alumni import AlumniController
from app.middleware.auth_middleware import get_current_active_user
# Create Router instance for alumni endpoints
router = APIRouter()
@router.get("/", summary="Ambil semua data alumni dengan filter dan pagination")
def get_all(
skip: int = Query(0, ge=0, description="Jumlah data yang dilewati (offset)"),
limit: int = Query(10, ge=1, le=500, description="Jumlah data per halaman"),
search: Optional[str] = Query(None, description="Cari berdasarkan NIM, Nama, Pekerjaan, Instansi, atau Email"),
kode_prodi: Optional[str] = Query(None, description="Filter berdasarkan kode prodi (misal: 55301, 57401, 56401)"),
tahun_lulus: Optional[int] = Query(None, description="Filter berdasarkan tahun lulus / angkatan"),
status_kerja: Optional[str] = Query(None, description="Filter berdasarkan status pekerjaan"),
db: Session = Depends(get_db)
):
"""
Mengambil data alumni dengan dukungan filter multi-kriteria dan pagination.
"""
return AlumniController.get_all_alumni(
db=db,
skip=skip,
limit=limit,
search=search,
kode_prodi=kode_prodi,
tahun_lulus=tahun_lulus,
status_kerja=status_kerja,
)
@router.get("/{alumni_id}", summary="Ambil detail lengkap alumni berdasarkan ID")
def get_by_id(alumni_id: int, db: Session = Depends(get_db)):
"""
Mengambil detail lengkap data satu alumni beserta pekerjaan, kompetensi,
jawaban kuesioner tracer study, dan hasil klasterisasi.
"""
return AlumniController.get_alumni(db, alumni_id)
@router.post("/public-tracer-lookup", summary="Cek status NIM & verifikasi kepemilikan Email untuk Tracer Study")
def public_tracer_lookup(
lookup_in: PublicTracerLookupRequest,
db: Session = Depends(get_db)
):
"""
Endpoint publik untuk kuesioner mandiri alumni:
Mengecek apakah NIM sudah terdaftar, dan memvalidasi kecocokan email jika ingin mengedit data.
"""
return AlumniController.public_tracer_lookup(db, lookup_in)
@router.post("/public-tracer-submit", summary="Kirim atau perbarui kuesioner Tracer Study oleh Alumni (Publik)")
def public_tracer_submit(
submit_in: PublicTracerSubmitRequest,
db: Session = Depends(get_db)
):
"""
Endpoint publik untuk alumni mengirim respons kuesioner (Create/Update).
"""
return AlumniController.public_tracer_submit(db, submit_in)
@router.post("/", status_code=status.HTTP_201_CREATED, summary="Tambah data alumni baru")
def create(
alumni_in: AlumniCreate,
db: Session = Depends(get_db),
current_user = Depends(get_current_active_user)
):
"""
Menambahkan data alumni baru ke database.
Membutuhkan autentikasi token Bearer JWT.
"""
return AlumniController.create_alumni(db, alumni_in)
@router.put("/{alumni_id}", summary="Perbarui data alumni")
def update(
alumni_id: int,
alumni_in: AlumniUpdate,
db: Session = Depends(get_db),
current_user = Depends(get_current_active_user)
):
"""
Memperbarui field data alumni berdasarkan ID.
Membutuhkan autentikasi token Bearer JWT.
"""
return AlumniController.update_alumni(db, alumni_id, alumni_in)
@router.delete("/{alumni_id}", summary="Hapus data alumni")
def delete(
alumni_id: int,
db: Session = Depends(get_db),
current_user = Depends(get_current_active_user)
):
"""
Menghapus data alumni berdasarkan ID dari database.
Membutuhkan autentikasi token Bearer JWT.
"""
return AlumniController.delete_alumni(db, alumni_id)

View File

@ -0,0 +1,15 @@
from fastapi import APIRouter
from app.routers import auth, alumni, prodi, clustering, clustering_results, keywords, dashboard, import_data
# Base API Router instance to compile sub-routers
api_router = APIRouter()
# Register sub-routers with prefixes and API tags
api_router.include_router(auth.router, prefix="/auth", tags=["Authentication"])
api_router.include_router(alumni.router, prefix="/alumni", tags=["Alumni"])
api_router.include_router(prodi.router, prefix="/prodi", tags=["Prodi"])
api_router.include_router(clustering.router, prefix="/clustering", tags=["Clustering ML"])
api_router.include_router(clustering_results.router, prefix="/clustering", tags=["Clustering Results"])
api_router.include_router(keywords.router, prefix="/keywords", tags=["Keywords"])
api_router.include_router(dashboard.router, prefix="/dashboard", tags=["Dashboard"])
api_router.include_router(import_data.router, prefix="/import", tags=["Import Data"])

View File

@ -0,0 +1,51 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.config.database import get_db
from app.schemas.user import UserCreate, UserUpdate, UserLogin
from app.controllers.auth import AuthController
# Create Router instance for auth endpoints
router = APIRouter()
@router.post("/register", summary="Registrasi user baru")
def register(user_in: UserCreate, db: Session = Depends(get_db)):
"""
Endpoint untuk melakukan registrasi user baru.
"""
return AuthController.register_user(db, user_in)
@router.post("/login", summary="Login user untuk mendapatkan JWT token")
def login(login_in: UserLogin, db: Session = Depends(get_db)):
"""
Endpoint untuk login user.
"""
return AuthController.login_user(db, login_in.username, login_in.password)
@router.get("/users", summary="Daftar semua pengguna / Kaprodi")
def get_users(db: Session = Depends(get_db)):
"""
Endpoint untuk mengambil seluruh data pengguna sistem (Admin & Kaprodi).
"""
return AuthController.get_users(db)
@router.post("/users", summary="Tambah pengguna baru oleh Admin")
def create_user(user_in: UserCreate, db: Session = Depends(get_db)):
"""
Endpoint untuk membuat akun pengguna / Kaprodi baru.
"""
return AuthController.register_user(db, user_in)
@router.put("/users/{user_id}", summary="Perbarui data pengguna")
def update_user(user_id: int, user_in: UserUpdate, db: Session = Depends(get_db)):
"""
Endpoint untuk mengedit profil, role, prodi, status aktif, atau password user.
"""
return AuthController.update_user(db, user_id, user_in)
@router.delete("/users/{user_id}", summary="Hapus pengguna")
def delete_user(user_id: int, db: Session = Depends(get_db)):
"""
Endpoint untuk menghapus akun pengguna (selain akun super admin utama).
"""
return AuthController.delete_user(db, user_id)

View File

@ -0,0 +1,364 @@
"""
Router untuk Clustering Endpoint
"""
import math
from datetime import datetime
from fastapi import APIRouter, UploadFile, File, HTTPException, Depends, Query, Body
from fastapi.responses import JSONResponse, StreamingResponse
from typing import List, Optional, Dict, Any
from sqlalchemy.orm import Session
from sqlalchemy import or_
import pandas as pd
import io
from app.config.database import get_db
from app.models.models import ClusteringResult, ModelEvaluation
from app.models.alumni import Alumni
from app.schemas.clustering import (
ClusteringRequest,
ClusteringResponse,
ClusterResult,
AlumniInput,
StandardizeRequest,
StandardizeResponse
)
from app.services.ml_service import get_ml_service
from app.utils.standardization import ColumnStandardizer, merge_datasets, clean_data
router = APIRouter(tags=["Clustering ML"])
@router.post("/process", summary="Jalankan Pipeline Clustering dari Database MySQL")
@router.post("/run-db", summary="Alias Jalankan Pipeline Clustering dari Database")
def process_clustering_db(
tahun_lulus: Optional[int] = Query(None, description="Filter tahun kelulusan / angkatan (opsional)"),
n_clusters: int = Query(4, ge=2, le=10, description="Jumlah cluster K-Means"),
db: Session = Depends(get_db)
):
"""
Menjalankan proses Machine Learning Clustering (TF-IDF + K-Means K=4 + Interpretasi C0-C3)
langsung dari data alumni & pekerjaan yang ada di database MySQL.
Hasil otomatis disimpan ke tabel clustering_result dan model_evaluation.
"""
ml_service = get_ml_service()
result = ml_service.process_clustering_from_db(
db=db,
tahun_lulus=tahun_lulus,
n_clusters=n_clusters
)
if result.get("status") == "error":
raise HTTPException(status_code=400, detail=result.get("message"))
return result
@router.get("/results", summary="Ambil Hasil Clustering dengan Filter & Pagination")
def get_clustering_results(
skip: int = Query(0, ge=0),
limit: int = Query(10, ge=1, le=500),
search: Optional[str] = Query(None, description="Cari nama atau NIM"),
kategori: Optional[str] = Query(None, description="Filter kategori C0, C1, C2, C3"),
kode_prodi: Optional[str] = Query(None, description="Filter kode prodi"),
tahun_lulus: Optional[int] = Query(None, description="Filter tahun lulus"),
db: Session = Depends(get_db)
):
"""
Mengambil data hasil clustering alumni dari database lengkap dengan filter kategori C0-C3,
prodi, tahun, dan pencarian nama/NIM.
"""
from app.models.models import Pekerjaan
query = db.query(
ClusteringResult,
Alumni.nim,
Alumni.nama,
Alumni.kode_prodi,
Alumni.tahun_lulus,
Alumni.pekerjaan,
Alumni.instansi,
Alumni.status_kerja,
Pekerjaan.status_pekerjaan,
Pekerjaan.jenis_perusahaan,
Pekerjaan.nama_perusahaan,
Pekerjaan.jabatan,
Pekerjaan.teks_pekerjaan
).join(Alumni, ClusteringResult.alumni_id == Alumni.id)\
.outerjoin(Pekerjaan, Alumni.id == Pekerjaan.alumni_id)
if search:
s = f"%{search.strip()}%"
query = query.filter(or_(Alumni.nama.ilike(s), Alumni.nim.ilike(s), Alumni.pekerjaan.ilike(s), Pekerjaan.teks_pekerjaan.ilike(s)))
if kategori:
query = query.filter(ClusteringResult.kategori == kategori.strip().upper())
if kode_prodi:
query = query.filter(Alumni.kode_prodi == str(kode_prodi).strip())
if tahun_lulus:
query = query.filter(Alumni.tahun_lulus == int(tahun_lulus))
total = query.count()
rows = query.order_by(ClusteringResult.id.desc()).offset(skip).limit(limit).all()
items = []
for r in rows:
cr = r[0]
pek_nama = r[10] if (r[10] and r[10].strip() not in ['', 'nan', 'None']) else (r[5] or "-")
pek_jab = r[11] if (r[11] and r[11].strip() not in ['', 'nan', 'None']) else (r[6] or "-")
pek_status = r[8] if (r[8] and r[8].strip() not in ['', 'nan', 'None']) else (r[7] or "-")
pek_jenis = r[9] if (r[9] and r[9].strip() not in ['', 'nan', 'None']) else "-"
pek_teks = r[12] if (r[12] and r[12].strip() not in ['', 'nan', 'None']) else f"{pek_status} {pek_jenis} {pek_nama} {pek_jab}".replace('-', '').strip()
if not pek_teks:
pek_teks = "-"
items.append({
"id": cr.id,
"alumni_id": cr.alumni_id,
"nim": r[1],
"nama": r[2],
"kode_prodi": r[3],
"tahun_lulus": r[4],
"status_pekerjaan": pek_status,
"jenis_perusahaan": pek_jenis,
"nama_perusahaan": pek_nama,
"jabatan": pek_jab,
"teks_pekerjaan": pek_teks,
"cluster": cr.cluster,
"kategori": cr.kategori,
"profile_match": cr.profile_match,
"matched_keyword": cr.matched_keyword or "",
"model_version": cr.model_version,
"created_at": cr.created_at
})
page = (skip // limit) + 1 if limit > 0 else 1
total_pages = math.ceil(total / limit) if limit > 0 else 1
return {
"success": True,
"data": {
"items": items,
"total": total,
"page": page,
"limit": limit,
"total_pages": total_pages
}
}
@router.get("/summary", summary="Ringkasan Statistik Hasil Clustering Terkini")
def get_clustering_summary(
tahun_lulus: Optional[int] = Query(None, description="Filter tahun kelulusan / angkatan (opsional)"),
kode_prodi: Optional[str] = Query(None, description="Filter kode prodi (opsional)"),
db: Session = Depends(get_db)
):
"""Mengambil ringkasan statistik distribusi C0-C3 dan evaluasi model terkini."""
query = db.query(ClusteringResult).join(Alumni, Alumni.id == ClusteringResult.alumni_id)
if tahun_lulus:
query = query.filter(Alumni.tahun_lulus == int(tahun_lulus))
if kode_prodi:
query = query.filter(Alumni.kode_prodi == str(kode_prodi).strip())
from sqlalchemy import func
# Eksekusi 1 single query agregasi GROUP BY kategori
cat_counts = query.with_entities(
ClusteringResult.kategori,
func.count(ClusteringResult.id)
).group_by(ClusteringResult.kategori).all()
dist = {'C0': 0, 'C1': 0, 'C2': 0, 'C3': 0}
total = 0
for kat, cnt in cat_counts:
k_str = str(kat).upper().strip() if kat else 'C3'
if k_str in dist:
dist[k_str] = int(cnt)
total += int(cnt)
latest_eval = db.query(ModelEvaluation).order_by(ModelEvaluation.created_at.desc()).first()
return {
"total_clustered": total,
"distribution": dist,
"silhouette_score": latest_eval.silhouette_score if latest_eval else None,
"model_version": latest_eval.model_version if latest_eval else None,
"k": latest_eval.k if latest_eval else 4,
"tahun_lulus": tahun_lulus,
"kode_prodi": kode_prodi
}
@router.get("/iteration-details", summary="Ambil Detail Riwayat Iterasi & Perhitungan Matematis K-Means")
def get_iteration_details(
tahun_lulus: Optional[int] = Query(None, description="Filter tahun kelulusan / angkatan (opsional)"),
alumni_id: Optional[int] = Query(None, description="ID alumni spesifik untuk inspeksi perhitungan detail"),
db: Session = Depends(get_db)
):
"""
Mengambil log lengkap iterasi perulangan K-Means, karakteristik centroid,
dan alur transformasi 5 tahap (Kalimat -> Preprocessing -> TF-IDF -> K-Means -> Klaster)
berdasarkan dataset tahun kelulusan yang dipilih.
"""
ml_service = get_ml_service()
details = ml_service.get_latest_iteration_details(db=db, tahun_lulus=tahun_lulus, target_alumni_id=alumni_id)
return {
"success": True,
"data": details
}
def _build_export_dataframe(
db: Session,
search: Optional[str] = None,
kategori: Optional[str] = None,
kode_prodi: Optional[str] = None,
tahun_lulus: Optional[int] = None
) -> pd.DataFrame:
from app.models.models import Pekerjaan
query = db.query(
ClusteringResult,
Alumni.nim,
Alumni.nama,
Alumni.kode_prodi,
Alumni.tahun_lulus,
Alumni.pekerjaan,
Alumni.instansi,
Alumni.status_kerja,
Pekerjaan.status_pekerjaan,
Pekerjaan.jenis_perusahaan,
Pekerjaan.nama_perusahaan,
Pekerjaan.jabatan,
Pekerjaan.teks_pekerjaan
).join(Alumni, ClusteringResult.alumni_id == Alumni.id)\
.outerjoin(Pekerjaan, Alumni.id == Pekerjaan.alumni_id)
if search:
s = f"%{search.strip()}%"
query = query.filter(or_(
Alumni.nama.ilike(s),
Alumni.nim.ilike(s),
Alumni.pekerjaan.ilike(s),
Pekerjaan.teks_pekerjaan.ilike(s)
))
if kategori:
query = query.filter(ClusteringResult.kategori == kategori.strip().upper())
if kode_prodi:
query = query.filter(Alumni.kode_prodi == str(kode_prodi).strip())
if tahun_lulus:
query = query.filter(Alumni.tahun_lulus == int(tahun_lulus))
rows = query.order_by(ClusteringResult.id.asc()).all()
prodi_map = {
'55301': 'D4 Teknik Informatika',
'57401': 'D3 Manajemen Informatika',
'56401': 'D3 Teknik Komputer',
'55302': 'D4 TIF Kampus Nganjuk',
'55304': 'D4 TIF Kampus Sidoarjo',
}
kategori_labels = {
'C0': 'Sesuai Profil Lulusan',
'C1': 'Bekerja, Bidang Diketahui Formal',
'C2': 'Bekerja, Kurang Teridentifikasi',
'C3': 'Belum / Tidak Bekerja'
}
export_records = []
for idx, r in enumerate(rows, start=1):
cr = r[0]
kp = str(r[3] or '').strip()
prodi_name = prodi_map.get(kp, kp)
kat = cr.kategori or '-'
kat_label = kategori_labels.get(kat, '-')
pek_nama = r[10] if (r[10] and r[10].strip() not in ['', 'nan', 'None']) else (r[5] or "-")
pek_jab = r[11] if (r[11] and r[11].strip() not in ['', 'nan', 'None']) else (r[6] or "-")
pek_status = r[8] if (r[8] and r[8].strip() not in ['', 'nan', 'None']) else (r[7] or "-")
pek_jenis = r[9] if (r[9] and r[9].strip() not in ['', 'nan', 'None']) else "-"
pek_teks = r[12] if (r[12] and r[12].strip() not in ['', 'nan', 'None']) else f"{pek_status} {pek_jenis} {pek_nama} {pek_jab}".replace('-', '').strip()
export_records.append({
"No": idx,
"NIM": r[1],
"Nama Alumni": r[2],
"Program Studi": prodi_name,
"Tahun Lulus": r[4],
"Status Kerja": pek_status,
"Nama Perusahaan / Instansi": pek_nama,
"Jabatan / Posisi": pek_jab,
"Jenis Perusahaan": pek_jenis,
"Teks Pekerjaan": pek_teks if pek_teks else "-",
"Klaster": f"Cluster {cr.cluster}",
"Kategori": kat,
"Interpretasi Relevansi": kat_label,
"Kata Kunci Cocok": cr.matched_keyword or "-"
})
return pd.DataFrame(export_records)
@router.get("/export/excel", summary="Unduh Hasil Clustering ke File Excel (.xlsx)")
def export_clustering_excel(
search: Optional[str] = Query(None, description="Cari nama atau NIM"),
kategori: Optional[str] = Query(None, description="Filter kategori C0, C1, C2, C3"),
kode_prodi: Optional[str] = Query(None, description="Filter kode prodi"),
tahun_lulus: Optional[int] = Query(None, description="Filter tahun lulus"),
db: Session = Depends(get_db)
):
"""
Ekspor hasil clustering alumni yang tersimpan di MySQL ke berkas spreadsheet Microsoft Excel (.xlsx).
Mendukung filter tahun kelulusan, program studi, kategori relevansi C0-C3, dan kata kunci pencarian.
"""
df = _build_export_dataframe(db, search, kategori, kode_prodi, tahun_lulus)
output = io.BytesIO()
with pd.ExcelWriter(output, engine='openpyxl') as writer:
df.to_excel(writer, index=False, sheet_name='Hasil Klastering')
output.seek(0)
filename = f"Hasil_Clustering_Alumni_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
headers = {
'Content-Disposition': f'attachment; filename="{filename}"'
}
return StreamingResponse(
output,
media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
headers=headers
)
@router.get("/export/csv", summary="Unduh Hasil Clustering ke File CSV (.csv)")
def export_clustering_csv(
search: Optional[str] = Query(None, description="Cari nama atau NIM"),
kategori: Optional[str] = Query(None, description="Filter kategori C0, C1, C2, C3"),
kode_prodi: Optional[str] = Query(None, description="Filter kode prodi"),
tahun_lulus: Optional[int] = Query(None, description="Filter tahun lulus"),
db: Session = Depends(get_db)
):
"""
Ekspor hasil clustering alumni yang tersimpan di MySQL ke berkas CSV dengan encoding UTF-8.
"""
df = _build_export_dataframe(db, search, kategori, kode_prodi, tahun_lulus)
output = io.BytesIO()
df.to_csv(output, index=False, encoding='utf-8-sig')
output.seek(0)
filename = f"Hasil_Clustering_Alumni_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
headers = {
'Content-Disposition': f'attachment; filename="{filename}"'
}
return StreamingResponse(
output,
media_type='text/csv; charset=utf-8',
headers=headers
)

View File

@ -0,0 +1,231 @@
"""
Router untuk CRUD Clustering Results
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List
from app.config.database import get_db
from app.schemas.models import (
ClusteringResultCreate,
ClusteringResultResponse,
ModelEvaluationCreate,
ModelEvaluationResponse,
BulkClusteringResult
)
from app.models.models import ClusteringResult, ModelEvaluation
from app.models.alumni import Alumni
router = APIRouter(prefix="/clustering", tags=["Clustering Results"])
# ============== CLUSTERING RESULTS ==============
@router.get("/results", response_model=List[ClusteringResultResponse])
def get_all_results(
skip: int = 0,
limit: int = 100,
db: Session = Depends(get_db)
):
"""Ambil semua hasil clustering"""
results = db.query(ClusteringResult).offset(skip).limit(limit).all()
return results
@router.get("/results/{alumni_id}", response_model=ClusteringResultResponse)
def get_result_by_alumni(
alumni_id: int,
db: Session = Depends(get_db)
):
"""Ambil hasil clustering berdasarkan alumni_id"""
result = db.query(ClusteringResult).filter(
ClusteringResult.alumni_id == alumni_id
).first()
if not result:
raise HTTPException(status_code=404, detail="Hasil clustering tidak ditemukan")
return result
@router.post("/results", response_model=ClusteringResultResponse)
def create_result(
result_in: ClusteringResultCreate,
db: Session = Depends(get_db)
):
"""Tambah hasil clustering"""
# Cek apakah alumni exists
alumni = db.query(Alumni).filter(Alumni.id == result_in.alumni_id).first()
if not alumni:
raise HTTPException(status_code=404, detail="Alumni tidak ditemukan")
# Cek apakah sudah ada hasil untuk alumni ini
existing = db.query(ClusteringResult).filter(
ClusteringResult.alumni_id == result_in.alumni_id
).first()
if existing:
raise HTTPException(status_code=400, detail="Hasil clustering sudah ada untuk alumni ini")
result = ClusteringResult(**result_in.model_dump())
db.add(result)
db.commit()
db.refresh(result)
return result
@router.post("/results/bulk")
def create_bulk_results(
bulk_data: BulkClusteringResult,
db: Session = Depends(get_db)
):
"""Simpan hasil clustering dan evaluasi model"""
try:
# 1. Simpan evaluasi model
eval_data = {
"model_version": bulk_data.model_version,
"k": bulk_data.k,
"inertia": bulk_data.inertia,
"silhouette_score": bulk_data.silhouette_score
}
evaluation = ModelEvaluation(**eval_data)
db.add(evaluation)
db.flush()
# 2. Simpan hasil clustering per alumni
results_saved = 0
for item in bulk_data.results:
# Cek apakah alumni exists
alumni = db.query(Alumni).filter(Alumni.id == item["alumni_id"]).first()
if not alumni:
continue
# Hapus hasil lama jika ada
old = db.query(ClusteringResult).filter(
ClusteringResult.alumni_id == item["alumni_id"]
).first()
if old:
db.delete(old)
# Simpan hasil baru
result_data = {
"alumni_id": item["alumni_id"],
"model_version": bulk_data.model_version,
"k": bulk_data.k,
"cluster": item["cluster"],
"kategori": item["kategori"],
"profile_match": item.get("profile_match", False),
"matched_keyword": item.get("matched_keyword", "")
}
result = ClusteringResult(**result_data)
db.add(result)
results_saved += 1
db.commit()
return {
"status": "success",
"model_evaluation_id": evaluation.id,
"results_saved": results_saved
}
except Exception as e:
db.rollback()
raise HTTPException(status_code=500, detail=str(e))
@router.delete("/results/{alumni_id}")
def delete_result(
alumni_id: int,
db: Session = Depends(get_db)
):
"""Hapus hasil clustering berdasarkan alumni_id"""
result = db.query(ClusteringResult).filter(
ClusteringResult.alumni_id == alumni_id
).first()
if not result:
raise HTTPException(status_code=404, detail="Hasil clustering tidak ditemukan")
db.delete(result)
db.commit()
return {"message": "Hasil clustering berhasil dihapus"}
# ============== MODEL EVALUATIONS ==============
@router.get("/evaluations", response_model=List[ModelEvaluationResponse])
def get_all_evaluations(
skip: int = 0,
limit: int = 10,
db: Session = Depends(get_db)
):
"""Ambil semua evaluasi model"""
evaluations = db.query(ModelEvaluation).order_by(
ModelEvaluation.created_at.desc()
).offset(skip).limit(limit).all()
return evaluations
@router.get("/evaluations/latest", response_model=ModelEvaluationResponse)
def get_latest_evaluation(db: Session = Depends(get_db)):
"""Ambil evaluasi model terbaru"""
evaluation = db.query(ModelEvaluation).order_by(
ModelEvaluation.created_at.desc()
).first()
if not evaluation:
raise HTTPException(status_code=404, detail="Tidak ada evaluasi model")
return evaluation
@router.post("/evaluations", response_model=ModelEvaluationResponse)
def create_evaluation(
eval_in: ModelEvaluationCreate,
db: Session = Depends(get_db)
):
"""Tambah evaluasi model baru"""
evaluation = ModelEvaluation(**eval_in.model_dump())
db.add(evaluation)
db.commit()
db.refresh(evaluation)
return evaluation
# ============== STATISTIK ==============
@router.get("/stats")
def get_clustering_stats(db: Session = Depends(get_db)):
"""Ambil statistik hasil clustering"""
results = db.query(ClusteringResult).all()
if not results:
return {
"total": 0,
"by_kategori": {},
"by_cluster": {}
}
# Count by kategori
kategori_count = {}
for r in results:
kategori_count[r.kategori] = kategori_count.get(r.kategori, 0) + 1
# Count by cluster
cluster_count = {}
for r in results:
cluster_count[f"Cluster_{r.cluster}"] = cluster_count.get(f"Cluster_{r.cluster}", 0) + 1
# Count by prodi
prodi_kategori = {}
alumni_with_results = db.query(Alumni).join(ClusteringResult).all()
return {
"total": len(results),
"by_kategori": kategori_count,
"by_cluster": cluster_count,
"model_version": results[0].model_version if results else None
}

View File

@ -0,0 +1,539 @@
"""
Router untuk Dashboard API - PRD Section 22
"""
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from sqlalchemy import func, or_
from typing import Optional, List, Dict, Any
from app.config.database import get_db
from app.models.alumni import Alumni
from app.models.models import Pekerjaan, Kompetensi, ClusteringResult, ModelEvaluation, TracerResponse
router = APIRouter(tags=["Dashboard"])
@router.get("/stats")
def get_dashboard_stats(
kode_prodi: Optional[str] = Query(None),
tahun_lulus: Optional[int] = Query(None),
db: Session = Depends(get_db)
):
"""
Dashboard Utama - PRD Section 22
Menampilkan: total alumni, total bekerja, total belum bekerja, distribusi C0-C3
Mendukung filter prodi (khusus role Kaprodi atau Admin) dan filter angkatan/tahun_lulus
"""
prodi_filter = kode_prodi if (kode_prodi and kode_prodi != "all") else None
# Total alumni
q_alumni = db.query(Alumni)
if prodi_filter:
q_alumni = q_alumni.filter(Alumni.kode_prodi == prodi_filter)
if tahun_lulus:
q_alumni = q_alumni.filter(Alumni.tahun_lulus == int(tahun_lulus))
total_alumni = q_alumni.count()
# Total hasil clustering
q_cluster = db.query(ClusteringResult).join(Alumni, Alumni.id == ClusteringResult.alumni_id)
if prodi_filter:
q_cluster = q_cluster.filter(Alumni.kode_prodi == prodi_filter)
if tahun_lulus:
q_cluster = q_cluster.filter(Alumni.tahun_lulus == int(tahun_lulus))
total_clustered = q_cluster.count()
# Distribusi kategori C0-C3
q_kategori = db.query(
ClusteringResult.kategori,
func.count(ClusteringResult.id).label('count')
).join(Alumni, Alumni.id == ClusteringResult.alumni_id)
if prodi_filter:
q_kategori = q_kategori.filter(Alumni.kode_prodi == prodi_filter)
if tahun_lulus:
q_kategori = q_kategori.filter(Alumni.tahun_lulus == int(tahun_lulus))
kategori_dist = q_kategori.group_by(ClusteringResult.kategori).all()
kategori_dict = {k: c for k, c in kategori_dist}
# Ambil model evaluation terbaru
latest_eval = db.query(ModelEvaluation).order_by(
ModelEvaluation.created_at.desc()
).first()
# Get unique tahun lulus
q_tahun = db.query(Alumni.tahun_lulus)
if prodi_filter:
q_tahun = q_tahun.filter(Alumni.kode_prodi == prodi_filter)
tahun_list = q_tahun.distinct().order_by(Alumni.tahun_lulus.desc()).all()
tahun_lulus = [t[0] for t in tahun_list if t[0]]
return {
"total_alumni": total_alumni,
"total_clustered": total_clustered,
"kategori": {
"C0": kategori_dict.get("C0", 0),
"C1": kategori_dict.get("C1", 0),
"C2": kategori_dict.get("C2", 0),
"C3": kategori_dict.get("C3", 0),
},
"silhouette_score": latest_eval.silhouette_score if latest_eval else None,
"model_version": latest_eval.model_version if latest_eval else None,
"tahun_lulus": tahun_lulus # Include tahun for dropdown
}
@router.get("/by-prodi")
def get_stats_by_prodi(
db: Session = Depends(get_db)
):
"""Distribusi alumni dan kategori per prodi"""
# Get alumni count by prodi
prodi_stats = db.query(
Alumni.kode_prodi,
func.count(Alumni.id).label('total')
).group_by(Alumni.kode_prodi).all()
# Get clustering results by prodi and kategori
results = db.query(
Alumni.kode_prodi,
ClusteringResult.kategori,
func.count(ClusteringResult.id).label('count')
).join(
ClusteringResult, Alumni.id == ClusteringResult.alumni_id
).group_by(
Alumni.kode_prodi, ClusteringResult.kategori
).all()
# Format results
prodi_data = {}
for prodi, total in prodi_stats:
prodi_data[prodi] = {"total": total, "C0": 0, "C1": 0, "C2": 0, "C3": 0}
for prodi, kategori, count in results:
if prodi in prodi_data:
prodi_data[prodi][kategori] = count
return prodi_data
@router.get("/by-year")
def get_stats_by_year(
kode_prodi: Optional[str] = Query(None),
db: Session = Depends(get_db)
):
"""Distribusi alumni dan tren kategori C0-C3 per tahun kelulusan secara kronologis (Ascending), mendukung filter prodi"""
prodi_filter = kode_prodi if (kode_prodi and kode_prodi != "all") else None
# 1. Total alumni per tahun lulus urut dari tahun terlama ke terbaru
q_year = db.query(
Alumni.tahun_lulus,
func.count(Alumni.id).label('total')
).filter(Alumni.tahun_lulus.isnot(None))
if prodi_filter:
q_year = q_year.filter(Alumni.kode_prodi == prodi_filter)
year_totals = q_year.group_by(Alumni.tahun_lulus).order_by(Alumni.tahun_lulus.asc()).all()
# 2. Distribusi per kategori C0, C1, C2, C3 per tahun
q_cat = db.query(
Alumni.tahun_lulus,
ClusteringResult.kategori,
func.count(ClusteringResult.id).label('count')
).join(ClusteringResult, Alumni.id == ClusteringResult.alumni_id)\
.filter(Alumni.tahun_lulus.isnot(None))
if prodi_filter:
q_cat = q_cat.filter(Alumni.kode_prodi == prodi_filter)
cat_results = q_cat.group_by(Alumni.tahun_lulus, ClusteringResult.kategori)\
.order_by(Alumni.tahun_lulus.asc()).all()
# Susun struktur data kronologis
years_list = [str(y[0]) for y in year_totals if y[0]]
breakdown_map = {str(y[0]): {"total": y[1], "C0": 0, "C1": 0, "C2": 0, "C3": 0} for y in year_totals if y[0]}
for thn, kat, cnt in cat_results:
thn_str = str(thn)
if thn_str in breakdown_map and kat in breakdown_map[thn_str]:
breakdown_map[thn_str][kat] = cnt
# Format series untuk area / line chart
c0_series = [breakdown_map[y]["C0"] for y in years_list]
c1_series = [breakdown_map[y]["C1"] for y in years_list]
c2_series = [breakdown_map[y]["C2"] for y in years_list]
c3_series = [breakdown_map[y]["C3"] for y in years_list]
return {
"years": years_list,
"breakdown": breakdown_map,
"series": [
{"name": "C0 - Sesuai Profil", "data": c0_series, "color": "#059669"},
{"name": "C1 - Bidang Diketahui", "data": c1_series, "color": "#2563eb"},
{"name": "C2 - Kurang Teridentifikasi", "data": c2_series, "color": "#d97706"},
{"name": "C3 - Belum Bekerja", "data": c3_series, "color": "#64748b"},
],
"totals_by_year": {str(year): total for year, total in year_totals}
}
@router.get("/by-cluster")
def get_stats_by_cluster(
db: Session = Depends(get_db)
):
"""Distribusi alumni per cluster"""
cluster_stats = db.query(
ClusteringResult.cluster,
ClusteringResult.kategori,
func.count(ClusteringResult.id).label('count')
).group_by(
ClusteringResult.cluster,
ClusteringResult.kategori
).all()
# Format results
cluster_data = {}
for cluster, kategori, count in cluster_stats:
key = f"Cluster_{cluster}"
if key not in cluster_data:
cluster_data[key] = {"total": 0, "kategori": {}}
cluster_data[key]["total"] += count
cluster_data[key]["kategori"][kategori] = count
return cluster_data
@router.get("/competency-profile")
def get_competency_profile(
db: Session = Depends(get_db)
):
"""Profil kompetensi rata-rata per kategori"""
# Get average competency scores by kategori
results = db.query(
ClusteringResult.kategori,
func.avg(Kompetensi.etika_lulus).label('etika'),
func.avg(Kompetensi.keahlian_lulus).label('keahlian'),
func.avg(Kompetensi.bahasa_inggris_lulus).label('bahasa_inggris'),
func.avg(Kompetensi.teknologi_informasi_lulus).label('teknologi_informasi'),
func.avg(Kompetensi.komunikasi_lulus).label('komunikasi'),
func.avg(Kompetensi.kerja_sama_lulus).label('kerja_sama'),
func.avg(Kompetensi.pengembangan_diri_lulus).label('pengembangan_diri'),
func.count(Kompetensi.id).label('count')
).join(
Kompetensi, Alumni.id == Kompetensi.alumni_id
).join(
ClusteringResult, Alumni.id == ClusteringResult.alumni_id
).group_by(
ClusteringResult.kategori
).all()
profile = {}
for r in results:
profile[r.kategori] = {
"etika": round(float(r.etika), 2) if r.etika else None,
"keahlian": round(float(r.keahlian), 2) if r.keahlian else None,
"bahasa_inggris": round(float(r.bahasa_inggris), 2) if r.bahasa_inggris else None,
"teknologi_informasi": round(float(r.teknologi_informasi), 2) if r.teknologi_informasi else None,
"komunikasi": round(float(r.komunikasi), 2) if r.komunikasi else None,
"kerja_sama": round(float(r.kerja_sama), 2) if r.kerja_sama else None,
"pengembangan_diri": round(float(r.pengembangan_diri), 2) if r.pengembangan_diri else None,
"count": r.count
}
return profile
@router.get("/company-types")
def get_top_company_types(
limit: int = Query(10, ge=1, le=50),
db: Session = Depends(get_db)
):
"""Top jenis perusahaan berdasarkan hasil clustering"""
results = db.query(
Pekerjaan.jenis_perusahaan,
func.count(Pekerjaan.id).label('count')
).join(
Alumni, Pekerjaan.alumni_id == Alumni.id
).join(
ClusteringResult, Alumni.id == ClusteringResult.alumni_id
).group_by(
Pekerjaan.jenis_perusahaan
).order_by(
func.count(Pekerjaan.id).desc()
).limit(limit).all()
return {
"jenis_perusahaan": [
{"jenis": j, "count": c} for j, c in results
]
}
@router.get("/top-keywords")
def get_top_matched_keywords(
limit: int = Query(10, ge=1, le=50),
db: Session = Depends(get_db)
):
"""Top keywords yang match dengan kamus prodi"""
# Get all matched keywords
results = db.query(ClusteringResult.matched_keyword).filter(
ClusteringResult.matched_keyword.isnot(None),
ClusteringResult.matched_keyword != ""
).all()
# Count keyword frequency
keyword_count = {}
for r in results:
if r.matched_keyword:
# Split by comma for multiple keywords
keywords = [k.strip() for k in r.matched_keyword.split(",")]
for kw in keywords:
keyword_count[kw] = keyword_count.get(kw, 0) + 1
# Sort and limit
sorted_keywords = sorted(keyword_count.items(), key=lambda x: x[1], reverse=True)[:limit]
return {
"keywords": [
{"keyword": kw, "count": c} for kw, c in sorted_keywords
]
}
@router.get("/akreditasi-tables")
def get_akreditasi_tables(
ts_year: Optional[int] = Query(None, description="Tahun Laporan TS (misal 2024 atau 2025)"),
kode_prodi: Optional[str] = Query(None, description="Kode program studi atau 'all'"),
mode: Optional[str] = Query("ts_range", description="'ts_range' (TS-2 s/d TS) atau 'all_years'"),
db: Session = Depends(get_db)
):
"""
Tabel Akreditasi LAM INFOKOM (Kriteria 9 / IKU-1):
- Tabel 2.B.4: Rata-rata Masa Tunggu Lulusan untuk Bekerja Pertama Kali
- Tabel 2.B.5: Kesesuaian Bidang Kerja Lulusan (Infokom vs Non-Infokom & Lingkup Kerja)
Mendukung filter TS-2, TS-1, TS dan pemisahan per Program Studi (TIF, MIF, TKK).
"""
# 1. Dapatkan daftar tahun kelulusan yang valid (< 2026)
year_rows = db.query(Alumni.tahun_lulus)\
.filter(Alumni.tahun_lulus.isnot(None), Alumni.tahun_lulus < 2026)\
.distinct().order_by(Alumni.tahun_lulus.desc()).all()
available_years = [y[0] for y in year_rows if y[0]]
# Tentukan TS Tahun (default 2025 jika tidak disediakan, atau tahun terbaru yang valid)
if not ts_year:
ts_year = 2025 if 2025 in available_years else (available_years[0] if available_years else 2025)
# Tentukan deret tahun yang akan dihitung
if mode == "all_years":
target_years = sorted(available_years)
else:
# Standar LAM INFOKOM: 3 Tahun Lulus Terakhir (TS-2, TS-1, TS)
target_years = [ts_year - 2, ts_year - 1, ts_year]
# Kamus Nama Prodi Resmi JTI Polije
PRODI_INFO = {
"all": "Semua Program Studi (Jurusan TI)",
"55301": "D4 Teknik Informatika (TIF)",
"57401": "D3 Manajemen Informatika (MIF)",
"56401": "D3 Teknik Komputer (TKK)",
"55302": "D4 Teknik Rekayasa Komputer",
"55304": "D3 Manajemen Informatika (Kampus Lain)"
}
prodi_filter = kode_prodi if (kode_prodi and kode_prodi != "all") else None
prodi_label = PRODI_INFO.get(kode_prodi, "Semua Program Studi (Jurusan TI)") if kode_prodi else "Semua Program Studi (Jurusan TI)"
rows_2b4 = []
rows_2b5 = []
sum_lulusan = 0
sum_terlacak = 0
weighted_waktu_sum = 0.0
weighted_waktu_count = 0
sum_infokom = 0
sum_non_infokom = 0
sum_multinasional = 0
sum_nasional = 0
sum_wirausaha = 0
for year in target_years:
# Tentukan label TS (misal TS-2, TS-1, TS)
diff = ts_year - year
if diff == 0:
ts_label = "TS"
elif diff > 0:
ts_label = f"TS-{diff}"
else:
ts_label = f"TS+{abs(diff)}"
display_label = f"{ts_label} ({year})" if mode == "ts_range" else f"{year} ({ts_label})"
# A. Jumlah Lulusan
q_lulus = db.query(Alumni).filter(Alumni.tahun_lulus == year)
if prodi_filter:
q_lulus = q_lulus.filter(Alumni.kode_prodi == prodi_filter)
n_lulus = q_lulus.count()
# B. Jumlah Lulusan yang Terlacak (isi TracerResponse atau memiliki riwayat kerja)
q_terlacak = db.query(Alumni).join(TracerResponse, Alumni.id == TracerResponse.alumni_id)\
.filter(Alumni.tahun_lulus == year)
if prodi_filter:
q_terlacak = q_terlacak.filter(Alumni.kode_prodi == prodi_filter)
n_terlacak = q_terlacak.count()
# C. Rata-rata Waktu Tunggu (Bulan) — dihitung dari alumni yang bekerja dengan bulan_dapat_kerja > 0
q_waktu = db.query(
func.avg(TracerResponse.bulan_dapat_kerja),
func.count(TracerResponse.id)
).join(Alumni, Alumni.id == TracerResponse.alumni_id)\
.filter(
Alumni.tahun_lulus == year,
TracerResponse.bulan_dapat_kerja.isnot(None),
TracerResponse.bulan_dapat_kerja > 0
)
if prodi_filter:
q_waktu = q_waktu.filter(Alumni.kode_prodi == prodi_filter)
avg_waktu_res, count_waktu = q_waktu.first()
avg_waktu = round(float(avg_waktu_res), 2) if avg_waktu_res is not None else 0.0
# D. Profesi Bidang Infokom (C0)
q_c0 = db.query(ClusteringResult).join(Alumni, Alumni.id == ClusteringResult.alumni_id)\
.filter(Alumni.tahun_lulus == year, ClusteringResult.kategori == "C0")
if prodi_filter:
q_c0 = q_c0.filter(Alumni.kode_prodi == prodi_filter)
n_infokom = q_c0.count()
# E. Profesi Bidang NON Infokom (C1 + C2)
q_non_c0 = db.query(ClusteringResult).join(Alumni, Alumni.id == ClusteringResult.alumni_id)\
.filter(Alumni.tahun_lulus == year, ClusteringResult.kategori.in_(["C1", "C2"]))
if prodi_filter:
q_non_c0 = q_non_c0.filter(Alumni.kode_prodi == prodi_filter)
n_non_infokom = q_non_c0.count()
# F. Lingkup Tempat Kerja: Multinasional / Internasional
q_multi = db.query(TracerResponse).join(Alumni, Alumni.id == TracerResponse.alumni_id)\
.filter(
Alumni.tahun_lulus == year,
or_(
TracerResponse.tingkatan_tempat_kerja.ilike("%multinasional%"),
TracerResponse.tingkatan_tempat_kerja.ilike("%internasional%"),
TracerResponse.jenis_perusahaan_full.ilike("%multilateral%")
)
)
if prodi_filter:
q_multi = q_multi.filter(Alumni.kode_prodi == prodi_filter)
n_multi = q_multi.count()
# G. Lingkup Tempat Kerja: Nasional (BUMN, Instansi Pusat, Swasta Nasional)
q_nas = db.query(TracerResponse).join(Alumni, Alumni.id == TracerResponse.alumni_id)\
.filter(
Alumni.tahun_lulus == year,
TracerResponse.tingkatan_tempat_kerja.ilike("%nasional%")
)
if prodi_filter:
q_nas = q_nas.filter(Alumni.kode_prodi == prodi_filter)
n_nas = q_nas.count()
# H. Lingkup Tempat Kerja: Wirausaha
q_wira = db.query(Pekerjaan).join(Alumni, Alumni.id == Pekerjaan.alumni_id)\
.filter(
Alumni.tahun_lulus == year,
or_(
Pekerjaan.status_pekerjaan.ilike("%wiraswasta%"),
Pekerjaan.jenis_perusahaan.ilike("%wiraswasta%")
)
)
if prodi_filter:
q_wira = q_wira.filter(Alumni.kode_prodi == prodi_filter)
n_wira = q_wira.count()
# Masukkan ke baris tabel 2.B.4
rows_2b4.append({
"ts_code": ts_label,
"tahun_lulus": year,
"tahun_label": display_label,
"jumlah_lulusan": n_lulus,
"jumlah_terlacak": n_terlacak,
"persen_terlacak": round((n_terlacak / n_lulus * 100), 1) if n_lulus > 0 else 0,
"rata_waktu_tunggu": avg_waktu
})
# Masukkan ke baris tabel 2.B.5
rows_2b5.append({
"ts_code": ts_label,
"tahun_lulus": year,
"tahun_label": display_label,
"jumlah_lulusan": n_lulus,
"jumlah_terlacak": n_terlacak,
"profesi_infokom": n_infokom,
"profesi_non_infokom": n_non_infokom,
"persen_infokom": round((n_infokom / n_terlacak * 100), 1) if n_terlacak > 0 else 0,
"lingkup_multinasional": n_multi,
"lingkup_nasional": n_nas,
"lingkup_wirausaha": n_wira
})
sum_lulusan += n_lulus
sum_terlacak += n_terlacak
if avg_waktu > 0 and count_waktu:
weighted_waktu_sum += (avg_waktu * count_waktu)
weighted_waktu_count += count_waktu
sum_infokom += n_infokom
sum_non_infokom += n_non_infokom
sum_multinasional += n_multi
sum_nasional += n_nas
sum_wirausaha += n_wira
overall_avg_waktu = round(weighted_waktu_sum / weighted_waktu_count, 2) if weighted_waktu_count > 0 else 0.0
# Summary Totals
total_2b4 = {
"ts_code": "Jumlah",
"tahun_label": "Jumlah / Rata-rata",
"jumlah_lulusan": sum_lulusan,
"jumlah_terlacak": sum_terlacak,
"persen_terlacak": round((sum_terlacak / sum_lulusan * 100), 1) if sum_lulusan > 0 else 0,
"rata_waktu_tunggu": overall_avg_waktu
}
total_2b5 = {
"ts_code": "Jumlah",
"tahun_label": "Jumlah",
"jumlah_lulusan": sum_lulusan,
"jumlah_terlacak": sum_terlacak,
"profesi_infokom": sum_infokom,
"profesi_non_infokom": sum_non_infokom,
"persen_infokom": round((sum_infokom / sum_terlacak * 100), 1) if sum_terlacak > 0 else 0,
"lingkup_multinasional": sum_multinasional,
"lingkup_nasional": sum_nasional,
"lingkup_wirausaha": sum_wirausaha
}
available_prodis = [
{"kode": "all", "nama": "Semua Program Studi (Jurusan TI)"},
{"kode": "55301", "nama": "D4 Teknik Informatika (TIF)"},
{"kode": "57401", "nama": "D3 Manajemen Informatika (MIF)"},
{"kode": "56401", "nama": "D3 Teknik Komputer (TKK)"}
]
return {
"status": "success",
"meta": {
"ts_year": ts_year,
"kode_prodi": kode_prodi or "all",
"prodi_label": prodi_label,
"mode": mode,
"standard": "Instrumen Akreditasi Program Studi (IAPS) LAM INFOKOM Kriteria 9"
},
"available_years": available_years,
"available_prodis": available_prodis,
"tabel_2b4": {
"title": "Tabel 2.B.4 Rata-rata Masa Tunggu Lulusan untuk Bekerja Pertama Kali",
"rows": rows_2b4,
"total": total_2b4
},
"tabel_2b5": {
"title": "Tabel 2.B.5. Kesesuaian Bidang Kerja Lulusan",
"rows": rows_2b5,
"total": total_2b5
}
}

View File

@ -0,0 +1,99 @@
"""
Router untuk Import Data Alumni dari CSV/Excel
Mendukung semua kolom tracer study 2019-2025
File ini adalah router utama yang mendelegasikan ke import_service.py
"""
from fastapi import APIRouter, UploadFile, File, HTTPException, Depends, Form
from sqlalchemy.orm import Session
from sqlalchemy import func
from app.config.database import get_db
from app.services.import_service import import_data
from app.models.alumni import Alumni
from app.models.models import TracerResponse, Kompetensi, Pekerjaan
router = APIRouter(prefix="", tags=["Import Data"])
@router.post("/import-full")
async def import_full(
tahun: str = Form(...),
file: UploadFile = File(...),
db: Session = Depends(get_db)
):
"""
Import CSV dengan SEMUA kolom tracer study.
Data akan disimpan ke tabel: alumni, pekerjaan, kompetensi, tracer_responses
"""
try:
content = await file.read()
result = import_data(tahun, content, file.filename, db)
if result["status"] == "error":
raise HTTPException(status_code=400, detail=result["message"])
return result
except HTTPException:
raise
except Exception as e:
db.rollback()
import traceback
print(f"Import error: {traceback.format_exc()}")
raise HTTPException(status_code=400, detail=f"Error: {str(e)}")
@router.get("/stats")
async def get_import_stats(db: Session = Depends(get_db)):
"""Ambil statistik data alumni di database"""
total_alumni = db.query(Alumni).count()
total_pekerjaan = db.query(Pekerjaan).count()
total_kompetensi = db.query(Kompetensi).count()
total_tracer = db.query(TracerResponse).count()
prodi_stats = db.query(
Alumni.kode_prodi,
func.count(Alumni.id).label('count')
).group_by(Alumni.kode_prodi).all()
tahun_stats = db.query(
Alumni.tahun_lulus,
func.count(Alumni.id).label('count')
).group_by(Alumni.tahun_lulus).order_by(Alumni.tahun_lulus.desc()).all()
return {
"total_alumni": total_alumni,
"total_pekerjaan": total_pekerjaan,
"total_kompetensi": total_kompetensi,
"total_tracer_responses": total_tracer,
"by_prodi": [{"prodi": p, "count": c} for p, c in prodi_stats],
"by_tahun": [{"tahun": t, "count": c} for t, c in tahun_stats]
}
@router.get("/template")
async def download_template():
"""Download template CSV untuk import data"""
import csv
from fastapi.responses import StreamingResponse
import io
template_data = [
["nimhsmsmh", "nmmhsmsmh", "kdpstmsmh", "tahun_lulus", "F8", "F5b", "F5c", "F1101", "F5a1", "F5a2", "F1761", "F1763", "F1765", "F1767", "F1769", "F1771", "F1773"],
["A001", "Nama Alumni 1", "57401", "2024", "1", "PT ABC", "Software Engineer", "3", "Jawa Timur", "Jember", "4", "4", "3", "4", "4", "4", "3"],
["A002", "Nama Alumni 2", "56401", "2024", "2", "", "", "", "", "", "3", "3", "3", "3", "3", "3", "3"]
]
output = io.StringIO()
writer = csv.writer(output, delimiter=';')
for row in template_data:
writer.writerow(row)
output.seek(0)
return StreamingResponse(
output,
media_type='text/csv',
headers={'Content-Disposition': 'attachment; filename=template_import_alumni.csv'}
)

View File

@ -0,0 +1,202 @@
"""
Router untuk Keyword Dictionary - PRD Section 7 & 24
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from app.config.database import get_db
from app.schemas.models import (
KeywordDictionaryCreate,
KeywordDictionaryUpdate,
KeywordDictionaryResponse
)
from app.models.models import KeywordDictionary
router = APIRouter(tags=["Keyword Dictionary"])
@router.get("/", response_model=List[KeywordDictionaryResponse])
def get_all_keywords(
search: Optional[str] = None,
kode_prodi: Optional[str] = None,
aktif: Optional[bool] = None,
skip: int = 0,
limit: int = 500,
db: Session = Depends(get_db)
):
"""Ambil semua keyword dengan filter prodi, status aktif, dan pencarian kata kunci"""
query = db.query(KeywordDictionary)
if search:
query = query.filter(KeywordDictionary.keyword.ilike(f"%{search.strip()}%"))
if kode_prodi:
query = query.filter(KeywordDictionary.kode_prodi == kode_prodi.strip().upper())
if aktif is not None:
query = query.filter(KeywordDictionary.aktif == aktif)
return query.order_by(KeywordDictionary.kode_prodi.asc(), KeywordDictionary.keyword.asc()).offset(skip).limit(limit).all()
@router.get("/by-prodi/{kode_prodi}", response_model=List[KeywordDictionaryResponse])
def get_keywords_by_prodi(
kode_prodi: str,
db: Session = Depends(get_db)
):
"""Ambil keyword berdasarkan kode prodi"""
keywords = db.query(KeywordDictionary).filter(
KeywordDictionary.kode_prodi == kode_prodi,
KeywordDictionary.aktif == True
).all()
return keywords
@router.post("/", response_model=KeywordDictionaryResponse)
def create_keyword(
keyword_in: KeywordDictionaryCreate,
db: Session = Depends(get_db)
):
"""Tambah keyword baru"""
# Cek apakah keyword sudah ada
existing = db.query(KeywordDictionary).filter(
KeywordDictionary.kode_prodi == keyword_in.kode_prodi,
KeywordDictionary.keyword == keyword_in.keyword
).first()
if existing:
raise HTTPException(status_code=400, detail="Keyword sudah ada")
keyword = KeywordDictionary(**keyword_in.model_dump())
db.add(keyword)
db.commit()
db.refresh(keyword)
return keyword
@router.post("/bulk")
def create_bulk_keywords(
keywords: List[KeywordDictionaryCreate],
db: Session = Depends(get_db)
):
"""Tambah multiple keywords sekaligus"""
added = 0
for kw in keywords:
existing = db.query(KeywordDictionary).filter(
KeywordDictionary.kode_prodi == kw.kode_prodi,
KeywordDictionary.keyword == kw.keyword
).first()
if not existing:
keyword = KeywordDictionary(**kw.model_dump())
db.add(keyword)
added += 1
db.commit()
return {"status": "success", "keywords_added": added}
@router.put("/{keyword_id}", response_model=KeywordDictionaryResponse)
def update_keyword(
keyword_id: int,
keyword_in: KeywordDictionaryUpdate,
db: Session = Depends(get_db)
):
"""Update keyword"""
keyword = db.query(KeywordDictionary).filter(
KeywordDictionary.id == keyword_id
).first()
if not keyword:
raise HTTPException(status_code=404, detail="Keyword tidak ditemukan")
for key, value in keyword_in.model_dump(exclude_unset=True).items():
setattr(keyword, key, value)
db.commit()
db.refresh(keyword)
return keyword
@router.delete("/{keyword_id}")
def delete_keyword(
keyword_id: int,
hard: bool = True,
db: Session = Depends(get_db)
):
"""Hapus keyword (default: hapus permanen jika hard=True, nonaktifkan jika hard=False)"""
keyword = db.query(KeywordDictionary).filter(
KeywordDictionary.id == keyword_id
).first()
if not keyword:
raise HTTPException(status_code=404, detail="Keyword tidak ditemukan")
if hard:
db.delete(keyword)
db.commit()
return {"message": "Keyword berhasil dihapus permanen"}
else:
keyword.aktif = False
db.commit()
return {"message": "Keyword berhasil dinonaktifkan"}
# ============== SEED DEFAULT KEYWORDS ==============
@router.post("/seed-defaults")
def seed_default_keywords(db: Session = Depends(get_db)):
"""Isi default keywords sesuai PRD Section 7"""
default_keywords = [
# TKK - Teknik Komputer
{"kode_prodi": "TKK", "keyword": "jaringan", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "network administrator", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "network engineer", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "LAN/WAN", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "cloud computing", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "IoT", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "embedded system", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "firmware", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "hardware", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "sysadmin", "kategori_keyword": "technical"},
{"kode_prodi": "TKK", "keyword": "IT support", "kategori_keyword": "technical"},
# MIF - Manajemen Informatika
{"kode_prodi": "MIF", "keyword": "programmer", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "software developer", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "database", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "SQL", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "data analyst", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "data warehouse", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "business intelligence", "kategori_keyword": "technical"},
{"kode_prodi": "MIF", "keyword": "ERD", "kategori_keyword": "technical"},
# TIF - Teknik Informatika
{"kode_prodi": "TIF", "keyword": "software engineer", "kategori_keyword": "technical"},
{"kode_prodi": "TIF", "keyword": "quality assurance", "kategori_keyword": "technical"},
{"kode_prodi": "TIF", "keyword": "QA/tester", "kategori_keyword": "technical"},
{"kode_prodi": "TIF", "keyword": "IT entrepreneur", "kategori_keyword": "technical"},
{"kode_prodi": "TIF", "keyword": "startup teknologi", "kategori_keyword": "technical"},
{"kode_prodi": "TIF", "keyword": "manajemen proyek IT", "kategori_keyword": "technical"},
{"kode_prodi": "TIF", "keyword": "konsultan perangkat lunak", "kategori_keyword": "technical"},
]
added = 0
for kw in default_keywords:
existing = db.query(KeywordDictionary).filter(
KeywordDictionary.kode_prodi == kw["kode_prodi"],
KeywordDictionary.keyword == kw["keyword"]
).first()
if not existing:
keyword = KeywordDictionary(**kw)
db.add(keyword)
added += 1
db.commit()
return {
"status": "success",
"message": f"Default keywords ditambahkan: {added}"
}

View File

@ -0,0 +1,51 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from typing import List
from app.config.database import get_db
from app.controllers.prodi import ProdiController
from app.schemas.prodi import (
ProdiCreate,
ProdiUpdate,
ProdiResponse,
)
router = APIRouter(
tags=["Prodi"]
)
@router.get("/", response_model=List[ProdiResponse])
def get_all_prodi(db: Session = Depends(get_db)):
return ProdiController.get_all(db)
@router.get("/{prodi_id}", response_model=ProdiResponse)
def get_prodi(prodi_id: int, db: Session = Depends(get_db)):
return ProdiController.get_by_id(db, prodi_id)
@router.post("/", response_model=ProdiResponse, status_code=201)
def create_prodi(
prodi: ProdiCreate,
db: Session = Depends(get_db)
):
return ProdiController.create(db, prodi)
@router.put("/{prodi_id}", response_model=ProdiResponse)
def update_prodi(
prodi_id: int,
prodi: ProdiUpdate,
db: Session = Depends(get_db)
):
return ProdiController.update(db, prodi_id, prodi)
@router.delete("/{prodi_id}")
def delete_prodi(
prodi_id: int,
db: Session = Depends(get_db)
):
ProdiController.delete(db, prodi_id)
return {"message": "Data prodi berhasil dihapus"}

View File

@ -0,0 +1,497 @@
"""
Router untuk Pertanyaan dan Pilihan Jawaban Tracer Study (CRUD Management)
PRD Reference: Pertanyaan-dan-jawaban.md
"""
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from sqlalchemy import or_, func
from pydantic import BaseModel, ConfigDict
from typing import List, Optional
from app.config.database import get_db
from app.models.models import Question, AnswerOption
from app.middleware.auth_middleware import get_current_active_user
router = APIRouter(prefix="/questions", tags=["Questions & Answer Options"])
# ========== SCHEMAS ==========
class AnswerOptionBase(BaseModel):
kode: str
teks: str
urutan: Optional[int] = 0
is_active: Optional[bool] = True
class AnswerOptionCreate(AnswerOptionBase):
pass
class AnswerOptionUpdate(BaseModel):
kode: Optional[str] = None
teks: Optional[str] = None
urutan: Optional[int] = None
is_active: Optional[bool] = None
class AnswerOptionResponse(AnswerOptionBase):
id: int
question_id: int
model_config = ConfigDict(from_attributes=True)
class QuestionBase(BaseModel):
kode: str
pertanyaan: str
tipe: str = "pilihan" # dropdown, pilihan, skala, teks, date, ya_tidak
section: str = "kuesioner_utama"
nomor_form: Optional[int] = 0
tahun: Optional[str] = "all"
is_active: Optional[bool] = True
class QuestionCreate(QuestionBase):
options: Optional[List[AnswerOptionBase]] = []
class QuestionUpdate(BaseModel):
kode: Optional[str] = None
pertanyaan: Optional[str] = None
tipe: Optional[str] = None
section: Optional[str] = None
nomor_form: Optional[int] = None
tahun: Optional[str] = None
is_active: Optional[bool] = None
class QuestionSchema(BaseModel):
id: int
kode: str
pertanyaan: str
tipe: str
section: str
nomor_form: int
tahun: Optional[str] = "all"
is_active: bool = True
options: List[AnswerOptionResponse] = []
model_config = ConfigDict(from_attributes=True)
class QuestionListResponse(BaseModel):
items: List[QuestionSchema]
total: int
sections: List[str]
class FormSchema(BaseModel):
questions: List[QuestionSchema]
sections: List[str]
# ========== ENDPOINTS ==========
@router.get("/", response_model=QuestionListResponse, summary="Ambil daftar semua pertanyaan dengan filter & search")
def get_all_questions(
search: Optional[str] = Query(None, description="Cari teks pertanyaan atau kode pertanyaan"),
section: Optional[str] = Query(None, description="Filter berdasarkan section"),
is_active: Optional[bool] = Query(None, description="Filter status aktif"),
skip: int = Query(0, ge=0),
limit: int = Query(200, ge=1, le=500),
db: Session = Depends(get_db)
):
"""
Mengambil daftar semua pertanyaan tracer study beserta pilihan jawabannya.
Mendukung pencarian teks/kode dan filter section.
"""
query = db.query(Question)
if search and search.strip():
term = f"%{search.strip()}%"
query = query.filter(or_(Question.kode.ilike(term), Question.pertanyaan.ilike(term)))
if section and section.strip() and section != "all":
query = query.filter(Question.section == section.strip())
if is_active is not None:
query = query.filter(Question.is_active == is_active)
total = query.count()
questions = query.order_by(Question.nomor_form.asc(), Question.id.asc()).offset(skip).limit(limit).all()
# Ambil list unique sections yang ada di DB
all_sections_raw = db.query(Question.section).distinct().all()
sections = [s[0] for s in all_sections_raw if s[0]]
# Batch load all answer options in ONE query instead of N individual queries
q_ids = [q.id for q in questions]
options_by_q = {q.id: [] for q in questions}
if q_ids:
all_opts = db.query(AnswerOption).filter(
AnswerOption.question_id.in_(q_ids)
).order_by(AnswerOption.urutan.asc(), AnswerOption.id.asc()).all()
for opt in all_opts:
options_by_q.setdefault(opt.question_id, []).append(opt)
items = []
for q in questions:
opts = options_by_q.get(q.id, [])
q_dict = {
"id": q.id,
"kode": q.kode,
"pertanyaan": q.pertanyaan,
"tipe": q.tipe or "pilihan",
"section": q.section or "kuesioner_utama",
"nomor_form": q.nomor_form or 0,
"tahun": q.tahun or "all",
"is_active": q.is_active if q.is_active is not None else True,
"options": [AnswerOptionResponse.model_validate(o) for o in opts]
}
items.append(QuestionSchema(**q_dict))
return QuestionListResponse(items=items, total=total, sections=sections)
@router.get("/stats", summary="Ringkasan statistik pertanyaan dan opsi jawaban")
def get_question_stats(db: Session = Depends(get_db)):
"""
Ringkasan jumlah pertanyaan aktif, total opsi jawaban, dan rincian per section.
"""
total_q = db.query(Question).count()
active_q = db.query(Question).filter(Question.is_active == True).count()
total_opts = db.query(AnswerOption).count()
section_breakdown = db.query(
Question.section,
func.count(Question.id)
).group_by(Question.section).all()
return {
"total_questions": total_q,
"active_questions": active_q,
"total_options": total_opts,
"sections": {s[0]: s[1] for s in section_breakdown if s[0]}
}
@router.get("/formulir", response_model=FormSchema, summary="Ambil semua pertanyaan untuk form alumni")
def get_formulir(db: Session = Depends(get_db)):
"""
Ambil semua pertanyaan aktif dan pilihan jawaban untuk formulir tracer study.
"""
questions = db.query(Question).filter(Question.is_active == True).order_by(Question.nomor_form).all()
q_ids = [q.id for q in questions]
options_by_q = {q.id: [] for q in questions}
if q_ids:
all_opts = db.query(AnswerOption).filter(
AnswerOption.question_id.in_(q_ids),
AnswerOption.is_active == True
).order_by(AnswerOption.urutan.asc(), AnswerOption.id.asc()).all()
for opt in all_opts:
options_by_q.setdefault(opt.question_id, []).append(opt)
result_questions = []
sections = []
for q in questions:
options = options_by_q.get(q.id, [])
question_data = QuestionSchema(
id=q.id,
kode=q.kode,
pertanyaan=q.pertanyaan,
tipe=q.tipe or "pilihan",
section=q.section or "kuesioner_utama",
nomor_form=q.nomor_form or 0,
tahun=q.tahun or "all",
is_active=True,
options=[AnswerOptionResponse.model_validate(o) for o in options]
)
result_questions.append(question_data)
if q.section and q.section not in sections:
sections.append(q.section)
return FormSchema(questions=result_questions, sections=sections)
@router.get("/sections", summary="Daftar section unik")
def get_sections(db: Session = Depends(get_db)):
sections = db.query(Question.section).distinct().all()
return {"sections": [s[0] for s in sections if s[0]]}
@router.get("/{question_id}", response_model=QuestionSchema, summary="Ambil detail pertanyaan beserta opsi jawaban")
def get_question_detail(question_id: int, db: Session = Depends(get_db)):
q = db.query(Question).filter(Question.id == question_id).first()
if not q:
raise HTTPException(status_code=404, detail="Pertanyaan tidak ditemukan")
options = db.query(AnswerOption).filter(
AnswerOption.question_id == q.id
).order_by(AnswerOption.urutan).all()
return QuestionSchema(
id=q.id,
kode=q.kode,
pertanyaan=q.pertanyaan,
tipe=q.tipe or "pilihan",
section=q.section or "kuesioner_utama",
nomor_form=q.nomor_form or 0,
tahun=q.tahun or "all",
is_active=q.is_active if q.is_active is not None else True,
options=[AnswerOptionResponse.model_validate(o) for o in options]
)
def resequence_questions(db: Session):
"""
Mengurutkan ulang seluruh nomor_form pertanyaan dari 1 sampai N
secara berkesinambungan tanpa ada celah atau nomor kembar.
"""
questions = db.query(Question).order_by(Question.nomor_form.asc(), Question.id.asc()).all()
for idx, q in enumerate(questions, start=1):
q.nomor_form = idx
db.commit()
@router.post("/reorder", summary="Rapikan ulang seluruh nomor urut pertanyaan agar berurutan 1 sampai N")
def reorder_all_questions(db: Session = Depends(get_db)):
"""
Menata ulang nomor urut pertanyaan (nomor_form) dari 1 sampai N secara berkesinambungan
berdasarkan urutan saat ini.
"""
resequence_questions(db)
total = db.query(Question).count()
return {
"status": "success",
"message": f"Berhasil merapikan nomor urut untuk {total} pertanyaan secara berurutan (1-{total}).",
"total": total
}
@router.post("/", response_model=QuestionSchema, status_code=status.HTTP_201_CREATED, summary="Tambah pertanyaan baru")
def create_question(question_in: QuestionCreate, db: Session = Depends(get_db)):
existing = db.query(Question).filter(Question.kode == question_in.kode.strip()).first()
if existing:
raise HTTPException(status_code=400, detail=f"Pertanyaan dengan kode '{question_in.kode}' sudah ada")
# Tentukan nomor urut berikutnya jika tidak diisi atau jika melompat terlalu jauh
max_no = db.query(func.max(Question.nomor_form)).scalar() or 0
assigned_no = question_in.nomor_form if (question_in.nomor_form and question_in.nomor_form > 0) else (max_no + 1)
new_q = Question(
kode=question_in.kode.strip(),
pertanyaan=question_in.pertanyaan.strip(),
tipe=question_in.tipe,
section=question_in.section,
nomor_form=assigned_no,
tahun=question_in.tahun or "all",
is_active=question_in.is_active if question_in.is_active is not None else True,
)
db.add(new_q)
db.flush()
# Tambahkan options jika disertakan
created_options = []
if question_in.options:
for idx, opt in enumerate(question_in.options, start=1):
new_opt = AnswerOption(
question_id=new_q.id,
kode=opt.kode.strip(),
teks=opt.teks.strip(),
urutan=opt.urutan if opt.urutan else idx,
is_active=opt.is_active if opt.is_active is not None else True
)
db.add(new_opt)
created_options.append(new_opt)
db.commit()
# Pastikan seluruh pertanyaan tersusun rapi berurutan 1..N
resequence_questions(db)
db.refresh(new_q)
return QuestionSchema(
id=new_q.id,
kode=new_q.kode,
pertanyaan=new_q.pertanyaan,
tipe=new_q.tipe,
section=new_q.section,
nomor_form=new_q.nomor_form,
tahun=new_q.tahun,
is_active=new_q.is_active,
options=[AnswerOptionResponse.model_validate(o) for o in created_options]
)
@router.put("/{question_id}", response_model=QuestionSchema, summary="Perbarui pertanyaan")
def update_question(question_id: int, question_in: QuestionUpdate, db: Session = Depends(get_db)):
q = db.query(Question).filter(Question.id == question_id).first()
if not q:
raise HTTPException(status_code=404, detail="Pertanyaan tidak ditemukan")
if question_in.kode and question_in.kode.strip() != q.kode:
existing = db.query(Question).filter(Question.kode == question_in.kode.strip()).first()
if existing and existing.id != question_id:
raise HTTPException(status_code=400, detail=f"Kode '{question_in.kode}' sudah digunakan oleh pertanyaan lain")
q.kode = question_in.kode.strip()
if question_in.pertanyaan is not None:
q.pertanyaan = question_in.pertanyaan.strip()
if question_in.tipe is not None:
q.tipe = question_in.tipe
if question_in.section is not None:
q.section = question_in.section
if question_in.nomor_form is not None:
q.nomor_form = question_in.nomor_form
if question_in.tahun is not None:
q.tahun = question_in.tahun
if question_in.is_active is not None:
q.is_active = question_in.is_active
db.commit()
# Jika nomor_form diubah, rapikan kembali urutan pertanyaan
if question_in.nomor_form is not None:
resequence_questions(db)
db.refresh(q)
options = db.query(AnswerOption).filter(
AnswerOption.question_id == q.id
).order_by(AnswerOption.urutan).all()
return QuestionSchema(
id=q.id,
kode=q.kode,
pertanyaan=q.pertanyaan,
tipe=q.tipe,
section=q.section,
nomor_form=q.nomor_form,
tahun=q.tahun,
is_active=q.is_active,
options=[AnswerOptionResponse.model_validate(o) for o in options]
)
@router.delete("/{question_id}", summary="Hapus pertanyaan beserta opsi jawabannya")
def delete_question(question_id: int, hard: bool = True, db: Session = Depends(get_db)):
q = db.query(Question).filter(Question.id == question_id).first()
if not q:
raise HTTPException(status_code=404, detail="Pertanyaan tidak ditemukan")
kode_q = q.kode
if hard:
# Cascade delete answer_options
db.query(AnswerOption).filter(AnswerOption.question_id == question_id).delete()
db.delete(q)
db.commit()
# Otomatis rapikan urutan sisa pertanyaan sehingga tidak ada nomor yang bolong / melompat
resequence_questions(db)
return {"status": "success", "message": f"Pertanyaan '{kode_q}' berhasil dihapus dan nomor urut seluruh pertanyaan telah dirapikan secara berkesinambungan"}
else:
q.is_active = False
db.commit()
return {"status": "success", "message": f"Pertanyaan '{kode_q}' dinonaktifkan"}
# ========== ANSWER OPTIONS SUB-ENDPOINTS ==========
@router.post("/{question_id}/options", response_model=AnswerOptionResponse, status_code=status.HTTP_201_CREATED, summary="Tambah opsi jawaban baru ke pertanyaan")
def add_answer_option(question_id: int, option_in: AnswerOptionCreate, db: Session = Depends(get_db)):
q = db.query(Question).filter(Question.id == question_id).first()
if not q:
raise HTTPException(status_code=404, detail="Pertanyaan tidak ditemukan")
new_opt = AnswerOption(
question_id=question_id,
kode=option_in.kode.strip(),
teks=option_in.teks.strip(),
urutan=option_in.urutan or 0,
is_active=option_in.is_active if option_in.is_active is not None else True
)
db.add(new_opt)
db.commit()
db.refresh(new_opt)
return AnswerOptionResponse.model_validate(new_opt)
@router.put("/options/{option_id}", response_model=AnswerOptionResponse, summary="Perbarui opsi jawaban")
def update_answer_option(option_id: int, option_in: AnswerOptionUpdate, db: Session = Depends(get_db)):
opt = db.query(AnswerOption).filter(AnswerOption.id == option_id).first()
if not opt:
raise HTTPException(status_code=404, detail="Pilihan jawaban tidak ditemukan")
if option_in.kode is not None:
opt.kode = option_in.kode.strip()
if option_in.teks is not None:
opt.teks = option_in.teks.strip()
if option_in.urutan is not None:
opt.urutan = option_in.urutan
if option_in.is_active is not None:
opt.is_active = option_in.is_active
db.commit()
db.refresh(opt)
return AnswerOptionResponse.model_validate(opt)
@router.delete("/options/{option_id}", summary="Hapus opsi jawaban")
def delete_answer_option(option_id: int, db: Session = Depends(get_db)):
opt = db.query(AnswerOption).filter(AnswerOption.id == option_id).first()
if not opt:
raise HTTPException(status_code=404, detail="Pilihan jawaban tidak ditemukan")
db.delete(opt)
db.commit()
return {"status": "success", "message": "Pilihan jawaban berhasil dihapus"}
@router.post("/sync-jti-prodi-options", summary="Inisialisasi opsi program studi JTI pada pertanyaan kdpstmsnmh")
def sync_jti_prodi_options(db: Session = Depends(get_db)):
"""
Menyinkronkan pilihan jawaban pertanyaan nomor 2 (kdpstmsnmh) agar secara khusus memuat
Program Studi Jurusan Teknologi Informasi (TIF, MIF, TKK).
"""
q = db.query(Question).filter(Question.kode == "kdpstmsnmh").first()
if not q:
# Create question kdpstmsnmh if not exists
q = Question(
kode="kdpstmsnmh",
pertanyaan="Program Studi",
tipe="pilihan",
section="identitas",
nomor_form=2,
tahun="all",
is_active=True
)
db.add(q)
db.flush()
# Clear existing options for this question
db.query(AnswerOption).filter(AnswerOption.question_id == q.id).delete()
jti_prodis = [
{"kode": "55301", "teks": "Teknik Informatika (55301)", "urutan": 1},
{"kode": "57401", "teks": "Manajemen Informatika (57401)", "urutan": 2},
{"kode": "56401", "teks": "Teknik Komputer (56401)", "urutan": 3},
{"kode": "55302", "teks": "Teknik Informatika Kampus Kab. Nganjuk (55302)", "urutan": 4},
{"kode": "55304", "teks": "Teknik Informatika Kampus Kab. Sidoarjo (55304)", "urutan": 5},
]
for p in jti_prodis:
opt = AnswerOption(
question_id=q.id,
kode=p["kode"],
teks=p["teks"],
urutan=p["urutan"],
is_active=True
)
db.add(opt)
db.commit()
return {
"status": "success",
"message": f"Berhasil menginisialisasi {len(jti_prodis)} opsi prodi Teknologi Informasi pada pertanyaan 'kdpstmsnmh'",
"options": jti_prodis
}

View File

@ -0,0 +1,176 @@
from pydantic import BaseModel, EmailStr, Field, ConfigDict, field_validator, model_validator
from datetime import datetime
from typing import Optional, Any, List, Dict
class AlumniBase(BaseModel):
nim: str = Field(..., description="Nomor Induk Mahasiswa (NIM)")
nama: str = Field(..., min_length=2, description="Nama lengkap alumni")
tahun_lulus: int = Field(..., ge=1900, le=2100, description="Tahun lulus alumni")
status_kerja: Optional[str] = Field(None, description="Status pekerjaan saat ini")
pekerjaan: Optional[str] = Field(None, description="Nama pekerjaan/posisi jika bekerja")
instansi: Optional[str] = Field(None, description="Nama instansi/perusahaan tempat bekerja")
no_hp: Optional[str] = Field(None, description="Nomor handphone/WhatsApp aktif")
email: Optional[str] = Field(None, description="Email aktif alumni")
kode_prodi: Optional[str] = Field(None, description="Kode program studi")
class AlumniCreate(AlumniBase):
pass
class AlumniUpdate(BaseModel):
nim: Optional[str] = None
nama: Optional[str] = None
tahun_lulus: Optional[int] = None
status_kerja: Optional[str] = None
pekerjaan: Optional[str] = None
instansi: Optional[str] = None
no_hp: Optional[str] = None
email: Optional[str] = None
kode_prodi: Optional[str] = None
class AlumniResponse(AlumniBase):
id: int
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
@model_validator(mode='before')
@classmethod
def exclude_relationships(cls, data: Any) -> Any:
"""Convert SQLAlchemy objects to dict, excluding relationship attributes"""
if hasattr(data, '__dict__'):
result = {}
for key, value in data.__dict__.items():
if key.startswith('_') or key in ['pekerjaan_detail', 'kompetensi', 'tracer_response', 'clustering_results']:
continue
if hasattr(value, '__tablename__'):
result[key] = None
else:
result[key] = value
return result
return data
class PekerjaanDetail(BaseModel):
id: Optional[int] = None
status_pekerjaan: Optional[str] = None
jenis_perusahaan: Optional[str] = None
nama_perusahaan: Optional[str] = None
jabatan: Optional[str] = None
tingkatan_tempat_kerja: Optional[str] = None
provinsi: Optional[str] = None
kabupaten_kota: Optional[str] = None
teks_pekerjaan: Optional[str] = None
model_config = ConfigDict(from_attributes=True)
class KompetensiDetail(BaseModel):
id: Optional[int] = None
etika_lulus: Optional[str] = None
keahlian_lulus: Optional[str] = None
bahasa_inggris_lulus: Optional[str] = None
teknologi_informasi_lulus: Optional[str] = None
komunikasi_lulus: Optional[str] = None
kerja_sama_lulus: Optional[str] = None
pengembangan_diri_lulus: Optional[str] = None
model_config = ConfigDict(from_attributes=True)
class ClusteringResultDetail(BaseModel):
id: Optional[int] = None
model_version: Optional[str] = None
k: Optional[int] = None
cluster: Optional[int] = None
kategori: Optional[str] = None
profile_match: Optional[bool] = None
matched_keyword: Optional[str] = None
created_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class AlumniDetailResponse(AlumniBase):
id: int
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
pekerjaan_detail: Optional[PekerjaanDetail] = None
kompetensi: Optional[KompetensiDetail] = None
tracer_response: Optional[Dict[str, Any]] = None
clustering_results: Optional[List[ClusteringResultDetail]] = None
model_config = ConfigDict(from_attributes=True)
@model_validator(mode='before')
@classmethod
def process_relations(cls, data: Any) -> Any:
if hasattr(data, '__dict__'):
result = {}
for key, value in data.__dict__.items():
if key.startswith('_'):
continue
if key == 'tracer_response' and value is not None and hasattr(value, '__dict__'):
# Convert tracer_response sqlalchemy object to dict
tr_dict = {k: v for k, v in value.__dict__.items() if not k.startswith('_') and not hasattr(v, '__tablename__')}
result[key] = tr_dict
else:
result[key] = value
return result
return data
class AlumniPaginationResponse(BaseModel):
total: int
page: int
limit: int
total_pages: int
data: List[AlumniResponse]
class PublicTracerLookupRequest(BaseModel):
nim: str = Field(..., description="Nomor Induk Mahasiswa (NIM)")
email: Optional[str] = Field(None, description="Email / Gmail untuk verifikasi kepemilikan")
class PublicTracerSubmitRequest(BaseModel):
nim: str = Field(..., description="Nomor Induk Mahasiswa (NIM)")
nama: str = Field(..., min_length=2, description="Nama lengkap alumni")
kode_prodi: str = Field(..., description="Kode prodi (55301, 57401, 56401, dll)")
tahun_lulus: int = Field(..., ge=1990, le=2100, description="Tahun kelulusan")
email: str = Field(..., description="Email / Gmail aktif alumni")
no_hp: Optional[str] = Field(None, description="Nomor WhatsApp / HP aktif")
status_kerja: str = Field(..., description="Status kerja: bekerja, belum_bekerja, wiraswasta, melanjutkan, mencari_kerja")
# Detail Pekerjaan (jika bekerja / wiraswasta)
nama_perusahaan: Optional[str] = None
jabatan: Optional[str] = None
jenis_perusahaan: Optional[str] = None
tingkatan_tempat_kerja: Optional[str] = None
hubungan_studi: Optional[str] = None
# Identitas Extended (Pertanyaan-dan-jawaban.md)
kode_pt: Optional[str] = "005019"
nik: Optional[str] = None
npwp: Optional[str] = None
# Karir & Gaji Extended
bulan_dapat_kerja: Optional[int] = None
rata_pendapatan: Optional[str] = None
provinsi_kerja: Optional[str] = None
kab_kota_kerja: Optional[str] = None
posisi_wiraswasta: Optional[str] = None
# Studi Lanjut
sumber_biaya_studi: Optional[str] = None
pt_studi_lanjut: Optional[str] = None
prodi_studi_lanjut: Optional[str] = None
tanggal_masuk_studi: Optional[str] = None
# Pembiayaan & Kesesuaian
sumber_biaya_kuliah: Optional[str] = None
tingkat_pendidikan_tepat: Optional[str] = None
# Data Ekstra / Detail Kuesioner (Kompetensi, Metode Pembelajaran, Cara Cari Kerja, dll)
data_extra: Optional[dict] = None

View File

@ -0,0 +1,59 @@
"""
Pydantic Schemas untuk Clustering
"""
from pydantic import BaseModel, Field
from typing import List, Optional
from datetime import datetime
class ClusteringRequest(BaseModel):
"""Request untuk clustering"""
n_clusters: int = Field(default=3, ge=2, le=10, description="Jumlah cluster")
auto_k: bool = Field(default=False, description="Auto-detect jumlah cluster optimal")
tahun: Optional[List[str]] = Field(default=None, description="Filter tahun (opsional)")
class AlumniInput(BaseModel):
"""Data alumni untuk clustering"""
nama: str
nim: Optional[str] = None
perusahaan: str
jabatan: str
class ClusterResult(BaseModel):
"""Hasil clustering untuk satu alumni"""
nama: str
nim: Optional[str] = None
perusahaan: str
jabatan: str
cluster: int
cluster_label: str
class ClusteringResponse(BaseModel):
"""Response dari clustering"""
status: str
message: Optional[str] = None
total_records: int
n_clusters: int
distribution: dict
summary: Optional[dict] = None
top_features: Optional[dict] = None
data: List[ClusterResult]
class StandardizeRequest(BaseModel):
"""Request untuk standarisasi data"""
files: List[str] = Field(description="List filename yang diupload")
tahun: List[str] = Field(description="List tahun untuk setiap file")
class StandardizeResponse(BaseModel):
"""Response dari standarisasi"""
status: str
message: Optional[str] = None
total_records: int
years_processed: List[str]
data: Optional[List[AlumniInput]] = None

View File

@ -0,0 +1,167 @@
"""
Schemas untuk Tabel Baru - PRD Section 24
"""
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
# ============== PEKERJAAN ==============
class PekerjaanBase(BaseModel):
alumni_id: int
status_pekerjaan: Optional[str] = None
jenis_perusahaan: Optional[str] = None
nama_perusahaan: Optional[str] = None
jabatan: Optional[str] = None
tingkatan_tempat_kerja: Optional[str] = None
provinsi: Optional[str] = None
kabupaten_kota: Optional[str] = None
teks_pekerjaan: Optional[str] = None
class PekerjaanCreate(PekerjaanBase):
pass
class PekerjaanUpdate(BaseModel):
status_pekerjaan: Optional[str] = None
jenis_perusahaan: Optional[str] = None
nama_perusahaan: Optional[str] = None
jabatan: Optional[str] = None
tingkatan_tempat_kerja: Optional[str] = None
provinsi: Optional[str] = None
kabupaten_kota: Optional[str] = None
teks_pekerjaan: Optional[str] = None
class PekerjaanResponse(PekerjaanBase):
id: int
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ============== KOMPETENSI ==============
class KompetensiBase(BaseModel):
alumni_id: int
etika_lulus: Optional[int] = None
keahlian_lulus: Optional[int] = None
bahasa_inggris_lulus: Optional[int] = None
teknologi_informasi_lulus: Optional[int] = None
komunikasi_lulus: Optional[int] = None
kerja_sama_lulus: Optional[int] = None
pengembangan_diri_lulus: Optional[int] = None
class KompetensiCreate(KompetensiBase):
pass
class KompetensiUpdate(BaseModel):
etika_lulus: Optional[int] = None
keahlian_lulus: Optional[int] = None
bahasa_inggris_lulus: Optional[int] = None
teknologi_informasi_lulus: Optional[int] = None
komunikasi_lulus: Optional[int] = None
kerja_sama_lulus: Optional[int] = None
pengembangan_diri_lulus: Optional[int] = None
class KompetensiResponse(KompetensiBase):
id: int
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ============== CLUSTERING RESULT ==============
class ClusteringResultBase(BaseModel):
alumni_id: int
model_version: Optional[str] = None
k: int
cluster: int
kategori: str # C0, C1, C2, C3
profile_match: bool = False
matched_keyword: Optional[str] = None
class ClusteringResultCreate(ClusteringResultBase):
pass
class ClusteringResultResponse(ClusteringResultBase):
id: int
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ============== MODEL EVALUATION ==============
class ModelEvaluationBase(BaseModel):
model_version: str
k: int
inertia: float
silhouette_score: float
class ModelEvaluationCreate(ModelEvaluationBase):
pass
class ModelEvaluationResponse(ModelEvaluationBase):
id: int
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ============== KEYWORD DICTIONARY ==============
class KeywordDictionaryBase(BaseModel):
kode_prodi: str # TIF, MIF, TKK
keyword: str
kategori_keyword: Optional[str] = None
aktif: bool = True
class KeywordDictionaryCreate(KeywordDictionaryBase):
pass
class KeywordDictionaryUpdate(BaseModel):
keyword: Optional[str] = None
kategori_keyword: Optional[str] = None
aktif: Optional[bool] = None
class KeywordDictionaryResponse(KeywordDictionaryBase):
id: int
created_at: Optional[datetime] = None
class Config:
from_attributes = True
# ============== BULK IMPORT ==============
class BulkAlumniCreate(BaseModel):
"""Untuk import bulk alumni dari file Excel"""
alumni_list: List[dict]
class BulkClusteringResult(BaseModel):
"""Untuk save hasil clustering"""
model_version: str
k: int
inertia: float
silhouette_score: float
results: List[dict] # List of {alumni_id, cluster, kategori, profile_match, matched_keyword}

View File

@ -0,0 +1,30 @@
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
class ProdiBase(BaseModel):
kode_prodi: str
nama_prodi: str
jenjang: str
jurusan: str
class ProdiCreate(ProdiBase):
pass
class ProdiUpdate(BaseModel):
kode_prodi: Optional[str] = None
nama_prodi: Optional[str] = None
jenjang: Optional[str] = None
jurusan: Optional[str] = None
class ProdiResponse(ProdiBase):
id: int
created_at: datetime
updated_at: Optional[datetime] = None
model_config = {
"from_attributes": True
}

View File

@ -0,0 +1,45 @@
from pydantic import BaseModel, EmailStr, Field, ConfigDict
from datetime import datetime
from typing import Optional
class UserBase(BaseModel):
username: str = Field(..., min_length=3, max_length=50, description="Username untuk login")
nama: Optional[str] = Field(None, max_length=150, description="Nama lengkap pemilik akun")
email: EmailStr = Field(..., description="Alamat email valid")
role: Optional[str] = Field("admin", description="Role akun: admin atau kaprodi")
kode_prodi: Optional[str] = Field(None, description="Kode prodi jika role kaprodi")
class UserCreate(UserBase):
password: str = Field(..., min_length=6, description="Password minimal 6 karakter")
class UserUpdate(BaseModel):
nama: Optional[str] = None
email: Optional[EmailStr] = None
role: Optional[str] = None
kode_prodi: Optional[str] = None
password: Optional[str] = None
is_active: Optional[bool] = None
class UserLogin(BaseModel):
username: str = Field(..., description="Username untuk login")
password: str = Field(..., description="Password user")
class UserResponse(UserBase):
id: int
is_active: bool
created_at: Optional[datetime] = None
updated_at: Optional[datetime] = None
model_config = ConfigDict(from_attributes=True)
class Token(BaseModel):
access_token: str
token_type: str
username: Optional[str] = None
nama: Optional[str] = None
role: Optional[str] = None
kode_prodi: Optional[str] = None
class TokenData(BaseModel):
username: Optional[str] = None

View File

@ -0,0 +1,8 @@
{
"folders": [
{
"path": "../../.."
}
],
"settings": {}
}

View File

@ -0,0 +1,2 @@
# Services package - business logic untuk import
from .import_service import import_data

View File

@ -0,0 +1,83 @@
from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from app.repositories.alumni import alumni_repository
from app.schemas.alumni import AlumniCreate, AlumniUpdate
from app.models.alumni import Alumni
from typing import List, Optional, Tuple
class AlumniService:
"""
Service containing business logic for Alumni tracking features.
"""
@staticmethod
def get_by_id(db: Session, alumni_id: int) -> Alumni:
"""Fetch alumni by ID or raise HTTP 404 if not found."""
alumni = alumni_repository.get(db, alumni_id)
if not alumni:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Data alumni dengan ID {alumni_id} tidak ditemukan"
)
return alumni
@staticmethod
def get_by_id_detailed(db: Session, alumni_id: int) -> Alumni:
"""Fetch alumni by ID with all relations (pekerjaan, kompetensi, tracer_responses, clustering)."""
alumni = alumni_repository.get_with_relations(db, alumni_id)
if not alumni:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Data alumni dengan ID {alumni_id} tidak ditemukan"
)
return alumni
@staticmethod
def get_all(db: Session, skip: int = 0, limit: int = 100) -> List[Alumni]:
"""Fetch all alumni with pagination limits."""
return alumni_repository.get_all(db, skip=skip, limit=limit)
@staticmethod
def get_filtered(
db: Session,
skip: int = 0,
limit: int = 10,
search: Optional[str] = None,
kode_prodi: Optional[str] = None,
tahun_lulus: Optional[int] = None,
status_kerja: Optional[str] = None,
) -> Tuple[List[Alumni], int]:
"""Fetch alumni with multi-criteria filtering and count."""
return alumni_repository.get_filtered(
db=db,
skip=skip,
limit=limit,
search=search,
kode_prodi=kode_prodi,
tahun_lulus=tahun_lulus,
status_kerja=status_kerja,
)
@staticmethod
def create(db: Session, alumni_in: AlumniCreate) -> Alumni:
"""Create a new alumni record after verifying NIM uniqueness."""
existing_nim = alumni_repository.get_by_nim(db, alumni_in.nim)
if existing_nim:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Alumni dengan NIM {alumni_in.nim} sudah terdaftar"
)
return alumni_repository.create(db, alumni_in)
@staticmethod
def update(db: Session, alumni_id: int, alumni_in: AlumniUpdate) -> Alumni:
"""Update an existing alumni record or raise HTTP 404 if not found."""
alumni = AlumniService.get_by_id(db, alumni_id)
return alumni_repository.update(db, alumni, alumni_in)
@staticmethod
def delete(db: Session, alumni_id: int) -> Alumni:
"""Delete an alumni record by ID or raise HTTP 404 if not found."""
alumni = AlumniService.get_by_id(db, alumni_id)
deleted = alumni_repository.delete(db, alumni_id)
return deleted if deleted is not None else alumni

View File

@ -0,0 +1,123 @@
from sqlalchemy.orm import Session
from fastapi import HTTPException, status
from app.repositories.user import user_repository
from app.schemas.user import UserCreate, UserUpdate, Token
from app.utils.security import get_password_hash, verify_password, create_access_token
from typing import Optional, List
class AuthService:
"""
Service containing authentication-related business logic.
Bridge between the controllers and repositories.
"""
@staticmethod
def register(db: Session, user_in: UserCreate):
# 1. Check if user already exists by username
existing_user = user_repository.get_by_username(db, user_in.username)
if existing_user:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Username sudah terdaftar"
)
# 2. Check if user already exists by email
existing_email = user_repository.get_by_email(db, user_in.email)
if existing_email:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email sudah terdaftar"
)
# 3. Hash the user password
hashed_password = get_password_hash(user_in.password)
# 4. Save user to database
db_user_data = {
"username": user_in.username,
"nama": user_in.nama or user_in.username,
"email": user_in.email,
"role": user_in.role or "admin",
"kode_prodi": user_in.kode_prodi,
"hashed_password": hashed_password,
"is_active": True
}
return user_repository.create(db, db_user_data)
@staticmethod
def login(db: Session, username: str, password: str) -> Token:
# 1. Retrieve user by username
user = user_repository.get_by_username(db, username)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Username atau password salah",
headers={"WWW-Authenticate": "Bearer"},
)
# 2. Verify password hash matches plain text
if not verify_password(password, user.hashed_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Username atau password salah",
headers={"WWW-Authenticate": "Bearer"},
)
# 3. Ensure user is active
if not user.is_active:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Akun dinonaktifkan. Silakan hubungi Administrator."
)
# 4. Generate JWT token
access_token = create_access_token(subject=user.username)
return Token(
access_token=access_token,
token_type="bearer",
username=user.username,
nama=user.nama or user.username,
role=user.role or "admin",
kode_prodi=user.kode_prodi
)
@staticmethod
def get_all_users(db: Session):
return user_repository.get_all(db, skip=0, limit=200)
@staticmethod
def update_user(db: Session, user_id: int, user_in: UserUpdate):
user = user_repository.get(db, user_id)
if not user:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Pengguna tidak ditemukan")
# Check email duplicate
if user_in.email and user_in.email != user.email:
existing_email = user_repository.get_by_email(db, user_in.email)
if existing_email and existing_email.id != user_id:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Email sudah digunakan oleh akun lain")
update_data = {}
if user_in.nama is not None:
update_data["nama"] = user_in.nama
if user_in.email is not None:
update_data["email"] = user_in.email
if user_in.role is not None:
update_data["role"] = user_in.role
if user_in.kode_prodi is not None:
update_data["kode_prodi"] = user_in.kode_prodi
if user_in.is_active is not None:
update_data["is_active"] = user_in.is_active
if user_in.password:
update_data["hashed_password"] = get_password_hash(user_in.password)
return user_repository.update(db, user, update_data)
@staticmethod
def delete_user(db: Session, user_id: int):
user = user_repository.get(db, user_id)
if not user:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Pengguna tidak ditemukan")
if user.username == "admin" or user.id == 1:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Akun Super Admin utama tidak boleh dihapus")
return user_repository.delete(db, user_id)

View File

@ -0,0 +1,511 @@
"""
Service untuk import data tracer study.
Logika utama ada di sini.
"""
import io
import json
import pandas as pd
from typing import Dict, Any, List, Optional
from sqlalchemy.orm import Session
from app.parsers.column_finder import find_column, get_value, check_available_columns
from app.parsers.converters import parse_2024_value, parse_date, konversi_jawaban, convert_value_for_field
from app.parsers.mappings import (
YEAR_CONFIG,
IDENTITAS_MAPPING,
PEKERJAAN_MAPPING,
STUDI_LANJUT_MAPPING,
KESESUAIAN_MAPPING,
KOMPETENSI_LULUS_MAPPING,
KOMPETENSI_SAAT_INI_MAPPING,
METODE_PEMBELAJARAN_MAPPING,
WAKTU_CARI_KERJA_MAPPING,
CARA_CARI_KERJA_MAPPING,
LAMARAN_KEAKTIFAN_MAPPING,
KESESUAIAN_PEKERJAAN_MAPPING,
NUMERIC_FIELDS,
get_field_code,
)
def load_full_mapping():
"""Load full column mapping dari file JSON"""
try:
mapping_path = "C:/Users/syifa/TA-PROJEK/Model/preprocessing/full_column_mapping.json"
with open(mapping_path, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
print(f"Warning: Could not load full_column_mapping.json: {e}")
return {}
def import_data(
tahun: str,
file_content: bytes,
filename: str,
db: Session
) -> Dict[str, Any]:
"""
Import data dari CSV/Excel.
Args:
tahun: Tahun data (2019-2025)
file_content: Bytes content dari file
filename: Nama file untuk tentukan format
db: SQLAlchemy session
Returns:
Dict dengan status dan stats
"""
# Validasi file
filename_lower = filename.lower()
if not filename_lower.endswith(('.csv', '.xlsx', '.xls')):
return {
"status": "error",
"message": "File harus format CSV atau Excel (.csv, .xlsx, .xls)"
}
# Baca file
if filename_lower.endswith('.csv'):
df = pd.read_csv(io.BytesIO(file_content), sep=';', encoding='utf-8-sig')
else:
df = pd.read_excel(io.BytesIO(file_content))
# Bersihkan baris yang seluruhnya kosong (misal trailing empty rows di CSV)
df = df.dropna(how='all')
if df.empty:
return {
"status": "error",
"message": "File kosong"
}
# Get source columns
source_cols = list(df.columns)
# Statistics
stats = {
"tahun": tahun,
"total_rows": len(df),
"imported": 0,
"skipped": 0,
"errors": []
}
# Get year-specific configuration
year_config = YEAR_CONFIG.get(tahun, {})
is_2024_format = bool(year_config.get('is_text_format', False))
if is_2024_format:
print(f"[Import {tahun}] DETECTED: Format 2024 - menggunakan parser khusus")
# Import models
from app.models.alumni import Alumni
from app.models.models import Pekerjaan, Kompetensi, TracerResponse
# Process each row
for idx, row in df.iterrows():
nim: str = ""
try:
# ========================================
# AMBIL DATA IDENTITAS
# ========================================
nim = str(get_value(row, source_cols, IDENTITAS_MAPPING['nim'], ''))
nama = get_value(row, source_cols, IDENTITAS_MAPPING['nama'], '')
# Fallback khusus data historis tanpa NIM
if (not nim or str(nim).strip() == '' or str(nim).strip().lower() == 'nan') and nama and 'KHOSNOL' in str(nama).upper():
nim = 'E41171725'
if not nim or str(nim).strip() == '' or str(nim).strip().lower() == 'nan':
stats["skipped"] += 1
continue
# ========================================
# CREATE/UPDATE ALUMNI
# ========================================
existing_alumni = db.query(Alumni).filter(Alumni.nim == nim).first()
email = get_value(row, source_cols, IDENTITAS_MAPPING['email'], '')
raw_prodi = str(get_value(row, source_cols, IDENTITAS_MAPPING['kode_prodi'], ''))
# Extract clean prodi code (e.g., "Teknik Informatika (55301)" -> "55301", "57401.0" -> "57401")
import re
match_prodi = re.search(r'\((\d+)\)', raw_prodi)
if match_prodi:
kode_prodi = match_prodi.group(1)
else:
cleaned_prodi = raw_prodi.strip()
if cleaned_prodi.endswith('.0'):
cleaned_prodi = cleaned_prodi[:-2]
kode_prodi = cleaned_prodi
# Parse tahun lulus from row or parameter
row_tahun = get_value(row, source_cols, IDENTITAS_MAPPING['tahun_lulus'], None)
if row_tahun is not None and str(row_tahun).strip() not in ['', 'nan', 'None']:
try:
tahun_lulus_val = int(float(str(row_tahun).strip()))
except (ValueError, TypeError):
tahun_lulus_val = int(tahun) if tahun.isdigit() else 2024
else:
tahun_lulus_val = int(tahun) if tahun.isdigit() else 2024
# Get status pekerjaan
status_sp = str(get_value(row, source_cols, PEKERJAAN_MAPPING['status_saat_ini'], ''))
status_kerja = _parse_status_pekerjaan(status_sp)
# Get data pekerjaan untuk alumni
nama_perusahaan = get_value(row, source_cols, PEKERJAAN_MAPPING['nama_perusahaan'], '')
jabatan_raw = get_value(row, source_cols, PEKERJAAN_MAPPING['jabatan'], '')
if is_2024_format and jabatan_raw:
_, jab_teks = parse_2024_value(jabatan_raw)
jabatan = jab_teks or str(jabatan_raw)
elif jabatan_raw:
jab_conv = konversi_jawaban('F5C', jabatan_raw)
jabatan = str(jab_conv) if jab_conv is not None else str(jabatan_raw)
else:
jabatan = ''
if existing_alumni:
existing_alumni.nama = nama
existing_alumni.email = email
existing_alumni.tahun_lulus = tahun_lulus_val
existing_alumni.kode_prodi = kode_prodi
existing_alumni.status_kerja = status_kerja
existing_alumni.pekerjaan = nama_perusahaan
existing_alumni.instansi = jabatan
db.merge(existing_alumni)
else:
alumni = Alumni(
nim=nim,
nama=nama,
email=email,
tahun_lulus=tahun_lulus_val,
kode_prodi=kode_prodi,
status_kerja=status_kerja,
pekerjaan=nama_perusahaan,
instansi=jabatan
)
db.add(alumni)
db.flush()
target_alumni = existing_alumni or db.query(Alumni).filter(Alumni.nim == nim).first()
if not target_alumni:
continue
alumni_id = target_alumni.id
# ========================================
# CREATE/UPDATE PEKERJAAN
# ========================================
_import_pekerjaan(db, row, source_cols, alumni_id, tahun, is_2024_format)
# ========================================
# CREATE/UPDATE KOMPETENSI
# ========================================
_import_kompetensi(db, row, source_cols, alumni_id, tahun, is_2024_format)
# ========================================
# CREATE/UPDATE TRACER RESPONSE
# ========================================
_import_tracer_response(db, row, source_cols, alumni_id, tahun, is_2024_format, nim=str(nim) if nim else None)
db.flush()
stats["imported"] += 1
except Exception as e:
db.rollback()
row_idx = int(idx) + 1 if isinstance(idx, (int, float)) else str(idx)
stats["errors"].append({
"row": row_idx,
"nim": nim if nim else "-",
"error": str(e)
})
stats["skipped"] += 1
db.commit()
return {
"status": "success",
"message": f"Berhasil import {stats['imported']} data dari tahun {tahun}",
"stats": stats
}
def _parse_status_pekerjaan(status_sp: str) -> Optional[str]:
"""
Parse status pekerjaan dari nilai F8 (Instrumen Tracer Study).
Sesuai dokumen Pertanyaan-dan-jawaban.md:
1 - Bekerja (full time/part time)
2 - Belum memungkinkan bekerja
3 - Wiraswasta
4 - Melanjutkan Pendidikan
5 - Tidak kerja tetapi sedang mencari kerja
"""
if status_sp is None:
return None
sp = status_sp.strip().lower()
if sp in ['', 'nan', 'none', '0', '0.0', '-']:
return None
# 1. Cek kode numerik (misal: "1", "1 - ...", "... (1)", "2- ...")
import re
code_match = re.search(r'(?:^|\s|\()([1-5])(?:\s*[-–)]|$)', sp)
if code_match:
code = code_match.group(1)
if code == '1':
return 'bekerja'
elif code == '2':
return 'belum_bekerja'
elif code == '3':
return 'wiraswasta'
elif code == '4':
return 'melanjutkan'
elif code == '5':
return 'mencari_kerja'
# 2. Fallback pencocokan teks (urutan prioritas penting: cek opsi negatif terlebih dahulu)
if 'tidak kerja' in sp or 'mencari kerja' in sp or 'sedang mencari' in sp:
return 'mencari_kerja'
elif 'belum' in sp:
return 'belum_bekerja'
elif 'wiraswasta' in sp:
return 'wiraswasta'
elif 'melanjutkan' in sp or 'pendidikan' in sp or 'studi' in sp:
return 'melanjutkan'
elif 'bekerja' in sp:
return 'bekerja'
return None
def _import_pekerjaan(db: Session, row, source_cols: list, alumni_id: int, tahun: str, is_2024_format: bool):
"""Import data pekerjaan"""
from app.models.models import Pekerjaan
existing = db.query(Pekerjaan).filter(Pekerjaan.alumni_id == alumni_id).first()
values = {}
status_sp = str(get_value(row, source_cols, PEKERJAAN_MAPPING['status_saat_ini'], ''))
values['status_pekerjaan'] = _parse_status_pekerjaan(status_sp)
values['nama_perusahaan'] = get_value(row, source_cols, PEKERJAAN_MAPPING['nama_perusahaan'], '')
jab_raw = get_value(row, source_cols, PEKERJAAN_MAPPING['jabatan'], '')
if is_2024_format and jab_raw:
_, jab_teks = parse_2024_value(jab_raw)
values['jabatan'] = jab_teks or str(jab_raw)
elif jab_raw:
jab_conv = konversi_jawaban('F5C', jab_raw)
values['jabatan'] = str(jab_conv) if jab_conv is not None else str(jab_raw)
else:
values['jabatan'] = ''
jp_raw = get_value(row, source_cols, PEKERJAAN_MAPPING['jenis_perusahaan_full'], '')
if is_2024_format and jp_raw:
_, jp_teks = parse_2024_value(jp_raw)
values['jenis_perusahaan'] = jp_teks or str(jp_raw)
elif jp_raw:
jp_conv = konversi_jawaban('F1101', jp_raw)
values['jenis_perusahaan'] = str(jp_conv) if jp_conv is not None else str(jp_raw)
else:
values['jenis_perusahaan'] = ''
ting_raw = get_value(row, source_cols, PEKERJAAN_MAPPING['tingkatan_tempat_kerja'], '')
if is_2024_format and ting_raw:
_, ting_teks = parse_2024_value(ting_raw)
values['tingkatan_tempat_kerja'] = ting_teks or str(ting_raw)
elif ting_raw:
ting_conv = konversi_jawaban('F5D', ting_raw)
values['tingkatan_tempat_kerja'] = str(ting_conv) if ting_conv is not None else str(ting_raw)
else:
values['tingkatan_tempat_kerja'] = ''
prov_raw = get_value(row, source_cols, PEKERJAAN_MAPPING['provinsi_kerja'], '')
if prov_raw is not None and str(prov_raw).strip() not in ['', 'nan', 'None']:
if is_2024_format:
_, prov_teks = parse_2024_value(prov_raw)
values['provinsi'] = prov_teks or str(prov_raw)
else:
prov_conv = konversi_jawaban('F5A1', prov_raw)
values['provinsi'] = str(prov_conv) if prov_conv is not None else str(prov_raw)
kab_raw = get_value(row, source_cols, PEKERJAAN_MAPPING['kab_kota_kerja'], '')
if kab_raw is not None and str(kab_raw).strip() not in ['', 'nan', 'None']:
if is_2024_format:
_, kab_teks = parse_2024_value(kab_raw)
values['kabupaten_kota'] = kab_teks or str(kab_raw)
else:
kab_conv = konversi_jawaban('F5A2', kab_raw)
values['kabupaten_kota'] = str(kab_conv) if kab_conv is not None else str(kab_raw)
# Gabungkan 4 kolom teks pekerjaan (Status + Jenis + Perusahaan + Jabatan)
sp_val = values.get('status_pekerjaan', '') or ''
jp_val = values.get('jenis_perusahaan', '') or ''
np_val = values.get('nama_perusahaan', '') or ''
jab_val = values.get('jabatan', '') or ''
teks_pekerjaan = f"{sp_val} {jp_val} {np_val} {jab_val}".strip()
values['teks_pekerjaan'] = teks_pekerjaan
if existing:
for key, val in values.items():
if hasattr(existing, key) and val is not None:
setattr(existing, key, val)
db.merge(existing)
else:
pekerjaan = Pekerjaan(alumni_id=alumni_id)
for key, val in values.items():
if hasattr(pekerjaan, key) and val is not None:
setattr(pekerjaan, key, val)
db.add(pekerjaan)
def _import_kompetensi(db: Session, row, source_cols: list, alumni_id: int, tahun: str, is_2024_format: bool):
"""Import data kompetensi"""
from app.models.models import Kompetensi
existing = db.query(Kompetensi).filter(Kompetensi.alumni_id == alumni_id).first()
values = {}
for field, cols in KOMPETENSI_LULUS_MAPPING.items():
db_key = field.replace('_full', '')
val = get_value(row, source_cols, cols)
if val is None or pd.isna(val) or str(val).strip() in ['', 'nan', 'None', '-', '_']:
continue
if is_2024_format:
kode, teks = parse_2024_value(val)
if teks:
values[db_key] = teks
elif kode is not None:
field_code = get_field_code(field, KOMPETENSI_LULUS_MAPPING)
values[db_key] = konversi_jawaban(field_code, kode)
else:
values[db_key] = str(val).strip()
else:
field_code = get_field_code(field, KOMPETENSI_LULUS_MAPPING)
converted = konversi_jawaban(field_code, val)
if converted is not None:
values[db_key] = str(converted)
elif str(val).strip() in ['0', '0.0']:
values[db_key] = None
else:
values[db_key] = str(val).strip()
if existing:
for key, val in values.items():
if val is not None and hasattr(existing, key):
setattr(existing, key, val)
db.merge(existing)
else:
kompetensi = Kompetensi(alumni_id=alumni_id)
for key, val in values.items():
if val is not None and hasattr(kompetensi, key):
setattr(kompetensi, key, val)
db.add(kompetensi)
def _import_tracer_response(db: Session, row, source_cols: list, alumni_id: int, tahun: str, is_2024_format: bool, nim: Optional[str] = None):
"""Import data tracer response"""
from app.models.models import TracerResponse
existing = db.query(TracerResponse).filter(TracerResponse.alumni_id == alumni_id).first()
year_config = YEAR_CONFIG.get(tahun, {})
skip_jumlah = year_config.get('skip_jumlah_perusahaan', False)
# Combine all mappings for tracer response
all_mapping = {}
all_mapping.update(IDENTITAS_MAPPING)
all_mapping.update(PEKERJAAN_MAPPING)
all_mapping.update(STUDI_LANJUT_MAPPING)
all_mapping.update(KESESUAIAN_MAPPING)
all_mapping.update(KOMPETENSI_LULUS_MAPPING)
all_mapping.update(KOMPETENSI_SAAT_INI_MAPPING)
all_mapping.update(METODE_PEMBELAJARAN_MAPPING)
all_mapping.update(WAKTU_CARI_KERJA_MAPPING)
all_mapping.update(CARA_CARI_KERJA_MAPPING)
all_mapping.update(LAMARAN_KEAKTIFAN_MAPPING)
all_mapping.update(KESESUAIAN_PEKERJAAN_MAPPING)
tracer_data = {}
for field, cols in all_mapping.items():
if field in ['nim', 'nama', 'tahun_lulus', 'kode_prodi']:
continue
if skip_jumlah and field == 'jumlah_perusahaan':
continue
val = get_value(row, source_cols, cols)
if val is None or pd.isna(val):
continue
# Skip invalid values
if isinstance(val, str) and val.strip() in ['', 'nan', 'None', '-', '_']:
continue
field_code = get_field_code(field, all_mapping)
fc_upper = field_code.upper() if field_code else ''
if is_2024_format:
kode, teks = parse_2024_value(val)
# Integer columns
if field in ['bulan_dapat_kerja', 'bulan_dapat_kerja_setelah', 'bulan_cari_sebelum_lulus', 'bulan_cari_setelah_wisuda']:
if kode is not None:
tracer_data[field] = kode
elif isinstance(val, (int, float)):
tracer_data[field] = int(val)
continue
# Non-integer columns: prefer clean text response
if teks and len(teks) > 0:
tracer_data[field] = teks
elif kode is not None:
converted = konversi_jawaban(field_code, kode)
tracer_data[field] = str(converted) if converted is not None else str(kode)
else:
tracer_data[field] = str(val).strip()
else:
# Format lama (2019-2023)
converted = konversi_jawaban(field_code, val)
if field in ['bulan_dapat_kerja', 'bulan_dapat_kerja_setelah', 'bulan_cari_sebelum_lulus', 'bulan_cari_setelah_wisuda']:
try:
tracer_data[field] = int(float(str(val).strip()))
except (ValueError, TypeError):
pass
elif converted is not None:
tracer_data[field] = str(converted)
elif str(val).strip() in ['0', '0.0'] and fc_upper in ['F1761', 'F1762', 'F1763', 'F1764', 'F1765', 'F1766', 'F1767', 'F1768', 'F1769', 'F1770', 'F1771', 'F1772', 'F1773', 'F1774', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 'F27']:
# 0 for competency/learning method in old format means not answered / None
tracer_data[field] = None
else:
tracer_data[field] = str(val).strip()
# Handle date field
tanggal_masuk = get_value(row, source_cols, STUDI_LANJUT_MAPPING['tanggal_masuk_studi'])
if tanggal_masuk is not None and not pd.isna(tanggal_masuk):
parsed_date = parse_date(tanggal_masuk)
tracer_data['tanggal_masuk_studi'] = parsed_date
else:
tracer_data['tanggal_masuk_studi'] = None
if existing:
if nim and hasattr(existing, 'nim'):
existing.nim = nim
for key, val in tracer_data.items():
if hasattr(existing, key):
setattr(existing, key, val)
db.merge(existing)
else:
tracer = TracerResponse(alumni_id=alumni_id, nim=nim)
for key, val in tracer_data.items():
if hasattr(tracer, key):
setattr(tracer, key, val)
db.add(tracer)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
from sqlalchemy.orm import Session
from fastapi import HTTPException
from app.repositories.prodi import ProdiRepository
from app.schemas.prodi import ProdiCreate, ProdiUpdate
class ProdiService:
@staticmethod
def get_all(db: Session):
return ProdiRepository.get_all(db)
@staticmethod
def get_by_id(db: Session, prodi_id: int):
prodi = ProdiRepository.get_by_id(db, prodi_id)
if not prodi:
raise HTTPException(
status_code=404,
detail="Data prodi tidak ditemukan"
)
return prodi
@staticmethod
def create(db: Session, prodi: ProdiCreate):
# Cek apakah kode prodi sudah digunakan
data = ProdiRepository.get_all(db)
for item in data:
if item.kode_prodi == prodi.kode_prodi:
raise HTTPException(
status_code=400,
detail="Kode prodi sudah digunakan"
)
return ProdiRepository.create(db, prodi)
@staticmethod
def update(db: Session, prodi_id: int, prodi: ProdiUpdate):
if not ProdiRepository.get_by_id(db, prodi_id):
raise HTTPException(
status_code=404,
detail="Data prodi tidak ditemukan"
)
return ProdiRepository.update(db, prodi_id, prodi)
@staticmethod
def delete(db: Session, prodi_id: int):
if not ProdiRepository.get_by_id(db, prodi_id):
raise HTTPException(
status_code=404,
detail="Data prodi tidak ditemukan"
)
return ProdiRepository.delete(db, prodi_id)

View File

@ -0,0 +1,14 @@
from typing import Any, Dict, Optional
def format_response(success: bool, message: str, data: Optional[Any] = None) -> Dict[str, Any]:
"""
Format standard API JSON responses to match client-side expectations.
Usage Example: return format_response(True, "Data fetched successfully", alumni_list)
"""
response = {
"success": success,
"message": message
}
if data is not None:
response["data"] = data
return response

View File

@ -0,0 +1,27 @@
from datetime import datetime, timedelta, timezone
from typing import Any, Union, Optional
from jose import jwt
import bcrypt
from app.config.config import settings
def verify_password(plain_password: str, hashed_password: str) -> bool:
"""Compare a plain text password with its bcrypt hash to verify identity."""
return bcrypt.checkpw(plain_password.encode('utf-8'), hashed_password.encode('utf-8'))
def get_password_hash(password: str) -> str:
"""Generate a bcrypt hash from a plain text password."""
return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
def create_access_token(subject: Union[str, Any], expires_delta: Optional[timedelta] = None) -> str:
"""
Generate a JSON Web Token (JWT) containing the subject (e.g. username/id).
Accepts an optional expiration delta, defaulting to the config setting.
"""
if expires_delta:
expire = datetime.now(timezone.utc) + expires_delta
else:
expire = datetime.now(timezone.utc) + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, settings.JWT_SECRET_KEY, algorithm=settings.JWT_ALGORITHM)
return encoded_jwt

View File

@ -0,0 +1,193 @@
"""
Standarisasi Kolom Module
Memetakan kolom dari berbagai tahun ke kolom standar
"""
import pandas as pd
import json
from pathlib import Path
from typing import Dict, List, Optional
class ColumnStandardizer:
"""
Kelas untuk menstandarisasi kolom dari berbagai file Excel
dengan struktur kolom yang berbeda-beda
"""
def __init__(self, mapping_file: str = None):
"""
Args:
mapping_file: Path ke file JSON mapping kolom
"""
if mapping_file is None:
# Default path
mapping_file = Path(__file__).parent.parent / "column_mapping.json"
self.mapping_file = Path(mapping_file)
self.mappings = self._load_mappings()
def _load_mappings(self) -> Dict:
"""Load mapping dari file JSON"""
if not self.mapping_file.exists():
raise FileNotFoundError(f"Mapping file tidak ditemukan: {self.mapping_file}")
with open(self.mapping_file, 'r', encoding='utf-8') as f:
return json.load(f)
def get_mapping(self, year: str) -> Dict:
"""
Ambil mapping untuk tahun tertentu
Args:
year: Tahun data (2022, 2023, 2024)
Returns:
Dictionary dengan mapping kolom
"""
if year not in self.mappings:
raise ValueError(f"Mapping untuk tahun {year} tidak ditemukan. "
f"Tahun yang tersedia: {list(self.mappings.keys())}")
return self.mappings[year]
def detect_year(self, df: pd.DataFrame, filename: str = None) -> Optional[str]:
"""
Deteksi tahun dari DataFrame atau filename
Args:
df: DataFrame untuk dicek kolomnya
filename: Nama file (opsional)
Returns:
Tahun yang terdeteksi atau None
"""
# Cek dari filename
if filename:
for year in self.mappings.keys():
if year in filename:
return year
# Cek dari kolom yang tersedia
available_years = []
for year, mapping in self.mappings.items():
match_count = sum(1 for col in mapping.values() if col in df.columns)
if match_count >= 2: # Minimal 2 kolom cocok
available_years.append((year, match_count))
if available_years:
# Pilih tahun dengan match terbanyak
return max(available_years, key=lambda x: x[1])[0]
return None
def standardize(self, df: pd.DataFrame, year: str = None, filename: str = None) -> pd.DataFrame:
"""
Standarisasi kolom DataFrame
Args:
df: DataFrame asli
year: Tahun data (auto-detect jika None)
filename: Nama file (opsional, untuk auto-detect)
Returns:
DataFrame dengan kolom standar
"""
# Deteksi tahun jika tidak specified
if year is None:
year = self.detect_year(df, filename)
if year is None:
raise ValueError("Tidak dapat mendeteksi tahun data. "
f"Pastikan kolom sesuai dengan mapping yang tersedia.")
# Ambil mapping
mapping = self.get_mapping(year)
# Buat DataFrame baru dengan kolom standar
result = pd.DataFrame()
for target_col, source_col in mapping.items():
if source_col in df.columns:
result[target_col] = df[source_col]
else:
result[target_col] = None
return result
def standardize_multiple(self, dfs: List[pd.DataFrame],
years: List[str] = None,
filenames: List[str] = None) -> List[pd.DataFrame]:
"""
Standarisasi multiple DataFrame sekaligus
Args:
dfs: List DataFrame
years: List tahun (auto-detect jika None)
filenames: List nama file (opsional)
Returns:
List DataFrame yang sudah distandarisasi
"""
results = []
for i, df in enumerate(dfs):
year = years[i] if years else None
filename = filenames[i] if filenames else None
standardized = self.standardize(df, year, filename)
results.append(standardized)
return results
def merge_datasets(dfs: List[pd.DataFrame]) -> pd.DataFrame:
"""
Gabungkan multiple DataFrame menjadi satu
Args:
dfs: List DataFrame
Returns:
DataFrame gabungan
"""
return pd.concat(dfs, ignore_index=True)
def clean_data(df: pd.DataFrame) -> pd.DataFrame:
"""
Basic data cleaning
Args:
df: DataFrame
Returns:
DataFrame yang sudah dibersihkan
"""
result = df.copy()
# Hapus baris dengan semua nilai kosong
result = result.dropna(how='all')
# Hapus duplikat
result = result.drop_duplicates()
# Isi nilai kosong dengan string kosong
result = result.fillna('')
return result
if __name__ == "__main__":
# Contoh penggunaan
standardizer = ColumnStandardizer()
# Sample data 2024
sample_2024 = pd.DataFrame({
"4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)": ["Ali", "Budi"],
"9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b": ["Google", "Tokopedia"],
"10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c": ["Engineer", "Analyst"]
})
# Standarisasi
standardized = standardizer.standardize(sample_2024, year="2024")
print("Data Standarisasi:")
print(standardized)

View File

@ -0,0 +1,20 @@
{
"2022": {
"nama": "Nama Lengkap",
"perusahaan": "Nama Perusahaan",
"jabatan": "Jabatan",
"nim": "NIM"
},
"2023": {
"nama": "Nama Alumni",
"perusahaan": "Perusahaan",
"jabatan": "Posisi",
"nim": "NIU"
},
"2024": {
"nama": "4. Nama Lengkap / nmmhsmsmh (Gunakan Huruf Besar)",
"perusahaan": "9. Apa nama perusahaan/kantor tempat Anda bekerja? f5b",
"jabatan": "10. Bila Anda berwiraswasta, apa posisi/jabatan Anda saat ini ? f5c",
"nim": "3. NIM / nimhsmsmh (Gunakan Huruf Besar) "
}
}

View File

@ -0,0 +1,89 @@
CREATE TABLE IF NOT EXISTS tracer_responses (
id INT AUTO_INCREMENT PRIMARY KEY,
alumni_id INT NOT NULL UNIQUE,
kode_pt VARCHAR(20),
nik VARCHAR(20),
npwp VARCHAR(20),
telepon VARCHAR(20),
email VARCHAR(255),
status_saat_ini VARCHAR(50),
bulan_dapat_kerja INT,
dapet_kerja_6_bulan INT,
rata_pendapatan VARCHAR(50),
bulan_dapat_kerja_setelah INT,
provinsi_kerja VARCHAR(100),
kab_kota_kerja VARCHAR(100),
jenis_perusahaan_full VARCHAR(100),
jumlah_perusahaan INT,
nama_perusahaan VARCHAR(255),
jabatan VARCHAR(150),
tingkatan_tempat_kerja VARCHAR(50),
sumber_biaya_studi VARCHAR(50),
pt_studi_lanjut VARCHAR(255),
prodi_studi_lanjut VARCHAR(255),
tanggal_masuk_studi DATETIME,
sumber_biaya_kuliah VARCHAR(50),
keeratan_bidang_studi VARCHAR(50),
tingkat_pendidikan_tepat VARCHAR(50),
etika_lulus_full INT,
etika_saat_ini INT,
keahlian_lulus_full INT,
keahlian_saat_ini INT,
bahasa_inggris_lulus_full INT,
bahasa_inggris_saat_ini INT,
teknologi_informasi_lulus_full INT,
teknologi_informasi_saat_ini INT,
komunikasi_lulus_full INT,
komunikasi_saat_ini INT,
kerja_sama_lulus_full INT,
kerja_sama_saat_ini INT,
pengembangan_diri_lulus_full INT,
pengembangan_diri_saat_ini INT,
metode_perkuliahan INT,
metode_demonstrasi INT,
metode_proyek_riset INT,
metode_magang INT,
metode_praktikum INT,
metode_kerja_lapangan INT,
metode_diskusi INT,
mulai_cari_kerja VARCHAR(50),
bulan_cari_sebelum_lulus INT,
bulan_cari_setelah_wisuda INT,
cari_iklan INT,
cari_melamar_tanpa_lowongan INT,
cari_bursa_pameran INT,
cari_internet INT,
cari_dihubungi_perusahaan INT,
cari_kemenakertrans INT,
cari_agen_tenaga_kerja INT,
cari_pusat_karir INT,
cari_kantor_mahasiswa INT,
cari_jejaring INT,
cari_relasi INT,
cari_bangun_usaha INT,
cari_magang INT,
cari_tempat_kuliah INT,
cari_lainnya INT,
jumlah_perusahaan_dilamar INT,
jumlah_perusahaan_merespons INT,
jumlah_perusahaan_wawancara INT,
aktif_cari_kerja_4_minggu VARCHAR(50),
kerja_tidak_sesuai_1 VARCHAR(50),
kerja_tidak_sesuai_2 VARCHAR(50),
alasan_tidak_sesuai_1 VARCHAR(50),
alasan_tidak_sesuai_2 VARCHAR(50),
alasan_tidak_sesuai_3 VARCHAR(50),
alasan_tidak_sesuai_4 VARCHAR(50),
alasan_tidak_sesuai_5 VARCHAR(50),
alasan_tidak_sesuai_6 VARCHAR(50),
alasan_tidak_sesuai_7 VARCHAR(50),
alasan_tidak_sesuai_8 VARCHAR(50),
alasan_tidak_sesuai_9 VARCHAR(50),
alasan_tidak_sesuai_10 VARCHAR(50),
alasan_tidak_sesuai_11 VARCHAR(50),
alasan_tidak_sesuai_lainnya TEXT,
data_extra TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (alumni_id) REFERENCES alumni(id) ON DELETE CASCADE
);

View File

@ -0,0 +1,275 @@
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='', database='tracerstudy_db', port=3306, charset='utf8mb4')
cur = conn.cursor()
# ===== PERTANYAAN =====
questions_data = [
# Section 1 - Identitas
{'kode': 'kdptimsmh', 'pertanyaan': 'Kode Perguruan Tinggi', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 1},
{'kode': 'kdpstmsnmh', 'pertanyaan': 'Kode Program Studi', 'tipe': 'pilihan', 'section': 'identitas', 'nomor_form': 2},
{'kode': 'nimhsmsnmh', 'pertanyaan': 'NIM / Nomor Mahasiswa', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 3},
{'kode': 'nmmhsmsnmh', 'pertanyaan': 'Nama Lengkap', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 4},
{'kode': 'telepon', 'pertanyaan': 'Nomor Telepon/HP (Whatsapp)', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 5},
{'kode': 'email', 'pertanyaan': 'Alamat Email', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 6},
{'kode': 'tahun_lulus', 'pertanyaan': 'Tahun Lulus', 'tipe': 'dropdown', 'section': 'identitas', 'nomor_form': 7},
{'kode': 'nik', 'pertanyaan': 'NIK / Nomor Induk Kependudukan', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 8},
{'kode': 'npwp', 'pertanyaan': 'NPWP', 'tipe': 'teks', 'section': 'identitas', 'nomor_form': 9},
# Section 2 - Kuesioner Utama
{'kode': 'F8', 'pertanyaan': 'Jelaskan status Anda saat ini?', 'tipe': 'dropdown', 'section': 'kuesioner_utama', 'nomor_form': 1},
{'kode': 'F502', 'pertanyaan': 'Dalam berapa bulan Anda mendapatkan pekerjaan pertama?', 'tipe': 'dropdown', 'section': 'kuesioner_utama', 'nomor_form': 2},
{'kode': 'F505', 'pertanyaan': 'Berapa rata-rata pendapatan Anda per bulan?', 'tipe': 'pilihan', 'section': 'kuesioner_utama', 'nomor_form': 4},
{'kode': 'F5a1', 'pertanyaan': 'Provinsi tempat bekerja', 'tipe': 'dropdown', 'section': 'kuesioner_utama', 'nomor_form': 5},
{'kode': 'F5a2', 'pertanyaan': 'Kabupaten/Kota tempat bekerja', 'tipe': 'dropdown', 'section': 'kuesioner_utama', 'nomor_form': 6},
{'kode': 'F1101', 'pertanyaan': 'Jenis perusahaan/instansi/institusi tempat bekerja', 'tipe': 'pilihan', 'section': 'kuesioner_utama', 'nomor_form': 7},
{'kode': 'F5b', 'pertanyaan': 'Nama perusahaan/kantor', 'tipe': 'teks', 'section': 'kuesioner_utama', 'nomor_form': 8},
{'kode': 'F5c', 'pertanyaan': 'Posisi/Jabatan (Wiraswasta)', 'tipe': 'pilihan', 'section': 'kuesioner_utama', 'nomor_form': 9},
{'kode': 'F5d', 'pertanyaan': 'Tingkatan tempat kerja', 'tipe': 'pilihan', 'section': 'kuesioner_utama', 'nomor_form': 10},
# Studi Lanjut
{'kode': 'F18a', 'pertanyaan': 'Sumber biaya Studi Lanjut', 'tipe': 'dropdown', 'section': 'studi_lanjut', 'nomor_form': 11},
{'kode': 'F18b', 'pertanyaan': 'Nama PT Studi Lanjut', 'tipe': 'teks', 'section': 'studi_lanjut', 'nomor_form': 12},
{'kode': 'F18c', 'pertanyaan': 'Program Studi Studi Lanjut', 'tipe': 'teks', 'section': 'studi_lanjut', 'nomor_form': 13},
{'kode': 'F18d', 'pertanyaan': 'Tanggal Masuk Studi Lanjut', 'tipe': 'date', 'section': 'studi_lanjut', 'nomor_form': 14},
# Pembiayaan & Kesesuaian
{'kode': 'F1201', 'pertanyaan': 'Sumber pembiayaan kuliah', 'tipe': 'pilihan', 'section': 'kesesuaian', 'nomor_form': 15},
{'kode': 'F14', 'pertanyaan': 'Seberapa erat hubungan bidang studi dengan pekerjaan', 'tipe': 'pilihan', 'section': 'kesesuaian', 'nomor_form': 16},
{'kode': 'F15', 'pertanyaan': 'Tingkat pendidikan yang tepat untuk pekerjaan saat ini', 'tipe': 'pilihan', 'section': 'kesesuaian', 'nomor_form': 17},
# Kompetensi
{'kode': 'F1761', 'pertanyaan': 'Kompetensi ETIKA saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 18},
{'kode': 'F1762', 'pertanyaan': 'Kompetensi ETIKA saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 19},
{'kode': 'F1763', 'pertanyaan': 'Kompetensi KEAHLIAN BIDANG ILMU saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 20},
{'kode': 'F1764', 'pertanyaan': 'Kompetensi KEAHLIAN BIDANG ILMU saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 21},
{'kode': 'F1765', 'pertanyaan': 'Kompetensi BAHASA INGGRIS saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 22},
{'kode': 'F1766', 'pertanyaan': 'Kompetensi BAHASA INGGRIS saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 23},
{'kode': 'F1767', 'pertanyaan': 'Kompetensi TEKNOLOGI INFORMASI saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 24},
{'kode': 'F1768', 'pertanyaan': 'Kompetensi TEKNOLOGI INFORMASI saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 25},
{'kode': 'F1769', 'pertanyaan': 'Kompetensi KOMUNIKASI saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 26},
{'kode': 'F1770', 'pertanyaan': 'Kompetensi KOMUNIKASI saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 27},
{'kode': 'F1771', 'pertanyaan': 'Kompetensi KERJA SAMA TIM saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 28},
{'kode': 'F1772', 'pertanyaan': 'Kompetensi KERJA SAMA TIM saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 29},
{'kode': 'F1773', 'pertanyaan': 'Kompetensi PENGEMBANGAN DIRI saat LULUS', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 30},
{'kode': 'F1774', 'pertanyaan': 'Kompetensi PENGEMBANGAN DIRI saat INI', 'tipe': 'skala', 'section': 'kompetensi', 'nomor_form': 31},
# Metode Pembelajaran
{'kode': 'F21', 'pertanyaan': 'Perkuliahan', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 32},
{'kode': 'F22', 'pertanyaan': 'Demonstrasi', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 33},
{'kode': 'F23', 'pertanyaan': 'Partisipasi dalam proyek riset', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 34},
{'kode': 'F24', 'pertanyaan': 'Magang', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 35},
{'kode': 'F25', 'pertanyaan': 'Praktikum', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 36},
{'kode': 'F26', 'pertanyaan': 'Kerja Lapangan', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 37},
{'kode': 'F27', 'pertanyaan': 'Diskusi', 'tipe': 'skala', 'section': 'metode_pembelajaran', 'nomor_form': 38},
# Waktu Cari Kerja
{'kode': 'F301', 'pertanyaan': 'Kapan mulai mencari pekerjaan?', 'tipe': 'pilihan', 'section': 'waktu_cari_kerja', 'nomor_form': 39},
{'kode': 'F302', 'pertanyaan': 'Berapa bulan sebelum lulus mencari kerja?', 'tipe': 'dropdown', 'section': 'waktu_cari_kerja', 'nomor_form': 40},
{'kode': 'F303', 'pertanyaan': 'Berapa bulan setelah wisuda mencari kerja?', 'tipe': 'dropdown', 'section': 'waktu_cari_kerja', 'nomor_form': 41},
# Cara Cari Kerja
{'kode': 'F401', 'pertanyaan': 'Melamar melalui iklan di koran/majalah/brosur?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 42},
{'kode': 'F402', 'pertanyaan': 'Melamar ke perusahaan tanpa mengetahui lowongan?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 43},
{'kode': 'F403', 'pertanyaan': 'Pergi ke bursa/pameran kerja?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 44},
{'kode': 'F404', 'pertanyaan': 'Mencari lewat internet/iklan online/milis?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 45},
{'kode': 'F405', 'pertanyaan': 'Dihubungi perusahaan?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 46},
{'kode': 'F406', 'pertanyaan': 'Menghubungi Kemenakertrans?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 47},
{'kode': 'F407', 'pertanyaan': 'Menghubungi agen tenaga kerja komersial/swasta?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 48},
{'kode': 'F408', 'pertanyaan': 'Informasi dari pusat/kantor pengembangan karir?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 49},
{'kode': 'F409', 'pertanyaan': 'Menghubungi kantor kemahasiswaan?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 50},
{'kode': 'F410', 'pertanyaan': 'Membangun jejaring (network)?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 51},
{'kode': 'F411', 'pertanyaan': 'Melaui relasi (dosen, orang tua, teman)?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 52},
{'kode': 'F412', 'pertanyaan': 'Membangun bisnis sendiri?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 53},
{'kode': 'F413', 'pertanyaan': 'Melalui penempatan kerja/magang?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 54},
{'kode': 'F414', 'pertanyaan': 'Bekerja di tempat yang sama dengan waktu kuliah?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 55},
{'kode': 'F415', 'pertanyaan': 'Cara lain?', 'tipe': 'ya_tidak', 'section': 'cara_cari_kerja', 'nomor_form': 56},
# Jumlah Lamaran
{'kode': 'F6', 'pertanyaan': 'Jumlah perusahaan yang dilamar', 'tipe': 'dropdown', 'section': 'lamaran', 'nomor_form': 57},
{'kode': 'F7', 'pertanyaan': 'Jumlah perusahaan yang merespons', 'tipe': 'dropdown', 'section': 'lamaran', 'nomor_form': 58},
{'kode': 'F7a', 'pertanyaan': 'Jumlah perusahaan yang mengundang wawancara', 'tipe': 'dropdown', 'section': 'lamaran', 'nomor_form': 59},
# Aktif Cari Kerja
{'kode': 'F1001', 'pertanyaan': 'Aktif mencari pekerjaan dalam 4 minggu terakhir?', 'tipe': 'pilihan', 'section': 'aktif_cari_kerja', 'nomor_form': 60},
# Kesesuaian Pekerjaan
{'kode': 'F1601', 'pertanyaan': 'Pekerjaan sesuai dengan pendidikan?', 'tipe': 'pilihan', 'section': 'kesesuaian_pekerjaan', 'nomor_form': 61},
{'kode': 'F1602', 'pertanyaan': 'Alasan belum dapat pekerjaan sesuai?', 'tipe': 'pilihan', 'section': 'kesesuaian_pekerjaan', 'nomor_form': 62},
{'kode': 'F1603', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (1)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 63},
{'kode': 'F1604', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (2)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 64},
{'kode': 'F1605', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (3)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 65},
{'kode': 'F1606', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (4)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 66},
{'kode': 'F1607', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (5)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 67},
{'kode': 'F1608', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (6)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 68},
{'kode': 'F1609', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (7)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 69},
{'kode': 'F1610', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (8)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 70},
{'kode': 'F1611', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (9)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 71},
{'kode': 'F1612', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (10)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 72},
{'kode': 'F1613', 'pertanyaan': 'Alasan mengambil pekerjaan tidak sesuai (11)?', 'tipe': 'ya_tidak', 'section': 'alasan_tidak_sesuai', 'nomor_form': 73},
{'kode': 'F1614', 'pertanyaan': 'Alasan lainnya', 'tipe': 'teks', 'section': 'alasan_tidak_sesuai', 'nomor_form': 74},
]
# Insert questions
for q in questions_data:
cur.execute('''
INSERT INTO questions (kode, pertanyaan, tipe, section, nomor_form)
VALUES (%s, %s, %s, %s, %s)
ON DUPLICATE KEY UPDATE pertanyaan = VALUES(pertanyaan)
''', (q['kode'], q['pertanyaan'], q['tipe'], q['section'], q['nomor_form']))
conn.commit()
print(f'Successfully inserted {len(questions_data)} questions')
# ===== JAWABAN OPTIONS =====
answer_options = [
# F8 - Status saat ini
('F8', '1', 'Bekerja (full time/part time)', 1),
('F8', '2', 'Belum memungkinkan bekerja', 2),
('F8', '3', 'Wiraswasta', 3),
('F8', '4', 'Melanjutkan Pendidikan', 4),
('F8', '5', 'Tidak kerja tetapi sedang mencari kerja', 5),
# F505 - Pendapatan
('F505', '1000000', 'Rp 1.000.000', 1),
('F505', '1500000', 'Rp 1.500.000', 2),
('F505', '2000000', 'Rp 2.000.000', 3),
('F505', '2500000', 'Rp 2.500.000', 4),
('F505', '3000000', 'Rp 3.000.000', 5),
('F505', '3500000', 'Rp 3.500.000', 6),
('F505', '4000000', 'Rp 4.000.000', 7),
('F505', '4500000', 'Rp 4.500.000', 8),
('F505', '5000000', 'Rp 5.000.000', 9),
('F505', '6000000', 'Rp 6.000.000', 10),
('F505', '7000000', 'Rp 7.000.000', 11),
('F505', '8000000', '>Rp 8.000.000', 12),
# F1101 - Jenis perusahaan
('F1101', '1', 'Instansi pemerintah', 1),
('F1101', '2', 'Organisasi non-profit/Lembaga Swadaya Masyarakat', 2),
('F1101', '3', 'Perusahaan swasta', 3),
('F1101', '4', 'Wiraswasta/perusahaan sendiri', 4),
('F1101', '5', 'Lainnya', 5),
('F1101', '6', 'BUMN/BUMD', 6),
('F1101', '7', 'Institusi/Organisasi Multilateral', 7),
# F5d - Tingkatan tempat kerja
('F5d', '1', 'Lokal/wilayah/wiraswasta tidak berbadan hukum', 1),
('F5d', '2', 'Nasional/wiraswasta berbadan hukum', 2),
('F5d', '3', 'Multinasional/Internasional', 3),
# F5c - Jabatan wiraswasta
('F5c', '1', 'Founder', 1),
('F5c', '2', 'Co-Founder', 2),
('F5c', '3', 'Staff', 3),
('F5c', '4', 'Freelance/Kerja Lepas', 4),
# F18a - Sumber biaya studi lanjut
('F18a', '1', 'Biaya Sendiri', 1),
('F18a', '2', 'Beasiswa', 2),
# F1201 - Sumber biaya kuliah
('F1201', '1', 'Biaya Sendiri/Keluarga', 1),
('F1201', '2', 'Beasiswa ADIK', 2),
('F1201', '3', 'Beasiswa BIDIKMISI', 3),
('F1201', '4', 'Beasiswa PPA', 4),
('F1201', '5', 'Beasiswa AFIRMASI', 5),
('F1201', '6', 'Beasiswa Perusahaan/Swasta', 6),
('F1201', '7', 'Lainnya', 7),
# F14 - Keeratan bidang studi
('F14', '1', 'Sangat Erat', 1),
('F14', '2', 'Erat', 2),
('F14', '3', 'Cukup Erat', 3),
('F14', '4', 'Kurang Erat', 4),
('F14', '5', 'Tidak sama sekali', 5),
# F15 - Tingkat pendidikan tepat
('F15', '1', 'Setingkat lebih tinggi', 1),
('F15', '2', 'Tingkat yang sama', 2),
('F15', '3', 'Setingkat lebih rendah', 3),
('F15', '4', 'Tidak perlu pendidikan tinggi', 4),
# F301 - Mulai cari kerja
('F301', '1', 'Saya mencari kerja sebelum lulus', 1),
('F301', '2', 'Saya mencari kerja sesudah wisuda', 2),
('F301', '3', 'Saya tidak mencari kerja', 3),
# F1001 - Aktif cari kerja
('F1001', '1', 'Tidak', 1),
('F1001', '2', 'Tidak, tapi saya sedang menunggu hasil lamaran kerja', 2),
('F1001', '3', 'Ya, saya akan mulai bekerja dalam 2 minggu ke depan', 3),
('F1001', '4', 'Ya, tapi saya belum pasti akan bekerja dalam 2 minggu ke depan', 4),
('F1001', '5', 'Lainnya', 5),
# F1601 - Kesesuaian pekerjaan
('F1601', '0', 'Tidak sesuai', 1),
('F1601', '1', 'Pekerjaan saya sekarang sudah sesuai dengan pendidikan saya', 2),
# F1602 - Alasan belum sesuai
('F1602', '0', 'Pekerjaan saya sudah sesuai', 1),
('F1602', '1', 'Saya belum mendapatkan pekerjaan yang lebih sesuai', 2),
]
# Insert answer options with question_id lookup
for kode, kode_jawaban, teks, urutan in answer_options:
# Get question_id from questions table
cur.execute('SELECT id FROM questions WHERE kode = %s', (kode,))
result = cur.fetchone()
if result:
question_id = result[0]
cur.execute('''
INSERT INTO answer_options (question_id, kode, teks, urutan)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE teks = VALUES(teks)
''', (question_id, kode_jawaban, teks, urutan))
conn.commit()
print(f'Successfully inserted answer options')
# Skala 1-5 (untuk kompetensi dan metode pembelajaran)
skala_labels = ['Sangat Rendah', 'Rendah', 'Netral', 'Tinggi', 'Sangat Tinggi']
for kode in ['F1761', 'F1762', 'F1763', 'F1764', 'F1765', 'F1766', 'F1767', 'F1768', 'F1769', 'F1770', 'F1771', 'F1772', 'F1773', 'F1774']:
cur.execute('SELECT id FROM questions WHERE kode = %s', (kode,))
result = cur.fetchone()
if result:
question_id = result[0]
for i, label in enumerate(skala_labels, 1):
cur.execute('''
INSERT INTO answer_options (question_id, kode, teks, urutan)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE teks = VALUES(teks)
''', (question_id, str(i), label, i))
# Metode pembelajaran - scale berbeda
metode_labels = ['Sangat Besar', 'Besar', 'Cukup Besar', 'Kurang', 'Tidak Sama Sekali']
for kode in ['F21', 'F22', 'F23', 'F24', 'F25', 'F26', 'F27']:
cur.execute('SELECT id FROM questions WHERE kode = %s', (kode,))
result = cur.fetchone()
if result:
question_id = result[0]
for i, label in enumerate(metode_labels, 1):
cur.execute('''
INSERT INTO answer_options (question_id, kode, teks, urutan)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE teks = VALUES(teks)
''', (question_id, str(i), label, i))
# Ya/Tidak untuk cara cari kerja
for kode in ['F401', 'F402', 'F403', 'F404', 'F405', 'F406', 'F407', 'F408', 'F409', 'F410', 'F411', 'F412', 'F413', 'F414', 'F415']:
cur.execute('SELECT id FROM questions WHERE kode = %s', (kode,))
result = cur.fetchone()
if result:
question_id = result[0]
for i, label in enumerate(['Tidak', 'Ya'], 0):
cur.execute('''
INSERT INTO answer_options (question_id, kode, teks, urutan)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE teks = VALUES(teks)
''', (question_id, str(i), label, i))
conn.commit()
print('All answer options inserted successfully!')
conn.close()

20
Backend/requirements.txt Normal file
View File

@ -0,0 +1,20 @@
fastapi>=0.110.0
uvicorn[standard]>=0.28.0
sqlalchemy>=2.0.0
pydantic>=2.6.0
pydantic-settings>=2.2.0
python-dotenv>=1.0.1
passlib[bcrypt]>=1.7.4
python-jose[cryptography]>=3.3.0
python-multipart>=0.0.9
bcrypt>=4.1.0
email-validator>=2.0.0
# Machine Learning Dependencies
scikit-learn>=1.4.0
nltk>=3.8.0
sastrawi>=1.0.0
openpyxl>=3.1.0
pandas>=2.0.0
numpy>=1.24.0

Some files were not shown because too many files have changed in this diff Show More