Python & AI Tutorials Logo
Pemrograman Python

4. Bekerja dengan Angka

Di Bab 3, kamu belajar cara membuat variabel dan bekerja dengan tipe numerik dasar Python: integer (bilangan bulat) dan floating-point (float). Sekarang saatnya membuat angka-angka itu bekerja. Di bab ini, kamu akan belajar cara melakukan perhitungan, mengombinasikan operasi, dan menggunakan alat bawaan Python untuk bekerja dengan data numerik.

Angka adalah bagian yang fundamental dalam pemrograman. Entah kamu menghitung total, memproses pengukuran, mengelola inventaris, atau menganalisis data, kamu akan perlu melakukan operasi aritmetika. Python membuat operasi numerik menjadi sederhana dan intuitif, tetapi ada beberapa detail penting yang perlu dipahami—terutama tentang bagaimana berbagai jenis pembagian bekerja, bagaimana operator berinteraksi, dan bagaimana perilaku bilangan floating-point.

Di akhir bab ini, kamu akan lebih percaya diri melakukan perhitungan, memahami perilaku operator, dan menggunakan fungsi numerik Python untuk menyelesaikan masalah dunia nyata.

4.1) Aritmetika Dasar: Penjumlahan, Pengurangan, dan Perkalian

Mari mulai dengan operasi aritmetika yang paling mendasar. Python menggunakan simbol yang sudah familiar untuk matematika dasar, dan operasi-operasi ini bekerja seperti yang kamu harapkan dari aritmetika sehari-hari.

4.1.1) Penjumlahan dengan Operator +

Operator + menjumlahkan dua angka. Operator ini bekerja baik dengan integer maupun floating-point:

python
# basic_addition.py
# Adding integers
total = 15 + 27
print(total)  # Output: 42
 
# Adding floats
price = 19.99 + 5.50
print(price)  # Output: 25.49
 
# You can add multiple numbers in one expression
sum_total = 10 + 20 + 30 + 40
print(sum_total)  # Output: 100

Penjumlahan sangat langsung, tetapi ada satu detail penting: ketika kamu menambahkan integer dan float, Python secara otomatis mengonversi hasilnya menjadi float untuk mempertahankan presisi desimal:

python
# mixed_addition.py
result = 10 + 3.5
print(result)  # Output: 13.5
print(type(result))  # Output: <class 'float'>

Konversi otomatis ini terjadi karena float bisa merepresentasikan bilangan bulat dan desimal, sementara integer tidak bisa merepresentasikan desimal. Python memilih tipe yang tidak akan menghilangkan informasi.

4.1.2) Pengurangan dengan Operator -

Operator - mengurangkan angka kedua dari angka pertama:

python
# basic_subtraction.py
# Subtracting integers
difference = 100 - 42
print(difference)  # Output: 58
 
# Subtracting floats
remaining = 50.75 - 12.25
print(remaining)  # Output: 38.5
 
# Subtraction can produce negative results
balance = 20 - 35
print(balance)  # Output: -15

Seperti penjumlahan, pengurangan juga mempromosikan integer menjadi float ketika kamu mencampur tipe:

python
# mixed_subtraction.py
result = 100 - 0.01
print(result)  # Output: 99.99
print(type(result))  # Output: <class 'float'>

4.1.3) Perkalian dengan Operator *

Operator * mengalikan dua angka:

python
# basic_multiplication.py
# Multiplying integers
product = 6 * 7
print(product)  # Output: 42
 
# Multiplying floats
area = 3.5 * 2.0
print(area)  # Output: 7.0
 
# Multiplying by zero always gives zero
result = 1000 * 0
print(result)  # Output: 0

Perkalian mengikuti aturan konversi tipe yang sama. Ketika kamu mengalikan integer dengan float, hasilnya adalah float:

python
# mixed_multiplication.py
result = 5 * 2.5
print(result)  # Output: 12.5
print(type(result))  # Output: <class 'float'>
 
# Even if the result is a whole number
result = 4 * 2.0
print(result)  # Output: 8.0 (note the .0)
print(type(result))  # Output: <class 'float'>

Perhatikan pada contoh terakhir bahwa meski 4 × 2.0 sama dengan 8, Python merepresentasikannya sebagai 8.0 karena salah satu operannya adalah float. Tipe hasil bergantung pada tipe input, bukan pada apakah hasil matematisnya kebetulan bilangan bulat.

4.1.4) Contoh Praktis dengan Aritmetika Dasar

Mari lihat bagaimana operasi-operasi ini bekerja bersama dalam skenario yang realistis:

python
# shopping_cart.py
# Calculate a shopping cart total
item1_price = 12.99
item2_price = 8.50
item3_price = 15.00
 
subtotal = item1_price + item2_price + item3_price
print(f"Subtotal: ${subtotal}")  # Output: Subtotal: $36.49
 
tax_rate = 0.08
tax = subtotal * tax_rate
print(f"Tax: ${tax}")  # Output: Tax: $2.9192
 
total = subtotal + tax
print(f"Total: ${total}")  # Output: Total: $39.4092
python
# temperature_change.py
# Calculate temperature change
morning_temp = 45.5
afternoon_temp = 68.2
 
change = afternoon_temp - morning_temp
print(f"Temperature increased by {change} degrees")
# Output: Temperature increased by 22.7 degrees

Operasi dasar ini membentuk fondasi untuk perhitungan yang lebih kompleks. Memahami cara kerjanya—terutama bagaimana Python menangani konversi tipe—akan membantu kamu menghindari kejutan ketika programmu melakukan perhitungan.

4.2) Pembagian, Pembagian Lantai, dan Sisa: /, //, dan %

Pembagian di Python lebih bernuansa dibanding penjumlahan, pengurangan, atau perkalian. Python menyediakan tiga operator terkait pembagian yang berbeda, masing-masing memiliki tujuan yang berbeda. Memahami kapan menggunakan masing-masing sangat penting untuk menulis program yang benar.

4.2.1) Pembagian Biasa dengan /

Operator / melakukan "true division"—selalu mengembalikan hasil floating-point, bahkan saat membagi dua integer:

python
# true_division.py
# Dividing integers
result = 10 / 2
print(result)  # Output: 5.0 (note: float, not 5)
print(type(result))  # Output: <class 'float'>
 
# Division that doesn't result in a whole number
result = 10 / 3
print(result)  # Output: 3.3333333333333335
 
# Dividing floats
result = 15.5 / 2.5
print(result)  # Output: 6.2

Inti pentingnya adalah bahwa / selalu menghasilkan float, bahkan ketika kedua operan adalah integer dan hasilnya secara matematis adalah bilangan bulat. Ini memang sengaja: Python ingin pembagian berperilaku konsisten dan mempertahankan presisi desimal.

Perilaku ini berbeda dengan beberapa bahasa pemrograman lain di mana pembagian dua integer menghasilkan integer. Di Python 3, jika kamu menginginkan hasil integer, kamu perlu menggunakan pembagian lantai (yang akan kita bahas berikutnya) atau melakukan konversi eksplisit pada hasilnya.

4.2.2) Pembagian Lantai dengan //

Operator // melakukan "floor division"—ia membagi lalu membulatkan ke bawah ke bilangan bulat terdekat. Ketika kedua operan adalah integer, hasilnya adalah integer. Ketika salah satu operan adalah float, hasilnya adalah float (tapi tetap dibulatkan ke bawah):

python
# floor_division.py
# Floor division with integers
result = 10 // 3
print(result)  # Output: 3 (not 3.333...)
print(type(result))  # Output: <class 'int'>
 
# Even division still gives an integer
result = 10 // 2
print(result)  # Output: 5 (integer, not 5.0)
print(type(result))  # Output: <class 'int'>
 
# Floor division with floats gives a float
result = 10.0 // 3
print(result)  # Output: 3.0
print(type(result))  # Output: <class 'float'>

"Membulatkan ke bawah" di sini berarti bergerak menuju minus tak hingga (negative infinity), bukan sekadar menghapus bagian desimal. Ini penting untuk bilangan negatif:

python
# floor_division_negative.py
# Positive numbers: rounds down (toward negative infinity)
result = 7 // 2
print(result)  # Output: 3
 
# Negative numbers: still rounds toward negative infinity
result = -7 // 2
print(result)  # Output: -4 (not -3!)
 
# Why -4? Because -3.5 rounded down (toward negative infinity) is -4
# Think of the number line: ... -4, -3.5, -3, -2, -1, 0, 1, 2, 3, 3.5, 4 ...

Floor division berguna ketika kamu perlu membagi item menjadi kelompok atau menghitung berapa banyak unit lengkap yang muat dalam suatu kuantitas:

python
# floor_division_practical.py
# How many complete dozens in 50 eggs?
eggs = 50
eggs_per_dozen = 12
complete_dozens = eggs // eggs_per_dozen
print(f"Complete dozens: {complete_dozens}")  # Output: Complete dozens: 4
 
# How many full hours in 150 minutes?
minutes = 150
full_hours = minutes // 60
print(f"Full hours: {full_hours}")  # Output: Full hours: 2

4.2.3) Sisa (Modulo) dengan %

Operator % (disebut "modulo" atau "mod") mengembalikan sisa setelah pembagian. Operator ini menjawab pertanyaan: "Setelah dibagi, berapa sisa yang tersisa?"

python
# modulo_basic.py
# 10 divided by 3 is 3 with remainder 1
result = 10 % 3
print(result)  # Output: 1
 
# 10 divided by 2 is 5 with remainder 0 (even division)
result = 10 % 2
print(result)  # Output: 0
 
