• PEMROGRAMAN WEB DINAMIS

    Pengertian web dinamis adalah suatu web yang konten atau isinya dapat berubah-ubah setiap saat. Sebab dalam teknologi pembuatan web dinamis sudah dirancang semudah mungkin bagi pemakai atau user yang menggunakan web tersebut..

  • SIMULASI DAN KOMUNIKASI DIGITAL

    Suatu proses peniruan dalam bentuk visual yang dideskripsikan menyerupai kata, gambar dan grafis..

  • SISTEM KOMPUTER

    Sistem komputer adalah suatu jaringan elektronik yang terdiri dari perangkat lunak dan perangkat keras yang melakukan tugas tertentu (menerima input, memproses input, menyimpan perintah-perintah, dan menyediakan output dalam bentuk informasi). Selain itu dapat pula diartikan sebagai elemen-elemen yang terkait untuk menjalankan suatu aktivitas dengan menggunakan komputer..

  • DASAR DESAIN GRAPIS

    Banyak yang berpikiran kalau desain yang baik adalah yang membutuhkan jam kerja yang banyak, membutuhkan skill tinggi dan aplikasi yang mahal. Ya, memang, tapi sebenarnya desain yang baik adalah desain yang sederhana, yang membuat setiap orang yang melihatnya mudah menangkap maksud dari sebuah bentuk visual tersebut..

  • BASIS DATA

    Pangkalan data atau basis data (bahasa Inggris: database) adalah kumpulan informasi yang disimpan di dalam komputer secara sistematik sehingga dapat diperiksa menggunakan suatu program komputer untuk memperoleh informasi dari basis data tersebut. Perangkat lunak yang digunakan untuk mengelola dan memanggil kueri (query) basis data disebut sistem manajemen basis data (database management system, DBMS). Sistem basis data dipelajari dalam ilmu informasi.

📱 Materi & Praktikum Flutter: Struktur Kontrol Project | Aplikasi Penilaian Siswa


📱 Materi & Praktikum Flutter: Struktur Kontrol

Project: Aplikasi Penilaian Siswa


🎯 Tujuan Pembelajaran

Setelah mempelajari materi ini, mahasiswa mampu:

  1. Memahami & menerapkan if, switch, loop, break, continue, nested loop

  2. Mengimplementasikan struktur kontrol dalam aplikasi Flutter nyata

  3. Membangun Aplikasi Penilaian yang valid sesuai kebutuhan dunia nyata


📚 BAGIAN 1: MATERI (Dengan Konteks Nyata)

1.1 if — Pengambilan Keputusan

Konteks nyata: Guru menentukan status kelulusan berdasarkan nilai.

dart
// Logika kelulusan sekolah
int nilai = 78;
String status;

if (nilai >= 75) {
  status = "LULUS";
} else if (nilai >= 60) {
  status = "REMEDIAL";
} else {
  status = "TIDAK LULUS";
}

Analogi: Seperti satpam sekolah — hanya membuka pintu jika syarat terpenuhi.


1.2 switch — Pemilihan Berdasarkan Kategori

Konteks nyata: Konversi nilai angka ke huruf (A, B, C, D, E).

dart
int nilai = 85;
String grade;

switch (nilai ~/ 10) {   // pembagian bulat
  case 10:
  case 9:
    grade = "A";
    break;
  case 8:
    grade = "B";
    break;
  case 7:
    grade = "C";
    break;
  case 6:
    grade = "D";
    break;
  default:
    grade = "E";
}
// grade = "B"

Kapan pakai switch? Saat kondisi berupa pilihan diskrit (bukan rentang).


1.3 loop — Perulangan

Konteks nyata: Menghitung rata-rata nilai dari banyak siswa.

dart
List<int> nilaiSiswa = [80, 75, 90, 65, 85];

// for — tahu jumlah pastinya
int total = 0;
for (int i = 0; i < nilaiSiswa.length; i++) {
  total += nilaiSiswa[i];
}
double rataRata = total / nilaiSiswa.length; // 79.0

// for-in — lebih bersih untuk koleksi
int total2 = 0;
for (var n in nilaiSiswa) {
  total2 += n;
}

// while — kondisi dinamis
int attempt = 0;
while (attempt < 3) {
  print("Percobaan login ke-${attempt + 1}");
  attempt++;
}

1.4 break — Hentikan Paksa

Konteks nyata: Guru berhenti input nilai jika siswa sudah tidak hadir.

dart
List<int?> nilai = [80, 75, null, 90, 85];

