def teka_teki_teko( batas) :
"" "
Fungsi yang mencetak angka dari 1 sampai batas dengan aturan khusus
:param batas: bilangan batas (unsigned integer, minimal 20)
:raises ValueError: jika batas tidak memenuhi kriteria
:raises TypeError: jika batas bukan integer
" ""
# Validasi tipe data
if not isinstance( batas, int ) :
raise TypeError
( "Parameter batas harus berupa integer" )
# Validasi nilai minimum dan unsigned (positif)
if batas < 0 :
raise ValueError
( "Parameter batas harus berupa unsigned integer (positif)" )
if batas < 20 :
raise ValueError
( "Parameter batas harus memiliki nilai paling sedikit 20" )
# Loop dari 1 sampai batas
for i in range( 1 , batas + 1 ) :
output = ""
# Cek pembagian dengan 2, 3, dan 5
if i % 2 == 0 :
output += "Teka"
if i % 3 == 0 :
output += "Teki"
if i % 5 == 0 :
output += "Teko"
# Jika tidak ada yang habis dibagi, cetak angka
if output == "" :
output = str( i)
print( output)
# Testing dan contoh penggunaan
if __name__ == "__main__" :
print( "=== TESTING FUNGSI TEKA TEKI TEKO ===\n " )
# Test case valid
try:
print( "Test dengan batas 30:" )
teka_teki_teko( 30 )
print( )
except ( ValueError, TypeError) as e:
print( f"Error: {e}\n " )
# Test case dengan input invalid
test_cases = [
( "string" , "Input bukan integer" ) ,
( - 5 , "Input negatif" ) ,
( 15 , "Input kurang dari 20" ) ,
( 19 , "Input tepat di bawah minimum" )
]
print( "=== TESTING ERROR HANDLING ===" )
for test_input, description in test_cases:
try:
print( f"\n Test {description} ({test_input}):" )
teka_teki_teko( test_input)
except ( ValueError, TypeError) as e:
print( f"Error berhasil ditangkap: {e}" )
ZGVmIHRla2FfdGVraV90ZWtvKGJhdGFzKToKICAgICIiIgogICAgRnVuZ3NpIHlhbmcgbWVuY2V0YWsgYW5na2EgZGFyaSAxIHNhbXBhaSBiYXRhcyBkZW5nYW4gYXR1cmFuIGtodXN1cwogICAgCiAgICA6cGFyYW0gYmF0YXM6IGJpbGFuZ2FuIGJhdGFzICh1bnNpZ25lZCBpbnRlZ2VyLCBtaW5pbWFsIDIwKQogICAgOnJhaXNlcyBWYWx1ZUVycm9yOiBqaWthIGJhdGFzIHRpZGFrIG1lbWVudWhpIGtyaXRlcmlhCiAgICA6cmFpc2VzIFR5cGVFcnJvcjogamlrYSBiYXRhcyBidWthbiBpbnRlZ2VyCiAgICAiIiIKICAgICMgVmFsaWRhc2kgdGlwZSBkYXRhCiAgICBpZiBub3QgaXNpbnN0YW5jZShiYXRhcywgaW50KToKICAgICAgICByYWlzZSBUeXBlRXJyb3IoIlBhcmFtZXRlciBiYXRhcyBoYXJ1cyBiZXJ1cGEgaW50ZWdlciIpCiAgICAKICAgICMgVmFsaWRhc2kgbmlsYWkgbWluaW11bSBkYW4gdW5zaWduZWQgKHBvc2l0aWYpCiAgICBpZiBiYXRhcyA8IDA6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiUGFyYW1ldGVyIGJhdGFzIGhhcnVzIGJlcnVwYSB1bnNpZ25lZCBpbnRlZ2VyIChwb3NpdGlmKSIpCiAgICAKICAgIGlmIGJhdGFzIDwgMjA6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiUGFyYW1ldGVyIGJhdGFzIGhhcnVzIG1lbWlsaWtpIG5pbGFpIHBhbGluZyBzZWRpa2l0IDIwIikKICAgIAogICAgIyBMb29wIGRhcmkgMSBzYW1wYWkgYmF0YXMKICAgIGZvciBpIGluIHJhbmdlKDEsIGJhdGFzICsgMSk6CiAgICAgICAgb3V0cHV0ID0gIiIKICAgICAgICAKICAgICAgICAjIENlayBwZW1iYWdpYW4gZGVuZ2FuIDIsIDMsIGRhbiA1CiAgICAgICAgaWYgaSAlIDIgPT0gMDoKICAgICAgICAgICAgb3V0cHV0ICs9ICJUZWthIgogICAgICAgIGlmIGkgJSAzID09IDA6CiAgICAgICAgICAgIG91dHB1dCArPSAiVGVraSIKICAgICAgICBpZiBpICUgNSA9PSAwOgogICAgICAgICAgICBvdXRwdXQgKz0gIlRla28iCiAgICAgICAgCiAgICAgICAgIyBKaWthIHRpZGFrIGFkYSB5YW5nIGhhYmlzIGRpYmFnaSwgY2V0YWsgYW5na2EKICAgICAgICBpZiBvdXRwdXQgPT0gIiI6CiAgICAgICAgICAgIG91dHB1dCA9IHN0cihpKQogICAgICAgIAogICAgICAgIHByaW50KG91dHB1dCkKCiMgVGVzdGluZyBkYW4gY29udG9oIHBlbmdndW5hYW4KaWYgX19uYW1lX18gPT0gIl9fbWFpbl9fIjoKICAgIHByaW50KCI9PT0gVEVTVElORyBGVU5HU0kgVEVLQSBURUtJIFRFS08gPT09XG4iKQogICAgCiAgICAjIFRlc3QgY2FzZSB2YWxpZAogICAgdHJ5OgogICAgICAgIHByaW50KCJUZXN0IGRlbmdhbiBiYXRhcyAzMDoiKQogICAgICAgIHRla2FfdGVraV90ZWtvKDMwKQogICAgICAgIHByaW50KCkKICAgIGV4Y2VwdCAoVmFsdWVFcnJvciwgVHlwZUVycm9yKSBhcyBlOgogICAgICAgIHByaW50KGYiRXJyb3I6IHtlfVxuIikKICAgIAogICAgIyBUZXN0IGNhc2UgZGVuZ2FuIGlucHV0IGludmFsaWQKICAgIHRlc3RfY2FzZXMgPSBbCiAgICAgICAgKCJzdHJpbmciLCAiSW5wdXQgYnVrYW4gaW50ZWdlciIpLAogICAgICAgICgtNSwgIklucHV0IG5lZ2F0aWYiKSwKICAgICAgICAoMTUsICJJbnB1dCBrdXJhbmcgZGFyaSAyMCIpLAogICAgICAgICgxOSwgIklucHV0IHRlcGF0IGRpIGJhd2FoIG1pbmltdW0iKQogICAgXQogICAgCiAgICBwcmludCgiPT09IFRFU1RJTkcgRVJST1IgSEFORExJTkcgPT09IikKICAgIGZvciB0ZXN0X2lucHV0LCBkZXNjcmlwdGlvbiBpbiB0ZXN0X2Nhc2VzOgogICAgICAgIHRyeToKICAgICAgICAgICAgcHJpbnQoZiJcblRlc3Qge2Rlc2NyaXB0aW9ufSAoe3Rlc3RfaW5wdXR9KToiKQogICAgICAgICAgICB0ZWthX3Rla2lfdGVrbyh0ZXN0X2lucHV0KQogICAgICAgIGV4Y2VwdCAoVmFsdWVFcnJvciwgVHlwZUVycm9yKSBhcyBlOgogICAgICAgICAgICBwcmludChmIkVycm9yIGJlcmhhc2lsIGRpdGFuZ2thcDoge2V9IikKICAgIAogIA==