Arcade Türü Oyun Programlamayı ve Bilgisayar Bilimleri Öğrenin

Arcade Türü Oyun Programlamayı
ve Bilgisayar Bilimleri Öğrenin

Chapter 18: Hata Yakalama

Video: Kural Dışı Durum İşleme

İstisnalar, kodun çalıştırılması esnasında gerçekleşebilecek anormal durumlarla başa çıkabilmek için kullanılır. İstisnalar çoğu zaman dosya ve ağ işlemlerinde kullanılır. Bu, kodun biten disk alanıyla, ağ hatalarıyla ya da izin hatalarıyla incelikle baş edebilmesine izin verir.

18.1 Terimler

İstisnalarla çalışırken kullanılan birkaç terim ve ifade bulunmaktadır:

18.2 Hataları İşlemek

Hataları işlemek için kullanılan kod basittir. Alttaki örneğe bakın:

# Sıfıra bölmek
try:
    x = 5/0
except:
    print("Sıfıra bölme hatası")

2. satırda try ifadesi var. Altındaki her girintili satır "try bloğu"nun bir parçasıdır. Bu bloğun altında except ifadesi ile başlamayan ve girintilenmemiş bir kod bulunamaz. try ifadesi çalıştırılması denenecek olan kod bölümünü tanımlar.

Eğer bu kodun işlenmesi sırasında herhangi bir istisna(hata) ortaya çıkarsa çalıştırma işlemi hemen "yakalama bloğu"na atlayacaktır. Yakalama bloğu 4. satırda except ifadesinin altındadır. Bu kod hata ile baş etmekten sorumludur.

Ayrıca, Yazıdan bir sayı elde etmek için gerçekleştirilen çevirme işlemi esnasında da gerçekleşen hataları yakalamak mümkündür. Mesela:

# Geçersiz sayı dönüştürmesi
try:
    x = int("fred")
except:
    print ("fred ifadesi sayıya çevrilirken hata oluştu")

"fred" bir tamsayıya çevrilemediği için 3. satırda bir hata yükseltiliyor. 5. satırdaki kod bir hata mesajı yazdıracaktır.

Altta bu örneğin daha genişletilmiş bir versiyonu bulunmaktadır. Kullanıcının bir tamsayı girip girmedinden emin olmak için hatas kontrol ediyor. Kod 5. satırda gerçekleşebilecek muhtemelen dönüştürme hatalasını yakalamak için hata yakalamayı kullanıyor. Kullanıcı tamsayı dıışında başka bir şey girerse, 5. satırdaki dönüştürme işlemi sırasında bir hata yükseltiliyor. 6. satırdaki numberEntered değişkenini True yapan kod 5. satırda bir hata oluşursa çalıştırılmıyor.

numberEntered=False
while numberEntered == False:
    numberString = input("Bir tamsayı girin: ")
    try:
        n = int(numberString)
        numberEntered = True
    except:
        print ("Hata, geçersiz tamsayı")

Özellikle dosyalar onlarla işlem yapılırken hata vermeye meyillidir. Disk dolabilir, kullanıcı program dosyaya yazarken o dosyayı silebilir, dosya taşınabilir veya USB sürücü işlemin ortasında çıkarılabilir. Ayrıca bu tür hatalar da hata ayıklama ile kolayca yakalanabilir.

# Dosya açılırken hata
try:
    f = open('myfile.txt')
except:
    print("Dosya açılırken hata oluştu")  

Birden çok hata türü farklı olarak yakalanabilir ve işlenebilir. Bu, kullanıcıya basitçe "bir hata meydana geldi." demekten daha kesin bir hata mesajı sağlayacak ve daha kullanışlı olacaktır.

Alttaki kodta, farklı hata türleri 5-8. satırlarda meydana gelebilir. 9. satırda except'ten sonraya IOError'u taşıyarak, bu kod tarafından sadece Giriş ve Çıkış (Input and Output - IO) hataları yakalanabilir. Aynı şekilde 11. satır sadece değerlerin dönüştürülmesinde ortaya çıkan hatalarla ve 13. satır 0'a bölme hatalarıyla baş ediyor. Son hata yakalama 15. satırda gerçekleşiyor. 15. satır özel bir hata türü içermediği için, üstteki except bloklarında yer almayan bütün hataları yakalayacaktır. "Hepsini-yakalayan" except ifadesi her zaman en sonra olmalıdır.

1. satırda, 16. satırda hangi tür hatanın gerçekleştiğini yazdırmak için kullanılacak sys kütüphanesi import ediliyor.

import sys

# Çoklu hatalar   
try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
    x = 101/i
except IOError:
    print ("I/O hatası")
except ValueError:
    print ("Veri bir tamsayıya çevrilemedi.")
