28 Nisan 2013 Pazar

Python'da Daha Okunabilir Kod Yazmak

Her ne kadar sitede çeşitli Python konularında eğitimler olsa da, bu eğitimlerin hepsini ilgilendiren, verimliliği ve üretkenliği arttıran bir unsur var: Okunabilirlik.

Okunabilirliğe neden dikkat edilmesi gerekildiği sorulabilir. En başta şunu biliyoruzki Python'da, diğer çoğu popüler dillerdeki gibi gelişigüzel yazamıyoruz. Bu iyi bir şey; geliştiriciler zorla da olsa düzgün kod yazıyorlar ve okunabilirlik artıyor. Aynı zamanda kötü bir şey; en ufak sözdizim hatasında bile program çalışmıyor.

İster yazılımınızı açık kaynak (open-source) olarak geliştirin (tabiki de buna teşvik ediyoruz), isterseniz de kapalı olarak. Her durumda da kodunuzun, okunabilirliğinin ve anlaşılabilirliğinin yüksek olması gerekiyor.

Bu yazıda çeşitli ipuçları ile var olan kodumuzu nasıl daha okunabilir ve anlaşılabilir hale getirebileceğimizden bahsedeceğiz. Örnek olarak ise, Making Games With Python & Pygame adlı kitaptan yararlanarak geliştirdiğimiz aşağıda ki PyGame kodlarını kullanacağız:

import pygame, sys 
from pygame.locals import * 
pygame.init() 
displaysurf=pygame.display.set_mode((400,300)) 
pygame.display.set_caption('Hello World') 
white=(255,255,255) 
green=(0,255,0) 
blue=(0,0,128) 
fontObj=pygame.font.Font('freesansbold.ttf',32) 
textSurfaceObj=fontObj.render('Hello World!',True,green,blue) 
textRectObj=textSurfaceObj.get_rect() 
textRectObj.center=(200,150) 
while 1: 
 displaysurf.fill(white) 
 displaysurf.blit(textSurfaceObj,textRectObj) 
 for event in pygame.event.get(): 
  if event.type==quit: 
   pygame.quit() 
   sys.exit() 
 pygame.display.update()

1 – Boş Satırlara Dikkat!

Evet, gördüğünüz gibi kodun durumu vahim. Bunu yazanı geç, okuyan çocuk bile kör oldu diyebileceğimiz bir halde.

Herşeyden önce asla ve asla boş satır kullanmaktan çekinmeyin. Kodda neyin ne olduğunu anlamanın başlıca yolu, kod parçacıklarını birbirinden ayırt edebilmektir. Dolayısı ile en azından içe aktarma (import), ilklendirme (initialization) ve döngü (loop) kısımlarını ayırmamız, bunların da aralarına boşluk atmamız yararımıza olacaktır.

import pygame, sys 
from pygame.locals import * 

pygame.init() 
displaysurf=pygame.display.set_mode((400,300)) 
pygame.display.set_caption('Hello World') 

white=(255,255,255) 
green=(0,255,0) 
blue=(0,0,128) 

fontObj=pygame.font.Font('freesansbold.ttf',32) 
textSurfaceObj=fontObj.render('Hello World!',True,green,blue) 
textRectObj=textSurfaceObj.get_rect() 
textRectObj.center=(200,150) 

while 1: 
 displaysurf.fill(white) 
 displaysurf.blit(textSurfaceObj,textRectObj) 
 
 for event in pygame.event.get(): 
  if event.type==quit: 
   pygame.quit() 
   sys.exit() 
 
 pygame.display.update()

2 – Bize Boşluk Lazım!

Genellikle atamalar ve kontrol sistemlerinde boşluk kullanımı önemlidir. Değişkeni ve değişkene verilen değeri ya da karşılaştırılan değeri anlayabilmek gereklidir. Bu nedenle atamalar ve kontrol sistemlerinde mutlaka boşluk kullanın. Bunun yanısıra, kodlarınızda virgülle ayırdığınız parametrelere de virgülden sonra boşluk atın.

