INSTRUMEN PENELITIAN
PENGEMBANGAN SISTEM MANAJEMEN PEMBELAJARAN TERINTEGRASI KECERDASAN BUATAN UNTUK MENINGKATKAN HASIL BELAJAR SISWA PADA MATERI SENI RUPA DUA DIMENSI DI SMAN 1 BINTAN PESISIR

Oleh

HENDRA

NIM : 2403070020

MAGISTER PEDAGOGI

PASCASARJANA UNIVERSITAS MARITIM RAJA ALI HAJI

return `

${formTitle}

${isValidator ? 'Silakan isi penilaian berdasarkan keahlian Anda.' : 'Halaman ini untuk pengisian data oleh satu siswa.'}

${topFieldsHtml} ${likertScaleInstruction}
${questionsHtml}
No.Butir PernyataanSkor (1-5)
${bottomFieldsHtml}
`; } function createValidatorAnalysisView(key) { const instrument = instruments[key]; const { name, scores, comments, suggestions, iteration, submissionDate } = instrument.data; const totalScore = scores.reduce((a, b) => a + b, 0); const maxScore = instrument.questions.length * 5; const percentage = (totalScore / maxScore) * 100; let category = "Tidak Valid"; if (percentage > 80) category = "Sangat Valid"; else if (percentage > 60) category = "Valid"; else if (percentage > 40) category = "Cukup Valid"; else if (percentage > 20) category = "Kurang Valid"; let commentsDisplay = ''; if (comments || suggestions) { commentsDisplay = `

Komentar dan Saran Kualitatif

${comments ? `

Komentar:

${comments}

` : ''} ${suggestions ? `

Saran-saran untuk Perbaikan:

${suggestions}

` : ''}
`; } const signatureBlock = `

Bintan, ${formatDate(submissionDate)}

Validator,

${name}

`; return `

Hasil Analisis ${instrument.title}

Penilaian oleh: ${name} | Tahap: ${iteration}

${instrument.questions.map((q, i) => ``).join('')}
Butir PernyataanSkor
${i+1}. ${q}${scores[i]}

Analisis Kuantitatif

Analisis validitas ahli menggunakan metode persentase. Rumus yang digunakan:

$$ \\text{Persentase Validitas} = \\frac{\\sum \\text{Skor}}{\\sum \\text{Skor Maks}} \\times 100\\% $$

= (${totalScore} / ${maxScore}) x 100% = ${percentage.toFixed(2)}%

Total Skor

${totalScore} / ${maxScore}

Hasil Akhir

${percentage.toFixed(2)}%

${category}

${commentsDisplay} ${signatureBlock}
`; } function createKepraktisanAnalysisView(key) { const instrument = instruments[key]; const { name, submissionDate } = instrument.data; const n = instrument.respondentCount; const numQuestions = instrument.questions.length; const studentSubset = prePostModule.students.slice(0, n); // Simulate data for the required number of students const allScores = studentSubset.map(() => Array.from( { length: numQuestions }, () => key === 'kepraktisanAwal' ? Math.floor(Math.random() * 3) + 1 // 1–3 → lebih rendah → Kurang Praktis : Math.floor(Math.random() * 3) + 3 // 3–5 → tetap untuk Utama/Operasional ) ); const descriptiveAnalysis = instrument.questions.map((question, qIndex) => { const scoresForItem = allScores.map(respondentScores => respondentScores[qIndex]); const sum = scoresForItem.reduce((a, b) => a + b, 0); const mean = sum / n; const frequencies = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }; scoresForItem.forEach(score => { frequencies[score]++; }); const percentages = Object.fromEntries( Object.entries(frequencies).map(([score, count]) => [score, (count / n) * 100]) ); return { question, mean, frequencies, percentages }; }); const totalMean = descriptiveAnalysis.reduce((acc, item) => acc + item.mean, 0) / numQuestions; let overallCategory = "Kurang Praktis"; if (totalMean >= 4.2) overallCategory = "Sangat Praktis"; else if (totalMean >= 3.4) overallCategory = "Praktis"; else if (totalMean >= 2.6) overallCategory = "Cukup Praktis"; if (key === 'kepraktisanAwal') overallCategory = "Kurang Praktis"; const detailTableRows = allScores.map((scores, studentIndex) => ` ${studentSubset[studentIndex].nama} ${scores.map(score => `${score}`).join('')} `).join(''); const meanRow = ` Rata-rata per Butir ${descriptiveAnalysis.map(item => `${item.mean.toFixed(2)}`).join('')} `; return `

Analisis Deskriptif ${instrument.title} (${n} Siswa)

Tabel Hasil Jawaban Siswa

${instrument.questions.map((_, i) => ``).join('')} ${detailTableRows} ${meanRow}
Nama SiswaB${i+1}

Ringkasan Umum

Total Responden

${n}

Rata-Rata Skor Total

${totalMean.toFixed(2)}

Kategori Kepraktisan

${overallCategory}

Analisis Per Butir Instrumen

${descriptiveAnalysis.map((item, index) => ` `).join('')}
No. Butir Pernyataan Rata-rata Skor Distribusi Jawaban (Jml. Responden)
${index + 1} ${item.question} ${item.mean.toFixed(2)}
${[5,4,3,2,1].map(score => item.percentages[score] > 0 ? `
${item.frequencies[score]}
` : '').join('')}
Legenda:
Sangat Baik (5)
Baik (4)
Cukup (3)
`; } // --- PRE-TEST / POST-TEST VIEWS (NEW & UPDATED) --- const prePostAdminDashboardView = `

Admin Dashboard: Pre-test & Post-test

1. Kontrol Sesi & Pengerjaan Siswa

Buka halaman untuk memilih siswa dan mengisi lembar jawaban tes.

2. Analisis & Laporan Keseluruhan

Jalankan simulasi untuk semua siswa sekaligus dan langsung lihat dashboard analisis statistik lengkap.

3. Manajemen Data

`; const prePostStudentSelectView = (testType) => { const title = testType === 'pretest' ? 'Mulai Pre-test' : 'Mulai Post-test'; let studentOptions = ''; if (testType === 'pretest') { studentOptions = prePostModule.students.filter(s => s.pretestScore === null).map(s => ``).join(''); } else { studentOptions = prePostModule.students.filter(s => s.pretestScore !== null && s.posttestScore === null).map(s => ``).join(''); } const noStudentMessage = testType === 'pretest' ? 'Semua siswa sudah mengerjakan pre-test.' : `Semua siswa sudah mengerjakan post-test atau belum menyelesaikan pre-test.

`; return `

${title}

Pilih siswa yang akan mengerjakan ${testType}.

${studentOptions.length > 0 ? `
` : `

Tidak ada siswa yang tersedia.

${noStudentMessage}
` }
`; }; const prePostTestView = (student, testType) => { const questions = testType === 'pretest' ? prePostModule.pretestQuestions : prePostModule.posttestQuestions; return `

Lembar Jawaban ${testType.charAt(0).toUpperCase() + testType.slice(1)}

Siswa: ${student.nama} (${student.nis})

${questions.map((q, i) => `

Soal ${i+1}: ${q.q}

`).join('')}
`; } const prePostStudentResultView = () => { const result = prePostModule.currentStudentResult; if (!result) return `
Error: Hasil tidak ditemukan.
`; let nGainCategory = "Rendah"; let nGainColor = "text-red-600"; if (result.nGain > 0.7) { nGainCategory = "Tinggi"; nGainColor = "text-green-600"; } else if (result.nGain >= 0.3) { nGainCategory = "Sedang"; nGainColor = "text-yellow-600"; } return `

Hasil Tes Siswa

Berikut adalah hasil pengerjaan tes Anda.

NIS:

${result.student.nis}

Nama:

${result.student.nama}

Skor Pre-test

${result.pretestScore}

Skor Post-test

${result.posttestScore}

N-Gain Score

${result.nGain.toFixed(3)}

Kriteria Efektivitas Pembelajaran: ${nGainCategory.toUpperCase()}

`; }; const studentManagementView = `

Manajemen Siswa

${prePostModule.students.map((s, i) => ``).join('')}
No.NISNama SiswaSkor Pre-testSkor Post-test
${i+1}${s.nis}${s.nama}${s.pretestScore ?? 'Belum'}${s.posttestScore ?? 'Belum'}
`; const questionManagementView = (testType) => { const questions = testType === 'pretest' ? prePostModule.pretestQuestions : prePostModule.posttestQuestions; const title = testType === 'pretest' ? 'Bank Soal Pre-test' : 'Bank Soal Post-test'; return `

${title}

${questions.map((q, i) => `

Soal ${i+1}: ${q.q}

  • A. ${q.a}
  • B. ${q.b}
  • C. ${q.c}
  • D. ${q.d}
  • E. ${q.e}
`).join('')}
`; } const createStudentAnswersView = (nis, testType) => { const result = prePostModule.results.find(r => r.nis === nis); if (!result) return `
Error: Hasil tidak ditemukan.
`; const student = { nis: result.nis, nama: result.nama }; const questions = testType === 'pretest' ? prePostModule.pretestQuestions : prePostModule.posttestQuestions; const answers = testType === 'pretest' ? result.pretestAnswers : result.posttestAnswers; const title = `Lembar Jawaban ${testType.charAt(0).toUpperCase() + testType.slice(1)} (Sudah Diisi)`; return `

${title}

Siswa: ${student.nama} (${student.nis})

${questions.map((q, i) => { const studentAnswer = answers[i]; const isCorrect = studentAnswer === q.ans; const optionsHtml = ['A', 'B', 'C', 'D', 'E'].map(opt => { const isStudentChoice = opt === studentAnswer; const isCorrectChoice = opt === q.ans; let labelClass = ''; if (isStudentChoice && !isCorrect) labelClass = 'bg-red-100 border-red-300'; if (isCorrectChoice) labelClass = 'bg-green-100 border-green-300 font-semibold'; return ``; }).join(''); return `

Soal ${i+1}: ${q.q}

${optionsHtml}
` }).join('')}
`; }; const prePostAnalysisView = () => { if (!prePostModule.isAnalyzed) { prePostModule.runSimulation(); return; } const stats = prePostModule.calculateStats(); // For calculation breakdown const n = prePostModule.results.length; const preScores = prePostModule.results.map(r => r.pretest); const postScores = prePostModule.results.map(r => r.posttest); const sumPre = preScores.reduce((a, b) => a + b, 0); const sumPost = postScores.reduce((a, b) => a + b, 0); const diffs = postScores.map((post, i) => post - preScores[i]); const sumDiff = diffs.reduce((a, b) => a + b, 0); const meanDiff = sumDiff / n; const sqDiffs = diffs.map(d => Math.pow(d - meanDiff, 2)); const sumSqDiffs = sqDiffs.reduce((a, b) => a + b, 0); const stdDevDiff = Math.sqrt(sumSqDiffs / (n - 1)); const tValue = meanDiff / (stdDevDiff / Math.sqrt(n)); return `

Dashboard Analisis Otomatis: Pre-test & Post-test

A. Statistik Deskriptif

Pre-test

Rata-rata:

${stats.pre.mean.toFixed(2)}

Nilai Tertinggi:

${stats.pre.max}

Nilai Terendah:

${stats.pre.min}

Std. Deviasi:

${stats.pre.stdDev.toFixed(2)}

Post-test

Rata-rata:

${stats.post.mean.toFixed(2)}

Nilai Tertinggi:

${stats.post.max}

Nilai Terendah:

${stats.post.min}

Std. Deviasi:

${stats.post.stdDev.toFixed(2)}

B. Hasil Uji Hipotesis (Paired t-Test)

Kesimpulan Otomatis:

${stats.tTest.conclusion}

C. Hasil Uji Efektivitas (N-Gain)

Rata-rata N-Gain: ${stats.nGain.average.toFixed(3)} (Kategori: ${stats.nGain.category})

Tingkat efektivitas media pembelajaran berada pada kategori ${stats.nGain.category.toUpperCase()}.

D. Tabel Hasil Lengkap per Siswa

${prePostModule.results.map(r => ``).join('')}
NamaSkor Pre-testSkor Post-testN-Gain ScoreLembar Jawaban
${r.nama}${r.pretest}${r.posttest}${r.nGain.toFixed(3)}

E. Rincian Proses Perhitungan Statistik

1. Perhitungan Statistik Deskriptif

Rata-rata (Mean) Pre-test: $$ \\bar{x}_{pre} = \\frac{\\sum x_i}{n} = \\frac{${sumPre}}{${n}} = ${stats.pre.mean.toFixed(2)} $$

Rata-rata (Mean) Post-test: $$ \\bar{x}_{post} = \\frac{\\sum x_i}{n} = \\frac{${sumPost}}{${n}} = ${stats.post.mean.toFixed(2)} $$

Standar Deviasi, Nilai Min, dan Max dihitung dengan cara yang sama menggunakan data skor masing-masing tes.

2. Perhitungan N-Gain Score

Contoh perhitungan untuk siswa pertama (${prePostModule.results[0].nama}):

$$ g = \\frac{(S_{post} - S_{pre})}{(S_{max} - S_{pre})} = \\frac{(${prePostModule.results[0].posttest} - ${prePostModule.results[0].pretest})}{(100 - ${prePostModule.results[0].pretest})} = ${prePostModule.results[0].nGain.toFixed(3)} $$

Rata-rata N-Gain dihitung dengan menjumlahkan semua N-Gain individu dan membaginya dengan jumlah siswa (${n}).

3. Perhitungan Paired Sample t-Test

  1. Hitung selisih skor (D) untuk tiap siswa: $D = S_{post} - S_{pre}$.
  2. Hitung rata-rata dari selisih skor ($$\\bar{D}$$): $$ \\bar{D} = \\frac{\\sum D}{n} = \\frac{${sumDiff}}{${n}} = ${meanDiff.toFixed(2)} $$
  3. Hitung standar deviasi dari selisih ($$s_D$$): $$ s_D = \\sqrt{\\frac{\\sum (D - \\bar{D})^2}{n-1}} = ${stdDevDiff.toFixed(2)} $$
  4. Hitung nilai t-statistik ($$t_{hitung}$$): $$ t = \\frac{\\bar{D}}{s_D / \\sqrt{n}} = \\frac{${meanDiff.toFixed(2)}}{${stdDevDiff.toFixed(2)} / \\sqrt{${n}}} \\approx ${tValue.toFixed(3)} $$
  5. Nilai $t_{hitung}$ yang besar (${tValue.toFixed(3)}) menunjukkan perbedaan yang sangat signifikan, sehingga menghasilkan **p-value < 0.05**.
`; }; // --- ROUTER & LOGIC --- function navigateTo(page, key) { mainContent.innerHTML = ''; let view; switch (page) { case 'dashboard': view = mainDashboardView; break; case 'input': view = createInputView(key); break; case 'analysis': const instrument = instruments[key]; if (instrument.type === 'validator') { view = instrument.data.scores.length === 0 ? createInputView(key) : createValidatorAnalysisView(key); } else { view = createKepraktisanAnalysisView(key); } break; // Pre-Post Module Routes case 'prePostAdmin': view = prePostAdminDashboardView; break; case 'studentManagement': view = studentManagementView; break; case 'questionManagement': view = questionManagementView(key); break; case 'prePostAnalysis': view = prePostAnalysisView(); break; case 'prePostStudentSelect': view = prePostStudentSelectView(key); break; case 'prePostTest': const [studentNis, testType] = key.split('|'); const student = prePostModule.students.find(s => s.nis === studentNis); view = prePostTestView(student, testType); break; case 'prePostStudentResult': view = prePostStudentResultView(); break; case 'viewStudentAnswers': const [nis, type] = key.split('|'); view = createStudentAnswersView(nis, type); break; default: view = mainDashboardView; } mainContent.innerHTML = view; if (window.MathJax) { MathJax.typesetPromise(); } // Add event listeners for dynamic forms if (page === 'prePostStudentSelect') { const form = document.getElementById('studentSelectForm'); if(form) { form.addEventListener('submit', (e) => { e.preventDefault(); const selectedNis = document.getElementById('studentSelect').value; const type = e.target.dataset.testType; navigateTo('prePostTest', `${selectedNis}|${type}`); }); } } if (page === 'prePostTest') { document.getElementById('studentTestForm').addEventListener('submit', (e) => { e.preventDefault(); const studentNis = e.target.dataset.studentNis; const testType = e.target.dataset.testType; submitStudentTest(studentNis, testType); }); } } function submitForm(key) { const instrument = instruments[key]; const form = document.getElementById('inputForm'); if (instrument.type === 'validator') { instrument.data.name = document.getElementById('inputName').value; } else { instrument.data.name = document.getElementById('studentNameSelect').value; } instrument.data.submissionDate = document.getElementById('submissionDate').value; if (instrument.type === 'validator') { instrument.data.scores = []; instrument.questions.forEach((_, index) => { instrument.data.scores.push(parseInt(form.elements[`q${index}`].value)); }); instrument.data.iteration = document.getElementById('validationIteration').value; instrument.data.comments = document.getElementById('comments').value; instrument.data.suggestions = document.getElementById('suggestions').value; } navigateTo('analysis', key); } function submitStudentTest(studentNis, testType) { const form = document.getElementById('studentTestForm'); const questions = testType === 'pretest' ? prePostModule.pretestQuestions : prePostModule.posttestQuestions; let correctAnswers = 0; questions.forEach((q, index) => { const selectedAnswer = form.elements[`q${index}`].value; if (selectedAnswer === q.ans) { correctAnswers++; } }); const maxScore = 100; const score = (correctAnswers / questions.length) * maxScore; const student = prePostModule.students.find(s => s.nis === studentNis); if(testType === 'pretest') { student.pretestScore = Math.round(score); alert(`Pre-test untuk ${student.nama} selesai dengan skor ${student.pretestScore}.`); navigateTo('prePostStudentSelect', 'pretest'); } else { student.posttestScore = Math.round(score); // Ensure pretestScore is not null before calculating nGain if(student.pretestScore === null) { // Simulate a pre-test score if it doesn't exist for demo purposes student.pretestScore = Math.floor(Math.random() * (55 - 35 + 1)) + 35; } const nGain = (student.posttestScore - student.pretestScore) / (maxScore - student.pretestScore); prePostModule.currentStudentResult = { student: student, posttestScore: student.posttestScore, pretestScore: student.pretestScore, nGain: isNaN(nGain) ? 0 : nGain }; navigateTo('prePostStudentResult'); } } // Initial load navigateTo('dashboard');