# Works with floats too
result = 10.5 % 3
print(result)  # Output: 1.5

Operator modulo sangat berguna untuk beberapa pola pemrograman umum:

Mengecek apakah sebuah angka genap atau ganjil:

python
# even_odd_check.py
number = 17
 
if number % 2 == 0:
    print(f"{number} is even")
else:
    print(f"{number} is odd")
# Output: 17 is odd

Mendapatkan sisa item:

python
# leftover_items.py
eggs = 50
eggs_per_dozen = 12
 
leftover = eggs % eggs_per_dozen
print(f"Leftover eggs: {leftover}")  # Output: Leftover eggs: 2

Membungkus nilai dalam suatu rentang (seperti aritmetika jam):

python
# clock_arithmetic.py
# What hour is it 25 hours from now? (on a 12-hour clock)
current_hour = 10
hours_later = 25
future_hour = (current_hour + hours_later) % 12
print(f"Hour: {future_hour}")  # Output: Hour: 11

4.2.4) Hubungan Antara //, %, dan /

Floor division dan modulo sangat berhubungan. Bersama-sama, keduanya memberikan hasil pembagian yang lengkap:

python
# division_relationship.py
dividend = 17
divisor = 5
 
quotient = dividend // divisor  # How many times 5 goes into 17
remainder = dividend % divisor  # What's left over
 
print(f"{dividend} ÷ {divisor} = {quotient} remainder {remainder}")
# Output: 17 ÷ 5 = 3 remainder 2
 
# You can verify: quotient * divisor + remainder should equal dividend
verification = quotient * divisor + remainder
print(f"Verification: {quotient} × {divisor} + {remainder} = {verification}")
# Output: Verification: 3 × 5 + 2 = 17

Hubungan ini selalu benar: untuk sembarang angka a dan b (dengan b tidak nol), a == (a // b) * b + (a % b).

4.2.5) Memilih Operator Pembagian yang Tepat

Berikut panduan singkat untuk memilih operator mana yang akan digunakan:

  • Gunakan / ketika kamu butuh hasil matematis yang tepat dengan desimal (paling umum dalam perhitungan)
  • Gunakan // ketika kamu ingin menghitung berapa banyak kelompok lengkap yang muat (seperti lusin, jam, halaman)
  • Gunakan % ketika kamu butuh sisa atau jumlah yang tersisa (seperti cek genap/ganjil, membungkus nilai, mencari sisa)
python
# choosing_operators.py
# Scenario: Distributing 47 candies among 6 children
 
candies = 47
children = 6
 
# How many candies per child? (use //)
per_child = candies // children
print(f"Each child gets {per_child} candies")  # Output: Each child gets 7 candies
 
# How many candies are left over? (use %)
leftover = candies % children
print(f"Leftover candies: {leftover}")  # Output: Leftover candies: 5
 
# What's the exact average? (use /)
average = candies / children
print(f"Average per child: {average}")  # Output: Average per child: 7.833333333333333

4.3) Operator Penugasan Gabungan (Augmented Assignment)

Saat pemrograman, kamu akan sering perlu memperbarui sebuah variabel dengan melakukan operasi pada nilai saat ini. Misalnya, menambahkan ke total berjalan, mengurangi dari saldo, atau mengalikan nilai dengan suatu faktor. Python menyediakan cara singkat untuk melakukan ini dengan operator penugasan gabungan (augmented assignment).

4.3.1) Apa Itu Operator Penugasan Gabungan

Operator penugasan gabungan mengombinasikan operasi aritmetika dengan penugasan. Alih-alih menulis:

python
# traditional_update.py
count = 10
count = count + 5  # Add 5 to count
print(count)  # Output: 15

Kamu bisa menulis:

python
# augmented_update.py
count = 10
count += 5  # Same as: count = count + 5
print(count)  # Output: 15

Kedua versi melakukan hal yang persis sama, tetapi versi augmented lebih ringkas dan dengan jelas menyatakan maksudnya: "tambahkan count sebesar 5."

4.3.2) Semua Operator Penugasan Gabungan

Python menyediakan operator penugasan gabungan untuk semua operasi aritmetika:

python
# all_augmented_operators.py
# Addition
x = 10
x += 5  # x = x + 5
print(f"After += 5: {x}")  # Output: After += 5: 15
 
# Subtraction
x = 10
x -= 3  # x = x - 3
print(f"After -= 3: {x}")  # Output: After -= 3: 7
 
# Multiplication
x = 10
x *= 4  # x = x * 4
print(f"After *= 4: {x}")  # Output: After *= 4: 40
 
# Division
x = 10
x /= 2  # x = x / 2
print(f"After /= 2: {x}")  # Output: After /= 2: 5.0
 
# Floor division
x = 10
x //= 3  # x = x // 3
print(f"After //= 3: {x}")  # Output: After //= 3: 3
 
# Modulo
x = 10
x %= 3  # x = x % 3
print(f"After %= 3: {x}")  # Output: After %= 3: 1
 
# Exponentiation (we'll see more about ** in section 4.6)
x = 2
x **= 3  # x = x ** 3 (2 to the power of 3)
print(f"After **= 3: {x}")  # Output: After **= 3: 8

4.3.3) Penggunaan Umum Operator Penugasan Gabungan

Operator penugasan gabungan sangat berguna dalam beberapa pola pemrograman umum:

Mengakumulasi total:

python
# accumulating_total.py
total = 0
total += 10  # Add first item
total += 25  # Add second item
total += 15  # Add third item
print(f"Total: {total}")  # Output: Total: 50

Menghitung kemunculan:

python
# counting.py
count = 0
# Imagine these happen as we process data
count += 1  # Found one
count += 1  # Found another
count += 1  # Found another
print(f"Count: {count}")  # Output: Count: 3

Memperbarui saldo:

python
# balance_updates.py
balance = 100.00
balance -= 25.50  # Purchase
balance += 50.00  # Deposit
balance -= 10.00  # Purchase
print(f"Balance: ${balance}")  # Output: Balance: $114.5

Menerapkan operasi berulang:

python
# repeated_operations.py
value = 100
value *= 1.1  # Increase by 10%
value *= 1.1  # Increase by 10% again
value *= 1.1  # Increase by 10% again
print(f"Value after three 10% increases: {value}")
# Output: Value after three 10% increases: 133.10000000000002

4.3.4) Detail Penting tentang Penugasan Gabungan

Penugasan gabungan membuat objek baru untuk tipe immutable:

Ingat dari Bab 3 bahwa angka itu immutable—kamu tidak bisa mengubah nilai sebuah angka, hanya membuat angka baru. Ketika kamu menulis x += 5, Python membuat objek angka baru dan menugaskannya ke x. Objek angka lama dibuang (kita akan membahas konsep ini lebih dalam di Bab 17 saat kita membahas model objek Python):

python
# augmented_with_immutables.py
x = 10
print(id(x))  # Output: (some memory address)
 
x += 5
print(id(x))  # Output: (different memory address)

Untuk sekarang, cukup pahami bahwa x += 5 setara dengan x = x + 5—ini hanya penulisan singkat yang nyaman, bukan operasi yang fundamentalnya berbeda.

Kamu tidak bisa memakai penugasan gabungan sebelum variabel itu ada:

python
# augmented_requires_existing.py
# This will cause an error:
# count += 1  # NameError: name 'count' is not defined
 
# You must initialize the variable first:
count = 0
count += 1  # Now this works
print(count)  # Output: 1

Konversi tipe terjadi dengan cara yang sama:

python
# augmented_type_conversion.py
x = 10  # integer
x += 2.5  # Add a float
print(x)  # Output: 12.5
print(type(x))  # Output: <class 'float'>

Hasilnya mengikuti aturan konversi tipe yang sama seperti operator biasa: jika kamu mencampur integer dan float, hasilnya adalah float.

4.3.5) Kapan Menggunakan Penugasan Gabungan

Gunakan operator penugasan gabungan kapan pun kamu memperbarui sebuah variabel berdasarkan nilai saat ini. Operator ini membuat kode kamu:

  • Lebih ringkas: x += 5 lebih pendek daripada x = x + 5
  • Lebih mudah dibaca: Maksudnya langsung terlihat jelas
  • Lebih kecil kemungkinan terjadi kesalahan: Kamu tidak perlu mengulang nama variabel

Bandingkan dua versi ini:

python
# comparison.py
# Without augmented assignment
accumulated_distance_in_kilometers = 0
accumulated_distance_in_kilometers = accumulated_distance_in_kilometers + 10
accumulated_distance_in_kilometers = accumulated_distance_in_kilometers + 25
 
# With augmented assignment
accumulated_distance_in_kilometers = 0
accumulated_distance_in_kilometers += 10
accumulated_distance_in_kilometers += 25

Versi augmented lebih jelas dan lebih kecil kemungkinan terjadi salah ketik. Operator penugasan gabungan merupakan fitur kecil, tetapi sangat sering digunakan dalam kode Python nyata.

4.4) Prioritas Operator (Operator Precedence) dan Tanda Kurung

Ketika kamu menggabungkan beberapa operasi dalam satu ekspresi, Python membutuhkan aturan untuk menentukan urutan evaluasi. Apakah 2 + 3 * 4 dihitung sebagai (2 + 3) * 4 = 20 atau sebagai 2 + (3 * 4) = 14? Jawabannya bergantung pada prioritas operator—aturan yang menentukan operasi mana yang terjadi terlebih dahulu.

4.4.1) Memahami Prioritas Operator

