Latar Belakang

Di era digital saat ini, berbagai kegiatan kampus seperti lomba akademik, seni, olahraga, maupun inovasi teknologi semakin sering diselenggarakan oleh institusi pendidikan sebagai sarana pengembangan minat, bakat, dan soft skill mahasiswa. Namun, di balik maraknya kegiatan tersebut, masih banyak ditemukan permasalahan dalam pengelolaan teknis, terutama pada aspek administrasi dan penilaian lomba.
Salah satu tantangan utama adalah pengelolaan data peserta, proses seleksi, dan dokumentasi penilaian yang masih dilakukan secara manual. Penggunaan biasa atau pencatatan spreadsheet konvensional cenderung memakan waktu, tidak efisien, dan rawan terjadi kesalahan input maupun kehilangan data. Selain itu, proses seleksi yang dilakukan secara manual juga berisiko menimbulkan ketidaktepatan dalam menentukan peserta yang lolos ke tahap selanjutnya. Hal ini tidak hanya memperlambat jalannya lomba, tetapi juga dapat menurunkan kredibilitas panitia penyelenggara.Untuk menjawab tantangan tersebut, dibutuhkan sebuah solusi sistematis dan terintegrasi yang dapat membantu panitia dalam mengelola lomba secara lebih efisien, akurat, dan mudah dilacak. 
Oleh karena itu, dibangunlah sebuah sistem manajemen lomba berbasis database  menggunakan RStudio dan SQLite. Berikut ini implementasi sistem databasenya"
library(readxl)
## Warning: package 'readxl' was built under R version 4.4.2
library(RSQLite)
## Warning: package 'RSQLite' was built under R version 4.4.3
library(DBI)
## Warning: package 'DBI' was built under R version 4.4.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.2
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.2
#1. Koneksi ke Database SQLite
conn <- dbConnect(SQLite(), dbname = "lomba_mahasiswa.db")