except ZeroDivisionError:
    print ("Sıfıra bölme hatası")
except:
    print ("Beklenmeyen Hata:", sys.exc_info()[0])

Dahili hataların bir listesi şu adreste mevcuttur:
http://docs.python.org/library/exceptions.html\#bltin-exceptions

18.3 Örnek: Yüksek skoru kayıt etmek

Bu, oyunlar arasında yüksek skorun nasıl kaydedileceğini gösteriyor. Skor high_score.txt isimli bir dosyada saklanıyor.

"""
Show how to use exceptions to save a high score for a game.

Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/
"""


def get_high_score():
    # Default high score
    high_score = 0

    # Try to read the high score from a file
    try:
        high_score_file = open("high_score.txt", "r")
        high_score = int(high_score_file.read())
        high_score_file.close()
        print("The high score is", high_score)
    except IOError:
        # Error reading file, no high score
        print("There is no high score yet.")
    except ValueError:
        # There's a file there, but we don't understand the number.
        print("I'm confused. Starting with no high score.")

    return high_score


def save_high_score(new_high_score):
    try:
        # Write the file to disk
        high_score_file = open("high_score.txt", "w")
        high_score_file.write(str(new_high_score))
        high_score_file.close()
    except IOError:
        # Hm, can't write it.
        print("Unable to save the high score.")


def main():
    """ Main program is here. """
    # Get the high score
    high_score = get_high_score()

    # Get the score from the current game
    current_score = 0
    try:
        # Ask the user for his/her score
        current_score = int(input("What is your score? "))
    except ValueError:
        # Error, can't turn what they typed into a number
        print("I don't understand what you typed.")

    # See if we have a new high score
    if current_score > high_score:
        # We do! Save to disk
        print("Yea! New high score!")
        save_high_score(current_score)
    else:
        print("Better luck next time.")

# Call the main function, start up the game
if __name__ == "__main__":
    main()

18.4 Hata nesneleri

Bir hata hakkında daha fazla bilgi hata nesnelerinden çekilebilir. Bu nesneler bir hatayı yakalarken as anahtar kelimesi kullanılarak alınabilir. Örneğin:

try:
	x=5/0
except ZeroDivisionError as e:
	print(e)

e değişkeni hata hakkında daha fazla yazdırılabilecek bilgiyi içeriyor. Hata nesneleriyle daha fazlası da yapılabilir, fakat ne yazık ki bu işlem bu bölümün kapsamının ötesindedir.

18.5 Hata üretmek

Hatalar raise komutu ile üretilebilir. Örneğin:

# Generating exceptions
def getInput():
    userInput = input("Bir şey girin: ")
    if len(userInput) == 0:
        raise IOError("Kullanıcı hiçbir şey girmedi")
    
getInput()

Yukarıdaki kodu alın ve ona IOError hatasının yükseltildiği durum için hata yakalama kodunu ekleyin.

Ayrıca özel istisnalar oluşturmak da mümkündür, fakat bu konu bu kitabın kapsamının dışındadır. Meraklı okuyucular daha fazlasını şu adresten öğrenebilir:
http://docs.python.org/tutorial/errors.html#raising-exceptions

18.6 Düzgün hata kullanımı

Hatalar if ifadesi durumla başedebildiğinde kullanılmamalıdır. Normal kod mutlu yol senaryosunda çalışırken hata yükseltmemelidir. İyi yapılandırılmış try/catch kodunun takip edilmesi kolaydır. Çok sayıda hata içeren ve farklı-zor yakalayıcılara atlayan karışık kodun hata ayıklama işlemi bir kabus olabilir.

18.7 Tekrar

Buradaki sorular bir çalışma kağıdı şeklinde de indirilebilir:
[docx] [doc] [pdf]

  1. Alttaki terimleri tanımlayın:
    • Hata(İstisna):
    • Hata Yakalama(Başetme):
    • Try bloğu:
    • Catch bloğu:
    • Yakalanmamış hata:
    • Yükseltmek:
  2. Alttaki kodun sayı dönüştürme hatası başarılı olmazsa hatayı yazdıracak şekilde nasıl düzenlenebileceğini gösterin:
    user_input_string = input("Bir sayı girin")
    user_value = int(user_input_string)
    
  3. Alttaki kodun çıktısı ne olacaktır?
    x=5
    y=0
    print("A")
    try:
        print("B")
        a=x/y
        print("C")
    except:
        print("D")
    print ("E")
    print (a)
    
  4. 4. Alttaki kodun çıktısı ne olacaktır?
    x=5
    y=10
    print("A")
    try:
        print("B")
        a=x/y
        print("C")
    except:
        print("D")
    print ("E")
    print (a)
    

You are not logged in. Log in here and track your progress.