Python mengikuti aturan prioritas yang sama seperti yang kamu pelajari di matematika: perkalian dan pembagian terjadi sebelum penjumlahan dan pengurangan. Ini sering diingat dengan akronim PEMDAS (Parentheses, Exponents, Multiplication/Division, Addition/Subtraction), meski kita akan membahas eksponen di bagian 4.6.

python
# precedence_basic.py
# Multiplication happens before addition
result = 2 + 3 * 4
print(result)  # Output: 14 (not 20)
# Python calculates: 2 + (3 * 4) = 2 + 12 = 14
 
# Division happens before subtraction
result = 10 - 8 / 2
print(result)  # Output: 6.0 (not 1.0)
# Python calculates: 10 - (8 / 2) = 10 - 4.0 = 6.0

Berikut urutan prioritas untuk operator yang sudah kita pelajari sejauh ini (dari tertinggi ke terendah):

  1. Tanda kurung () — prioritas tertinggi, selalu dievaluasi dulu
  2. Eksponensiasi ** — (akan dibahas di bagian 4.6)
  3. Perkalian, Pembagian, Floor Division, Modulo *, /, //, % — level yang sama, dievaluasi dari kiri ke kanan
  4. Penjumlahan, Pengurangan +, - — level yang sama, dievaluasi dari kiri ke kanan

Mari lihat lebih banyak contoh bagaimana prioritas bekerja:

python
# precedence_examples.py
# Multiplication before addition
result = 5 + 2 * 3
print(result)  # Output: 11 (5 + 6)
 
# Division before subtraction
result = 20 - 10 / 2
print(result)  # Output: 15.0 (20 - 5.0)
 
# Multiple operations at the same level: left to right
result = 10 - 3 + 2
print(result)  # Output: 9 ((10 - 3) + 2)
 
result = 20 / 4 * 2
print(result)  # Output: 10.0 ((20 / 4) * 2)

4.4.2) Menggunakan Tanda Kurung untuk Mengontrol Urutan

Tanda kurung menimpa (override) prioritas default. Operasi di dalam tanda kurung selalu dilakukan terlebih dahulu, tidak peduli operator apa yang digunakan:

python
# parentheses_override.py
# Without parentheses: multiplication first
result = 2 + 3 * 4
print(result)  # Output: 14
 
# With parentheses: addition first
result = (2 + 3) * 4
print(result)  # Output: 20
 
# Another example
result = 10 - 8 / 2
print(result)  # Output: 6.0
 
result = (10 - 8) / 2
print(result)  # Output: 1.0

Kamu bisa menumpuk (nest) tanda kurung untuk membuat ekspresi yang lebih kompleks. Python mengevaluasi dari tanda kurung yang paling dalam ke luar:

python
# nested_parentheses.py
result = ((2 + 3) * 4) - 1
print(result)  # Output: 19
# Step 1: (2 + 3) = 5
# Step 2: (5 * 4) = 20
# Step 3: 20 - 1 = 19
 
result = 2 * (3 + (4 - 1))
print(result)  # Output: 12
# Step 1: (4 - 1) = 3
# Step 2: (3 + 3) = 6
# Step 3: 2 * 6 = 12

4.4.3) Saat Operator Memiliki Prioritas yang Sama

Ketika beberapa operator dengan level prioritas yang sama muncul dalam suatu ekspresi, Python mengevaluasinya dari kiri ke kanan (ini disebut "left associativity"):

python
# left_to_right.py
# Addition and subtraction: left to right
result = 10 - 3 + 2 - 1
print(result)  # Output: 8
# Evaluation: ((10 - 3) + 2) - 1 = (7 + 2) - 1 = 9 - 1 = 8
 
# Multiplication and division: left to right
result = 20 / 4 * 2
print(result)  # Output: 10.0
# Evaluation: (20 / 4) * 2 = 5.0 * 2 = 10.0
 
# This matters! Different order gives different result:
result = 20 / (4 * 2)
print(result)  # Output: 2.5

4.4.4) Contoh Praktis dengan Prioritas Operator

Mari lihat skenario nyata di mana memahami prioritas itu penting:

python
# temperature_conversion.py
# Convert Fahrenheit to Celsius: C = (F - 32) * 5 / 9
fahrenheit = 98.6
 
# Correct: parentheses ensure subtraction happens first
celsius = (fahrenheit - 32) * 5 / 9
print(f"{fahrenheit}°F = {celsius}°C")
# Output: 98.6°F = 37.0°C
 
# Wrong: without parentheses, multiplication happens first
# celsius = fahrenheit - 32 * 5 / 9  # This would be wrong!
# This would calculate: fahrenheit - ((32 * 5) / 9)
python
# calculate_average.py
# Calculate average of three numbers
num1 = 85
num2 = 92
num3 = 78
 
# Correct: parentheses ensure addition happens before division
average = (num1 + num2 + num3) / 3
print(f"Average: {average}")  # Output: Average: 85.0
 
# Wrong: without parentheses, only num3 is divided by 3
# average = num1 + num2 + num3 / 3  # This would be wrong!
# This would calculate: 85 + 92 + (78 / 3) = 85 + 92 + 26.0 = 203.0
python
# discount_calculation.py
# Calculate price after discount and tax
original_price = 100.00
discount_rate = 0.20
tax_rate = 0.08
 
# Calculate discount amount
discount = original_price * discount_rate
 
# Calculate price after discount
discounted_price = original_price - discount
 
# Calculate final price with tax
final_price = discounted_price * (1 + tax_rate)
print(f"Final price: ${final_price}")  # Output: Final price: $86.4
 
# Or in one expression (using parentheses to be clear):
final_price = (original_price * (1 - discount_rate)) * (1 + tax_rate)
print(f"Final price: ${final_price}")  # Output: Final price: $86.4

4.4.5) Praktik Terbaik untuk Prioritas Operator

Gunakan tanda kurung demi kejelasan, bahkan ketika tidak wajib:

Kadang menambah tanda kurung membuat maksudmu lebih jelas, walaupun tidak mengubah hasil:

python
# clarity_with_parentheses.py
# These are equivalent, but the second is clearer:
result = 2 + 3 * 4
result = 2 + (3 * 4)  # Clearer: shows you know multiplication happens first
 
# Complex expressions benefit from parentheses:
result = (subtotal * tax_rate) + (subtotal * tip_rate)  # Clear intent

Pecah ekspresi kompleks menjadi beberapa langkah:

Ketika suatu ekspresi menjadi terlalu kompleks, sering kali lebih baik memecahnya menjadi beberapa baris:

python
# breaking_into_steps.py
# Instead of this complex one-liner:
result = ((price * quantity) * (1 - discount)) * (1 + tax)
 
# Consider breaking it into steps:
subtotal = price * quantity
discounted = subtotal * (1 - discount)
final = discounted * (1 + tax)
result = final

Versi multi-langkah lebih mudah dibaca, di-debug, dan diverifikasi. Jangan mengorbankan kejelasan demi kehematan penulisan.

Kalau ragu, gunakan tanda kurung:

Jika kamu tidak yakin tentang prioritas, tambahkan tanda kurung. Interpreter Python tidak akan keberatan, dan dirimu di masa depan (atau programmer lain yang membaca kodenya) akan berterima kasih.

Memahami prioritas operator membantu kamu menulis ekspresi yang benar dan membaca kode orang lain. Prinsip utamanya: ketika mengombinasikan operasi, pikirkan urutan evaluasi, dan gunakan tanda kurung untuk membuat maksudmu eksplisit.

4.5) Mencampur Integer dan Float dalam Ekspresi

Kamu sudah melihat bahwa Python secara otomatis menangani pencampuran integer dan float dalam operasi sederhana. Sekarang mari kita bahas perilaku ini secara lebih sistematis dan memahami aturan yang mengatur konversi tipe dalam ekspresi numerik.

4.5.1) Aturan Promosi Tipe (Type Promotion Rule)

Ketika Python melakukan operasi aritmetika yang melibatkan integer dan float, Python secara otomatis mengonversi (atau "mempromosikan") integer menjadi float sebelum melakukan operasi. Hasilnya selalu float:

python
# type_promotion.py
# Integer + Float = Float
result = 10 + 3.5
print(result)  # Output: 13.5
print(type(result))  # Output: <class 'float'>
 
# Float + Integer = Float (order doesn't matter)
result = 3.5 + 10
print(result)  # Output: 13.5
print(type(result))  # Output: <class 'float'>
 
# This applies to all arithmetic operators
result = 5 * 2.0
print(result)  # Output: 10.0 (float, not int)
print(type(result))  # Output: <class 'float'>

Mengapa Python melakukan ini? Karena float dapat merepresentasikan bilangan bulat dan desimal, sementara integer tidak bisa merepresentasikan desimal. Mengonversi ke float mempertahankan semua informasi dan menghindari hilangnya presisi.

Berikut representasi visual bagaimana Python memutuskan tipe hasil:

Yes

No

Yes

No

Operation with
int and float

Any operand
is float?

Result is float

Division
operator /?

Result is int

4.5.2) Promosi Tipe dalam Ekspresi Kompleks

Ketika sebuah ekspresi berisi beberapa operasi dengan tipe yang bercampur, Python menerapkan aturan promosi di setiap langkah:

python
# complex_mixed_types.py
# Multiple operations with mixed types
result = 10 + 3.5 * 2
print(result)  # Output: 17.0
print(type(result))  # Output: <class 'float'>
 