#2. Menghapus Tabel Lama Jika Ada
tables <- c("penilaian", "pendaftaran", "kegiatan", "mahasiswa")
for (t in tables) {
  if (dbExistsTable(conn, t)) dbRemoveTable(conn, t)
}
# 3. Membuat Struktur Tabel
dbExecute(conn, "
CREATE TABLE mahasiswa (
  id_mahasiswa INTEGER PRIMARY KEY AUTOINCREMENT,
  nama TEXT,
  nim TEXT,
  prodi TEXT,
  angkatan INTEGER
);")
## [1] 0
dbExecute(conn, "
CREATE TABLE kegiatan (
  id_kegiatan INTEGER PRIMARY KEY AUTOINCREMENT,
  nama_kegiatan TEXT,
  jenis_kegiatan TEXT,
  tanggal_mulai TEXT,
  tanggal_selesai TEXT,
  lokasi TEXT,
  penyelenggara TEXT
);")
## [1] 0
dbExecute(conn, "
CREATE TABLE pendaftaran (
  id_pendaftaran INTEGER PRIMARY KEY AUTOINCREMENT,
  kode_pendaftaran TEXT,
  id_mahasiswa INTEGER,
  id_kegiatan INTEGER,
  tanggal_daftar TEXT,
  FOREIGN KEY(id_mahasiswa) REFERENCES mahasiswa(id_mahasiswa),
  FOREIGN KEY(id_kegiatan) REFERENCES kegiatan(id_kegiatan)
);")
## [1] 0
dbExecute(conn, "
CREATE TABLE penilaian (
  id_penilaian INTEGER PRIMARY KEY AUTOINCREMENT,
  id_pendaftaran INTEGER,
  tahap TEXT,
  nilai REAL,
  peringkat INTEGER,
  FOREIGN KEY(id_pendaftaran) REFERENCES pendaftaran(id_pendaftaran)
);")
## [1] 0
# 4. Baca Data Excel
pendaftar <- read_excel("D:/Tugas Semester 4/BASIS DATA/pendaftar_lomba.xlsx") %>%
  mutate(
    NIM = as.character(NIM),
    Tanggal_Daftar = as.character(Tanggal_Daftar)
  )

# 5. Menyimpan Mahasiswa
mahasiswa <- pendaftar %>%
  select(nama = Nama, nim = NIM, prodi = Prodi, angkatan = Angkatan) %>%
  distinct()
dbWriteTable(conn, "mahasiswa", mahasiswa, append = TRUE)

# 6. Menambah 1 Kegiatan sebagai contoh
dbExecute(conn, "
INSERT INTO kegiatan (nama_kegiatan, jenis_kegiatan, tanggal_mulai, tanggal_selesai, lokasi, penyelenggara)
VALUES ('Lomba KTI Nasional', 'Lomba', '2025-08-01', '2025-08-03', 'Auditorium Kampus', 'BEM FMIPA');
")
## [1] 1
# 7. Simpan Pendaftaran 
mahasiswa_db <- dbReadTable(conn, "mahasiswa")
pendaftaran <- pendaftar %>%
  left_join(mahasiswa_db, by = c("Nama" = "nama", "NIM" = "nim", "Prodi" = "prodi", "Angkatan" = "angkatan")) %>%
  mutate(id_kegiatan = 1,
         tanggal_daftar = Tanggal_Daftar) %>%
  select(id_mahasiswa, id_kegiatan, tanggal_daftar)

dbWriteTable(conn, "pendaftaran", pendaftaran, append = TRUE)

# 8. Menambahkan kode_pendaftaran (F101, F102, dst) 
pendaftaran_db <- dbReadTable(conn, "pendaftaran")
kode_unik <- sprintf("F1%02d", pendaftaran_db$id_pendaftaran)
for (i in seq_along(kode_unik)) {
  dbExecute(conn, sprintf("
    UPDATE pendaftaran
    SET kode_pendaftaran = '%s'
    WHERE id_pendaftaran = %d
  ", kode_unik[i], pendaftaran_db$id_pendaftaran[i]))
}

# 9 Simulasi Penilaian 
set.seed(42)
penyisihan <- pendaftaran_db %>%
  mutate(tahap = "Penyisihan",
         nilai = sample(70:90, n(), replace = TRUE)) %>%
  arrange(desc(nilai)) %>%
  mutate(peringkat = row_number()) %>%
  select(id_pendaftaran, tahap, nilai, peringkat)

semifinal <- penyisihan %>%
  slice_max(nilai, n = 3) %>%
  mutate(tahap = "Semifinal",
         nilai = sample(80:95, 3),
         peringkat = row_number())

final <- semifinal %>%
  slice_max(nilai, n = 2) %>%
  mutate(tahap = "Final",
         nilai = sample(85:100, 2),
         peringkat = row_number())

penilaian <- bind_rows(penyisihan, semifinal, final)
dbWriteTable(conn, "penilaian", penilaian, append = TRUE)

# 10 Fungsi Visualisasi Tiap Tahap
tampil_visual_tahap <- function(tahap_nama, warna = "Set2") {
  data <- dbGetQuery(conn, paste0("
    SELECT m.nama, p.nilai, p.peringkat
    FROM penilaian p
    JOIN pendaftaran d ON p.id_pendaftaran = d.id_pendaftaran
    JOIN mahasiswa m ON d.id_mahasiswa = m.id_mahasiswa
    WHERE tahap = '", tahap_nama, "'
    ORDER BY p.peringkat ASC;
  "))
  
  print(paste(" Hasil Tahap:", tahap_nama))
  print(data)
  
  ggplot(data, aes(x = reorder(nama, nilai), y = nilai, fill = nama)) +
    geom_col(width = 0.6, show.legend = FALSE) +
    geom_text(aes(label = nilai), vjust = -0.5, size = 4) +
    scale_fill_brewer(palette = warna) +
    labs(title = paste(" Nilai Tahap", tahap_nama),
         x = "Nama Peserta", y = "Nilai") +
    theme_minimal(base_size = 13)
}

# Menampilkan Visualisasi
tampil_visual_tahap("Penyisihan", "Pastel1")
## [1] " Hasil Tahap: Penyisihan"
##                  nama nilai peringkat
## 1  Fitriani Nurhaliza    87         1
## 2        Andi Saputra    86         2
## 3       Guntur Mahesa    86         3
## 4        Hani Oktavia    84         4
## 5       Dimas Hidayat    79         5
## 6      Ilham Ramadhan    76         6
## 7        Bunga Melati    74         7
## 8        Eka Prasetya    73         8
## 9        Joko Santoso    73         9
## 10      Citra Lestari    70        10
## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette Pastel1 is 9
## Returning the palette you asked for with that many colors

tampil_visual_tahap("Semifinal", "Set2")
## [1] " Hasil Tahap: Semifinal"
##                 nama nilai peringkat
## 1 Fitriani Nurhaliza    88         1
## 2       Andi Saputra    84         2
## 3      Guntur Mahesa    93         3

tampil_visual_tahap("Final", "Set1")
## [1] " Hasil Tahap: Final"
##                 nama nilai peringkat
## 1      Guntur Mahesa    88         1
## 2 Fitriani Nurhaliza    94         2