for (var n in nilai) {
  if (n == null) {
    print("Data tidak lengkap, hentikan input.");
    break;   // keluar dari loop
  }
  print("Nilai: $n");
}
// Output: 80, 75, "hentikan input"

1.5 continue — Lewati Iterasi

Konteks nyata: Lewati siswa yang tidak punya nilai (null) saat menghitung rata-rata.

dart
List<int?> nilai = [80, 75, null, 90, null, 85];
int total = 0;
int count = 0;

for (var n in nilai) {
  if (n == null) continue;   // skip yang null
  total += n;
  count++;
}
print("Rata-rata: ${total / count}");  // (80+75+90+85)/4 = 82.5

Perbedaan kunci:

breakcontinue
Menghentikan seluruh loopMelewati 1 iterasi saja

1.6 Nested Loop — Loop di Dalam Loop

Konteks nyata: Membuat tabel nilai (siswa × mata pelajaran).

dart
List<String> siswa = ["Budi", "Sari", "Andi"];
List<String> mapel = ["Matematika", "IPA", "B. Inggris"];
Map<String, List<int>> nilai = {
  "Budi": [80, 75, 90],
  "Sari": [85, 88, 92],
  "Andi": [70, 65, 78],
};

for (var s in siswa) {
  print("=== $s ===");
  for (int j = 0; j < mapel.length; j++) {
    print("${mapel[j]}: ${nilai[s]![j]}");
  }
}

Analogi: Menelusuri baris × kolom tabel — seperti membaca rapor per baris (siswa) lalu per kolom (mapel).


🛠️ BAGIAN 2: PRAKTIKUM — APLIKASI PENILAIAN

📋 Spesifikasi Aplikasi

Nama: SIAKNILAI — Sistem Input & Analisis Nilai Siswa

Fitur (mapping struktur kontrol):

FiturStruktur Kontrol
Input nilai & tentukan status kelulusanif
Tampilkan grade A-Eswitch
Hitung total & rata-rata seluruh siswaloop
Stop input bila nilai di luar 0-100break
Skip siswa tanpa nama saat analisiscontinue
Tampilkan tabel siswa × mapelnested loop

📁 Struktur Project

text
lib/
├── main.dart
├── models/
│   └── siswa.dart
├── services/
│   └── penilaian_service.dart    ← LOGIKA STRUKTUR KONTROL
└── screens/
    ├── home_screen.dart
    └── hasil_screen.dart

1️⃣ models/siswa.dart

dart
class Siswa {
  final String nama;
  final Map<String, int> nilaiMapel; // mapel -> nilai

  Siswa({required this.nama, required this.nilaiMapel});

  double get rataRata {
    int total = 0;
    for (var n in nilaiMapel.values) {
      total += n;
    }
    return nilaiMapel.isEmpty ? 0 : total / nilaiMapel.length;
  }

  String get status {
    if (rataRata >= 75) return "LULUS";
    else if (rataRata >= 60) return "REMEDIAL";
    else return "TIDAK LULUS";
  }

  String get grade {
    switch (rataRata ~/ 10) {
      case 10:
      case 9: return "A";
      case 8: return "B";
      case 7: return "C";
      case 6: return "D";
      default: return "E";
    }
  }
}

2️⃣ services/penilaian_service.dart — Inti Praktikum

dart
import '../models/siswa.dart';

class PenilaianService {
  // ===== LOOP + IF + BREAK: hitung rata-rata kelas, stop jika data invalid =====
  static Map<String, dynamic> hitungKelas(List<Siswa> daftar) {
    int total = 0;
    int jumlahNilai = 0;
    int jumlahSiswa = 0;

    for (var siswa in daftar) {
      // SKIP siswa tanpa nama (CONTINUE)
      if (siswa.nama.trim().isEmpty) {
        continue;
      }

      // VALIDASI: nilai harus 0-100, jika tidak → BREAK
      bool invalid = siswa.nilaiMapel.values.any((n) => n < 0 || n > 100);
      if (invalid) {
        print("⚠️ Data tidak valid pada ${siswa.nama}, hentikan perhitungan.");
        break;
      }

      // NESTED LOOP: jumlahkan setiap nilai mapel
      for (var nilai in siswa.nilaiMapel.values) {
        total += nilai;
        jumlahNilai++;
      }
      jumlahSiswa++;
    }

    double rataKelas = jumlahNilai == 0 ? 0 : total / jumlahNilai;

    return {
      "total": total,
      "jumlahNilai": jumlahNilai,
      "jumlahSiswa": jumlahSiswa,
      "rataKelas": rataKelas,
      "predikatKelas": _predikatKelas(rataKelas), // SWITCH
    };
  }