# What happens step by step:
# 1. 3.5 * 2 → 3.5 * 2.0 (2 promoted to float) → 7.0 (float)
# 2. 10 + 7.0 → 10.0 + 7.0 (10 promoted to float) → 17.0 (float)
 
# Another example
result = 5 / 2 + 3
print(result)  # Output: 5.5
print(type(result))  # Output: <class 'float'>
 
# Step by step:
# 1. 5 / 2 → 2.5 (division always produces float)
# 2. 2.5 + 3 → 2.5 + 3.0 (3 promoted to float) → 5.5 (float)

Begitu ada operasi dalam ekspresi yang menghasilkan float, semua operasi berikutnya yang melibatkan hasil tersebut juga akan menghasilkan float.

4.5.3) Kasus Khusus: Pembagian Biasa Selalu Menghasilkan Float

Ingat dari bagian 4.2 bahwa operator / selalu menghasilkan float, bahkan saat membagi dua integer:

python
# division_always_float.py
# Even when the result is a whole number
result = 10 / 2
print(result)  # Output: 5.0 (not 5)
print(type(result))  # Output: <class 'float'>
 
# This means any expression with / will have a float result
result = 10 / 2 + 3  # 5.0 + 3 → 5.0 + 3.0 → 8.0
print(result)  # Output: 8.0
print(type(result))  # Output: <class 'float'>

Jika kamu ingin hasil integer dari pembagian, gunakan floor division // (namun ingat, ini membulatkan ke bawah):

python
# floor_division_integer.py
# Floor division with integers produces an integer
result = 10 // 2
print(result)  # Output: 5 (integer)
print(type(result))  # Output: <class 'int'>
 
# But floor division with any float produces a float
result = 10.0 // 2
print(result)  # Output: 5.0 (float)
print(type(result))  # Output: <class 'float'>

4.5.4) Implikasi Praktis dari Pencampuran Tipe

Memahami promosi tipe membantumu memprediksi dan mengontrol tipe hasil:

python
# practical_type_mixing.py
# Calculating price per item
total_cost = 47.50
num_items = 5
 
price_per_item = total_cost / num_items  # Float / int → float
print(f"Price per item: ${price_per_item}")
# Output: Price per item: $4.75
 
# Calculating average (will be float even if inputs are integers)
total_points = 450
num_tests = 5
 
average = total_points / num_tests  # Int / int → float
print(f"Average: {average}")  # Output: Average: 90.0
 
# If you need an integer result, convert explicitly
average_rounded = int(total_points / num_tests)
print(f"Average (as integer): {average_rounded}")
# Output: Average (as integer): 90

4.5.5) Saat Hasil Integer Penting

Kadang kamu secara khusus membutuhkan hasil integer untuk penghitungan, indexing, atau operasi diskrit lainnya. Berikut cara memastikan kamu mendapat integer:

python
# ensuring_integer_results.py
# Using floor division when you need integer results
items = 47
items_per_box = 12
 
# How many complete boxes?
complete_boxes = items // items_per_box  # Integer result
print(f"Complete boxes: {complete_boxes}")
# Output: Complete boxes: 3
 
# If you use regular division, you get a float
boxes_float = items / items_per_box
print(f"Boxes (float): {boxes_float}")
# Output: Boxes (float): 3.9166666666666665
 
# Converting float to integer (truncates toward zero)
boxes_truncated = int(boxes_float)
print(f"Boxes (truncated): {boxes_truncated}")
# Output: Boxes (truncated): 3

Perhatikan perbedaannya: // membulatkan ke bawah (menuju minus tak hingga), sedangkan int() memotong (truncate) menuju nol. Untuk bilangan positif hasilnya sama, tetapi untuk bilangan negatif hasilnya berbeda:

python
# truncation_vs_floor.py
# For positive numbers: same result
print(7 // 2)    # Output: 3
print(int(7/2))  # Output: 3
 
# For negative numbers: different results
print(-7 // 2)    # Output: -4 (rounds down toward negative infinity)
print(int(-7/2))  # Output: -3 (truncates toward zero)

4.5.6) Menghindari Hasil Float yang Tak Terduga

Kadang kamu mungkin terkejut mendapatkan float ketika mengharapkan integer. Ini biasanya terjadi karena pembagian atau pencampuran tipe:

python
# unexpected_floats.py
# Calculating average - result is always float because of division
count = 10
total = 100
average = total / count
print(average)  # Output: 10.0 (float, even though it's a whole number)
 
# If you need an integer and you know it divides evenly:
average_int = total // count
print(average_int)  # Output: 10 (integer)
 
# Or convert explicitly:
average_int = int(total / count)
print(average_int)  # Output: 10 (integer)

Intinya: aturan promosi tipe Python dirancang untuk mempertahankan presisi dan menghindari kehilangan data. Ketika kamu mencampur integer dan float, atau ketika kamu menggunakan pembagian biasa, harapkan hasil float. Jika kamu butuh integer, gunakan floor division atau konversi eksplisit, tapi pahami bagaimana keduanya menangani pembulatan.

4.6) Fungsi Numerik Bawaan yang Berguna: abs(), min(), max(), dan pow()

Python menyediakan beberapa fungsi bawaan yang melakukan operasi numerik umum. Fungsi-fungsi ini bekerja dengan integer maupun float, dan merupakan alat esensial untuk pemrograman sehari-hari. Mari kita jelajahi yang paling sering digunakan.

4.6.1) Nilai Absolut dengan abs()

Fungsi abs() mengembalikan nilai absolut suatu angka—jaraknya dari nol, mengabaikan tanda:

python
# absolute_value.py
# Absolute value of negative numbers
result = abs(-42)
print(result)  # Output: 42
 
# Absolute value of positive numbers (unchanged)
result = abs(42)
print(result)  # Output: 42
 
# Works with floats too
result = abs(-3.14)
print(result)  # Output: 3.14
 
# Absolute value of zero is zero
result = abs(0)
print(result)  # Output: 0

Fungsi nilai absolut berguna setiap kali kamu peduli pada besaran (magnitude) tetapi tidak pada arah:

python
# practical_abs.py
# Calculate temperature difference (magnitude only)
morning_temp = 45.5
evening_temp = 38.2
 
difference = abs(evening_temp - morning_temp)
print(f"Temperature changed by {difference} degrees")
# Output: Temperature changed by 7.3 degrees
 
# Calculate distance between two points (always positive)
position1 = 10
position2 = 25
 
distance = abs(position2 - position1)
print(f"Distance: {distance}")  # Output: Distance: 15
 
# Works the same regardless of order
distance = abs(position1 - position2)
print(f"Distance: {distance}")  # Output: Distance: 15

4.6.2) Mencari Nilai Minimum dan Maksimum dengan min() dan max()

Fungsi min() mengembalikan nilai terkecil dari argumennya, dan max() mengembalikan nilai terbesar:

python
# min_max_basic.py
# Find minimum of two numbers
smallest = min(10, 25)
print(smallest)  # Output: 10
 
# Find maximum of two numbers
largest = max(10, 25)
print(largest)  # Output: 25
 
# Works with more than two arguments
smallest = min(5, 12, 3, 18, 7)
print(smallest)  # Output: 3
 
largest = max(5, 12, 3, 18, 7)
print(largest)  # Output: 18
 
# Works with floats and mixed types
smallest = min(3.5, 2, 4.1, 1.9)
print(smallest)  # Output: 1.9

Fungsi-fungsi ini sangat berguna untuk mencari nilai ekstrem dalam data:

python
# practical_min_max.py
# Find the best and worst test scores
test1 = 85
test2 = 92
test3 = 78
test4 = 95
 
highest_score = max(test1, test2, test3, test4)
lowest_score = min(test1, test2, test3, test4)
 
print(f"Highest score: {highest_score}")  # Output: Highest score: 95
print(f"Lowest score: {lowest_score}")    # Output: Lowest score: 78
 
# Clamp a value within a range
value = 150
minimum = 0
maximum = 100
 
# Ensure value is not below minimum
value = max(value, minimum)
# Ensure value is not above maximum
value = min(value, maximum)
 
print(f"Clamped value: {value}")  # Output: Clamped value: 100

Pola clamping (menggunakan max() dan min() bersama-sama) umum digunakan ketika kamu perlu membatasi nilai ke rentang tertentu:

python
# clamping_pattern.py
def clamp(value, min_value, max_value):
    """Constrain value to be within [min_value, max_value]"""
    return max(min_value, min(value, max_value))
 
# Test the clamp function
print(clamp(150, 0, 100))   # Output: 100 (too high, clamped to max)
print(clamp(-10, 0, 100))   # Output: 0 (too low, clamped to min)
print(clamp(50, 0, 100))    # Output: 50 (within range, unchanged)

4.6.3) Eksponensiasi dengan pow()

Fungsi pow() mempangkatkan sebuah angka. Python juga memiliki operator ** untuk eksponensiasi, yang lebih umum digunakan, tetapi pow() menawarkan beberapa fitur tambahan:

python
# exponentiation.py
# Using the ** operator (most common)
result = 2 ** 3  # 2 to the power of 3
print(result)  # Output: 8
 
result = 5 ** 2  # 5 squared
print(result)  # Output: 25
 
# Using pow() function (equivalent)
result = pow(2, 3)
print(result)  # Output: 8
 
result = pow(5, 2)
print(result)  # Output: 25
 
# Negative exponents give fractions
result = 2 ** -3  # 1 / (2^3) = 1/8
print(result)  # Output: 0.125
 
# Fractional exponents give roots
result = 9 ** 0.5  # Square root of 9
print(result)  # Output: 3.0
 
