Siyah ekran, yukarıdan aşağıya akan yeşil karakterler, her sütunun başında parlayan bir harf. 1999’da vizyona giren The Matrix’in bu “dijital yağmur” sahnesi, bilgisayar dünyasının en tanınan görüntülerinden biri oldu. Bu yazıda aynı efekti 50 satırlık bir Python koduyla kendi terminalinde yaratıyoruz. Hiçbir kütüphane kurmadan, sadece Python’un kendi araçlarıyla.

Kodlar hazır bir not defterinde: Colab’da Aç. Not defterinde Colab’da çalışan bir sürüm de var.
Efekt aslında nasıl çalışıyor?
Görüntü karmaşık ama arkasındaki fikir basit. Ekranı sütunlara böl ve her sütunda bir “damla” düşün:
- Her sütunun bir damlası var ve damlanın başı belirli bir satırda duruyor.
- Her karede damla bir satır aşağı iniyor. Yeni yerine parlak beyaz rastgele bir karakter yazılıyor; bir önceki yer yeşile dönüyor.
- Damlanın belirli bir uzunlukta kuyruğu var. Kuyruğun ucundaki karakter silinerek boşluk bırakılıyor.
- Damla ekranın altından çıkınca, rastgele bir yükseklikten yeniden başlıyor.
Bütün sütunlar aynı kuralı izliyor; farklı yüksekliklerden başladıkları için de yağmur rastgele ve canlı görünüyor. Yani ekranda gördüğün “sihir”, Python Dersi 6’daki döngüler ve Python Dersi 7’deki listelerle yapılan küçük bir simülasyon.
Terminale renk ve konum söylemek: ANSI kaçış kodları
Normalde print yazıyı imlecin olduğu yere, sırayla yazar. Biz ise ekranın istediğimiz noktasına, istediğimiz renkte yazmak istiyoruz. Bunun için terminallerin anladığı özel komutlar var: ANSI kaçış kodları.
Hepsi \033[ ile başlar (çoğu yerde “ESC [” diye yazılır). Terminal bunları ekrana yazmaz, komut olarak uygular:
| Kod | Ne yapar? |
|---|---|
\033[32m | Yazı rengini yeşil yapar |
\033[97m | Yazı rengini parlak beyaz yapar |
\033[0m | Renkleri sıfırlar |
\033[2J | Ekranı temizler |
\033[5;10H | İmleci 5. satır, 10. sütuna götürür |
\033[?25l / \033[?25h | İmleci gizler / gösterir |
Kendin denemek için terminalde şunu çalıştır:
print("\033[32mBu yazı yeşil\033[0m, bu yazı normal.")
Kod
import osimport randomimport sysimport timeKARAKTERLER = "アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモ0123456789"YESIL = "\033[32m" # yazı rengi: yeşilBEYAZ = "\033[97m" # yazı rengi: parlak beyazSIFIRLA = "\033[0m" # renkleri sıfırlaTEMIZLE = "\033[2J" # ekranı temizleIMLEC_GIZLE = "\033[?25l"IMLEC_GOSTER = "\033[?25h"def yaz(satir, sutun, metin): """İmleci (satir, sutun) konumuna götürüp metni oraya yazar.""" sys.stdout.write(f"\033[{satir};{sutun}H{metin}")def yagmur(hiz=0.05, kuyruk=12): genislik, yukseklik = os.get_terminal_size() yukseklik -= 1 # en alt satıra yazıp ekranı kaydırmayalım damlalar = [random.randint(-yukseklik, 0) for _ in range(genislik)] sys.stdout.write(TEMIZLE + IMLEC_GIZLE) try: while True: for x in range(genislik): y = damlalar[x] # bu sütundaki damlanın başı if 1 <= y <= yukseklik: yaz(y, x + 1, BEYAZ + random.choice(KARAKTERLER)) if 1 <= y - 1 <= yukseklik: yaz(y - 1, x + 1, YESIL + random.choice(KARAKTERLER)) if 1 <= y - kuyruk <= yukseklik: yaz(y - kuyruk, x + 1, " ") # kuyruğun ucunu sil damlalar[x] += 1 if y - kuyruk > yukseklik: # damla ekranın altından çıktı damlalar[x] = random.randint(-yukseklik, 0) sys.stdout.flush() time.sleep(hiz) except KeyboardInterrupt: # Ctrl+C ile çıkış pass finally: sys.stdout.write(SIFIRLA + IMLEC_GOSTER + TEMIZLE + "\033[H")if __name__ == "__main__": yagmur()
Kod adım adım
Karakterler. Filmdeki yağmur, Japon katakana alfabesine benzeyen karakterler ve rakamlardan oluşuyor. Biz de KARAKTERLER metnine yarım genişlikteki katakana harflerini ve rakamları koyduk. “Yarım genişlik” önemli: bu harfler terminalde tam bir sütun kaplar, böylece sütunlar kaymaz. random.choice(KARAKTERLER) her seferinde bu metinden rastgele bir karakter seçiyor.
Ekran boyutu. os.get_terminal_size() terminal penceresinin kaç sütun genişliğinde ve kaç satır yüksekliğinde olduğunu verir. Yağmur pencereni büyütürsen daha geniş yağar.
Damlalar listesi. damlalar her sütun için tek bir sayı tutan bir liste: o sütundaki damlanın başı hangi satırda? Başlangıçta hepsi ekranın üstünde, eksi sayılarda; böylece her damla farklı zamanda ekrana girer. Bu tek satırlık liste kurma yazımını (liste üreteci) yarınki kod kartında ayrıntılı anlatacağım.
Ana döngü. while True sonsuza kadar döner. Her turda tüm sütunlar gezilir ve her sütun için üç iş yapılır: başa beyaz karakter, bir üstüne yeşil karakter, kuyruğun ucuna boşluk. if 1 <= y <= yukseklik kontrolleri, ekranın dışına yazmaya kalkışmamak için.
Her seferinde tüm ekranı çizmiyoruz. Sadece değişen üç hücreyi güncelliyoruz. Bu yüzden kod geniş bir pencerede bile akıcı çalışıyor. sys.stdout.write ise print gibi, ama sona otomatik satır atlama eklemiyor; flush() da biriken yazıları tek seferde ekrana gönderiyor.
Temiz çıkış. Ctrl+C’ye basınca Python KeyboardInterrupt hatası fırlatır. try / except bu hatayı yakalıyor, finally bloğu da ne olursa olsun çalışıp renkleri sıfırlıyor, imleci geri getiriyor ve ekranı temizliyor. Bunu yapmasaydık, programdan çıktıktan sonra terminal yeşil ve imleçsiz kalırdı. Hata yönetimini ileride Python Dersi 13’te ayrıntılı göreceğiz.
Çalıştırmak
- Kodu kopyala ve
matrix.pyadıyla kaydet. - Terminali aç, dosyanın olduğu klasöre git ve
python matrix.pyyaz (bazı sistemlerdepython3 matrix.py). - Yağmuru durdurmak için Ctrl+C.
Mac ve Linux terminallerinde, Windows’ta da Windows Terminal’de çalışır. Eski Windows komut isteminde (cmd) renkler görünmeyebilir; o zaman Windows Terminal’i dene.
Colab’da çalıştırmak
Colab’ın çıktı alanı gerçek bir terminal değil; renkleri gösterir ama imleci istediğimiz yere götüremez. Bu yüzden not defterinde farklı bir yöntem kullandım: Ekranı iç içe bir liste olarak tutuyoruz (her satır bir liste, ekran da satırların listesi) ve her karede ekranı silip baştan yazdırıyoruz:
izgara = [[" "] * genislik for _ in range(yukseklik)]izgara[y][x] = random.choice(KARAKTERLER) # y. satırın x. hücresi
Sonuç terminaldeki kadar akıcı olmasa da aynı fikir. İki yöntemi karşılaştırmak da bir ders: Aynı görüntüyü “sadece değişeni güncelle” ya da “her şeyi baştan çiz” diye iki farklı algoritmayla üretebiliyoruz.
Kendin dene
yagmur(hiz=0.1)ile yavaş,yagmur(hiz=0.02)ile hızlı bir yağmur.kuyruk=25ile uzun kuyruklu damlalar.KARAKTERLERmetnine kendi adının harflerini ekle.- Yeşil yerine mavi bir yağmur için
YESIL = "\033[34m". - Zor olan: Ekranın ortasında sabit duran bir yazı göster, yağmur onun etrafından aksın.
Son söz
Matrix’i ilk izlediğimde lisedeydim. O akan yeşil ekrana hayran kalmıştım. Belki de bilgisayar mühendisliği bana ilk o zaman bu kadar havalı gelmişti. Yıllar sonra aynı yağmuru kendi yazdığım birkaç satır kodla kendi terminalimde görmek ise bambaşka bir duyguydu: O zaman ekranın arkasında bir sihir olduğunu düşünüyordum, şimdi o sihrin döngülerden ve listelerden oluştuğunu biliyorum.
Bir de tavsiye: Hem görsel olarak hem de sorduğu sorularla çok güzel, felsefi bir film serisi. İzlemediysen mutlaka izle; izlediysen bu yazıdan sonra bir kez daha izlemek isteyebilirsin.

Bir yanıt yazın