import pygame, sys 
from pygame.locals import * 

pygame.init() 
displaysurf = pygame.display.set_mode((400, 300)) 
pygame.display.set_caption('Hello World') 

white = (255, 255, 255) 
green = (0, 255, 0) 
blue = (0, 0, 128) 

fontObj = pygame.font.Font('freesansbold.ttf', 32) 
textSurfaceObj = fontObj.render('Hello World!', True, green, blue) 
textRectObj = textSurfaceObj.get_rect() 
textRectObj.center = (200, 150) 

while 1: 
 displaysurf.fill(white) 
 displaysurf.blit(textSurfaceObj, textRectObj) 
 
 for event in pygame.event.get(): 
  if event.type == quit: 
   pygame.quit() 
   sys.exit() 
 
 pygame.display.update()

3 – Çoklu İfadelerde Hizalama da Ne?

Mesela PyGame ile bir oyun geliştiriyorsunuz, belirli renkleri başta yazmak istediniz. Bunları gelişi güzel yazmak yerine birbirine hizalı olarak yazmak anlaşılabilirliği çok etkileyecektir. Aşağıdaki kodda renk atamalarına dikkat edin, RGB renklerini daha anlaşılır bir şekilde atadık.

import pygame, sys 
from pygame.locals import * 

pygame.init() 
displaysurf = pygame.display.set_mode((400, 300)) 
pygame.display.set_caption('Hello World') 

white = (255, 255, 255) 
green = (  0, 255,   0) 
blue  = (  0,   0, 128) 

fontObj            = pygame.font.Font('freesansbold.ttf', 32) 
textSurfaceObj     = fontObj.render('Hello World!', True, green, blue) 
textRectObj        = textSurfaceObj.get_rect() 
textRectObj.center = (200, 150) 

while 1: 
 displaysurf.fill(white) 
 displaysurf.blit(textSurfaceObj, textRectObj) 
 
 for event in pygame.event.get(): 
  if event.type == quit: 
   pygame.quit() 
   sys.exit() 
 
 pygame.display.update()

4- Büyük Büyük Yazalım da Belli Olsun!

Python kodunuzda, en çok kullanacağınız ve en önemli gördüğünüz değişkenleri mutlaka büyük harflerle yazın. Belirliliği arttıracak ve değişkeni rahatça kodun içinden ayırt edebileceksiniz.

import pygame, sys 
from pygame.locals import * 

pygame.init() 
DISPLAYSURF = pygame.display.set_mode((400, 300)) 
pygame.display.set_caption('Hello World') 

WHITE = (255, 255, 255) 
GREEN = (  0, 255,   0) 
BLUE  = (  0,   0, 128) 

fontObj            = pygame.font.Font('freesansbold.ttf', 32) 
textSurfaceObj     = fontObj.render('Hello World!', True, GREEN, BLUE) 
textRectObj        = textSurfaceObj.get_rect() 
textRectObj.center = (200, 150) 

while 1: 
 DISPLAYSURF.fill(WHITE) 
 DISPLAYSURF.blit(textSurfaceObj, textRectObj) 
 
 for event in pygame.event.get(): 
  if event.type == quit: 
   pygame.quit() 
   sys.exit() 
 
 pygame.display.update()

5- Anlat Bakalım Ne Diyor Bu Kod?

Python olsun, diğer diller olsun farketmez. Ufak tefek betikler yazmıyorsanız, mutlaka kodunuzun içine yorum satırları ekleyin. Bunu hem açıklanabilirliği arttırmak, hem de kod segmentlerini (içe aktarma, ilklendirme, döngüler vs.) birbirinden kolayca ayırt etmek için kullanacağız.

# Modülleri içe aktarıyoruz
import pygame, sys 
from pygame.locals import * 

# Temel ilklendirmeleri yapalım
pygame.init() 
DISPLAYSURF = pygame.display.set_mode((400, 300)) 
pygame.display.set_caption('Hello World') 