result = 8 ** (1/3)  # Cube root of 8
print(result)  # Output: 2.0

Fungsi pow() bisa menerima argumen ketiga opsional untuk eksponensiasi modular (berguna dalam kriptografi dan teori bilangan, tetapi di luar cakupan aritmetika dasar):

python
# modular_exponentiation.py
# pow(base, exponent, modulus) computes (base ** exponent) % modulus efficiently
result = pow(2, 10, 100)  # (2^10) % 100
print(result)  # Output: 24
 
# This is more efficient than computing separately for large numbers:
# result = (2 ** 10) % 100  # Same result, but less efficient for large numbers

Untuk kebanyakan penggunaan sehari-hari, operator ** lebih nyaman daripada pow():

python
# practical_exponentiation.py
# Calculate compound interest: A = P(1 + r)^t
principal = 1000  # Initial amount
rate = 0.05       # 5% interest rate
years = 10
 
amount = principal * (1 + rate) ** years
print(f"Amount after {years} years: ${amount:.2f}")
# Output: Amount after 10 years: $1628.89
 
# Calculate area of a square
side_length = 5
area = side_length ** 2
print(f"Area: {area}")  # Output: Area: 25
 
# Calculate volume of a cube
side_length = 3
volume = side_length ** 3
print(f"Volume: {volume}")  # Output: Volume: 27

4.6.4) Mengombinasikan Fungsi-Fungsi Bawaan

Fungsi-fungsi ini bekerja dengan baik bersama untuk menyelesaikan masalah umum:

python
# combining_functions.py
# Find the range (difference between max and min)
values = [15, 42, 8, 23, 37]
value_range = max(values) - min(values)
print(f"Range: {value_range}")  # Output: Range: 34
 
# Note: We're using a list here (we'll learn about lists in detail in Chapter 13)
# For now, just understand that max() and min() can work with a list of values
 
# Calculate distance between two points in 2D space
x1, y1 = 3, 4
x2, y2 = 6, 8
 
# Distance formula: sqrt((x2-x1)^2 + (y2-y1)^2)
# We'll use ** for squaring (square root comes in section 4.11)
distance_squared = (x2 - x1) ** 2 + (y2 - y1) ** 2
distance = distance_squared ** 0.5  # Square root via fractional exponent
print(f"Distance: {distance}")  # Output: Distance: 5.0

Fungsi-fungsi bawaan ini adalah alat dasar dalam pemrograman Python. Mereka efisien, sudah teruji, dan bekerja konsisten di berbagai tipe numerik. Gunakan mereka kapan pun kamu butuh operasi-operasi umum ini—tidak perlu menulis implementasi sendiri.

4.7) Membulatkan Angka dengan round()

Saat bekerja dengan bilangan floating-point, kamu sering perlu membulatkan hasil ke jumlah tempat desimal tertentu untuk tampilan, perhitungan, atau penyimpanan. Fungsi round() di Python menyediakan kemampuan ini.

4.7.1) Pembulatan Dasar dengan round()

Fungsi round() menerima sebuah angka dan membulatkannya ke integer terdekat:

python
# basic_rounding.py
# Round to nearest integer
result = round(3.7)
print(result)  # Output: 4
 
result = round(3.2)
print(result)  # Output: 3
 
# Exactly halfway rounds to nearest even number (banker's rounding)
result = round(2.5)
print(result)  # Output: 2 (rounds to even)
 
result = round(3.5)
print(result)  # Output: 4 (rounds to even)
 
# Negative numbers work too
result = round(-3.7)
print(result)  # Output: -4
 
result = round(-3.2)
print(result)  # Output: -3

Perhatikan perilaku ketika membulatkan angka yang tepat di tengah antara dua integer (seperti 2.5 atau 3.5). Python menggunakan "round half to even" (sering disebut "banker's rounding"), yang membulatkan ke bilangan genap terdekat. Ini mengurangi bias dalam operasi pembulatan berulang. Untuk kebanyakan pemrograman sehari-hari, detail ini jarang menjadi masalah, tapi bagus untuk diketahui.

4.7.2) Membulatkan ke Jumlah Tempat Desimal Tertentu

Fungsi round() menerima argumen kedua opsional yang menentukan berapa banyak tempat desimal yang dipertahankan:

python
# decimal_places.py
# Round to 2 decimal places
result = round(3.14159, 2)
print(result)  # Output: 3.14
 
# Round to 1 decimal place
result = round(3.14159, 1)
print(result)  # Output: 3.1
 
# Round to 3 decimal places
result = round(2.71828, 3)
print(result)  # Output: 2.718
 
# You can round to 0 decimal places (same as omitting the argument)
result = round(3.7, 0)
print(result)  # Output: 4.0 (note: returns float, not int)

Saat kamu menentukan jumlah tempat desimal, round() mengembalikan float (bahkan jika kamu membulatkan ke 0 tempat desimal). Ketika argumen kedua dihilangkan, fungsi ini mengembalikan integer.

4.7.3) Penggunaan Praktis Pembulatan

Pembulatan sangat penting untuk menampilkan uang, pengukuran, dan nilai lain di mana presisi berlebihan tidak perlu atau membingungkan:

python
# practical_rounding.py
# Display prices with 2 decimal places
price = 19.99
tax_rate = 0.08
total = price * (1 + tax_rate)
 
print(f"Total (unrounded): ${total}")  # Output: Total (unrounded): $21.5892
print(f"Total (rounded): ${round(total, 2)}")  # Output: Total (rounded): $21.59
 
# Calculate and display average
total_score = 456
num_tests = 7
average = total_score / num_tests
 
print(f"Average (unrounded): {average}")  # Output: Average (unrounded): 65.14285714285714
print(f"Average (rounded): {round(average, 2)}")  # Output: Average (rounded): 65.14
 
# Round measurements to reasonable precision
distance_meters = 123.456789
distance_rounded = round(distance_meters, 1)
print(f"Distance: {distance_rounded} meters")  # Output: Distance: 123.5 meters

4.7.4) Pembulatan vs Truncating vs Floor/Ceiling

Penting untuk memahami bahwa pembulatan berbeda dari truncating (menghapus tempat desimal) atau operasi floor/ceiling:

python
# rounding_vs_others.py
value = 3.7
 
# Rounding: nearest integer
rounded = round(value)
print(f"Rounded: {rounded}")  # Output: Rounded: 4
 
# Truncating: remove decimal part (convert to int)
truncated = int(value)
print(f"Truncated: {truncated}")  # Output: Truncated: 3
 
# We'll see floor and ceil in section 4.11, but briefly:
# Floor: largest integer <= value (always rounds down)
# Ceiling: smallest integer >= value (always rounds up)

Untuk bilangan negatif, perbedaannya lebih mencolok:

python
# negative_rounding.py
value = -3.7
 
# Rounding: nearest integer
rounded = round(value)
print(f"Rounded: {rounded}")  # Output: Rounded: -4
 
# Truncating: toward zero
truncated = int(value)
print(f"Truncated: {truncated}")  # Output: Truncated: -3
 
# Floor (rounds down toward negative infinity): -4
# Ceiling (rounds up toward positive infinity): -3

4.7.5) Pertimbangan Penting Saat Membulatkan

Presisi floating-point dapat menyebabkan kejutan:

Karena cara komputer merepresentasikan bilangan floating-point (yang akan kita bahas di bagian 4.10), pembulatan tidak selalu menghasilkan tepat seperti yang kamu harapkan:

python
# rounding_surprises.py
# Sometimes rounding doesn't give the exact decimal you expect
value = 2.675
rounded = round(value, 2)
print(rounded)  # Output: 2.67 (not 2.68 as you might expect)
 
# This happens because 2.675 can't be represented exactly in binary floating-point
# The actual stored value is slightly less than 2.675

Untuk kebanyakan tujuan praktis, ini bukan masalah. Tetapi jika kamu bekerja dengan perhitungan finansial di mana aritmetika desimal yang tepat penting, kamu mungkin memerlukan modul decimal Python (yang tidak akan kita bahas di buku ini, tapi bagus untuk diketahui keberadaannya).

Membulatkan untuk tampilan vs perhitungan:

Sering kali kamu ingin membulatkan hanya untuk tampilan, sambil mempertahankan presisi penuh untuk perhitungan:

python
# rounding_for_display.py
price1 = 19.99
price2 = 15.49
tax_rate = 0.08
 
# Calculate with full precision
subtotal = price1 + price2
tax = subtotal * tax_rate
total = subtotal + tax
 
# Round only for display
print(f"Subtotal: ${round(subtotal, 2)}")  # Output: Subtotal: $35.48
print(f"Tax: ${round(tax, 2)}")            # Output: Tax: $2.84
print(f"Total: ${round(total, 2)}")        # Output: Total: $38.32
 
# The variables still contain full precision
print(f"Total (full precision): ${total}")
# Output: Total (full precision): $38.3184

Fungsi round() adalah salah satu fungsi bawaan Python yang paling sering digunakan. Gunakan ketika kamu perlu menyajikan hasil numerik dalam format yang mudah dibaca atau ketika kamu perlu membatasi presisi untuk tujuan tertentu.

4.8) Pola Numerik Umum (counter, total, rata-rata)

Sekarang kamu sudah memahami operasi numerik dan fungsi-fungsi Python, mari kita jelajahi pola umum yang akan sering kamu gunakan dalam program nyata. Pola-pola ini menjadi blok bangunan untuk memproses data numerik.

4.8.1) Counter: Melacak Berapa Banyak

