Lompat ke konten
dokumentasi.id
Commit a5cb8ad
v2
Star20 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

4

Validasi Opsi dan Loop Menu

Menu GhostTrack tidak menyimpan nomor opsinya di dalam kode pencetak menu. Nomor itu hidup di list options, dan satu fungsi kecil is_in_options menjadi satu-satunya gerbang yang memutuskan apakah sebuah nomor boleh dijalankan. Bagian ini membahas kedua struktur tersebut, nilai ValueError yang dilempar ketika validasi gagal, dan cara loop menu menyusun ulang dirinya setelah satu opsi selesai.

options sebagai sumber kebenaran nomor menu

options adalah list berisi lima dict, masing-masing dengan tiga kunci: num, text, dan func. GhostTR.py:180-207

numtextfunc
1IP TrackerIP_Track
2Show Your IPshowIP
3Phone Number TrackerphoneGW
4Username TrackerTrackLu
0Exitexit

Karena kelima entri memiliki kunci func, cabang print('No function detected') di dalam call_option tidak pernah tercapai dengan data saat ini. GhostTR.py:222-227

Dua konsumen membaca list yang sama. option_text merangkai seluruh entri menjadi baris teks berbentuk [ num ] text lewat satu loop, GhostTR.py:245-249, dan option menuliskan hasilnya ke stderr setelah banner besar, GhostTR.py:259-272. Banner itu sendiri dan dekorator is_option yang menempel padanya dibahas di Banner dan Dekorator is_option.

Gerbang is_in_options

is_in_options(num) melakukan pencarian linear atas options. Ia mengembalikan True pada entri pertama yang opt['num'] == num, dan False bila loop selesai tanpa kecocokan. GhostTR.py:252-256

Fungsi itu dipanggil sekali saja, di baris pertama call_option, sebagai penjaga sebelum dispatch. call_option(opt) memeriksa if not is_in_options(opt) lalu melempar ValueError('Option not found'); bila lolos, ia menelusuri options sekali lagi untuk mencari entri dengan option['num'] == opt dan memanggil option['func'](). GhostTR.py:219-227 Akibatnya satu pilihan yang valid melewati list options dua kali: sekali untuk validasi, sekali untuk dispatch.

Dua jalur ValueError

Titik validasiFungsi penjagaKondisi gagalReaksi
opt = int(input(...))maininput bukan angkacetak Please input number, lalu main() lagi
is_in_options(opt)call_optionnomor tidak ada di optionscetak isi ValueError, tunggu 2 detik, lalu execute_option(opt) lagi

Jalur pertama terjadi sebelum execute_option dipanggil: konversi int pada baris input berada di dalam try milik main, dan handler-nya mencetak Please input number, menunggu time.sleep(2), lalu memanggil main() kembali. GhostTR.py:296-306 Jalur kedua terjadi lebih dalam: call_option melempar ValueError('Option not found') GhostTR.py:219-227, dan execute_option menangkapnya, mencetak pesan error itu apa adanya, lalu mengulang pemanggilan. GhostTR.py:230-242 Penanganan KeyboardInterrupt pada kedua lapisan itu dibahas terpisah di Penanganan Error dan Interupsi.

Siklus keadaan loop menu

Kedua jalur ValueError di atas sama-sama berujung pada pemanggilan ulang fungsi, bukan pada while loop. Diagram berikut merangkum perpindahan keadaan dari menu tampil sampai opsi selesai dijalankan.

stateDiagram-v2
    [*] --> main
    main --> ReadInput: "option() lalu input()"
    ReadInput --> main: "ValueError: Please input number"
    ReadInput --> call_option: "opt = int(input(...))"
    call_option --> is_in_options: "cek nomor"
    is_in_options --> not_found: "False"
    not_found --> not_found: "ValueError: Option not found"
    is_in_options --> dispatch: "True"
    dispatch --> main: "Press enter to continue"
    dispatch --> [*]: "num 0: exit"
    style ReadInput fill:#8b5cf6,color:#fff
    style is_in_options fill:#f59e0b,color:#000
    style dispatch fill:#2d7d46,color:#fff
    style not_found fill:#dc2626,color:#fff
%% fig: Siklus keadaan loop menu GhostTrack
%% desc: Input diubah menjadi int, divalidasi is_in_options, lalu dispatch; kegagalan memutar kembali ke keadaan sebelumnya, bukan keluar dari loop.
Fig. 1: Siklus keadaan loop menu GhostTrackInput diubah menjadi int, divalidasi is_in_options, lalu dispatch; kegagalan memutar kembali ke keadaan sebelumnya, bukan keluar dari loop.

Setelah satu opsi selesai dijalankan, execute_option menunggu satu input(f'\n{Wh}[ {Gr}+ {Wh}] {Gr}Press enter to continue') lalu memanggil main() sehingga seluruh menu digambar ulang. GhostTR.py:230-234 Karena main sendiri memanggil option(), setiap putaran menu menambah satu frame pemanggilan baru, bukan mengembalikan kendali ke pemanggil sebelumnya. Loop berakhir hanya lewat opsi num 0 yang memanggil exit, atau lewat KeyboardInterrupt yang ditangkap di blok penjaga modul. GhostTR.py:309-315

⚠️ execute_option(opt) memanggil dirinya sendiri dengan opt yang sama persis setelah menangkap ValueError. Karena opt tidak pernah dibaca ulang dari input, kondisi gagal yang sama berulang: call_option melempar ValueError('Option not found') lagi, pesannya dicetak, time.sleep(2) dijalankan, dan rekursi berlanjut tanpa batas. Satu-satunya jalan keluar dari keadaan itu adalah KeyboardInterrupt. GhostTR.py:230-242