# Renklerimizi oluşturuyoruz
WHITE = (255, 255, 255) 
GREEN = (  0, 255,   0) 
BLUE  = (  0,   0, 128) 

# Diğer nesneleri ekleyelim
fontObj            = pygame.font.Font('freesansbold.ttf', 32) 
textSurfaceObj     = fontObj.render('Hello World!', True, green, blue) 
textRectObj        = textSurfaceObj.get_rect() 
textRectObj.center = (200, 150) 

# Oyun döngüsünü başlatıyoruz
while 1: 
 DISPLAYSURF.fill(WHITE) 
 DISPLAYSURF.blit(textSurfaceObj, textRectObj) 
 
 for event in pygame.event.get(): 
  if event.type == quit: 
   pygame.quit() 
   sys.exit() 
 
 pygame.display.update()

Bunun daha da ilerisi, kavramsal algılamayı etkileyen, değişken ve fonksiyon isimleri kullanmak (while 1 yerine, while Running gibi) oluyor ama genel olarak baktığımızda başlangıç seviyesi için bu kadarı yeterli.

Bu yazının amacı sadece kodda okunabilirliğe dikkat çekmek idi. İlk kodu ve son kodu ayrı ayrı çalıştırın, hiçbir fark görmeyeceksiniz çalışmasında. Ama kodun okurken, paylaşırken ve tekrardan geliştirirken gerçekten rahatlayacaksınız. Son olarak kodlarımıza bir göz atalım, nereden nereye diye:
 
Kodumuzun ilk hali:

import pygame, sys 
from pygame.locals import * 
pygame.init() 
displaysurf=pygame.display.set_mode((400,300)) 
pygame.display.set_caption('Hello World') 
white=(255,255,255) 
green=(0,255,0) 
blue=(0,0,128) 
fontObj=pygame.font.Font('freesansbold.ttf',32) 
textSurfaceObj=fontObj.render('Hello World!',True,green,blue) 
textRectObj=textSurfaceObj.get_rect() 
textRectObj.center=(200,150) 
while 1: 
 displaysurf.fill(white) 
 displaysurf.blit(textSurfaceObj,textRectObj) 
 for event in pygame.event.get(): 
  if event.type==quit: 
   pygame.quit() 
   sys.exit() 
 pygame.display.update()

Kodumuzun son hali:

# Modülleri içe aktarıyoruz
import pygame, sys 
from pygame.locals import * 

# Temel ilklendirmeleri yapalım
pygame.init() 
DISPLAYSURF = pygame.display.set_mode((400, 300)) 
pygame.display.set_caption('Hello World') 

# Renklerimizi oluşturuyoruz
WHITE = (255, 255, 255) 
GREEN = (  0, 255,   0) 
BLUE  = (  0,   0, 128) 

# Diğer nesneleri ekleyelim
fontObj            = pygame.font.Font('freesansbold.ttf', 32) 
textSurfaceObj     = fontObj.render('Hello World!', True, green, blue) 
textRectObj        = textSurfaceObj.get_rect() 
textRectObj.center = (200, 150) 

# Oyun döngüsünü başlatıyoruz
while 1: 
 DISPLAYSURF.fill(WHITE) 
 DISPLAYSURF.blit(textSurfaceObj, textRectObj) 
 
 for event in pygame.event.get(): 
  if event.type == quit: 
   pygame.quit() 
   sys.exit() 
 
 pygame.display.update()

Making Games With Python & Pygame adlı kitaptan, okunabilirliğe dikkat etmekle ilgili bir kesit:
“Asla böyle kod yazmayın. Eğer böyle programlama yaparsanız, banyoda aynaya bakarken Ada Lovelace'ın hayaleti aynadan çıkar ve sizi jacquard loom'un* ağzına fırlatır!”

* Bilgisayar teknolojisine katkısı olan bir tür dokuma tezgahı
http://en.wikipedia.org/wiki/Jacquard_loom

0 yorum :

Yorum Gönderme