Counter adalah variabel yang melacak berapa kali sesuatu terjadi. Kamu menginisialisasinya ke nol dan menambahkannya setiap kali suatu kejadian terjadi:

python
# basic_counter.py
# Count how many numbers we've processed
count = 0  # Initialize counter
 
# Process first number
count += 1
print(f"Processed {count} number(s)")  # Output: Processed 1 number(s)
 
# Process second number
count += 1
print(f"Processed {count} number(s)")  # Output: Processed 2 number(s)
 
# Process third number
count += 1
print(f"Processed {count} number(s)")  # Output: Processed 3 number(s)

Dalam program nyata, kamu biasanya menggunakan counter di dalam loop (loop) (yang akan kita pelajari di Bab 10 dan 11). Untuk sekarang, pahami polanya: mulai dari nol, tambah satu setiap kali.

Counter bisa melacak berbagai jenis kejadian:

python
# multiple_counters.py
# Track different categories
even_count = 0
odd_count = 0
 
# Check number 1
number = 4
if number % 2 == 0:
    even_count += 1
else:
    odd_count += 1
 
# Check number 2
number = 7
if number % 2 == 0:
    even_count += 1
else:
    odd_count += 1
 
# Check number 3
number = 10
if number % 2 == 0:
    even_count += 1
else:
    odd_count += 1
 
print(f"Even numbers: {even_count}")  # Output: Even numbers: 2
print(f"Odd numbers: {odd_count}")    # Output: Odd numbers: 1

4.8.2) Akumulator: Mengumpulkan Total

Akumulator adalah variabel yang mengumpulkan total berjalan. Seperti counter, kamu menginisialisasinya ke nol, tetapi alih-alih menambahkan satu setiap kali, kamu menambahkan jumlah yang bervariasi:

python
# basic_accumulator.py
# Calculate total sales
total_sales = 0  # Initialize accumulator
 
# First sale
sale = 19.99
total_sales += sale
print(f"Total so far: ${total_sales}")  # Output: Total so far: $19.99
 
# Second sale
sale = 34.50
total_sales += sale
print(f"Total so far: ${total_sales}")  # Output: Total so far: $54.49
 
# Third sale
sale = 12.00
total_sales += sale
print(f"Total so far: ${total_sales}")  # Output: Total so far: $66.49

Akumulator adalah dasar pemrosesan data. Akumulator memungkinkan kamu mengakumulasi nilai saat kamu memprosesnya:

python
# multiple_accumulators.py
# Track both total and count to calculate average later
total_score = 0
count = 0
 
# Process score 1
score = 85
total_score += score
count += 1
 
# Process score 2
score = 92
total_score += score
count += 1
 
# Process score 3
score = 78
total_score += score
count += 1
 
print(f"Total score: {total_score}")  # Output: Total score: 255
print(f"Number of scores: {count}")   # Output: Number of scores: 3

4.8.3) Menghitung Rata-Rata

Rata-rata menggabungkan pola counter dan akumulator: kamu butuh total (akumulator) dan jumlah (counter), lalu membaginya:

python
# calculating_average.py
# Calculate average of test scores
total_score = 0
count = 0
 
# Add scores
total_score += 85
count += 1
 
total_score += 92
count += 1
 
total_score += 78
count += 1
 
total_score += 88
count += 1
 
# Calculate average
average = total_score / count
print(f"Average score: {average}")  # Output: Average score: 85.75
 
# Often you'll want to round the average
average_rounded = round(average, 2)
print(f"Average (rounded): {average_rounded}")  # Output: Average (rounded): 85.75

Penting: Selalu cek pembagian dengan nol:

Saat menghitung rata-rata, kamu harus memastikan count tidak nol:

python
# safe_average.py
total_score = 0
count = 0
 
# If no scores were added, count is still 0
# Dividing by zero causes an error!
 
if count > 0:
    average = total_score / count
    print(f"Average: {average}")
else:
    print("No scores to average")
    # Output: No scores to average

Kita akan belajar lebih banyak tentang menangani kondisi seperti ini di Bab 8.

4.8.4) Mencari Nilai Maksimum dan Minimum Berjalan

Kadang kamu perlu melacak nilai terbesar atau terkecil yang pernah muncul sejauh ini: Kamu bisa menggunakan fungsi max() dan min() untuk mengimplementasikan ini:

python
# running_max_min_simplified.py
# Track highest and lowest using max() and min()
 
highest_temp = 72
lowest_temp = 72
 
# Update with new temperature
current_temp = 85
highest_temp = max(highest_temp, current_temp)
lowest_temp = min(lowest_temp, current_temp)
 
# Update with another temperature
current_temp = 68
highest_temp = max(highest_temp, current_temp)
lowest_temp = min(lowest_temp, current_temp)
 
print(f"High: {highest_temp}, Low: {lowest_temp}")
# Output: High: 85, Low: 68

4.9) Operator Bitwise untuk Integer: &, |, ^, <<, >> (Gambaran Singkat)

Operator bitwise bekerja pada bit-bit individual (digit biner) dari integer. Walaupun kamu tidak terlalu sering menggunakan operator ini dalam pemrograman sehari-hari seperti operator aritmetika, operator ini penting untuk tugas-tugas tertentu seperti bekerja dengan flag, permission, manipulasi data level rendah, dan optimisasi performa.

Bagian ini memberikan gambaran singkat. Memahami operasi bitwise mengharuskanmu memahami representasi biner, yang merupakan topik lebih dalam dari yang bisa kita jelaskan penuh di bab pengantar ini.

4.9.1) Memahami Representasi Biner (Pengantar Cepat)

Komputer menyimpan integer sebagai urutan bit (0 dan 1). Sebagai contoh:

  • Desimal 5 adalah biner 101 (1×4 + 0×2 + 1×1)
  • Desimal 12 adalah biner 1100 (1×8 + 1×4 + 0×2 + 0×1)

Fungsi bin() Python menampilkan representasi biner dari sebuah integer:

python
# binary_representation.py
# See binary representation of integers
print(bin(5))   # Output: 0b101
print(bin(12))  # Output: 0b1100
print(bin(255)) # Output: 0b11111111
 
# The 0b prefix indicates binary notation

4.9.2) Bitwise AND (&)

Operator & melakukan bitwise AND: setiap bit dalam hasil adalah 1 hanya jika bit yang bersesuaian di kedua operan adalah 1:

python
# bitwise_and.py
# 12 is 1100 in binary
# 10 is 1010 in binary
result = 12 & 10
print(result)  # Output: 8
print(bin(result))  # Output: 0b1000
 
# How it works:
#   1100  (12)
# & 1010  (10)
# ------
#   1000  (8)

Bitwise AND sering digunakan untuk mengecek apakah bit tertentu diset (mengetes flag):

python
# checking_flags.py
# File permissions example (simplified)
READ = 4    # 100 in binary
WRITE = 2   # 010 in binary
EXECUTE = 1 # 001 in binary
 
permissions = 6  # 110 in binary (READ + WRITE)
 
# Check if READ permission is set
has_read = (permissions & READ) != 0
print(f"Has read: {has_read}")  # Output: Has read: True
 
# Check if EXECUTE permission is set
has_execute = (permissions & EXECUTE) != 0
print(f"Has execute: {has_execute}")  # Output: Has execute: False

4.9.3) Bitwise OR (|)

Operator | melakukan bitwise OR: setiap bit dalam hasil adalah 1 jika bit yang bersesuaian di salah satu operan adalah 1:

python
# bitwise_or.py
# 12 is 1100 in binary
# 10 is 1010 in binary
result = 12 | 10
print(result)  # Output: 14
print(bin(result))  # Output: 0b1110
 
# How it works:
#   1100  (12)
# | 1010  (10)
# ------
#   1110  (14)

Bitwise OR digunakan untuk menggabungkan flag:

python
# combining_flags.py
READ = 4    # 100 in binary
WRITE = 2   # 010 in binary
EXECUTE = 1 # 001 in binary
 
# Grant READ and WRITE permissions
permissions = READ | WRITE
print(f"Permissions: {permissions}")  # Output: Permissions: 6
print(bin(permissions))  # Output: 0b110
 
# Add EXECUTE permission
permissions = permissions | EXECUTE
print(f"Permissions: {permissions}")  # Output: 7
print(bin(permissions))  # Output: 0b111

4.9.4) Bitwise XOR (^)

Operator ^ melakukan bitwise XOR (exclusive OR): setiap bit dalam hasil adalah 1 jika bit yang bersesuaian di operan berbeda:

python
# bitwise_xor.py
# 12 is 1100 in binary
# 10 is 1010 in binary
result = 12 ^ 10
print(result)  # Output: 6
print(bin(result))  # Output: 0b110
 
# How it works:
#   1100  (12)
# ^ 1010  (10)
# ------
#   0110  (6)

XOR memiliki sifat menarik, seperti men-toggle bit atau menukar nilai:

python
# xor_properties.py
# XOR with itself gives 0
result = 5 ^ 5
print(result)  # Output: 0
 
# XOR with 0 gives the original number
result = 5 ^ 0
print(result)  # Output: 5
 
# XOR is its own inverse (useful for simple encryption)
original = 42
key = 123
encrypted = original ^ key
decrypted = encrypted ^ key
print(f"Original: {original}, Encrypted: {encrypted}, Decrypted: {decrypted}")
# Output: Original: 42, Encrypted: 81, Decrypted: 42

4.9.5) Shift Kiri (<<) dan Shift Kanan (>>)

Operator << menggeser bit ke kiri, dan >> menggeser bit ke kanan:

python
# bit_shifting.py
# Left shift: multiply by powers of 2
result = 5 << 1  # Shift left by 1 bit
print(result)  # Output: 10
# 5 is 101 in binary, shifted left becomes 1010 (10)
 
result = 5 << 2  # Shift left by 2 bits
print(result)  # Output: 20
# 5 is 101 in binary, shifted left becomes 10100 (20)
 
# Right shift: divide by powers of 2 (floor division)
result = 20 >> 1  # Shift right by 1 bit
print(result)  # Output: 10
# 20 is 10100 in binary, shifted right becomes 1010 (10)
 
result = 20 >> 2  # Shift right by 2 bits
print(result)  # Output: 5
# 20 is 10100 in binary, shifted right becomes 101 (5)

Shift ke kiri sebesar n bit mengalikan dengan 2^n, dan shift ke kanan membagi dengan 2^n (floor division):

python
# shift_as_multiplication.py
# Left shift multiplies by powers of 2
print(3 << 1)  # Output: 6 (3 * 2^1 = 3 * 2)
print(3 << 2)  # Output: 12 (3 * 2^2 = 3 * 4)
print(3 << 3)  # Output: 24 (3 * 2^3 = 3 * 8)
 
# Right shift divides by powers of 2
print(24 >> 1)  # Output: 12 (24 // 2^1 = 24 // 2)
print(24 >> 2)  # Output: 6 (24 // 2^2 = 24 // 4)
print(24 >> 3)  # Output: 3 (24 // 2^3 = 24 // 8)

4.9.6) Kapan Menggunakan Operator Bitwise

Operator bitwise berguna dalam skenario tertentu:

  • Bekerja dengan flag dan permission biner (seperti file permission di Unix/Linux)
  • Manipulasi data level rendah (mengemas beberapa nilai ke dalam satu integer)
  • Pemrograman jaringan (memanipulasi alamat IP, flag protokol)
  • Pemrograman grafis dan game (manipulasi warna, deteksi tumbukan)
  • Optimisasi performa (bit shifting lebih cepat daripada perkalian/pembagian dengan pangkat dua)

Untuk sebagian besar tugas pemrograman sehari-hari, kamu tidak akan membutuhkan operator bitwise. Tetapi ketika kamu membutuhkannya—terutama saat bekerja dengan pemrograman sistem, jaringan, atau kode yang kritis terhadap performa—operator ini adalah alat yang sangat berguna.

Catatan: Gambaran ini mencakup dasar-dasarnya. Operasi bitwise menjadi lebih kompleks dengan bilangan negatif (melibatkan representasi two's complement), yang berada di luar cakupan pengenalan ini. Untuk sekarang, fokuslah memahami bahwa operator ini ada dan apa yang mereka lakukan secara garis besar.

4.10) Presisi Floating-Point dan Kesalahan Pembulatan (Penjelasan Sederhana)

Bilangan floating-point di Python (dan di sebagian besar bahasa pemrograman) dapat merepresentasikan rentang nilai yang sangat luas, dari pecahan kecil hingga angka yang sangat besar. Namun, bilangan ini memiliki keterbatasan yang bisa mengejutkan pemula: tidak semua angka desimal dapat direpresentasikan secara tepat. Bagian ini menjelaskan mengapa hal ini terjadi dan apa artinya bagi programmu.

4.10.1) Mengapa Bilangan Floating-Point Tidak Selalu Tepat

Komputer menyimpan bilangan floating-point dalam bentuk biner (basis 2), bukan desimal (basis 10). Beberapa pecahan desimal yang terlihat sederhana bagi kita tidak dapat direpresentasikan dengan tepat dalam biner, sama seperti 1/3 tidak dapat direpresentasikan dengan tepat dalam desimal (0.333333... berlanjut tanpa akhir).

Berikut contoh yang mengejutkan:

python
# floating_point_surprise.py
# This seems like it should be exactly 0.3
result = 0.1 + 0.2
print(result)  # Output: 0.30000000000000004 (not exactly 0.3!)
 
# Check if it equals 0.3
print(result == 0.3)  # Output: False

Ini bukan bug di Python—ini adalah keterbatasan mendasar dari cara komputer merepresentasikan bilangan floating-point. Angka desimal 0.1 tidak bisa direpresentasikan secara tepat dalam floating-point biner, sama seperti 1/3 tidak bisa direpresentasikan secara tepat dalam desimal.

4.10.2) Memahami Masalah Representasi

Mari kita lihat lebih banyak contoh perilaku ini:

python
# more_precision_examples.py
# Simple decimal values that aren't exact in binary
print(0.1)  # Output: 0.1 (Python rounds for display)
print(repr(0.1))  # Output: 0.1 (still rounded)
 
# But the actual stored value has tiny errors
print(0.1 + 0.1 + 0.1)  # Output: 0.30000000000000004
 
# Multiplication can accumulate these errors
result = 0.1 * 3
print(result)  # Output: 0.30000000000000004
 
# Some numbers are exact (powers of 2)
print(0.5)  # Output: 0.5 (exact)
print(0.25)  # Output: 0.25 (exact)
print(0.125)  # Output: 0.125 (exact)

Angka-angka yang merupakan pangkat dua (seperti 0.5, 0.25, 0.125) atau jumlah dari pangkat dua bisa direpresentasikan dengan tepat. Tetapi sebagian besar pecahan desimal tidak bisa.

4.10.3) Implikasi Praktis

Untuk kebanyakan pemrograman sehari-hari, kesalahan kecil ini tidak masalah. Tapi ada situasi di mana kamu perlu menyadarinya:

Membandingkan bilangan floating-point:

python
# comparing_floats.py
# Direct equality comparison can fail
a = 0.1 + 0.2
b = 0.3
 
print(a == b)  # Output: False (due to tiny difference)
 
# Better: check if they're close enough
difference = abs(a - b)
tolerance = 0.0001  # How close is "close enough"?
 
print(difference < tolerance)  # Output: True (they're close enough)
 
# Python 3.5+ provides math.isclose() for this (we'll see in section 4.11)

Akumulasi kesalahan dalam perhitungan berulang:

python
# accumulated_errors.py
# Adding 0.1 ten times
total = 0.0
for i in range(10):
    total += 0.1
 
print(total)  # Output: 0.9999999999999999 (not exactly 1.0)
print(total == 1.0)  # Output: False
 
# The error accumulates with each addition

Perhitungan finansial:

python
# financial_calculations.py
# Money calculations can have surprising results
price = 0.10
quantity = 3
total = price * quantity
 
print(total)  # Output: 0.30000000000000004
 
# For financial calculations, consider rounding to cents
total_cents = round(total * 100)  # Convert to cents
total_dollars = total_cents / 100
print(total_dollars)  # Output: 0.3
 
# Or use Python's decimal module for exact decimal arithmetic
# (beyond the scope of this chapter, but worth knowing about)

4.10.4) Strategi Bekerja dengan Bilangan Floating-Point

Bulatkan hasil untuk tampilan:

python
# rounding_for_display.py
result = 0.1 + 0.2
print(f"Result: {round(result, 2)}")  # Output: Result: 0.3
 
# Or use formatted output (we'll learn more in Chapter 6)
print(f"Result: {result:.2f}")  # Output: Result: 0.30

Jangan membandingkan float untuk kesetaraan persis:

python
# safe_float_comparison.py
a = 0.1 + 0.2
b = 0.3
 
# Instead of: if a == b:
# Use: if they're close enough
if abs(a - b) < 0.0001:
    print("Close enough to equal")
# Output: Close enough to equal

Sadar ketika presisi penting:

Untuk komputasi ilmiah, perhitungan finansial, atau domain lain di mana aritmetika desimal yang tepat sangat penting, kamu mungkin membutuhkan:

  • Modul decimal Python untuk aritmetika desimal yang tepat
  • Modul fractions Python untuk aritmetika rasional yang tepat
  • Pembulatan yang hati-hati pada titik-titik yang tepat dalam perhitunganmu

Modul-modul ini berada di luar cakupan bab ini, tapi mengetahui bahwa modul-modul tersebut ada sangat berguna.

4.10.5) Saat Presisi Floating-Point Tidak Masalah

Untuk sebagian besar tugas pemrograman sehari-hari, presisi floating-point sudah lebih dari cukup:

python
# when_precision_is_fine.py
# Calculating area
length = 5.5
width = 3.2
area = length * width
print(f"Area: {area:.2f} square meters")  # Output: Area: 17.60 square meters
 
# Converting temperature
fahrenheit = 98.6
celsius = (fahrenheit - 32) * 5 / 9
print(f"Temperature: {celsius:.1f}°C")  # Output: Temperature: 37.0°C
 
# Calculating average
total = 456.78
count = 7
average = total / count
print(f"Average: {average:.2f}")  # Output: Average: 65.25

Ketika kamu membulatkan hasil untuk tampilan atau ketika kesalahan kecil tidak signifikan dibanding presisi pengukuranmu, aritmetika floating-point bekerja dengan sangat baik.

4.10.6) Inti yang Perlu Diingat

Bilangan floating-point adalah pendekatan (aproksimasi) dari bilangan riil. Untuk kebanyakan tugas pemrograman, bilangan ini cukup akurat. Namun ingat:

  1. Jangan membandingkan float untuk kesetaraan persis—cek apakah nilainya cukup dekat
  2. Bulatkan hasil saat menampilkan untuk menghindari menunjukkan presisi yang tidak bermakna
  3. Sadar akan akumulasi kesalahan dalam perhitungan berulang
  4. Untuk perhitungan finansial, pertimbangkan membulatkan ke presisi yang sesuai atau menggunakan modul decimal