  // ===== SWITCH: predikat rata-rata kelas =====
  static String _predikatKelas(double rata) {
    if (rata >= 90) return "Sangat Baik";
    if (rata >= 75) return "Baik";
    if (rata >= 60) return "Cukup";
    return "Perlu Bimbingan";
  }

  // ===== NESTED LOOP: ranking siswa =====
  static List<Siswa> urutkanRanking(List<Siswa> daftar) {
    final hasil = List<Siswa>.from(daftar);
    // bubble sort sederhana
    for (int i = 0; i < hasil.length; i++) {
      for (int j = i + 1; j < hasil.length; j++) {
        if (hasil[j].rataRata > hasil[i].rataRata) {
          final tmp = hasil[i];
          hasil[i] = hasil[j];
          hasil[j] = tmp;
        }
      }
    }
    return hasil;
  }
}

3️⃣ screens/home_screen.dart

dart
import 'package:flutter/material.dart';
import '../models/siswa.dart';
import '../services/penilaian_service.dart';
import 'hasil_screen.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});
  
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _namaCtrl = TextEditingController();
  final _matCtrl = TextEditingController();
  final _ipaCtrl = TextEditingController();
  final _bindoCtrl = TextEditingController();

  final List<Siswa> _daftarSiswa = [];

  void _tambahSiswa() {
    // VALIDASI dengan IF
    if (_namaCtrl.text.trim().isEmpty) {
      _snack("Nama tidak boleh kosong");
      return;
    }

    final mat = int.tryParse(_matCtrl.text) ?? -1;
    final ipa = int.tryParse(_ipaCtrl.text) ?? -1;
    final bindo = int.tryParse(_bindoCtrl.text) ?? -1;

    if (mat < 0 || mat > 100 || ipa < 0 || ipa > 100 || bindo < 0 || bindo > 100) {
      _snack("Nilai harus 0-100");
      return;
    }

    setState(() {
      _daftarSiswa.add(Siswa(
        nama: _namaCtrl.text.trim(),
        nilaiMapel: {"Matematika": mat, "IPA": ipa, "B. Indonesia": bindo},
      ));
    });

    _namaCtrl.clear();
    _matCtrl.clear();
    _ipaCtrl.clear();
    _bindoCtrl.clear();
  }

  void _snack(String msg) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg)));
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("SIAKNILAI — Input Nilai")),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: _namaCtrl,
              decoration: const InputDecoration(labelText: "Nama Siswa"),
            ),
            Row(
              children: [
                Expanded(child: _numField(_matCtrl, "Mat")),
                const SizedBox(width: 8),
                Expanded(child: _numField(_ipaCtrl, "IPA")),
                const SizedBox(width: 8),
                Expanded(child: _numField(_bindoCtrl, "B.Indo")),
              ],
            ),
            const SizedBox(height: 12),
            Row(
              children: [
                Expanded(
                  child: ElevatedButton(
                    onPressed: _tambahSiswa,
                    child: const Text("Tambah"),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: ElevatedButton(
                    style: ElevatedButton.styleFrom(
                      backgroundColor: Colors.green,
                    ),
                    onPressed: _daftarSiswa.isEmpty
                        ? null
                        : () {
                            final analisis =
                                PenilaianService.hitungKelas(_daftarSiswa);
                            final ranking =
                                PenilaianService.urutkanRanking(_daftarSiswa);
                            Navigator.push(
                              context,
                              MaterialPageRoute(
                                builder: (_) => HasilScreen(
                                  analisis: analisis,
                                  ranking: ranking,
                                ),
                              ),
                            );
                          },
                    child: const Text("Analisis"),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16),
            Expanded(
              child: ListView.builder(
                itemCount: _daftarSiswa.length,
                itemBuilder: (_, i) {
                  final s = _daftarSiswa[i];
                  return Card(
                    child: ListTile(
                      title: Text(s.nama),
                      subtitle: Text(
                        "Mat:${s.nilaiMapel['Matematika']}  "
                        "IPA:${s.nilaiMapel['IPA']}  "
                        "BIndo:${s.nilaiMapel['B. Indonesia']}",
                      ),
                      trailing: Chip(
                        label: Text("${s.grade} | ${s.status}"),
                        backgroundColor: s.status == "LULUS"
                            ? Colors.green.shade100
                            : s.status == "REMEDIAL"
                                ? Colors.orange.shade100
                                : Colors.red.shade100,
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _numField(TextEditingController c, String label) {
    return TextField(
      controller: c,
      keyboardType: TextInputType.number,
      decoration: InputDecoration(labelText: label),
    );
  }
}

4️⃣ screens/hasil_screen.dart

dart
import 'package:flutter/material.dart';
import '../models/siswa.dart';

class HasilScreen extends StatelessWidget {
  final Map<String, dynamic> analisis;
  final List<Siswa> ranking;

  const HasilScreen({
    super.key,
    required this.analisis,
    required this.ranking,
  });

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Hasil Analisis")),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Ringkasan kelas
            Card(
              color: Colors.blue.shade50,
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text("Rata-rata Kelas: ${analisis['rataKelas'].toStringAsFixed(2)}",
                        style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                    Text("Predikat: ${analisis['predikatKelas']}"),
                    Text("Jumlah Siswa Dianalisis: ${analisis['jumlahSiswa']}"),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),
            const Text("🏆 Ranking Siswa",
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
            const SizedBox(height: 8),
            Expanded(
              child: ListView.builder(
                itemCount: ranking.length,
                itemBuilder: (_, i) {
                  final s = ranking[i];
                  return ListTile(
                    leading: CircleAvatar(child: Text("${i + 1}")),
                    title: Text(s.nama),
                    subtitle: Text(
                      "Rata-rata: ${s.rataRata.toStringAsFixed(1)} | "
                      "Grade ${s.grade} | ${s.status}",
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

5️⃣ main.dart

dart
import 'package:flutter/material.dart';
import 'screens/home_screen.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'SIAKNILAI',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const HomeScreen(),
    );
  }
}

🧪 BAGIAN 3: LEMBAR PRAKTIKUM

🔬 Uji Coba Wajib (Isi tabel hasil)

NoSkenario UjiStruktur Kontrol DiujiHasil yang Diharapkan
1Input Budi: 80, 75, 90if, switchGrade B, Status LULUS
2Input Sari: 85, 88, 92ifLULUS, ranking 1
3Input nilai 150if validasiSnackbar error
4Hapus nama, klik Analisiscontinue (di service)Siswa dilewati
5Tambah siswa nilai 200 lalu Analisisbreak (di service)Perhitungan berhenti, output peringatan
6Tambah 3 siswa, lihat rankingnested loop (sort)Urutan benar

✏️ Tugas Pengembangan (Mandiri)

  1. Modifikasi switch: Ubah grade menjadi skala A+, A, A-, B+... (min. 6 case).

  2. Tambah while: Buat menu "input cepat" yang terus meminta nilai sampai user menekan tombol "Selesai".

  3. Nested loop ekspor: Buat fitur cetak seluruh rapor dalam format teks (setiap siswa × mapel).

  4. break dengan label: Hentikan outer loop saat menemukan siswa dengan nilai di bawah 50.


📖 RANGKUMAN KONSEP

StrukturKapan DipakaiContoh di Project
if2+ jalur keputusanStatus kelulusan, validasi input
switchBanyak pilihan diskritGrade A-E
for / for-inJumlah iterasi diketahuiHitung total nilai
whileIterasi sampai kondisi(Tugas) input berulang
breakHentikan seluruh loopStop saat data invalid
continueLewati 1 iterasiSkip siswa tanpa nama
Nested loop2 dimensi (baris×kolom)Ranking (sort), tabel nilai

💡 KESIMPULAN

Aplikasi SIAKNILAI membuktikan bahwa struktur kontrol bukan konsep abstrak — ia adalah jantung logika bisnis aplikasi nyata. Setiap tombol di aplikasi penilaian di baliknya ada if, switch, loop, break, continue, dan nested loop yang bekerja bersama.

Pesan kunci: Kuasai struktur kontrol = kuasai cara komputer "berpikir" menyelesaikan masalah nyata.


Aktifitas pengembangan info bisa tambahkan:

  • 🎥 Script video demo langkah praktikum

  • 📝 Soal kuis/asesmen (pilihan ganda + essay)

  • 🔌 Versi integrasi API (simpan ke backend)

  • 🎨 Desain UI lebih kompleks (grafik nilai dengan fl_chart)

Tinggal pilih beberapa atau semuanya, kita akan lanjutkan! 🚀

Share:

Chat Admin

Chat via WhatsApp

Categories

Blogger Tricks

Blogger Themes