Saturday, 15 November 2025

Pengaturan sesi kode kartu_ujiant.php

 

Siap, Guru Duan — penjelasan bagian pengaturan sesi (session) pada kode Anda, disusun ringkas dan terfokus pada logika yang relevan agar gampang dipahami.


Inti pengaturan sesi (ringkasan cepat)

  1. Kapasitas total = jumlah semua kapasitas ruang yang dimasukkan oleh pengguna.

    foreach ($rooms as $r) $total_capacity += (int)$r['capacity'];
    

    Jika total 0, di-set ke 1 sebagai fallback.

  2. Jumlah sesi (num_sessions) dihitung dengan:

    $num_sessions = ceil($total_students / $total_capacity);
    

    Artinya: berapa batch (sesi) yang diperlukan supaya semua siswa muat bila tiap sesi memanfaatkan seluruh kapasitas semua ruang.

  3. Pembagian siswa ke sesi (sessions) — chunking sederhana:

    for each student idx:
        sno = floor(idx / total_capacity) + 1
        sessions[sno][] = student
    

    Jadi siswa diurutkan (berdasarkan ordered_students) lalu dibagi ke sesi secara berurutan: siswa ke-0..(capacity-1) → sesi 1, selanjutnya → sesi 2, dst.

  4. Slot tempat duduk per sesi (seating_by_session) — sama untuk setiap sesi:

    foreach rooms as r:
        for meja = 1..r['capacity']:
            fullslots[] = ['room'=>$r['name'], 'meja'=>$meja];
    seating_by_session[sno] = fullslots;
    

    Artinya: untuk tiap sesi dibuat daftar semua kursi (room+meja) berdasarkan urutan rooms dan kapasitasnya. Daftar slot ini tidak tergantung isi siswa; slot diindeks 0..N-1 dan dipetakan ke siswa berdasarkan indeks.

  5. Penentuan tanggal ujian (exam_dates): dimulai dari tanggal_mulai, melangkah hari demi hari dan hanya menyertakan Senin–Jumat sampai jumlah hari tercapai.


Bagaimana sesi digunakan saat generate/attendance

  • Saat generate kartu, kode membuat array assignments dengan memetakan tiap siswa di plan->sessions[$s] ke slot yang sesuai ($slots[$i]) sehingga setiap siswa mendapatkan room & meja dan session (sno). Jika slot tidak tersedia (jarang), ada fallback supaya meja tetap diberikan.

  • Saat generate daftar hadir, kode mengambil seating_by_session[$s] untuk sesi awal s dan membangun baris per slot (mengambil siswa yang sesuai indeks). Layout kolom untuk tiap tanggal dibuat berdasarkan jumlah sesi dan aturan khusus (lihat bawah).


Logika penjadwalan sesi ke tanggal (s_on_day)

Ada dua tempat penting memakai formula session-per-day:

  1. Pada kartu: untuk setiap tanggal $didx dihitung:

    $s_on_day = ((($sno - 1) + $didx) % $plan->num_sessions) + 1;
    

    Makna: untuk siswa yang berada di sesi awal sno, hari pertama (didx=0) ia tampil di sesi sno; hari berikutnya (didx=1) ia tampil di sesi sno+1 (mod num_sessions), dan seterusnya. Ini menggeser sesi tiap tanggal sehingga tidak semua siswa selalu di sesi 1 pada semua tanggal — membentuk rotasi sesi antar-hari.

  2. Pada daftar hadir (kolom sub-session untuk tiap tanggal):

    • Untuk hari Senin–Kamis dibuat 2 subkolom (sesi awal dan sesi awal + num_sessions). Itu implementasinya:

      if (hari Sen-Kam) {
          tampilkan s_on_day dan (s_on_day + num_sessions)
      } else { // Jumat
          tampilkan s_on_day
      }
      
    • Tujuannya: untuk membuat dua gelombang (sesi pagi & sesi siang) pada hari Senin–Kamis — representasi session dan session + num_sessions.

Contoh singkat: total_capacity = 100, num_sessions = 2 (sesi 1 & 2). Untuk siswa yang awalnya di sesi 1:

  • Hari 1 → s_on_day = 1

  • Hari 2 → s_on_day = 2
    Jika hari itu Senin–Kamis, daftar hadir menampilkan 2 subkolom: 1 dan 1+2 = 3 (tampaknya kode menampilkan s_on_day + num_sessions sehingga label bisa menjadi 3,4... — ini bergantung pada num_sessions; jika num_sessions=2, s_on_day + num_sessions = 3, artinya label '3' mungkin dimaksudkan untuk gelombang kedua — catatan tentang label ini di bagian tweak).


Edge case & fallback penting

  • Jika total_capacity = 0 → diset 1 supaya tidak div/0.

  • Jika jumlah siswa tidak kelipatan kapasitas, sesi terakhir akan berisi sisa siswa.

  • seating_by_session selalu membuat slot penuh sama untuk tiap sesi — artinya jika kapasitas cukup besar, ada slot kosong di akhir sesi jika siswa kurang.

  • exam_dates hanya ambil Senin–Jumat; jika jumlah_hari sangat besar loop dicegah dengan batas wajar (pada versi Anda ada safety tries).


Catatan implementasi & kemungkinan perbaikan yang berguna

  • Saat ini urutan siswa dibuat dulu (ordered_students) lalu chunking berdasarkan total_capacity. Ini sederhana tapi bisa menyebabkan ketidakseimbangan antar-ruang (mis. siswa dari satu kelas terkonsentrasi pada satu ruang jika urutan dan kapasitas cocok). Jika ingin sebaran lebih merata per-ruang, gunakan algoritma round-robin pada slot bukan chunking linear.

  • s_on_day + $num_sessions sebagai label subkolom menghasilkan label yang tidak selalu intuitif (mis. 1 & 3). Anda bisa mengganti agar subkol kedua menampilkan label 'Sesi ' . ($s_on_day + $num_sessions - $num_sessions) atau cukup ($s_on_day + $num_sessions/??) tergantung maksud label. Intinya: pastikan label merepresentasikan gelombang yang diinginkan (mis. 1 & 2 bukan 1 & 3).

  • Jika ingin agar slot ruangan diisi bergantian antar-ruang (mis. supaya tiap ruang berisi siswa dari berbagai kelas), ubah assignment menjadi loop slot per slot dan ambil student berikutnya (round-robin across rooms).

  • Jika butuh memulai dari sesi selain 1 (mis. shift start), boleh tambahkan input start_session dan ubah kalkulasi s_on_day dan chunk offset.


Kalau mau, saya bisa langsung:

  • ubah agar subkol kedua menampilkan label sesi yang lebih intuitif (mis. Sesi pagi / Sesi siang atau 1 & 2),

  • atau ubah assignment jadi round-robin per slot supaya sebaran antar-ruang lebih merata.

Kamu pilih yang mana, Guru Duan? Saya langsung terapkan tanpa tanya-tanya lagi.

Share:

0 comments:

Post a Comment