Memahami keterbatasan ini membantu kamu menulis program yang lebih tangguh dan menghindari bug yang mengejutkan. Kabar baiknya, untuk sebagian besar tugas pemrograman, aritmetika floating-point "langsung bekerja" jika kamu mengikuti panduan sederhana ini.

4.11) (Opsional) Fungsi Matematika Dasar dengan Modul math (sqrt, floor, ceil, pi)

Operator dan fungsi bawaan Python sudah mencakup aritmetika dasar, tetapi untuk operasi matematika yang lebih lanjut, Python menyediakan modul math. Modul adalah kumpulan fungsi dan nilai terkait yang bisa kamu gunakan dalam programmu. Kita akan belajar lebih banyak tentang modul di Bab 22, tapi untuk sekarang, kita akan memperkenalkan dasar-dasar yang kamu butuhkan untuk menggunakan modul math.

4.11.1) Mengimpor Modul math

Untuk menggunakan modul math, kamu perlu mengimpornya di awal program:

python
# importing_math.py
import math
 
# Now you can use functions from the math module
# by writing math.function_name()

Saat kamu mengimpor modul, kamu mendapatkan akses ke semua fungsi dan nilainya. Kamu menggunakannya dengan menulis nama modul, titik, lalu nama fungsi atau nilainya.

4.11.2) Konstanta Matematika: pi dan e

Modul math menyediakan nilai presisi tinggi untuk konstanta matematika penting:

python
# math_constants.py
import math
 
# Pi (π): ratio of circle's circumference to diameter
print(math.pi)  # Output: 3.141592653589793
 
# Euler's number (e): base of natural logarithms
print(math.e)  # Output: 2.718281828459045
 
# Using pi to calculate circle properties
radius = 5
circumference = 2 * math.pi * radius
area = math.pi * radius ** 2
 
print(f"Circumference: {circumference:.2f}")  # Output: Circumference: 31.42
print(f"Area: {area:.2f}")  # Output: Area: 78.54

4.11.3) Akar Kuadrat dengan sqrt()

Fungsi sqrt() menghitung akar kuadrat sebuah angka:

python
# square_root.py
import math
 
# Square root of perfect squares
result = math.sqrt(16)
print(result)  # Output: 4.0
 
result = math.sqrt(25)
print(result)  # Output: 5.0
 
# Square root of non-perfect squares
result = math.sqrt(2)
print(result)  # Output: 1.4142135623730951
 
# Using sqrt in calculations
# Distance formula: sqrt((x2-x1)^2 + (y2-y1)^2)
x1, y1 = 3, 4
x2, y2 = 6, 8
 
distance = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
print(f"Distance: {distance}")  # Output: Distance: 5.0

Perhatikan bahwa sqrt() mengembalikan float, bahkan untuk kuadrat sempurna. Juga, kamu tidak bisa mengambil akar kuadrat dari bilangan negatif dengan sqrt() (akan menyebabkan error).

4.11.4) Floor dan Ceiling dengan floor() dan ceil()

Fungsi floor() membulatkan ke bawah ke integer terdekat (menuju minus tak hingga), dan ceil() membulatkan ke atas (menuju plus tak hingga):

python
# floor_and_ceil.py
import math
 
# Floor: rounds down
result = math.floor(3.7)
print(result)  # Output: 3
 
result = math.floor(3.2)
print(result)  # Output: 3
 
# Ceiling: rounds up
result = math.ceil(3.7)
print(result)  # Output: 4
 
result = math.ceil(3.2)
print(result)  # Output: 4
 
# With negative numbers
result = math.floor(-3.7)
print(result)  # Output: -4 (rounds toward negative infinity)
 
result = math.ceil(-3.7)
print(result)  # Output: -3 (rounds toward positive infinity)

Fungsi-fungsi ini berguna ketika kamu perlu memastikan suatu nilai berada dalam rentang tertentu atau ketika kamu butuh hasil integer dengan perilaku pembulatan tertentu:

python
# practical_floor_ceil.py
import math
 
# How many boxes needed to pack all items?
items = 47
items_per_box = 12
 
# Use ceil to round up (need a full box even if not completely filled)
boxes_needed = math.ceil(items / items_per_box)
print(f"Boxes needed: {boxes_needed}")  # Output: Boxes needed: 4
 
# How many complete pages for a document?
total_lines = 250
lines_per_page = 30
 
# Use floor to count only complete pages
complete_pages = math.floor(total_lines / lines_per_page)
print(f"Complete pages: {complete_pages}")  # Output: Complete pages: 8

4.11.5) Membandingkan floor(), ceil(), round(), dan int()

Berguna untuk memahami bagaimana pendekatan pembulatan yang berbeda ini berbeda:

python
# comparing_rounding_methods.py
import math
 
value = 3.7
 
print(f"Original: {value}")
print(f"floor(): {math.floor(value)}")  # Output: floor(): 3
print(f"ceil(): {math.ceil(value)}")    # Output: ceil(): 4
print(f"round(): {round(value)}")       # Output: round(): 4
print(f"int(): {int(value)}")           # Output: int(): 3
 
# With negative numbers, the differences are more apparent
value = -3.7
 
print(f"\nOriginal: {value}")
print(f"floor(): {math.floor(value)}")  # Output: floor(): -4
print(f"ceil(): {math.ceil(value)}")    # Output: ceil(): -3
print(f"round(): {round(value)}")       # Output: round(): -4
print(f"int(): {int(value)}")           # Output: int(): -3

Berikut representasi visual bagaimana fungsi-fungsi ini berperilaku:

Value: 3.7

floor: 3
rounds down

ceil: 4
rounds up

round: 4
rounds to nearest

int: 3
truncates toward zero

Value: -3.7

floor: -4
rounds down toward -∞

ceil: -3
rounds up toward +∞

round: -4
rounds to nearest

int: -3
truncates toward zero

4.11.6) Fungsi Lain yang Berguna di Modul math

Modul math berisi banyak fungsi lain. Berikut beberapa yang juga sering berguna:

python
# other_math_functions.py
import math
 
# Absolute value (also available as built-in abs())
result = math.fabs(-5.5)
print(result)  # Output: 5.5
 
# Power function (also available as ** operator)
result = math.pow(2, 3)
print(result)  # Output: 8.0
 
# Trigonometric functions (angles in radians)
result = math.sin(math.pi / 2)  # sin(90 degrees)
print(result)  # Output: 1.0
 
result = math.cos(0)  # cos(0 degrees)
print(result)  # Output: 1.0
 
# Logarithms
result = math.log(math.e)  # Natural log (base e)
print(result)  # Output: 1.0
 
result = math.log10(100)  # Log base 10
print(result)  # Output: 2.0
 
# Check if a float is close to another (Python 3.5+)
a = 0.1 + 0.2
b = 0.3
result = math.isclose(a, b)
print(result)  # Output: True

Fungsi isclose() sangat berguna untuk membandingkan bilangan floating-point (seperti yang kita bahas di bagian 4.10):

python
# isclose_example.py
import math
 
# Instead of direct equality comparison
a = 0.1 + 0.2
b = 0.3
 
# Don't do this:
# if a == b:  # This would be False
 
# Do this instead:
if math.isclose(a, b):
    print("Values are close enough")
# Output: Values are close enough
 
# You can specify the tolerance
if math.isclose(a, b, rel_tol=1e-9):  # Very strict tolerance
    print("Values are very close")
# Output: Values are very close

4.11.7) Kapan Menggunakan Modul math

Gunakan modul math ketika kamu membutuhkan:

  • Konstanta matematika (π, e)
  • Akar kuadrat dan akar lain
  • Fungsi trigonometri (sin, cos, tan)
  • Fungsi logaritma dan eksponensial
  • Kontrol pembulatan yang presisi (floor, ceil)
  • Perbandingan floating-point (isclose)

Untuk aritmetika dasar (+, -, *, /, //, %, **), gunakan operator bawaan Python. Untuk operasi matematika yang lebih lanjut, impor dan gunakan modul math.

Modul math adalah bagian dari standard library Python, artinya selalu tersedia—kamu hanya perlu mengimpornya. Kita akan menjelajahi lebih banyak modul dan mempelajari sistem import secara detail di Bab 22.


Di bab ini, kamu telah belajar bagaimana bekerja dengan angka di Python: melakukan operasi aritmetika, memahami berbagai jenis pembagian, menggunakan prioritas operator, mencampur integer dan float, memakai fungsi numerik bawaan, mengenali pola numerik umum, bekerja dengan operator bitwise, memahami presisi floating-point, dan menggunakan modul math untuk operasi yang lebih lanjut.

Operasi numerik ini membentuk fondasi untuk banyak sekali tugas pemrograman, dari perhitungan sederhana hingga analisis data yang kompleks. Saat kamu terus belajar Python, kamu akan menggunakan operasi ini terus-menerus, sering kali dikombinasikan dengan struktur alur kontrol dan koleksi data yang akan kamu pelajari di bab-bab berikutnya.

Latih operasi-operasi ini sampai terasa alami. Cobalah menulis program kecil yang menghitung kuantitas dunia nyata: mengonversi suhu, menghitung luas dan volume, memproses data finansial, atau menganalisis pengukuran. Semakin sering kamu berlatih, semakin nyaman kamu dengan kemampuan numerik Python.

© 2025. Primesoft Co., Ltd.
support@primesoft.ai