Menu
CoddyTech

Magic method untuk wadah

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Python di Coddy. Pelajaran 35 dari 64.

Method ajaib container memungkinkan class-mu berperilaku seperti container bawaan (list, dictionary, dan sebagainya). Method ini memungkinkan pengindeksan, pemeriksaan panjang, dan perulangan pada object kustommu.

Berikut contoh class dengan method ajaib untuk container:

class CustomList:
    def __init__(self, items):
        self.items = items
    
    def __len__(self):
        return len(self.items)
    
    def __getitem__(self, index):
        return self.items[index]
    
    def __setitem__(self, index, value):
        self.items[index] = value
    
    def __iter__(self):
        return iter(self.items)
    
    def __contains__(self, item):
        return item in self.items

method __len__ membuat len() berfungsi:

my_list = CustomList([1, 2, 3, 4])
print(len(my_list))  # 4

method __getitem__ memungkinkan pengindeksan untuk mengambil nilai:

print(my_list[2])    # 3
print(my_list[0])    # 1

Method __setitem__ memungkinkan penggunaan indeks untuk penugasan:

my_list[1] = 10
print(my_list[1])    # 10

method __contains__ membuat operator in berfungsi:

print(3 in my_list)     # True
print(100 in my_list)   # False

Method __iter__ memungkinkan perulangan:

for item in my_list:
    print(item)

Output:

4
3
1
10
True
False
1
10
3
4

Poin Penting: Magic method container seperti __len__, __getitem__, __setitem__, __iter__, dan __contains__ membuat class kustommu berperilaku seperti container bawaan. Ini memberikan pengindeksan, iterasi, dan pengujian keanggotaan yang intuitif untuk object-mu.

challenge icon

Tantangan

Sedang

Dalam tantangan ini, kamu akan mengimplementasikan class Deck yang menyimulasikan setumpuk kartu remi dengan fungsionalitas lengkap dan mengikuti konvensi Python yang tepat.

Kamu hanya perlu mengedit file deck.py. Ikuti komentar TODO dalam kode yang memandumu untuk mengimplementasikan:

  • Inisialisasi standar setumpuk 52 kartu (menggunakan string seperti "2H", "KD", "AS")
  • Dukungan untuk operasi bawaan Python:
    • Pengindeksan (deck[0])
    • Pemeriksaan panjang (len(deck))
    • Perulangan (for card in deck)
    • Pemeriksaan keanggotaan ("AS" in deck)
  • Method shuffle untuk mengacak urutan kartu

Coba sendiri

from deck import Deck

# Penangan kasus uji menyeluruh
test_case = input()

def test_basic_functionality():
    deck = Deck()
    assert len(deck) == 52, f"Deck should have 52 cards, but has {len(deck)}"
    
    first_card = deck[0]
    assert isinstance(first_card, str), f"Card should be a string, but got {type(first_card)}"
    
    assert "AS" in deck, "Ace of Spades should be in the deck"
    assert "XY" not in deck, "XY is not a valid card and should not be in the deck"
    
    cards = [card for card in deck]
    assert len(cards) == 52, f"Iteration should yield 52 cards, but got {len(cards)}"
    
    original_first_five = [deck[i] for i in range(5)]
    deck.shuffle()
    shuffled_first_five = [deck[i] for i in range(5)]
    assert original_first_five != shuffled_first_five or len(deck) <= 5, "Shuffle should change card order"
    
    print("Basic functionality tests passed!")

def test_edge_cases():
    deck = Deck()
    
    # Uji akses kartu pertama dan terakhir
    first_card = deck[0]
    last_card = deck[51]
    assert isinstance(first_card, str) and isinstance(last_card, str), "First and last cards should be strings"
    
    # Uji pengindeksan negatif
    assert deck[-1] == deck[51], "Negative indexing should work correctly"
    
    # Uji akses di luar batas
    try:
        invalid_card = deck[52]
        print("Test failed: Should raise IndexError for out of bounds access")
    except IndexError:
        print("Edge case test passed: IndexError raised for out of bounds access")
    
    print("Edge case tests passed!")

