Python Java Eğitim Seti
Python Kapsamlı Eğitim
1.1 Programlamaya Giriş: Kodlamanın İlk Adımları
Programlama, bilgisayara belirli bir görevi yerine getirmesi için adım adım talimatlar verme sanatıdır. Python ise bu talimatları yazmayı en kolay hale getiren dillerden biridir.
Python'ı Benzersiz Kılanlar
- Okunabilirlik: Kod yapısı, doğal İngilizceye çok yakındır.
- Girinti (Indentation) Kuralı: Kod blokları süslü parantez yerine girinti (4 boşluk) ile ayrılır. Bu, düzenli kod yazmayı zorunlu kılar.
- Yorumlanan Dil: Kod, derleme (compilation) gerektirmeden direkt çalıştırılır (interpreter).
İlk Kodumuz:
# Tekrar kullanılabilecek ilk fonksiyonumuzu tanımlıyoruz
def selamla():
print("Python ile programlamaya hoş geldiniz!")
selamla()
1.2 Değişkenler ve Dinamik Veri Tipleri
Değişkenler, verileri (sayıları, metinleri, doğru/yanlış değerlerini) hafızada tutmak için kullanılan etiketlerdir. Python, dinamik tipleme kullandığı için değişken tanımlarken tip belirtmek zorunda kalmayız. Değer atandığında tipi otomatik belirlenir.
Temel Veri Tipleri:
- int: Tam sayılar (Örn:
100) - float: Ondalıklı sayılar (Örn:
3.14) - str: Metinler (Örn:
"Merhaba"- tek veya çift tırnak) - bool: Mantıksal değerler (Sadece
TrueveyaFalse- Büyük Harfe Dikkat!) - NoneType: Bir değerin olmadığını belirtir (Java'daki null karşılığı).
Örnek Tanımlamalar:
isim = "Ayşe"
yas = 30
boy = 1.75
aktif_mi = True
# Değişkenin tipini kontrol etme
print(type(yas)) # Çıktı: <class 'int'>
Önemli Not: Sayı ve metin tipi dönüşümleri (Type Casting) için int(), float(), str() fonksiyonları kullanılır.
1.3 Operatörler: Hesaplama ve Karşılaştırma
Operatörler, değişkenler ve değerler üzerinde işlemler yapmak için kullanılır.
Aritmetik Operatörler:
- + , - , *: Toplama, Çıkarma, Çarpma.
- /: Normal bölme (Sonuç her zaman float'tur).
- //: Tam sayı bölmesi (Sadece tam kısmı alır).
- %: Modülüs (Kalanı bulur).
- **: Üs alma (Örn:
2 ** 3 = 8).
Karşılaştırma Operatörleri (Sonuç: True/False):
- ==: Eşit mi? (Değer eşitliğini kontrol eder)
- !=: Eşit değil mi?
- > , < , >= , <=: Büyük, Küçük, Büyük Eşit, Küçük Eşit.
Mantıksal Operatörler (Anahtar Kelimeler):
- and: VE (Her iki koşul da True ise True)
- or: VEYA (Koşullardan biri True ise True)
- not: DEĞİL (Tersi)
Örnek Uygulama:
sonuc = (10 > 5) and (4 == 4) # True and True = True
print(sonuc)
# Atama operatörü (+=) kısaltması
sayac = 5
sayac += 2 # sayac = sayac + 2
print(sayac) # Çıktı: 7
1.4 Girdi ve Çıktı İşlemleri (print ve input)
Programımızın kullanıcı ile etkileşime girmesini sağlayan temel fonksiyonlardır.
Çıktı İşlemi (print):
Ekrana veri yazdırmak için kullanılır. Birden fazla değişken veya metin virgül (,) ile ayrılabilir.
ad = "Can"
yas = 28
print("İsim:", ad, "Yaş:", yas)
Önemli: F-String Kullanımı (Formatlama):
Değişkenleri metin içine gömmek için en modern ve temiz yol f-string kullanmaktır.
print(f"Benim adım {ad} ve {yas} yaşındayım.")
Girdi İşlemi (input):
Kullanıcıdan veri almak için kullanılır. DİKKAT: input() fonksiyonu, kullanıcı ne girerse girsin (sayı bile olsa) sonucu her zaman String olarak döndürür.
sayi1 = input("Bir sayı girin: ") # 'sayi1' şuan String tipinde!
# Hesaplama yapmak için int/float tipine dönüştürmek gerekir
sayi1_int = int(sayi1)
print(f"Girdiğiniz sayının iki katı: {sayi1_int * 2}")
1.5 Karar Yapıları: Kodun Akışını Yönlendirme
Belirli koşulların doğru olup olmamasına göre programın farklı kod yollarını izlemesini sağlar.
if, elif, else Yapısı:
- if: Koşulun doğru (True) olması durumunda çalışır.
- elif (Else If): İlk koşul yanlışsa, diğer koşulları kontrol eder.
- else: Yukarıdaki koşulların hiçbiri sağlanmazsa çalışır.
Tüm bloklar iki nokta üst üste (:) ile biter ve kod blokları girinti ile tanımlanır.
Örnek:
sicaklik = 32
if sicaklik > 30:
print("Hava çok sıcak.")
elif sicaklik > 20:
print("Hava ılık.")
else:
print("Hava serin.")
Tek Satırda if (Ternary Operator):
durum = "Geçti" if puan >= 50 else "Kaldı"
1.6 Döngüler: Tekrarlayan İşlemler
Aynı komut bloğunu defalarca çalıştırmak için kullanılırlar.
for Döngüsü:
Genellikle bir koleksiyonun (liste, string vb.) her bir elemanını veya belirli bir sayı aralığını gezmek için kullanılır.
Range Kullanımı: range(başlangıç, bitiş, adım) fonksiyonu ile sayı aralığı oluşturulur. Bitiş sayısı dahil değildir.
# 0'dan 4'e kadar (5 dahil değil)
for i in range(5):
print(i)
# Bir listedeki elemanları gezme
meyveler = ["elma", "armut", "muz"]
for meyve in meyveler:
print(meyve)
while Döngüsü:
Belirli bir koşul doğru (True) olduğu sürece çalışmaya devam eder.
hak = 3
while hak > 0:
print(f"Kalan hakkınız: {hak}")
hak -= 1 # Sonsuz döngüden kaçınmak için sayacı güncelleyin
Kontrol İfadeleri (break ve continue):
- break: Döngüyü tamamen durdurur ve döngüden çıkar.
- continue: Mevcut döngü adımının geri kalanını atlar ve bir sonraki adıma geçer.
1.7 Listeler (list): Esnek Diziler
Listeler, birden fazla elemanı tek bir değişken altında depolayan koleksiyonlardır. Python'daki listeler dinamiktir (boyutları değiştirilebilir) ve farklı veri tiplerini bir arada tutabilirler.
Tanımlama ve İndeksleme:
- Köşeli parantezler (
[]) ile tanımlanır. - İndeksleme her zaman 0'dan başlar.
- Negatif indeksleme:
-1son elemanı temsil eder.
Temel Listeler:
sayilar = [10, 20, 30, "Python"] # Farklı tipler bir arada
print(sayilar[1]) # Çıktı: 20
print(sayilar[-1]) # Çıktı: Python
Önemli Metotlar:
- append(): Listeye yeni eleman ekler (listenin sonuna).
- insert(index, element): Belirtilen indekse eleman ekler.
- remove(): Belirtilen değeri listeden kaldırır (ilk bulduğunu).
- pop(): Belirtilen indeksteki elemanı kaldırır ve döndürür.
- len(): Listenin uzunluğunu verir.
Dilimleme (Slicing):
liste = [10, 20, 30, 40, 50]
# 1. indeksten başla, 4. indekse kadar (4 dahil değil)
alt_liste = liste[1:4] # [20, 30, 40]
1.8 String İşlemleri: Metinlerle Çalışmak
Stringler (Metinler), Python'da bir karakter dizisi olarak kabul edilir ve değiştirilemez (Immutable) yapılardır. Yani bir stringin içindeki karakteri doğrudan değiştiremezsiniz; yeni bir string oluşturmanız gerekir.
Temel String Metotları:
- len(): Karakter sayısını verir.
- lower(), upper(): Tüm harfleri küçük/büyük yapar.
- strip(): Başındaki ve sonundaki boşlukları siler.
- split(): Stringi bir ayraç (separator) kullanarak listeye böler.
- replace(eski, yeni): Bir alt dizeyi başka bir alt dizeyle değiştirir.
- startswith(), endswith(): Metnin belirtilen alt dizeyle başlayıp başlamadığını kontrol eder.
String İndeksleme ve Dilimleme:
Stringler de listeler gibi indekslenebilir ve dilimlenebilir.
metin = "Python Eğitimi"
print(metin[0]) # Çıktı: P
print(metin[7:]) # 7. indeksten sonrasını alır: Eğitimi
Birleştirme (Concatenation):
tam_isim = "Ahmet" + " " + "Yılmaz"
1.9 Fonksiyonlara Giriş (def): Kod Tekrarını Önleme
Fonksiyonlar, belirli bir görevi yerine getiren, bir araya getirilmiş kod bloklarıdır. Kodun tekrarını azaltır ve okunurluğu artırır.
Fonksiyon Tanımlama:
def anahtar kelimesi ile tanımlanır.
- Parametreler: Fonksiyona dışarıdan gönderilen değerlerdir.
- return: Fonksiyonun çalışmayı bitirip bir değer döndürmesini sağlar.
returnkullanılmazsa, fonksiyon otomatik olarakNonedöndürür.
Parametresiz ve Geri Dönüşsüz:
def program_basladi():
print("Program başarılı bir şekilde başladı.")
program_basladi()
Parametreli ve Geri Dönüşlü:
def kare_al(sayi):
sonuc = sayi * sayi
return sonuc
kare = kare_al(4)
print(kare) # Çıktı: 16
1.10 Hata Yönetimi: Program Çökmesini Önleme (try/except)
Programın çalışırken beklenmeyen bir durumla (hata/istisna) karşılaşması ve bu duruma hazırlıklı olunmasıdır. Hata yönetiminde Python'da try ve except blokları kullanılır.
Yapısal Kullanım:
- try: Hata çıkma ihtimali olan kod buraya yazılır.
- except:
trybloğunda bir hata oluşursa, program akışı hemen bu bloğa geçer ve buradaki kod çalışır. - finally: Hata olsun ya da olmasın, her zaman çalışmasını istediğimiz kodlar buraya yazılır (Örn: Dosya kapatma).
Örnek: Sıfıra Bölme Hatası:
try:
sayi = int(input("Bir sayı girin: "))
sonuc = 10 / sayi
print(f"Sonuç: {sonuc}")
except ValueError:
print("HATA: Lütfen geçerli bir tam sayı giriniz.")
except ZeroDivisionError:
print("HATA: Bir sayı sıfıra bölünemez.")
finally:
print("İşlem kontrol edildi.")
Bu yapı sayesinde, kullanıcı yanlış bir değer girdiğinde veya sıfıra bölmeye çalıştığında program aniden durmak yerine kullanıcıya anlamlı bir mesaj gösterebilir.
2.1 İleri Fonksiyon Kullanımı: Argüman Çeşitleri
Orta seviyede, fonksiyonları daha esnek ve güçlü kılmak için kullanılan gelişmiş parametre geçirme yöntemlerini inceleriz.
Parametre Çeşitleri:
- Varsayılan Değerler: Parametreye bir değer atanmazsa kullanılacak ön tanımlı değerlerdir.
- Anahtar Kelime Argümanları (Keyword Args): Fonksiyon çağrılırken parametre isminin açıkça belirtilmesi. Bu, argüman sırasını dert etmemizi önler.
Örnek: Varsayılan ve Anahtar Kelime:
def rapor_olustur(ad, dil="Python", seviye="Orta"):
print(f"Rapor: {ad} / Dil: {dil} / Seviye: {seviye}")
rapor_olustur("Ali") # Varsayılanlar kullanılır
rapor_olustur(dil="Java", ad="Veli") # Sıra fark etmez
Değişken Sayıda Argüman (args ve kwargs):
- *args (Tuple): Fonksiyona kaç tane konumsal (sıralı) argüman geleceği bilinmediğinde kullanılır. Argümanlar
tupleolarak alınır. - *kwargs (Dictionary): Fonksiyona kaç tane anahtar-değer (keyword) argüman geleceği bilinmediğinde kullanılır. Argümanlar
dictionaryolarak alınır.
Bu yapılar, fonksiyonları esnek ve yeniden kullanılabilir yapar.
2.2 Modüller ve Kütüphaneler: Kodu Yapılandırma
Bir Modül, Python kodlarının (fonksiyon, sınıf, değişken) bulunduğu tek bir dosyadır (.py uzantılı). Kütüphane (Package) ise ilgili modülleri bir arada tutan bir dizindir.
Modüller, kodun tekrar kullanımını ve organizasyonunu sağlar.
Import Etme Yöntemleri:
- import math: Tüm modülü içe aktarır. Kullanım:
math.sqrt(16) - from math import pi: Sadece belirtilen fonksiyonu/değeri içe aktarır. Kullanım:
print(pi) - import os as i_s: Modülü farklı bir isimle içe aktarır (takma ad). Kullanım:
i_s.getcwd()
Standart Kütüphane Örneği (Random):
import random
# 1 ile 10 arasında rastgele tam sayı üretir
rastgele_sayi = random.randint(1, 10)
print(f"Zar sonucu: {rastgele_sayi}")
Öneri: Genellikle import modul_adi kullanımı tercih edilir, bu sayede hangi fonksiyonun hangi modülden geldiği belli olur.
2.3 Dosya İşlemleri: Veri Kalıcılığı
Programlarımızın bilgisayar hafızası dışında (kalıcı olarak) veri depolaması ve okuması için dosya işlemlerini kullanırız.
Dosya Modları:
- 'r' (read): Okuma modu. (Varsayılan)
- 'w' (write): Yazma modu. Dosya yoksa oluşturur, varsa içeriğini siler.
- 'a' (append): Ekleme modu. Var olan dosyanın sonuna ekler.
En Güvenli Yöntem: with open()
with open(...) yapısı (Context Manager), dosya işlemi bittiğinde veya hata oluştuğunda dosyayı otomatik olarak kapatmayı garanti eder. Bu, kaynak sızıntısını önler.
# Dosyaya veri yazma ('w' modu ile)
with open("rapor.txt", "w", encoding="utf-8") as dosya:
dosya.write("Bu ilk satır.
")
# Dosyayı okuma
with open("rapor.txt", "r", encoding="utf-8") as dosya:
icerik = dosya.read()
print(icerik)
2.4 Nesne Yönelimli Programlama (OOP) Giriş
OOP, programlamada gerçek dünyadaki varlıkları (nesneleri) modellemeye odaklanan bir yaklaşımdır. Büyük ve karmaşık projeleri yönetmeyi, kodun yeniden kullanılabilirliğini ve bakımını kolaylaştırır.
OOP'nin Dört Temel Prensibi:
- Kalıtım (Inheritance): Bir sınıfın başka bir sınıfın özelliklerini ve davranışlarını miras alması.
- Kapsülleme (Encapsulation): Verileri ve bu veriler üzerinde çalışan metotları bir araya getirme ve dışarıdan erişimi kontrol etme.
- Çok Biçimlilik (Polymorphism): Farklı nesnelerin aynı mesaja (metot ismine) farklı şekillerde cevap verebilmesi.
- Soyutlama (Abstraction): Yalnızca önemli bilgileri gösterme ve karmaşık detayları gizleme.
OOP, modern yazılım geliştirmede de facto standart bir yaklaşımdır.
2.5 Sınıflar (Classes) ve Nesneler: Kalıp ve Örnek
Bir Sınıf (Class), bir nesnenin (object) şablonu, planı veya kalıbıdır. Sınıf içinde; özellikler (attributes) (veriler) ve metotlar (methods) (davranışlar) bulunur.
Bir Nesne (Object), sınıftan üretilmiş somut bir örnektir (instance). Bir sınıftan istediğiniz kadar nesne üretebilirsiniz.
self Parametresi:
Sınıf içindeki metotların ilk parametresi her zaman self olmalıdır. self, metodu çağıran nesnenin kendisini temsil eder.
Sınıf ve Nesne Örneği:
class Araba:
def calistir(self): # Metot
print("Araba motoru çalıştı.")
# Nesne oluşturma (Instantiation)
araba1 = Araba()
araba2 = Araba()
araba1.calistir()
2.6 Yapıcılar (Constructors): Nesne Başlatma
Yapıcı (Constructor), bir sınıftan nesne oluşturulduğu anda otomatik olarak çalışan özel bir metottur. Python'da bu metot __init__ adını alır (çift alt çizgiye dikkat).
Görevi: Yeni oluşturulan nesnenin özelliklerine (attributes) ilk değerleri atamak ve nesneyi kullanıma hazırlamaktır.
__init__ Metodu Kullanımı:
class Calisan:
# __init__ yapıcı metot
def __init__(self, isim, maas):
self.isim = isim # Özelliğe değer atama
self.maas = maas
def bilgileri_goster(self):
print(f"Çalışan: {self.isim}, Maaş: {self.maas}")
# Nesne oluşturulurken parametreler zorunludur
personel = Calisan("Kemal", 7000)
personel.bilgileri_goster()
__init__ metodu, sınıfı kullanarak bir nesne oluşturduğunuz her an çağrılır.
2.7 Kalıtım (Inheritance): Yeniden Kullanılabilirlik
Kalıtım, bir sınıfın (Alt Sınıf / Child Class) başka bir sınıftan (Üst Sınıf / Parent Class) tüm özellik ve metotları miras almasını sağlar. Bu sayede kod tekrarı önlenir ve daha hiyerarşik bir yapı kurulur.
super() Kullanımı:
Alt sınıftaki yapıcı metot (__init__) içinde, üst sınıfın yapıcı metodunu çağırmak ve onun özelliklerini de başlatmak için super().__init__(...) kullanılır.
Örnek:
class Hayvan:
def __init__(self, ad):
self.ad = ad
def ses_cikar(self):
pass
class Kedi(Hayvan): # Kedi, Hayvan'dan miras alır
def __init__(self, ad, tur):
super().__init__(ad) # Üst sınıf yapısını çağır
self.tur = tur
def ses_cikar(self):
print(f"{self.ad} miyav diyor.")
tekir = Kedi("Tekir", "Ev Kedisi")
tekir.ses_cikar()
2.8 Kapsülleme (Encapsulation): Bilgi Gizleme
Kapsülleme, veri (özellik) ve bu veriyi manipüle eden metotların tek bir birim (sınıf) içinde toplanmasıdır. Temel amaç, bir nesnenin iç durumuna (verilerine) doğrudan ve kontrolsüz erişimi engellemektir.
Python'da Erişim Kontrolü:
Python'da katı bir 'private' kavramı yoktur; bunun yerine adlandırma kuralları kullanılır:
- Public (Genel): Normal isimler (
isim). Her yerden erişilebilir. - Protected (Korunmuş): Tek alt çizgi ile başlar (
_maas). Geliştiriciye "Buna dışarıdan dokunma" mesajı verir. - Private (Gizli): Çift alt çizgi ile başlar (
__parola). Python ismi değiştirir (Name Mangling) ve erişimi zorlaştırır.
Getter ve Setter Metotları: Kapsüllemeyi sağlamak için, özelliklere doğrudan erişmek yerine, bu metotlar aracılığıyla kontrollü erişim sağlanır.
2.9 Çok Biçimlilik (Polymorphism): Aynı İşlem, Farklı Davranış
Çok Biçimlilik, farklı sınıflardaki nesnelerin aynı isimdeki bir metoda farklı tepkiler verebilmesidir. "Birçok şekil" anlamına gelir ve kodun esnekliğini artırır.
Metot Geçersiz Kılma (Overriding):
Alt sınıfın, üst sınıftan miras aldığı bir metodu kendine özgü bir şekilde yeniden yazmasıdır. (Örn: Hayvan sınıfındaki ses_cikar() metodunu Kedi ve Köpek sınıflarında farklı şekilde uygulamak.)
Örnek:
class Sekil:
def alan_hesapla(self):
pass # Soyut bir metot
class Kare(Sekil):
def __init__(self, kenar):
self.k = kenar
def alan_hesapla(self):
return self.k * self.k # Kare'ye özgü hesaplama
class Ucgen(Sekil):
def alan_hesapla(self):
return "Üçgen formülü burada."
geometrik_nesneler = [Kare(5), Ucgen()]
for nesne in geometrik_nesneler:
print(nesne.alan_hesapla()) # Her nesne farklı cevap verir
2.10 Python Veri Yapıları: Koleksiyon Türleri
Python'daki temel koleksiyon tiplerini derinlemesine inceleme ve aralarındaki farkları anlama, veriyi doğru şekilde depolamayı sağlar.
Mutable (Değiştirilebilir) vs Immutable (Değiştirilemez):
- Değiştirilebilir (List, Dictionary, Set): İçeriği yerinde (bellekteki adresi değişmeden) düzenlenebilir.
- Değiştirilemez (String, Tuple): İçeriği bir kez oluşturulduktan sonra değiştirilemez. Değişiklik yapmak yeni bir nesne oluşturur.
Tuple (Demet): Parantezlerle () tanımlanır. Sıralı ve değiştirilemezdir. Özellikle fonksiyonlardan birden fazla değer döndürmek için idealdir.
Set (Küme): Süslü parantezlerle {} tanımlanır. Sırasızdır ve en önemlisi benzersiz elemanlar içerir (duplicate/tekrarlı eleman barındırmaz).
Dictionary (Sözlük): Anahtar (Key) ve Değer (Value) çiftleri ile çalışır. Anahtarlar benzersiz olmalıdır. {'isim': 'Deniz', 'yas': 25}
2.11 Soyut Veri Yapıları: Stack, Queue, Linked List
Bunlar, veriyi düzenleme ve erişim yöntemlerini tanımlayan temel soyut veri yapısı kavramlarıdır. Python'da genellikle yerleşik listeler kullanılarak modellenirler.
Stack (Yığın - LIFO):
Last In, First Out (Son Giren, İlk Çıkar) prensibiyle çalışır (Tıpkı üst üste dizilmiş tabaklar gibi). İşlemler: push() (ekle), pop() (çıkar).
Queue (Kuyruk - FIFO):
First In, First Out (İlk Giren, İlk Çıkar) prensibiyle çalışır (Tıpkı sinema kuyruğu gibi). İşlemler: enqueue() (ekle), dequeue() (çıkar).
Linked List (Bağlı Liste):
Verilerin, birbirine bağlanan düğümler (Node) halinde saklandığı dinamik bir yapıdır. Her düğüm hem veriyi hem de bir sonraki düğümün adresini tutar. Listenin boyutunun sürekli değiştiği durumlarda verimlidir.
2.12 Hata Yönetimi ve Özel Hata Sınıfları
Sadece var olan hataları yakalamak yerine, programın iş mantığına uymayan durumlar için kendimiz hata tanımlamayı öğreniriz. Bu, hata mesajlarını daha anlamlı hale getirir.
Hata Fırlatma (raise):
Belirli bir koşul oluştuğunda, bilerek bir hata fırlatmak (istisna oluşturmak) için raise anahtar kelimesi kullanılır.
yas = -5
if yas < 0:
raise ValueError("Yaş negatif olamaz!") # Hata fırlatma
Özel Hata Sınıfları (Custom Exceptions):
Kendi hata sınıfınızı oluşturmak için, genellikle Python'ın temel Exception sınıfından miras almanız gerekir.
class GecersizHizHatasi(Exception):
"Sürücünün hızı izin verilen limiti aşıyor."
# Kullanımı:
hiz = 130
if hiz > 120:
raise GecersizHizHatasi("Limit 120km/h'dir.")
2.13 Basit Algoritma Mantığı: Sıralama ve Arama
Algoritma, bir problemi çözmek veya belirli bir görevi yerine getirmek için izlenen adım adım talimatlar dizisidir. Etkili bir programcı olmak için algoritma mantığını anlamak esastır.
Sıralama Mantığı (Bubble Sort Örneği):
Listelerdeki elemanları küçükten büyüğe (veya tersi) dizmek. Bubble Sort, yan yana duran elemanları sürekli karşılaştırarak en büyük (veya en küçük) elemanı listenin sonuna doğru iterek çalışır.
Örnek Problem: Bir listede belirli bir elemanın olup olmadığını en hızlı nasıl buluruz?
Arama Mantığı (Binary Search'e Giriş):
Sıralı bir listede bir elemanı bulmanın en hızlı yollarından biridir. Listenin ortasındaki elemanla aranan değeri karşılaştırır ve listenin yarısını otomatik olarak eler. Her adımda arama aralığını yarıya indirerek çok hızlı sonuç verir. (Ancak listelerin sıralı olması şarttır.)
3.1 Lambda, Map, Filter, Reduce: Fonksiyonel Programlama
Bu araçlar, Python'da fonksiyonel programlama stilini benimseyerek, koleksiyonlar üzerinde hızlı ve okunaklı işlemler yapmamızı sağlar.
Lambda Fonksiyonları (Anonim Fonksiyonlar):
Tek bir ifade ile çalışan, küçük ve isimsiz fonksiyonlardır. Genellikle map ve filter gibi fonksiyonlarla tek seferlik işlem için kullanılır.
kare = lambda x: x * x
print(kare(5)) # Çıktı: 25
Map, Filter, Reduce:
- Map: Bir listenin her elemanına aynı işlemi uygular. Sonuç, yeni bir koleksiyondur.
- Filter: Bir listeden belirli bir koşulu (True/False) sağlayan elemanları seçer.
- Reduce: Bir liste elemanlarını ardışık olarak birleştirerek tek bir sonuç üretir (
functoolsmodülünden import edilmelidir).
Örnek Uygulama:
sayilar = [1, 2, 3, 4, 5]
# Map: Her sayıyı ikiyle çarp
cift_sayilar = list(map(lambda x: x * 2, sayilar))
print(f"Map sonucu: {cift_sayilar}") # [2, 4, 6, 8, 10]
# Filter: Sadece çift sayıları filtrele
sadece_cift = list(filter(lambda x: x % 2 == 0, sayilar))
print(f"Filter sonucu: {sadece_cift}") # [2, 4]
3.2 Generatörler ve Iteratorler: Bellek Verimliliği
Büyük veri setleriyle çalışırken programın hafıza (RAM) kullanımını optimize etmek için kullanılırlar.
Iterator (Yineleyici):
Bir koleksiyonun elemanları üzerinde tek tek gezinmeyi sağlayan bir nesnedir. iter() ile oluşturulur, next() ile bir sonraki elemana erişilir. Tüm elemanlar bellekte tutulur.
Generatör (Üreteç):
Tıpkı normal bir fonksiyon gibi tanımlanır, ancak return yerine yield anahtar kelimesini kullanır. yield, değeri üretir ve fonksiyonun durumunu dondurur. Bir sonraki çağrıldığında kaldığı yerden devam eder.
Avantajı: Değerleri sadece ihtiyaç duyulduğunda (anlık olarak) üretir. Bu sayede, çok büyük seriler için mükemmel bir bellek verimliliği sağlar.
Örnek (Sonsuz Fibonacci Serisi):
def fibonacci_generator():
a, b = 0, 1
while True:
yield a # Değeri döndür ve bekle
a, b = b, a + b
fib_gen = fibonacci_generator()
print(next(fib_gen)) # 0
print(next(fib_gen)) # 1
print(next(fib_gen)) # 1
3.3 Decorator ve Context Manager: Meta Programlama
Bu iki yapı, Python'ın ileri düzey özelliklerindendir ve kodun tekrar kullanımını ve temizliğini büyük ölçüde artırır.
Decorator (Dekoratörler):
Mevcut bir fonksiyonun veya sınıfın kodunu değiştirmeden ona yeni işlevler ekleyen fonksiyonlardır. Genellikle @islev_adi yapısıyla kullanılırlar. (Örn: Bir fonksiyonun çalışma süresini ölçmek).
Örnek Decorator:
def loglama_decorator(func):
def wrapper(*args, **kwargs):
print(f"Fonksiyon çalışıyor: {func.__name__}")
return func(*args, **kwargs)
return wrapper
@loglama_decorator
def topla(a, b):
return a + b
topla(3, 5) # Önce loglama çalışır, sonra toplama
Context Manager’lar (`with`):
Bir kaynağın (dosya, veritabanı bağlantısı, kilit) belirli bir bağlamda güvenli bir şekilde açılıp kapatılmasını yönetir. with open(...) yapısı en temel örneğidir.
Kendimize ait Context Manager'ları __enter__ ve __exit__ metotlarını kullanarak veya contextlib modülündeki @contextmanager dekoratörünü kullanarak oluşturabiliriz.
3.4 Paket Yönetimi ve Sanal Ortamlar: Profesyonel Geliştirme
Büyük projelerde bağımlılıkları yönetmek ve projeler arası çakışmayı önlemek için kritik öneme sahiptir.
Paket Yönetimi (`pip`):
Python'ın standart paket yöneticisi olan pip, harici kütüphaneleri (örneğin: Requests, Pandas) indirip kurmamızı sağlar. Projenin bağımlılıkları genellikle requirements.txt dosyasına yazılır.
# Yükleme:
pip install requests
# Bağımlılıkları kaydetme:
pip freeze > requirements.txt
Sanal Ortamlar (`venv`):
Sanal ortam, her projeye özel izole edilmiş bir Python ortamı oluşturur. Bu, bir projenin kullandığı kütüphane versiyonlarının başka bir projedeki versiyonlarla çakışmasını engeller.
Temel Komutlar:
- Oluşturma:
python -m venv my_env - Aktive Etme (Windows):
my_env\Scripts\activate - Aktive Etme (Linux/Mac):
source my_env/bin/activate
3.5 Dosya Türleriyle Çalışma (JSON, CSV): Veri Değişimi
Modern uygulamalar, yapılandırılmış verileri depolamak ve internet üzerinden değiş tokuş yapmak için yaygın olarak JSON ve CSV formatlarını kullanır. Python bu formatlar için yerleşik modüller sunar.
JSON (`json` modülü):
JavaScript Object Notation. İnsan tarafından okunabilir, hafif bir veri değişim formatıdır. Python'daki Dictionary ve List yapılarına çok benzer.
json.dumps(): Python objesini JSON String'ine çevirir.json.loads(): JSON String'ini Python objesine (Dictionary) çevirir.
JSON Örneği:
import json
veri = {'ad': 'Ali', 'yas': 30}
json_string = json.dumps(veri, indent=4)
print(json_string)
CSV (`csv` modülü):
Comma Separated Values (Virgülle Ayrılmış Değerler). Tablo verilerini (Excel, Veritabanı) depolamak için basit bir formattır.
Python'ın csv modülü, satır bazında okuma (Reader) ve yazma (Writer) işlemlerini kolaylaştırır.
3.6 Veri Tabanı Bağlantısı (ORM): Veri Kalıcılığı
Uygulama verilerini kalıcı olarak depolamak için veri tabanlarını kullanırız. Python'da SQL tabanlı veritabanları ile çalışmanın iki ana yolu vardır: Doğrudan SQL ve ORM.
SQLAlchemy (Popüler ORM):
ORM (Object-Relational Mapping), Python sınıflarını (nesneleri) veritabanı tablolarına eşleyen bir tekniktir. SQL komutlarını elle yazmak yerine, Python kodunu kullanarak veritabanı işlemleri yapmamızı sağlar.
Avantajları:
- SQL bilme gereksinimini azaltır (bazı durumlarda).
- Veritabanı türünü değiştirmeyi (MySQL'den PostgreSQL'e) kolaylaştırır.
- Güvenliği artırır (SQL Enjeksiyonu riskini azaltır).
Temel Adımlar (SQLite Örneği):
Python'ın yerleşik sqlite3 modülü ile veritabanına bağlanılabilir, sorgular çalıştırılabilir ve sonuçlar alınabilir.
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# Tablo oluşturma (ORM olmadan)
cursor.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER, name TEXT)')
conn.close()
3.7 API ve Web İstekleri (HTTP, REST): Uygulama İletişimi
API'ler (Application Programming Interface), farklı yazılım sistemlerinin birbirleriyle konuşmasını sağlayan kurallar ve protokollerdir. Web tabanlı API'ler genellikle HTTP protokolü ve REST mimarisine dayanır.
HTTP Metotları:
Sunucuya ne tür bir işlem yapılacağını belirtiriz:
- GET: Veri almak için kullanılır.
- POST: Yeni veri oluşturmak (göndermek) için kullanılır.
- PUT/PATCH: Var olan veriyi güncellemek için kullanılır.
- DELETE: Veriyi silmek için kullanılır.
Requests Kütüphanesi:
Python'da web isteği yapmanın en popüler ve kullanıcı dostu yolu Requests kütüphanesidir.
# pip install requests ile kurulmalıdır
import requests
response = requests.get('https://api.github.com/users/google')
if response.status_code == 200: # Başarılı yanıt kodu
veri = response.json()
print(f"Kullanıcı adı: {veri['login']}")
else:
print("Hata oluştu.")
3.8 Asenkron Programlama (async / await): Performans Artışı
Asenkron (Eş Zamansız) programlama, bir programın uzun süreli I/O işlemlerini (Web isteği, Dosya okuma/yazma, DB sorgusu) beklerken CPU'yu bloke etmeden diğer işleri yapmaya devam etmesini sağlar. Python'da asyncio kütüphanesi ve async/await anahtar kelimeleri kullanılır.
async ve await:
- async def: Bu fonksiyonun bir "coroutine" olduğunu, yani asenkron olarak çalışabileceğini belirtir.
- await: Bir coroutine'in bitmesini beklerken, programın kontrolü geri vermesini ve diğer coroutine'lerin çalışmasına izin vermesini sağlar.
Örnek:
import asyncio
async def zaman_alan_islem(gecikme):
print(f"Başladı: {gecikme} saniye bekleyecek")
await asyncio.sleep(gecikme) # Beklerken diğer işler çalışabilir
print(f"Bitti: {gecikme} saniye")
async def main():
# Bu iki işlem eş zamanlı çalışır, toplam süre 3 saniye civarında olur.
await asyncio.gather(
zaman_alan_islem(3),
zaman_alan_islem(1)
)
# asyncio.run(main())
3.9 Çoklu İş Parçacığı (Multithreading): Paralel Çalışma
Multithreading, bir programın aynı anda birden fazla görev (iş parçacığı/thread) yürütmesini sağlar. Özellikle I/O yoğun görevlerde (API isteği, ağ iletişimi, dosya okuma) performansı artırmak için kullanılır.
Global Interpreter Lock (GIL) Kısıtlaması:
Python'da GIL, aynı anda sadece bir iş parçacığının Python bayt kodunu çalıştırmasına izin verir. Bu nedenle, CPU yoğun görevlerde (matematiksel hesaplamalar) Multithreading gerçek paralellik sağlamaz (Bunun için multiprocessing kullanılır).
`threading` Modülü:
import threading
import time
def print_squares(number):
time.sleep(1) # I/O beklemesi simülasyonu
print(f"{number} karesi: {number * number}")
t1 = threading.Thread(target=print_squares, args=(10,))
t2 = threading.Thread(target=print_squares, args=(20,))
t1.start()
t2.start() # İki görev neredeyse aynı anda başlar
t1.join() # Thread'in bitmesini bekle
Önemli: GIL nedeniyle Multithreading, I/O operasyonlarında asenkron programlamaya benzer bir verimlilik sağlar.
3.10 Birim Testleri (Unit Testing): Kod Güvenilirliği
Birim Testleri, yazılımın en küçük bağımsız parçalarının (fonksiyonlar, metotlar) beklendiği gibi çalışıp çalışmadığını kontrol etme sürecidir. Temiz ve sürdürülebilir kodun temelini oluşturur.
Python'da Test Araçları:
- `unittest` Modülü: Python'ın standart kütüphanesinde yer alan test çatısıdır. Sınıf tabanlı bir yaklaşımla test case'leri ve süitleri oluşturmayı sağlar.
- `pytest` (Harici): Daha popüler bir harici kütüphanedir. Daha az kod gerektirir ve daha okunaklı, basit bir yapı sunar.
Unittest Örneği:
import unittest
def topla(a, b):
return a + b
class TestToplama(unittest.TestCase):
def test_iki_pozitif_sayi(self):
self.assertEqual(topla(3, 5), 8)
def test_negatif_sayilar(self):
self.assertEqual(topla(-1, 1), 0)
# if __name__ == '__main__':
# unittest.main()
Profesyonel bir uygulamada, her bir fonksiyonun temel durumları ve köşe durumları testlerle kontrol edilmelidir.
4.1 Yazılım Mimarisi: Büyük Resmi Yönetmek
Yazılım Mimarisi, bir sistemin yapısını, bileşenlerini ve bu bileşenlerin birbirleriyle olan ilişkilerini tanımlar. Büyük ölçekli uygulamaların sürdürülebilir, test edilebilir ve ölçeklenebilir olmasını sağlar.
Model-View-Controller (MVC) Mimarisi:
Geliştirmeyi 3 ana bileşene ayırır, bu da sorumlulukların net bir şekilde ayrılmasını sağlar:
- Model: Uygulamanın verileri ve iş mantığı (Data Access, Validasyon). (Python'da ORM sınıfları)
- View: Kullanıcıya sunulan arayüz (HTML, Template).
- Controller: Model ve View arasındaki köprüdür. Kullanıcı girdilerini alır, modeli günceller ve doğru View'ı seçer. (Python'da Django Views/Flask Routes)
Katmanlı Mimari (Layered Architecture):
Uygulamayı dikey olarak mantıksal katmanlara ayırır (Sunum, İş, Veri Erişim, vb.). Her katman yalnızca bir altındaki katmanla konuşur. Bu, modülerliği ve bağımsızlığı artırır.
Katman Örneği: Presentation Layer (API) -> Business Logic Layer -> Data Access Layer (ORM) -> Database
4.2 Design Patterns (Tasarım Kalıpları): Kanıtlanmış Çözümler
Tasarım Kalıpları, yazılım tasarımında sık karşılaşılan sorunlara getirilen yeniden kullanılabilir çözümlerdir. Kalıpları bilmek, daha temiz, esnek ve anlaşılır kod yazmanızı sağlar.
Temel Kategoriler:
- Yaratımsal (Creational): Nesne yaratma mekanizmalarını soyutlar. (Örn: Factory, Singleton)
- Yapısal (Structural): Sınıfların ve nesnelerin birleştirilmesiyle daha büyük yapılar oluşturur. (Örn: Adapter, Decorator, Facade)
- Davranışsal (Behavioral): Nesneler arası iletişimi ve sorumluluk atamasını yönetir. (Örn: Observer, Strategy)
Örnek: Singleton (Yaratımsal)
Bir sınıftan sadece tek bir nesne oluşturulmasını garanti eder. (Örn: Veritabanı bağlantı havuzu, Loglama yöneticisi).
class AyarYoneticisi:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(AyarYoneticisi, cls).__new__(cls)
return cls._instance
# a ve b aynı nesneyi temsil eder
a = AyarYoneticisi()
b = AyarYoneticisi()
print(a is b) # True
4.3 Framework Kullanımı: Django ve Flask
Framework'ler, web uygulamaları geliştirmek için gereken temel yapıları, araçları ve standartları sağlayarak geliştirme sürecini hızlandırır ve profesyonel bir zemin oluşturur.
Django (The Web Framework For Perfectionists):
Büyük ve karmaşık uygulamalar (monolitik) için idealdir. "Batteries Included" (Piller dahil) felsefesiyle gelir; ORM, Admin Paneli, Routing, Template Engine gibi her şey hazırdır.
- Mimarisi: MTV (Model-Template-View) (MVC'nin Django'ya uyarlanmış hali).
- Hız: Geliştirme hızı yüksektir, ancak başlangıçta öğrenme eğrisi biraz daha dik olabilir.
Flask (Micro-Framework):
Basit API'ler, küçük servisler veya mikro servisler için idealdir. Minimum çekirdek özelliklerle başlar ve ihtiyaca göre kütüphaneler eklenir.
- Mimarisi: Serbest yapıdadır, geliştirici kendi mimarisini (MVC, Layered) oluşturur.
- Esneklik: Hangi ORM'i, hangi veritabanını, hangi kimlik doğrulama sistemini kullanacağınıza siz karar verirsiniz.
4.4 API Geliştirme ve Entegrasyon (RESTful Servisler)
API geliştirmede ana hedef, verilerinizi standart HTTP metotları (GET, POST, PUT, DELETE) ve kaynak tabanlı URL'ler kullanarak dış dünyaya sunmaktır. Bu genellikle REST (Representational State Transfer) mimarisiyle yapılır.
REST Prensipleri:
- Kaynak Odaklı: Veriler, URL'lerde isimlerle temsil edilir (örn:
/users/123). - Durumsuz (Stateless): Sunucu, iki istek arasındaki istemci durumunu hatırlamaz. Her istek, işlemi tamamlamak için gerekli tüm bilgiyi içermelidir.
- Kesin HTTP Metotları: Her işlem doğru HTTP metoduyla eşleştirilir.
Python'da Geliştirme Araçları:
Django Rest Framework (DRF) veya Flask-RESTful gibi kütüphaneler, RESTful API'leri hızlı ve güvenli bir şekilde oluşturmak için kullanılır.
Entegrasyon İpuçları: Farklı sistemlerle entegrasyon yaparken, API anahtarları (API Keys), OAuth veya JWT (JSON Web Token) gibi modern kimlik doğrulama yöntemlerini kullanmak esastır.
4.5 Versiyon Kontrol (Git, GitHub): İşbirliği ve Geri Alma
Git, profesyonel yazılım geliştirmenin temel taşıdır. Kod tabanındaki değişiklikleri takip etmemizi, farklı özellikler üzerinde paralel çalışmamızı (branching) ve hatalı kodları kolayca geri almamızı sağlar.
Temel Git Akışı (Git Flow):
- Branching: Her yeni özellik veya hata düzeltmesi için ana koddan (genellikle
mainveyamaster) ayrı bir dal (branch) oluşturmak. - Commit: Yapılan değişiklikleri yerel depoya kaydetmek.
- Pull Request/Merge Request: Çalışmayı ana dal ile birleştirmek için resmi bir istek oluşturmak ve kod incelemesi (Code Review) yapmak.
GitHub/GitLab/Bitbucket: Bu servisler, Git depolarını uzaktan barındırarak takım çalışmasını ve kodun yedeklenmesini sağlar.
Profesyonel İpucu: Her zaman küçük, atomik (tek bir göreve odaklanmış) commit'ler yapın. Commit mesajlarınızda neyin neden değiştiğini açıklayın.
4.6 CI/CD ve DevOps Temelleri: Otomasyon
DevOps, yazılım geliştirmeyi (Dev) operasyonlarla (Ops) birleştiren bir kültür, uygulama ve araçlar bütünüdür. Amacı, daha hızlı ve güvenilir yazılım teslimatı yapmaktır.
Sürekli Entegrasyon (Continuous Integration - CI):
Geliştiricilerin kod değişikliklerini sık sık (günde birkaç kez) ana depoya entegre etme pratiğidir. Her entegrasyon, otomatik olarak test edilir ve doğrulama yapılır.
Sürekli Teslimat/Dağıtım (Continuous Delivery/Deployment - CD):
CI başarılı olduktan sonra, yazılımı otomatik olarak test ortamlarına (Delivery) veya doğrudan canlı ortama (Deployment) gönderme sürecidir.
Örnek Araçlar: Jenkins, GitHub Actions, GitLab CI, Docker, Kubernetes.
Örnek (Docker): Uygulamanızı ve tüm bağımlılıklarını tek bir kapsayıcı (container) içine alarak her ortamda aynı şekilde çalışmasını garantiler.
# Basit bir Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]
4.7 Veri Tabanı Tasarımı: Veri Bütünlüğü ve Performans
Veri tabanı tasarımı, verilerin mantıksal olarak yapılandırılması, depolanması ve bu sayede hızlı ve güvenilir bir şekilde erişilebilmesi için kritik öneme sahiptir.
Normalizasyon (Normalization):
Veri tekrarını (redundancy) en aza indirmek ve veri tutarlılığını sağlamak için tabloları belirli kurallara (1NF, 2NF, 3NF vb.) göre düzenleme sürecidir.
İlişkiler ve Anahtarlar:
- Primary Key (PK): Tablodaki her satırı benzersiz şekilde tanımlayan sütun (örn:
user_id). - Foreign Key (FK): Başka bir tablonun PK'sine referans veren sütun. Tablolar arası ilişkiyi kurar.
- İlişki Türleri: Bire Bir (1-1), Bire Çok (1-N), Çoka Çok (N-M - ara tablo gerektirir).
Veri Tabanı Türleri: İlişkisel (PostgreSQL, MySQL) ve İlişkisel Olmayan (NoSQL - MongoDB, Redis) arasındaki farkları ve ne zaman hangisinin kullanılacağını bilmek uzmanlık gerektirir.
4.8 Güvenlik Temelleri: Authentication ve Yetkilendirme
Güvenlik, profesyonel yazılım geliştirmenin en önemli yönüdür. Kullanıcı kimliğini doğrulama ve yetkilerini yönetme süreçleri kritik öneme sahiptir.
Authentication (Kimlik Doğrulama):
Kullanıcının iddia ettiği kişi olduğunu kanıtlama süreci (Kullanıcı adı/parola, 2FA).
Parola Saklama: Parolalar asla düz metin (plain text) olarak saklanmamalıdır. Sanalama (Hashing) algoritmaları (örneğin: bcrypt, Argon2) kullanılmalıdır.
Authorization (Yetkilendirme):
Kullanıcının kimliği doğrulandıktan sonra, sistem içinde hangi kaynaklara erişebileceğini belirleme (Rol Tabanlı Erişim Kontrolü - RBAC).
Önemli Güvenlik Açıkları (OWASP Top 10):
- SQL Injection: Kullanıcı girdileri ile SQL sorgularını değiştirmeye çalışmak. (Önlem: ORM kullanmak veya Parametreli Sorgular)
- Cross-Site Scripting (XSS): Kötü amaçlı istemci tarafı betiği enjekte etmek. (Önlem: Girdileri filtrelemek)
4.9 Performans Optimizasyonu: Hız ve Verimlilik
Uygulamaların yavaşlaması veya yüksek yük altında çökmesi, iş kaybına neden olur. Optimizasyon, bu sorunları önlemek için programın hızını ve kaynak (CPU, Bellek) kullanımını iyileştirme sürecidir.
Profilleme (Profiling):
Kodun hangi bölümlerinin en çok zaman aldığını veya en çok belleği tükettiğini tespit etme. Python'da cProfile ve timeit gibi modüller kullanılır.
Optimizasyon Teknikleri:
- Önbellekleme (Caching): Sık erişilen verileri (DB sorgu sonuçları, API yanıtları) hızlı bir depolama alanında (Redis, Memcached) tutmak.
- Sorgu Optimizasyonu: ORM kullanırken "N+1" probleminden kaçınmak (ön yükleme/prefetch).
- Asenkron/Paralel İşlem: I/O bekleme sürelerini azaltmak için
asyncioveyaMultithreadingkullanmak. - Veri Yapısı Seçimi: İşleme en uygun veri yapısını kullanmak (örneğin: arama için Set veya Dictionary kullanmak).
4.10 Büyük Ölçekli Proje Yönetimi ve SOLID
Büyük bir yazılım projesini başarıyla yönetmek sadece kod yazmaktan fazlasını gerektirir; mimari tutarlılık, işbirliği ve süreç yönetimi esastır.
Yazılım Geliştirme Metodolojileri:
- Agile (Çevik): Değişime hızlı adapte olmayı ve kısa iterasyonlarla (Sprint) değer sunmayı vurgular.
- Scrum/Kanban: Agile'ın uygulanma çerçeveleridir.
SOLID Prensipleri (Temiz Kodun Anahtarı):
OOP tabanlı yazılımları daha esnek, anlaşılır ve sürdürülebilir hale getiren 5 temel prensiptir:
- Single Responsibility Principle (Tek Sorumluluk Prensibi)
- Open/Closed Principle (Açık/Kapalı Prensibi)
- Liskov Substitution Principle (Liskov Yerine Koyma Prensibi)
- Interface Segregation Principle (Arayüz Ayırma Prensibi)
- Dependency Inversion Principle (Bağımlılık Tersine Çevirme Prensibi)
Örnek (SRP): Bir sınıfın yalnızca tek bir nedeni olmalıdır. Bir Kullanici sınıfı, hem kullanıcıyı kaydetme (Veri Katmanı) hem de kullanıcıya e-posta gönderme (İş Katmanı) işlerini yapmamalıdır.
5.1 Algoritma ve Veri Yapıları: Programcılığın Temeli
Programlamada hız ve verimlilik, doğru algoritma ve veri yapısı seçimine bağlıdır. Bu alan, sadece bir görevi çalıştırmak değil, onu en hızlı ve en az kaynakla çalıştırmakla ilgilidir.
Big O Notasyonu (Büyü O):
Bir algoritmanın performansı, giriş verisi boyutu büyüdükçe nasıl ölçekleneceğini (zaman ve bellek) matematiksel olarak ifade etme yöntemidir. En çok rastlananlar: O(1) sabit, O(log n) logaritmik, O(n) lineer ve O(n²) karesel.
Örnek: Bir listede eleman ararken; sıralı listelerde İkili Arama (Binary Search) O(log n) iken, sıralı olmayan listelerde basit lineer arama O(n)'dir.
Önemli Veri Yapıları:
- Hash Tabloları (Dictionaries): Python'da Dictionary olarak geçer. O(1) sabit zamanda arama, ekleme ve silme işlemlerini sağlar, bu nedenle en çok tercih edilen yapıdır.
- Ağaçlar (Trees): Hiyerarşik verileri (örneğin: dosya sistemi) depolamak ve optimize edilmiş arama (Binary Search Tree) yapmak için kullanılır.
- Grafikler (Graphs): İlişkileri (örneğin: sosyal ağlar, haritalar) modellemek için kullanılır. Yol bulma (Dijkstra) gibi karmaşık problemlerin çözümünde esastır.
Öğrenme Kaynağı: GeeksforGeeks'te popüler Algoritma ve Veri Yapıları (İngilizce)
5.2 Matematik ve Mantık Temelleri: Sorun Çözme Yeteneği
Programlama, matematiksel ve mantıksal düşüncenin uygulamasıdır. Bu temelleri anlamak, sadece kod yazmak değil, aynı zamanda problemleri etkin bir şekilde modellemek için gereklidir.
Ayrık Matematik Konuları:
- Küme Teorisi: Veri yapılarını (Setler, Kümeler) ve ilişkileri anlamak için temeldir.
- Mantık ve İspat: Koşullu ifadeler (if-else), döngü invaryantları ve algoritma doğrulaması için gereklidir.
- Olasılık ve İstatistik: Yapay zeka, makine öğrenimi ve veri analizi projelerinin temelini oluşturur.
Boolean Cebiri ve Mantık:
Tüm programlama dilleri, True ve False değerlerine dayanan Boolean mantığı üzerinde çalışır. Operatörler (AND, OR, NOT) ve De Morgan yasaları gibi konular, karmaşık koşulları temiz bir şekilde yazmanızı sağlar.
# x veya y yanlışsa, bu ifade yanlıştır.
# Mantık: not (A and B) == (not A or not B)
gecerli = not (hata_var and kullanici_engellendi)
Uzman İpucu: Basit matematiksel serileri ve sayı teorisini (asal sayılar, modüler aritmetik) bilmek, kriptografi ve bazı algoritma sorularında büyük avantaj sağlar.
5.3 Yazılım Testi ve Hata Ayıklama (Debugging)
Hata tespiti ve güvenilirliği sağlamak için test yazmak, kod yazmak kadar önemlidir. Hiçbir zaman 'hata içermeyen' bir kod yoktur; sadece 'yeterince test edilmiş' kod vardır.
Temel Test Çeşitleri:
- Birim Testi (Unit Test): Kodun en küçük parçalarını (fonksiyonlar, metotlar) izole ederek test eder.
- Entegrasyon Testi (Integration Test): Birden fazla bileşenin (örneğin: veritabanı bağlantısı, API entegrasyonu) birlikte çalışmasını test eder.
- Uçtan Uca Test (End-to-End Test): Kullanıcının yaptığı gibi, uygulamanın tamamını test eder (örneğin: bir web formu doldurup göndermek).
Hata Ayıklama (Debugging) Teknikleri:
Hata ayıklama, bir kodun neden beklendiği gibi çalışmadığını bulma sürecidir. Python'da pdb (Python Debugger) veya IDE'lerin (VS Code, PyCharm) yerleşik araçları kullanılır.
Debugging Adımları:
- Breakpoint (Kırılma Noktası) Koyma: Kodun o noktada durmasını sağlama.
- Step Into/Over: Adım adım ilerleme ve değişkenlerin o anki değerlerini gözlemleme.
- Değişken İzleme: Hata ayıklayıcıda (Debugger) kritik değişkenlerin değerlerini anlık olarak görme.
5.4 Temel Ağ (Network) Bilgisi: Uygulama İletişimi
Modern yazılım, neredeyse her zaman bir ağ üzerinden iletişim kurar. Ağ temellerini anlamak, API'lerin nasıl çalıştığını ve uygulamaların neden yavaşladığını anlamak için kritiktir.
TCP/IP ve OSI Modelleri:
Verinin kaynaktan hedefe nasıl iletildiğini katmanlar halinde açıklar (Uygulama, Taşıma, İnternet, Ağ Erişimi). Web uygulamaları, genellikle Uygulama Katmanında çalışan HTTP/HTTPS protokolünü kullanır.
IP Adresi ve Portlar:
IP Adresi: Bir cihazın ağdaki benzersiz adresidir (örn: 192.168.1.1).
Port: Bir cihazdaki belirli bir uygulamayı veya servisi tanımlayan numara (örn: HTTP için 80, HTTPS için 443, genellikle web uygulamaları için 8000/5000).
DNS ve Güvenlik (HTTPS):
DNS (Domain Name System): Alan adlarını (google.com) IP adreslerine çeviren telefon rehberidir. Uygulamanızın doğru sunucuya ulaşmasını sağlar.
HTTPS: HTTP'nin güvenli sürümüdür. Veri iletimini şifrelemek için SSL/TLS protokolünü kullanır. Tüm profesyonel uygulamalarda zorunludur.
5.5 API Dokümantasyonu ve Swagger/OpenAPI
Geliştirilen API'lerin diğer geliştiriciler (hem ekip içi hem dışı) tarafından kolayca anlaşılabilmesi ve kullanılabilmesi için dokümantasyon hayati önem taşır. Bu alanda standart haline gelen araçlar Swagger ve OpenAPI spesifikasyonudur.
OpenAPI Spesifikasyonu (OAS):
RESTful API'lerin yapısını (uç noktalar, parametreler, yanıt formatları, kimlik doğrulama) makine ve insan tarafından okunabilir bir formatta (JSON veya YAML) tanımlayan bir standarttır.
Swagger (Araç Seti):
OpenAPI spesifikasyonunu temel alan araçlar bütünüdür:
- Swagger UI: OpenAPI dosyasını alıp otomatik olarak etkileşimli, güzel bir web sayfası (dokümantasyon) oluşturan araçtır. Bu sayfada API uç noktalarını deneyebilirsiniz.
- Swagger Editor: OAS dosyalarını yazmanıza ve doğrulamanıza yardımcı olur.
Python'da Kullanımı: Flask/Django projelerinde (örneğin: DRF-Spectacular, Flasgger) kodunuzu okuyarak otomatik olarak OpenAPI uyumlu JSON/YAML dosyası oluşturulabilir. Bu sayede manuel dokümantasyon yükü azalır.
5.6 Yazılımda Etik ve Sürdürülebilirlik
Uzman bir yazılımcı sadece kodun teknik yönünü değil, uygulamanın toplumsal etkilerini ve uzun vadeli sürdürülebilirliğini de düşünmelidir.
Yazılım Etiği Konuları:
- Gizlilik (Privacy): Kullanıcı verilerinin toplanması, saklanması ve işlenmesinin şeffaf ve güvenli olması. (Örn: GDPR/KVKK uyumluluğu).
- Tarafsızlık (Bias): Algoritmaların, özellikle Makine Öğrenimi modellerinin, veri setlerindeki önyargıları (ırk, cinsiyet vb.) yansıtmamasını sağlamak.
- Erişilebilirlik (Accessibility): Engelli kullanıcılar dahil, herkesin uygulamayı kullanabilmesini sağlamak. (Örn: WCAG standartları).
Sürdürülebilirlik ve Yeşil Kod:
Bir uygulamanın çevre üzerindeki etkisini minimize etmek (enerji verimliliği) de yeni bir etik sorumluluktur. Daha az enerji tüketen, daha optimize algoritmalar ve daha verimli donanım kullanımı önemlidir.
Sorumluluk: Bir projede kullanılan kütüphanelerin lisanslarını (MIT, GPL, vb.) kontrol etmek ve hukuki riskleri yönetmek de uzman seviye geliştirici sorumluluğudur.