214 lines
6.2 KiB
PHP
214 lines
6.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\tables;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\Request;
|
|
use App\Models\Placement;
|
|
use App\Models\Classification;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use App\Models\Siswa;
|
|
use App\Models\Sertifikat;
|
|
use App\Models\Nilai;
|
|
use App\Imports\PlacementImport;
|
|
use Maatwebsite\Excel\Facades\Excel;
|
|
|
|
class PlacementController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$placement = Placement::all();
|
|
return view('content.placement.index', compact('placement'));
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
return view('content.placement.create');
|
|
}
|
|
|
|
public function edit(Request $request, $placementId)
|
|
{
|
|
$placement = Placement::find($placementId);
|
|
return view('content.placement.edit', compact('placement'));
|
|
}
|
|
|
|
public function calculate(Request $request)
|
|
{
|
|
$scorePerItem = intval(100 / count($request->data));
|
|
$user = Auth::user();
|
|
$siswa = Siswa::where("user_id", $user->id)->get();
|
|
|
|
// Fungsi untuk menghitung jarak Euclidean antara dua vektor
|
|
function euclideanDistance($vector1, $vector2)
|
|
{
|
|
$sum = 0;
|
|
for ($i = 0; $i < count($vector1); $i++) {
|
|
$sum += pow($vector1[$i] - $vector2[$i], 2);
|
|
}
|
|
return sqrt($sum);
|
|
}
|
|
|
|
// Fungsi untuk mencari tetangga terdekat
|
|
function findNeighbors($X_train, $y_train, $new_sample, $k)
|
|
{
|
|
$distances = [];
|
|
foreach ($X_train as $index => $sample) {
|
|
$dist = euclideanDistance($sample, $new_sample);
|
|
$distances[] = [$dist, $y_train[$index]];
|
|
}
|
|
usort($distances, function ($a, $b) {
|
|
return $a[0] - $b[0];
|
|
});
|
|
return array_slice($distances, 0, $k);
|
|
}
|
|
|
|
// Fungsi untuk memprediksi kelas dari sampel baru
|
|
function predictClass($X_train, $y_train, $new_sample, $k)
|
|
{
|
|
$neighbors = findNeighbors($X_train, $y_train, $new_sample, $k);
|
|
$counts = [];
|
|
foreach ($neighbors as $neighbor) {
|
|
$label = $neighbor[1];
|
|
$counts[$label] = isset($counts[$label]) ? $counts[$label] + 1 : 1;
|
|
}
|
|
arsort($counts);
|
|
$predictedClass = key($counts);
|
|
return $predictedClass;
|
|
}
|
|
|
|
// Data training
|
|
// SD -> 1
|
|
// SMP -> 2
|
|
// SMA -> 3
|
|
// [BOBOT TINGKAT, BOBOT NILAI]
|
|
$X_train = [
|
|
[3, 82],
|
|
[1, 86],
|
|
[1, 70],
|
|
[2, 88],
|
|
[1, 94],
|
|
[2, 78],
|
|
[2, 94],
|
|
[1, 76],
|
|
[3, 90],
|
|
[1, 72],
|
|
[1, 88],
|
|
[3, 80]
|
|
|
|
];
|
|
|
|
$y_train = ['Beginner', 'Beginner', 'Pre-Kids', 'Intermediate', 'Beginner', 'Beginner', 'Intermediate', 'Pre-Kids', 'Intermediate', 'Pre-Kids', 'Beginner', 'Beginner'];
|
|
|
|
$X_test = [];
|
|
$score = 0;
|
|
foreach ($request->data as $data) {
|
|
if ($data["jawaban_benar"] == $data["input_jawaban"]) {
|
|
$score = $score + $scorePerItem;
|
|
}
|
|
}
|
|
|
|
switch ($siswa[0]["jenjang"]) {
|
|
case "SD":
|
|
case "MI":
|
|
array_push($X_test, 1);
|
|
break;
|
|
case "SMP":
|
|
case "MTS":
|
|
array_push($X_test, 2);
|
|
break;
|
|
case "SMA":
|
|
case "SMK":
|
|
array_push($X_test, 3);
|
|
break;
|
|
case "Kuliah":
|
|
case "Umum":
|
|
array_push($X_test, 4);
|
|
break;
|
|
default:
|
|
array_push($X_test, 0);
|
|
}
|
|
|
|
array_push($X_test, $score);
|
|
|
|
// Jumlah tetangga terdekat yang akan digunakan
|
|
$k = 3;
|
|
|
|
// Lakukan prediksi kelas untuk data uji
|
|
$predictedClass = predictClass($X_train, $y_train, $X_test, $k);
|
|
|
|
// Gate
|
|
if ($X_test <= 1) {
|
|
$predictedClass = "Pre-Kids";
|
|
} else {
|
|
if ($predictedClass == "Pre-Kids") {
|
|
$predictedClass = "Beginner";
|
|
}
|
|
}
|
|
|
|
DB::transaction(function () use ($request, $score, $predictedClass) {
|
|
Classification::create([
|
|
"user_id" => json_decode($request->user)->id,
|
|
"nilai" => $score,
|
|
"hasil_kelas" => $predictedClass,
|
|
]);
|
|
|
|
Sertifikat::create([
|
|
"user_id" => json_decode($request->user)->id,
|
|
]);
|
|
|
|
Nilai::create([
|
|
"user_id" => json_decode($request->user)->id,
|
|
"writing" => 0,
|
|
"reading" => 0,
|
|
"listening" => 0,
|
|
"speaking" => 0
|
|
]);
|
|
|
|
$siswa = Siswa::where("user_id", "=", json_decode($request->user)->id)->first();
|
|
$siswa->update([
|
|
"level" => $predictedClass
|
|
]);
|
|
$siswa->save();
|
|
});
|
|
|
|
return $predictedClass;
|
|
}
|
|
|
|
public function insert(Request $request)
|
|
{
|
|
if (isset($request->file)) {
|
|
Placement::truncate();
|
|
Excel::import(new PlacementImport, request()->file('file'));
|
|
} else {
|
|
Placement::create([
|
|
"soal" => $request->soal,
|
|
"jawaban" => $request->jawaban,
|
|
"jawaban_benar" => $request->jawaban_benar,
|
|
]);
|
|
}
|
|
return redirect()->route("placement")->with("success", "Data Berhasil Disimpan!");
|
|
}
|
|
public function update(Request $request, $placementId)
|
|
{
|
|
$placement = Placement::find($placementId);
|
|
$placement->update([
|
|
"soal" => $request->soal,
|
|
"jawaban" => $request->jawaban,
|
|
"jawaban_benar" => $request->jawaban_benar,
|
|
]);
|
|
|
|
return redirect()->route("placement")->with("success", "Data Berhasil Diperbarui!");
|
|
}
|
|
|
|
public function destroy(Request $request, $placementId)
|
|
{
|
|
$id = $placementId;
|
|
$placement = Placement::find($id);
|
|
|
|
$placement->delete();
|
|
|
|
return redirect()->route("placement")->with("success", "Data Berhasil Dihapus!");
|
|
}
|
|
}
|