def test_card_uniqueness():
    deck = Deck()
    cards = [card for card in deck]
    unique_cards = set(cards)
    
    assert len(unique_cards) == 52, f"All cards should be unique, but found {len(unique_cards)} unique cards"
    
    # Pastikan kartu tertentu ada
    expected_cards = ["2H", "10S", "KD", "AC"]
    for card in expected_cards:
        assert card in deck, f"Expected card {card} not found in deck"
    
    print("Card uniqueness tests passed!")

def test_shuffle_behavior():
    deck = Deck()
    original_order = [card for card in deck]
    
    # Pengacakan pertama
    deck.shuffle()
    first_shuffle = [card for card in deck]
    assert len(first_shuffle) == 52, "Shuffle should preserve all 52 cards"
    assert set(first_shuffle) == set(original_order), "Shuffle should not add or remove cards"
    
    # Kemungkinan besar urutannya berubah (meski ada kemungkinan kecil urutannya tetap sama)
    different_order = (original_order != first_shuffle)
    
    # Pengacakan kedua untuk lebih memastikan
    deck.shuffle()
    second_shuffle = [card for card in deck]
    different_order_2 = (first_shuffle != second_shuffle)
    
    assert different_order or different_order_2, "Multiple shuffles should change the order"
    
    print("Shuffle behavior tests passed!")

def test_contains_behavior():
    deck = Deck()
    
    # Uji apakah semua kartu yang valid ada dalam deck
    suits = ['H', 'D', 'C', 'S']
    ranks = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
    
    for suit in suits:
        for rank in ranks:
            card = rank + suit
            assert card in deck, f"Valid card {card} should be in the deck"
    
    # Uji apakah kartu yang tidak valid tidak ada dalam deck
    invalid_cards = ["1H", "11S", "XD", "AX", "JX", ""]
    for card in invalid_cards:
        assert card not in deck, f"Invalid card {card} should not be in the deck"
    
    print("Contains behavior tests passed!")

def test_iteration_behavior():
    deck = Deck()
    
    # Uji iterasi
    card_count = 0
    for card in deck:
        card_count += 1
        assert isinstance(card, str), f"Each card should be a string, but got {type(card)}"
    
    assert card_count == 52, f"Iteration should yield 52 cards, but got {card_count}"
    
    # Uji iterasi berulang
    first_iteration = [card for card in deck]
    second_iteration = [card for card in deck]
    assert first_iteration == second_iteration, "Multiple iterations should yield the same order"
    
    print("Iteration behavior tests passed!")

# Jalankan pengujian yang sesuai berdasarkan input
if test_case == "basic_functionality":
    test_basic_functionality()
elif test_case == "edge_cases":
    test_edge_cases()
elif test_case == "card_uniqueness":
    test_card_uniqueness()
elif test_case == "shuffle_behavior":
    test_shuffle_behavior()
elif test_case == "contains_behavior":
    test_contains_behavior()
elif test_case == "iteration_behavior":
    test_iteration_behavior()
else:
    # Pengujian bawaan: jalankan rangkaian pengujian asli
    def test_deck():
        try:
            # Uji inisialisasi dan panjangnya
            deck = Deck()
            assert len(deck) == 52, f"Deck should have 52 cards, but has {len(deck)}"
            
            # Uji getitem
            first_card = deck[0]
            assert isinstance(first_card, str), f"Card should be a string, but got {type(first_card)}"
            
            # Uji contains
            assert "AS" in deck, "Ace of Spades should be in the deck"
            assert "XY" not in deck, "XY is not a valid card and should not be in the deck"
            
            # Uji iterasi
            cards = [card for card in deck]
            assert len(cards) == 52, f"Iteration should yield 52 cards, but got {len(cards)}"
            assert len(set(cards)) == 52, "All cards in the deck should be unique"
            
            # Uji shuffle (periksa apakah urutannya berubah)
            original_first_five = [deck[i] for i in range(5)]
            deck.shuffle()
            shuffled_first_five = [deck[i] for i in range(5)]
            assert original_first_five != shuffled_first_five or len(deck) <= 5, "Shuffle should change card order"
            
            # Periksa apakah shuffle tidak menghilangkan kartu
            assert len(deck) == 52, f"Deck should still have 52 cards after shuffle, but has {len(deck)}"
            
            print("All tests passed!")
        except AssertionError as e:
            print(f"Test failed: {e}")

    test_deck()
    print("Tests completed")
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Python online