
# Python, 1991 yılında Guido van Rossum tarafından geliştirilen ve günümüzde dünya çapında popüler olan bir programlama dilidir.
# Python, hem yeni başlayanlar hem de deneyimli yazılımcılar için ideal bir dil olarak kabul edilir.
# İşte Python'un temel özellikleri ve avantajları:
# 1. Okunabilirlik ve Sadelik
# Python, kodun okunabilirliği ve anlaşılabilirliğine büyük önem verir. Bu nedenle, sözdizimi (syntax) oldukça basittir ve kod yazarken
# karmaşık kurallara takılmadan, anlaşılır bir şekilde programlar yazabilirsiniz.
# 2. Yüksek Seviyeli Programlama Dili
# Python, yüksek seviyeli bir dildir, yani dilin kendisi birçok düşük seviyeli işlemi (örneğin bellek yönetimi) sizin için halleder.
# Bu, yazılımcıların daha az kod yazarak işlerini halletmelerini sağlar.
# 3. Dinamik Tip Sistemi
# Python, dinamik bir tip sistemine sahiptir. Bu, değişkenlerin veri tiplerinin çalıştırma zamanında belirlendiği anlamına gelir.
# Yani, bir değişkenin türünü başta belirtmenize gerek yoktur.
# 4. Zengin Kütüphane ve Modüller
# Python, çok geniş bir standart kütüphane ve modül koleksiyonuna sahiptir. Web geliştirme, veri analizi, yapay zeka, otomasyon,
# oyun geliştirme gibi birçok farklı alanda Python kütüphaneleri mevcuttur.
# 5. Taşınabilirlik
# Python, birçok farklı platformda (Windows, macOS, Linux) çalışabilir. Bu sayede yazdığınız Python kodunu farklı işletim sistemlerinde
# kullanabilirsiniz.
# 6. Çok Yönlülük
# Python, aşağıdaki gibi birçok farklı alanda kullanılabilir:
# Web Geliştirme: Flask ve Django gibi frameworkler ile güçlü web uygulamaları geliştirebilirsiniz.
# Veri Bilimi ve Yapay Zeka: Pandas, NumPy, Scikit-learn gibi kütüphaneler ile veri analizi yapabilir, yapay zeka projeleri
# geliştirebilirsiniz.
# Oyun Geliştirme: Pygame gibi kütüphanelerle oyunlar yazabilirsiniz.
# Otomasyon ve Scripting: Python, günlük görevleri otomatikleştirmek için sıklıkla kullanılır.
# 7. Topluluk ve Destek
# Python'un büyük bir geliştirici topluluğu vardır ve bu topluluk, dilin gelişimine katkıda bulunur. Ayrıca, Python ile ilgili her türlü
# soruyu kolayca çözebileceğiniz çok sayıda kaynak bulunmaktadır.
# Sonuç olarak:
# Python, öğrenmesi kolay, esnek, güçlü ve çok yönlü bir programlama dilidir. Başlangıç seviyesindeki geliştiriciler için mükemmel
# bir tercih olmasının yanı sıra, profesyonel projeler için de güçlü bir araçtır.
_sad = "merhaba"
print(_sad)
Python Kursuna Nasıl Çalışmalıyım?
Python öğrenmeye başlamak heyecan verici bir yolculuktur! Ancak, başarılı olabilmek için doğru bir yaklaşım benimsemek önemlidir. İşte Python kursunu en verimli şekilde nasıl çalışmanız gerektiğiyle ilgili bazı ipuçları:
1. Kurs İçeriğini Anlamaya Çalışın
Her derse başlamadan önce, kursun genel yapısını ve derslerin amacını anlamaya çalışın. Kursun hangi konuları kapsayacağını ve her modülün hedefini öğrenmek, size daha net bir yol haritası sunacaktır.
Modül Hedefleri: Her dersin başında o dersin hedeflerini ve öğrendiklerinizi not alın.
Kapsanan Konular: Python'un temellerinden ileri düzey konulara kadar geniş bir yelpazede bilgiler edineceksiniz. Bu konuları sırayla takip etmek önemlidir.
2. Teori ve Pratik Dengesini Kurun
Python sadece teorik bilgiyle öğrenilemez. Her öğrendiğiniz konuyu uygulamalı olarak denemelisiniz.
Teorik Bilgi: Her dersin başında o konunun teorik kısmını dikkatlice dinleyin ve not alın. Anlamadığınız yerleri tekrar edin.
Pratik Yapın: Öğrendiğiniz her konuyu uygulamaya dökün. Kendi başınıza küçük alıştırmalar yaparak, yeni öğrendiğiniz bilgileri pekiştirebilirsiniz.
3. Kod Yazarken Hata Yapmaktan Korkmayın
Python öğrenmenin bir parçası da hata yapmaktır. Yazdığınız kodda hatalar oluşabilir, ancak bu hataları anlamak ve çözmek öğrenmenizin bir parçasıdır.
Hataları Anlayın: Hata aldığınızda, hata mesajlarını dikkatlice okuyun. Hatanın ne olduğunu anlamaya çalışın ve çözüm arayarak kodunuzu düzeltin.
Deneyin ve Dönüştürün: Kodunuzu farklı şekillerde yazarak denemeler yapın. Bu, becerilerinizi geliştirmenize yardımcı olacaktır.
4. Alıştırmaları Düzenli Olarak Yapın
Her dersten sonra verilen alıştırmalar, öğrendiğiniz bilgileri pekiştirmeniz için çok önemlidir. Bu alıştırmaları mutlaka yapmalısınız.
Alıştırmaları Tamamlama: Alıştırmalar, öğrendiğiniz her konuyu test etmenin ve pratik yapmanın harika bir yoludur. Kurs boyunca ne kadar çok pratik yaparsanız, o kadar hızlı ilerlersiniz.
Zorlayıcı Alıştırmalar: Karşınıza zorlayıcı alıştırmalar çıkarsa, pes etmeyin! Bu tür alıştırmalar sizin daha iyi öğrenmenizi sağlayacaktır.
5. Proje Bazlı Öğrenmeye Geçin
Kursun ilerleyen bölümlerinde öğrendiklerinizi birleştirerek küçük projeler yapmaya başlayın. Proje yapmak, öğrendiğiniz her şeyi bir araya getirmenizi sağlar ve çok daha sağlam bir bilgi kazandırır.
Küçük Projeler: Basit uygulamalar veya araçlar yaparak öğrenmenizi pekiştirebilirsiniz. Örneğin, bir hesap makinesi, hava durumu uygulaması veya basit bir oyun yazabilirsiniz.
Büyük Projeler: Kursun sonunda daha kapsamlı projelere geçerek öğrendiklerinizi gerçek dünya problemleri üzerinde uygulayın.
6. Zamanı Yöneterek Çalışın
Python öğrenirken düzenli ve sürekli çalışmak önemlidir. Her gün belirli bir süre ayırarak öğrenme sürecinizi disiplinli bir hale getirebilirsiniz.
Günlük Çalışma Süresi: Her gün en az 30 dakika Python çalışarak, konuları sindirerek ilerleyin.
Kendi Temponuzda İlerleyin: Kursu hızlıca geçmek yerine, her konuyu sindirerek öğrenmeye odaklanın. Hızlı ilerlemek yerine derinlemesine bilgi edinmek, daha sağlam bir temel oluşturacaktır.
7. Kaynaklardan Faydalanın
Python öğrenirken sadece kurs materyalleriyle yetinmeyin. İnternette, kitaplarda ve forumlarda birçok ek kaynak bulabilirsiniz. Bu kaynaklar size daha fazla pratik yapma ve kavrayamadığınız noktaları anlama fırsatı verir.
Dokümantasyon: Python’un resmi dokümantasyonu ve diğer kaynakları, dilin özelliklerini anlamada yardımcı olabilir.
Topluluklar ve Forumlar: StackOverflow, Reddit gibi platformlarda sorular sorarak veya başkalarının sorunlarını çözerek öğrenebilirsiniz.
8. Sabırlı ve Azimli Olun
Python öğrenmek zaman alabilir. Zorlandığınızda yılmayın, pes etmeyin. Her yeni öğrenilen konu, becerilerinizi bir adım daha ileriye taşıyacaktır.
Motivasyon: Kendinizi motive edin ve her başarıyı kutlayın. Küçük hedefler belirleyerek bunları gerçekleştirmek, büyük hedeflere ulaşmanın en iyi yoludur.
Sürekli Gelişim: Python öğrenme süreci, yalnızca bir kursu bitirene kadar sürecek bir şey değil. Öğrendikçe, gelişim süreciniz de devam edecek.
Sonuç:
Python kursunu başarıyla tamamlamak için teoriyi öğrenip, bolca pratik yaparak, projeler üzerinde çalışmalısınız. Düzenli olarak çalışmak, sabırlı olmak ve zorlandığınız konularda yardım almak, başarıya ulaşmanızı sağlar. Kendi hızınızda ilerleyin ve öğrendikçe daha da motive olun. Python, sadece bir dil değil, aynı zamanda güçlü bir problem çözme aracıdır.
Başarılar dilerim, Python yolculuğunuzda keyifli öğrenmeler!
Bu dosya, Python programlama dilinin temel özelliklerini ve avantajlarını açıklayan bir metni içermektedir. Python'un okunabilirlik, sadelik, dinamik tip sistemi, zengin kütüphaneleri, taşınabilirlik ve çok yönlülük gibi öne çıkan özellikleri detaylandırılmaktadır. Ayrıca, Python'un web geliştirme, veri bilimi, yapay zeka, oyun geliştirme ve otomasyon gibi çeşitli alanlarda nasıl kullanılabileceği açıklanmış ve dilin güçlü topluluğu ve desteği de vurgulanmıştır. Bu yazı, Python hakkında genel bilgi edinmek isteyenler için temel bir kaynak sunmaktadır.
Bu derste, Python programlamaya başlamak için gerekli olan iki temel aracı kuruyoruz:
✅ Python'un resmi kurulum dosyasını indirip yüklüyoruz
✅ Visual Studio Code (VS Code) editörünü kuruyoruz
? PYTHON VERİ TİPLERİ VE DEĞİŞKENLER
? 1. DEĞİŞKEN NEDİR?
Değişken, bir veriyi geçici olarak hafızada tutan, isimlendirilmiş yapıdır.
Örnek:
isim = "Ahmet"
yas = 30
Burada 'isim' değişkeni "Ahmet" değerini tutar.
?️ Değişkenlerin Kuralları:
- Harf ya da alt çizgi (_) ile başlamalıdır.
- Sayı ile başlayamaz.
- Boşluk içeremez.
- Türkçe karakter kullanımı önerilmez.
? 2. VERİ TİPİ NEDİR?
Veri tipi, bir değişkende ne tür bilgi tutulduğunu ifade eder.
Python'daki bazı temel veri tipleri:
? int – Tam Sayılar
Örnek:
yas = 25 # int
? float – Ondalıklı Sayılar
Örnek:
boy = 1.75 # float
? complex – Karmaşık Sayılar
Örnek:
sayi = 3 + 4j # complex
? str – Metin (String)
Örnek:
isim = "Ayşe" # str
✅ bool – Mantıksal Değer
Örnek:
aktif = True # bool
? list – Liste
Örnek:
meyveler = ["elma", "armut"] # list
? tuple – Demet (değiştirilemez liste)
Örnek:
renkler = ("kırmızı", "mavi") # tuple
? dict – Sözlük
Örnek:
ogrenci = {"isim": "Zeynep", "yas": 21} # dict
? set – Küme
Örnek:
sayilar = {1, 2, 3} # set
? type() Fonksiyonu
Bir değişkenin veri tipini öğrenmek için type() fonksiyonu kullanılır.
Örnek:
print(type(yas)) # <class 'int'>
print(type(isim)) # <class 'str'>
? DEĞİŞKEN + VERİ TİPİ İLİŞKİSİ
Her değişkenin bir veri tipi vardır.
Python otomatik olarak türü algılar:
ad = "Ali" # str
sayi = 100 # int
ondalik = 3.14 # float
aktif_mi = False # bool
? Özet:
- Değişken: Veriye verdiğimiz isimdir.
- Veri Tipi: Saklanan bilginin türüdür.
- type(): Veri tipini kontrol eder.
? Ders: Python'da Integer (Tam Sayı) Değişkenler
Bu derste, Python programlama dilinde kullanılan integer (tam sayı) veri tipi ele alınmaktadır. Integer değişkenler, programlama sürecinde en sık karşılaşılan veri türlerinden biridir ve temel matematiksel işlemlerden döngülere kadar birçok alanda kullanılır.
? Bu derste öğrenecekleriniz:
Integer veri tipinin ne olduğu
Integer değişkenlerin nasıl tanımlandığı
Pozitif, negatif ve sıfır değerlerin nasıl saklandığı
Basit integer örnekleriyle uygulama
? Kod Örnekleri:
yas = 25
ogrenci_sayisi = 30
sıcaklık = -5
sifir = 0
Bu içerik, Python’a yeni başlayan öğrenciler için temel oluşturur ve ilerleyen konulara geçiş için sağlam bir altyapı sağlar.
? Python'da Float (Ondalıklı Sayılar) - Detaylı Anlatım!
Bu videoda Python programlama dilinde float veri tipini (ondalıklı sayılar) detaylı şekilde ele alıyoruz. Float nedir, nasıl kullanılır, hangi durumlarda tercih edilir hepsi bu videoda!
? Videoda neler var?
✅ Float veri tipi nedir?
✅ Float ve integer farkları
✅ Float ile matematiksel işlemler
✅ Tip dönüşümleri (string → float)
✅ Yuvarlama işlemleri (round)
✅ Dikkat edilmesi gereken noktalar
✅ Float'ın günlük kullanım alanları (fizik, finans, grafik vb.)
? Videodaki örnekler, Python öğrenen herkes için temel bir referans niteliğindedir. Özellikle yeni başlayanlar için sade ve anlaşılır bir anlatım sunuyoruz.
? Python'da Karmaşık Sayılar (complex Veri Tipi) | Detaylı Eğitim
Bu videoda Python'daki özel veri tiplerinden biri olan complex, yani karmaşık sayılar konusunu detaylı bir şekilde ele alıyoruz. Matematiksel olarak karmaşık sayıların yapısını, Python'daki tanımını, özelliklerini ve kullanım alanlarını örneklerle öğreniyoruz.
? Videoda Öğrenecekleriniz:
complex veri tipi nedir?
Gerçel ve sanal kısım ne demektir?
.real ve .imag özellikleri nasıl kullanılır?
Karmaşık sayılarla toplama ve çarpma işlemleri
cmath modülü ile faz açısı hesaplama
Mutlak değer alma ve dereceye çevirme işlemleri
? Karmaşık sayılar özellikle sinyal işleme, elektrik mühendisliği, kontrol sistemleri ve bilimsel hesaplamalarda yaygın olarak kullanılır.
? Python'u daha derinlemesine öğrenmek ve bilimsel programlama temellerinizi güçlendirmek istiyorsanız bu video tam size göre!
? Kullanılan Kodlar: Tüm örnekler videoda ayrıntılı olarak açıklanmıştır. Kodlara göz atmak için videoyu izlemeyi unutmayın.
? Yorumlarda sorularınızı paylaşabilirsiniz, hepsini cevaplıyorum.
Bu derste, Python programlamanın en temel veri yapılarından biri olan listeleri adım adım inceliyoruz. Liste oluşturma, elemanlara erişim, ekleme-silme işlemleri, liste kopyalama, iç içe listeler ve list comprehension gibi 15 önemli konuyu örneklerle sade bir dille anlattım.
Videoda ele alınan başlıca konular:
1. Liste nedir?
2. Liste oluşturma
3. Liste elemanlarına erişim
4. Eleman değiştirme
5. Eleman ekleme (append, insert)
6. Eleman silme (remove, pop, del)
7. Liste uzunluğu
8. Listeleri birleştirme
9. Arama ve sayma
10. Sıralama ve ters çevirme
11. Liste kopyalama
12. Liste temizleme
13. İç içe listeler
14. Listeyi döngüyle gezme
15. List Comprehension
Bu ders kimler için?
Python öğrenmeye yeni başlayanlar
Temel liste işlemlerini örneklerle öğrenmek isteyenler
Kodlama mantığını adım adım kavramak isteyen herkes
Mail : atunc8402@gmail.com
? String (Metin) Veri Tipi – Ders Açıklaması
? Dersin Amacı
Bu derste Python programlama dilinde en sık kullanılan veri tiplerinden biri olan string yani metin veri tipini detaylı bir şekilde öğreneceğiz. String’ler, yazı ile ilgili tüm işlemlerimizin temelini oluşturur. Kullanıcıdan alınan veriler, çıktılar, hata mesajları, dosya içerikleri gibi pek çok işlemde string veri tipini kullanırız.
? Neler Öğreneceğiz?
String veri tipi nasıl tanımlanır?
Tek tırnak, çift tırnak ve üç tırnak arasındaki farklar
String üzerinde indeksleme ve dilimleme işlemleri
Python’un sunduğu güçlü string metotları
String birleştirme ve formatlama yolları
Kullanıcıdan alınan verilerle pratik string uygulamaları
? Bu Dersi Neden Öğrenmelisin?
String’ler sadece yazı değil, veri işleme, form kontrolü, dosya okuma/yazma, regex (düzenli ifadeler) gibi birçok konunun da temelini oluşturur. Bu nedenle string mantığını öğrenmeden ileri seviye Python konularında rahat edemezsin.
Ayrıca bu derste string’lerle ilgili gerçek hayat problemlerine benzer örneklerle alıştırmalar da yapacağız. Böylece öğrendiğin bilgileri doğrudan uygulamaya geçirebileceksin.
? Ön Bilgi Gerekli mi?
Hayır! Bu dersi anlayabilmek için önceden herhangi bir programlama bilgisine sahip olman gerekmiyor. Ders sıfırdan başlayacak şekilde tasarlanmıştır. Yeni başlayanlar için ideal, ama aynı zamanda bilgilerini tazelemek isteyenler için de mükemmel bir fırsattır.
? Ders Sonunda Ne Kazanacaksın?
Python’da string veri tipi ile rahatça çalışabileceksin
Temel string işlemlerinde hızlanacaksın
Kodun okunabilirliğini ve kullanıcı etkileşimini artırabileceksin
Küçük metin projeleri ve mini uygulamalar geliştirebileceksin
? Python Tuple (Demet) Veri Tipi – Değiştirilemez Verilerle Tanışın
Python'un temel veri tiplerinden biri olan tuple (demet), sabit verileri düzenli bir şekilde saklamak için mükemmel bir çözümdür. Bu derste, tuple veri tipinin ne olduğunu, nasıl kullanıldığını ve neden önemli olduğunu öğreneceksiniz.
? Bu Derste Öğrenecekleriniz
Tuple nedir ve neden kullanılır?
Liste ile tuple arasındaki temel farklar
Tuple oluşturma yöntemleri
Elemanlara erişim, slicing, tekrar, uzunluk gibi işlemler
Tuple ile değişken atama (unpacking) ve fonksiyonlardan çoklu değer döndürme
Tuple’ın kullanım alanları ve avantajları
? Neden Önemli?
Tuple’lar, değişmezlik (immutability) prensibi sayesinde daha güvenli ve hızlı veri saklama sağlar. Özellikle sabit veri yapılarında, dictionary anahtarlarında ve çoklu dönüşlerin gerektiği fonksiyonlarda tuple kullanmak, Python’un gücünden daha verimli faydalanmanıza yardımcı olur.
?? Kimler Katılmalı?
Python’a yeni başlayanlar
Temel veri yapılarını öğrenmek isteyenler
Kodun daha güvenli, anlaşılır ve hızlı çalışmasını isteyen herkes
✨ Bonus: Tuple ile yazdığınız kod, sadece daha iyi değil, aynı zamanda daha profesyonel görünecek!
? Kod Açıklaması: Palindrom Kontrolü
import re
re modülü, düzenli ifadeler kullanarak metin işlemleri yapmamızı sağlar.
metin = input("Bir metin girin: ")
Kullanıcıdan bir metin alınır.
temiz = re.sub(r'[^a-zA-Z0-9]', '', metin).lower()
re.sub() fonksiyonu ile metindeki harf ve rakam dışındaki tüm karakterler kaldırılır.(Düzeltme : Rakamın kaldırıldığını söyledim ama sadece harf ve rakam dışındaki tüm karakterler kaldırılır.Yanlış bilgi verdiğim için özür dilerim.)
Yani boşluklar, noktalama işaretleri ve özel karakterler silinir.
Ardından .lower() ile tüm harfler küçük hale getirilir.
Bu adım sayesinde metni standart bir forma sokmuş oluruz.
Örneğin: "Ey edip, Adana’da pide ye!" → "eyedipadanadapideye"
if temiz == temiz[::-1]:
[::-1] ile metnin tersi alınır.
Temizlenmiş metin ile ters çevrilmiş hali karşılaştırılır.
Eğer ikisi aynıysa bu metin bir palindromdur.
print("Bu bir palindrom cümledir.")
else:
print("Bu bir palindrom değildir.")
Sonuca göre kullanıcı bilgilendirilir.
? Palindrom Nedir?
Palindrom, tersten okunduğunda da aynı kalan kelime veya cümlelerdir.
Örneğin:
"ey edip adanada pide ye"
"kabak"
"12321"
Soru ve Görüşleriniz için : atunc8402@gmail.com yada yorumlar kısmından bize soru ve görüşlerinizi ulaştırabilirsiniz.İyi çalışmalar dilerim.
Bu derste, Python programlama dilinde en temel veri tiplerinden biri olan Boolean (Mantıksal) veri tipi detaylı bir şekilde ele alınmaktadır.
Özellikle karar yapıları, koşullu ifadeler ve fonksiyonel kontroller için büyük önem taşıyan True ve False ifadelerinin ne anlama geldiğini, nasıl kullanıldığını örneklerle öğreneceksiniz.
Bu derste öğrenecekleriniz:
Boolean veri tipinin tanımı ve Python'daki kullanımı
Karşılaştırma operatörleri (==, !=, >, <, >=, <=)
Mantıksal operatörler (and, or, not) ile koşul oluşturma
if-else yapısında boolean kullanımı
bool() fonksiyonu ile farklı veri türlerinin boolean karşılığı
Gerçek hayattan kullanım örnekleri ve mini uygulamalar
Bu içerik, hem yeni başlayanlar için güçlü bir temel oluşturmakta, hem de programlama mantığını daha iyi kavramanıza yardımcı olmaktadır.
Kimler Katılmalı?
Python öğrenmeye yeni başlayanlar
Koşullu ifadeleri ve karar yapısını öğrenmek isteyenler
Programlama temellerini güçlendirmek isteyen
tüm seviyedeki öğrenciler
# Python Dictionary (Sözlük) Veri Tipi
# 1. Dictionary Nedir?
# Dictionary, verileri anahtar-değer (key-value) çiftleri şeklinde saklayan bir veri yapısıdır.
# Listeler gibi sıralı değildir, ancak veriye anahtar üzerinden hızlıca erişmemizi sağlar.
# {} süslü parantezler içinde tanımlanır.
# Örnek:
# # Bir dictionary örneği
ogrenci = {
"ad": "Ahmet",
"soyad": "Yılmaz",
"yas": 21,
"bolum": "Bilgisayar Mühendisliği"
}
print(ogrenci)
# 2. Dictionary Özellikleri
# Anahtarlar benzersiz olmalıdır. (Aynı key birden fazla olamaz.)
# Anahtarlar değiştirilemez (immutable) tipte olmalıdır: (string, int, float, tuple gibi).
# Değerler (values) ise her türlü veri tipi olabilir.
# 3. Dictionary Oluşturma Yöntemleri
# 1. Süslü Parantez Kullanarak
sehirler = {"Ankara": 6, "İstanbul": 34, "İzmir": 35}
# 2. dict() Fonksiyonu ile
sehirler = dict(Ankara=6, Istanbul=34, Izmir=35)
# 3. Liste veya Tuple Listesinden
sehirler = dict([("Ankara", 6), ("İstanbul", 34), ("İzmir", 35)])
# 4. Dictionary'de Elemanlara Erişim
# Anahtarla erişim:
print(ogrenci["ad"]) # Çıktı: Ahmet
# get() yöntemi ile erişim:
print(ogrenci.get("yas")) # Çıktı: 21
print(ogrenci.get("notlar", "Bulunamadı")) # Anahtar yoksa varsayılan döner
# 5. Dictionary'ye Eleman Ekleme ve Güncelleme
# Yeni bir anahtar-değer çifti ekleme:
ogrenci["ogrenci_no"] = 123456
# Mevcut bir değeri güncelleme:
ogrenci["yas"] = 22
# 6. Dictionary Elemanlarını Silme
# Belirli bir anahtarı silme:
del ogrenci["soyad"]
# pop() metodu ile silme ve değeri döndürme:
yas = ogrenci.pop("yas")
print(yas) # 22
# Tüm dictionary'yi temizleme:
ogrenci.clear()
# 7. Dictionary Üzerinde Döngü (for loop)
# Anahtarlar üzerinden gezinmek:
for anahtar in ogrenci:
print(anahtar, ":", ogrenci[anahtar])
# items() ile anahtar-değer ikilisi üzerinde gezinmek:
for anahtar, deger in ogrenci.items():
print(anahtar, "->", deger)
# 8. Önemli Dictionary Metodları
# Metod Açıklama
# keys() Tüm anahtarları döner
# values() Tüm değerleri döner
# items() Anahtar-değer çiftlerini döner
# update() Başka bir dictionary ile birleştirir
# pop(key) Belirtilen anahtarı siler ve değerini döner
# clear() Tüm elemanları siler
# Özet
# Dictionary'ler anahtar-değer yapısında veri saklar.
# Anahtarlar benzersizdir ve değiştirilemez veri tipinde olmalıdır.
# Hızlı veri erişimi ve güncelleme sağlar.
# Özellikle veri tabanı simülasyonları, API sonuçları ve karmaşık veri yapılarında çok kullanışlıdır.
Bu derste Python'da sözlük (dictionary) veri yapısını basit bir örnekle öğreneceğiz.
Örneğimiz bir telefon rehberi olacak.
İlk olarak bir sözlük oluşturduk.
Burada her anahtar (key) bir kişinin ismi, her değer (value) ise o kişinin telefon numarasıdır:
telefon_rehberi = {
"Ali": "0532 123 45 67",
"Ayşe": "0543 987 65 43",
"Mehmet": "0506 345 67 89",
}
Arama işlemi:
Bir kişinin numarasını öğrenmek için .get() metodunu kullandık.
Bu metod, eğer isim rehberde yoksa, hata vermek yerine varsayılan bir mesaj döndürür:
print(telefon_rehberi.get("Ali", "Kişi bulunamadı"))
Yeni kişi eklemek:
Sözlüğe yeni bir kayıt eklemek çok kolay.
Sadece ismi ve numarasını eşleştiriyoruz:
telefon_rehberi["Zeynep"] = "0533 111 22 33"
Rehberi listelemek:
Son olarak, tüm rehberi ekrana yazdırmak için for döngüsü kullandık.
Hem isim hem de numarayı birlikte alıp ekrana bastık:
for isim, numara in telefon_rehberi.items():
print(isim, ":", numara)
Bu örnek sayesinde hem Python sözlüklerinin temel kullanımını hem de nasıl pratik bir veri yapısı oluşturabileceğinizi öğrenmiş oldunuz.
# "universite" adında bir sözlük (dictionary) oluşturuyoruz.
# Bu sözlük üniversitenin fakültelerini temsil eden anahtarlar içeriyor.
universite = {
# "Mühendislik" anahtarı altında başka bir sözlük bulunuyor.
# Bu iç sözlük, mühendislik fakültesindeki öğrencileri tutuyor.
"Mühendislik": {
# "Ahmet" anahtarının karşılığı yine bir sözlük.
# Ahmet'in öğrenci bilgilerini (öğrenci numarası ve notu) içeriyor.
"Ahmet": {
"no": 101, # Ahmet'in öğrenci numarası (ID) 101
"not": 85 # Ahmet'in aldığı ders notu 85
},
# "Ayşe" de mühendislik fakültesinde kayıtlı başka bir öğrenci.
"Ayşe": {
"no": 102, # Ayşe'nin öğrenci numarası (ID) 102
"not": 92 # Ayşe'nin aldığı ders notu 92
}
},
# "İktisat" fakültesi için de ayrı bir anahtar bulunuyor.
# Bunun altında yine bir iç sözlük var: bu fakültedeki öğrenciler burada tutuluyor.
"İktisat": {
# "Mehmet" isimli öğrenciye ait bilgiler bir alt sözlükte saklanıyor.
"Mehmet": {
"no": 201, # Mehmet'in öğrenci numarası (ID) 201
"not": 78 # Mehmet'in aldığı ders notu 78
}
}
}
# Sık Yapılan Hatalar
# Anahtar bulunmazsa doğrudan [key] erişimi KeyError hatası verir.
# Bu yüzden güvenli erişim için get() metodu kullanılabilir.
# Dictionary içinde arama yaparken sadece anahtarlar kontrol edilir, değerler otomatik aranmaz:
telefon_rehberi= {"Ali":"05321234567"}
print("Ali" in telefon_rehberi)
print("05321234567" in telefon_rehberi)
# "Ali" in telefon_rehberi # True (anahtar kontrolü)
# "0532 123 45 67" in telefon_rehberi # False (değer kontrolü yapılmaz)
"""
Set Nedir?
- Set (küme), birden fazla öğeyi tek bir koleksiyonda saklayan bir veri tipidir.
- Setlerde öğeler benzersizdir (aynı öğe birden fazla bulunamaz).
- Setler sırasızdır (elemanların belli bir sırası yoktur, indekslenemezler).
- Setler değiştirilebilir (mutable) yapıdadır, yani içine öğe ekleyebilir veya çıkarabiliriz.
"""
# Set Oluşturma
# Set oluşturmanın iki temel yolu vardır:
# 1. Süslü parantez {} kullanarak set oluşturmak
meyveler = {"elma", "armut", "muz", "kiraz"}
# Burada "meyveler" adında 4 farklı meyve isminden oluşan bir set oluşturduk.
# 2. set() fonksiyonu kullanarak set oluşturmak
sebzeler = set(["domates", "salatalık", "biber", "patlıcan"])
# Liste gibi başka bir koleksiyon yapısından da set oluşturabiliriz.
Set Özellikleri
- Aynı öğe bir set içinde yalnızca bir kez bulunabilir. (Otomatik olarak tekrar eden elemanlar atılır.)
- Set öğelerinin sırası yoktur, bu yüzden belirli bir öğeye indeks ile erişim yapılamaz.
- Set içerisine sadece hashable (değiştirilemeyen) veri tipleri konabilir: int, str, tuple gibi.
- List, dict veya başka bir set doğrudan set içine konulamaz (TypeError verir).
Örnek: Aynı eleman iki kere eklenirse
renkler = {"kırmızı", "mavi", "kırmızı", "yeşil"}
print(renkler) # "kırmızı" sadece bir kere bulunur.
Not: set içindeki elemanların sırası eklediğimiz sıra olmayabilir.
# Set veri tipi sırasız (unordered) olduğu için, listelerdeki gibi indeks (indis) numarası kullanılarak elemanlara erişim mümkün değildir.
# Örneğin meyveler[0] şeklinde bir kullanım hata verecektir.
# Bu nedenle set içerisindeki elemanlara erişmek için for döngüsü gibi yineleyici (iteratif) yapılar kullanılır.
# Aşağıda dört meyveden oluşan bir set tanımlıyoruz: elma, armut, muz ve kiraz.
# Setlerde aynı eleman birden fazla kez yazılsa bile sadece bir kez saklanır (her eleman benzersizdir).
meyveler = {"elma", "armut", "muz", "kiraz"}
# for döngüsü ile set içerisindeki her bir elemanı sırasız olarak tek tek gezerek 'meyve' adlı geçici değişkene atıyoruz.
# Döngü her çalıştığında 'meyve' değişkeni setin bir elemanını tutar.
for meyve in meyveler:
# Her bir meyve elemanını ekrana yazdırıyoruz.
# Set sırasız olduğu için ekrana yazdırılan elemanların sırası her çalıştırmada farklı olabilir.
print(meyve)
Burada elma,armut,muz ve kiraz elemalarından oluşan bir set oluşturduk.
meyveler = {"elma", "armut", "muz", "kiraz"}
Tek bir eleman eklemek için add() metodu kullanılır.
meyveler.add("portakal") # "portakal" set'e eklenir.
print(meyveler) # {'portakal', 'armut', 'kiraz', 'elma', 'muz'}
Birden fazla eleman eklemek için update() metodu kullanılır.
meyveler.update(["çilek", "karpuz"])
update() içine liste, set veya başka bir iterable verilebilir.
print(meyveler) # {'karpuz', 'portakal', 'armut', 'çilek', 'kiraz', 'elma', 'muz'}
# Set'ten Eleman Silme
# Belirli bir elemanı kaldırmak için remove() veya discard() metodları kullanılır.
meyveler.remove("elma") # "elma" elemanını siler. Eğer "elma" yoksa KeyError hatası verir.
meyveler.discard("kavun") # "kavun" varsa siler, yoksa hiçbir şey yapmaz.
# Set'teki Tüm Elemanları Temizlemek
# clear() metodu ile set içindeki tüm elemanlar temizlenir.
meyveler.clear()
# Set'i Tamamen Silmek
# del anahtar kelimesi ile set nesnesi hafızadan tamamen silinir.
del meyveler
# Set Operasyonları (Kümeler Arası İşlemler)
# İki veya daha fazla set arasında çeşitli işlemler yapabiliriz.
A = {1, 2, 3, 4}
B = {3, 4, 5, 6}
# Birleştirme (Union)
# İki set'in tüm öğelerini birleştirir (tekrar edenler bir kez alınır).
print(A.union(B)) # Çıktı: {1, 2, 3, 4, 5, 6}
# Kesişim (Intersection)
# İki set'te ortak olan öğeleri bulur.
print(A.intersection(B)) # Çıktı: {3, 4}
# Fark (Difference)
# A setinde olup B setinde olmayan öğeleri bulur.
print(A.difference(B)) # Çıktı: {1, 2}
# (A - B) anlamına gelir A.difference(B)
# Simetrik Fark (Symmetric Difference)
# Sadece bir set'te bulunan, ortak olmayan öğeleri bulur.
print(A.symmetric_difference(B)) # Çıktı: {1, 2, 5, 6}
# A.symmetric_difference(B) = A - B U B-A
- Listelerdeki tekrar eden öğeleri kaldırmak için.
- İki koleksiyon arasında ortak elemanları veya farklılıkları bulmak için.
- Büyük veri kümelerinde hızlı arama yapmak için.
- Matematiksel küme işlemleri yapmak için.
- Veritabanlarında eşsiz (unique) kayıtları temsil etmek için.
# Küçük bir pratik örnek:
# Bir listenin tekrar eden elemanlarını kaldırmak
liste = [1, 2, 2, 3, 4, 4, 5]
benzersiz = list(set(liste)) # set(liste) = {1,2,3,4,5} => list(set(liste)) => list({1,2,3,4,5}) = [1,2,3,4,5]
print(benzersiz) # Çıktı: [1, 2, 3, 4, 5]
# ---
1. Aynı eleman birden fazla kez eklenemez:
renkler = {"kırmızı", "kırmızı", "mavi"}
print(renkler) # Çıktı: {'kırmızı', 'mavi'}
2. İndeks kullanılamaz:
meyveler = {"elma", "armut"}
print(meyveler[0]) # HATA! TypeError: 'set' object is not subscriptable
3. remove() ile olmayan bir elemanı silmeye çalışmak hata verir:
meyveler = {"muz", "kiraz"}
meyveler.remove("elma") # HATA! KeyError: 'elma'
Çözüm: discard() metodu kullanılabilir:
meyveler.discard("elma") # Hata vermez, elma yoksa geçer.
4. Set içine değiştirilebilir veri tipleri eklenemez:
veriler = {[1, 2], [3, 4]} # HATA! TypeError: unhashable type: 'list'
Çözüm: Değiştirilemeyen veri tipleri kullanılmalı, örneğin tuple:
veriler = {(1, 2), (3, 4)} # Geçerli
5. in operatörü set içinde doğrudan eleman var mı diye kontrol eder:
A = {"a", "b", "c"}
"a" in A # True
"z" in A # False
Ama nested yapılarda dikkatli olunmalı:
B = {"a", (1, 2)}
1 in B # False çünkü 1 doğrudan eleman değil.
1 in (1, 2) # True
# Python'da for Döngüsü (Detaylı Konu Anlatımı)
"""
for döngüsü, bir koleksiyonun (liste, tuple, set, sözlük, string vb.) üzerinde dolaşmak için kullanılır.
Her turda koleksiyondaki bir eleman alınır ve belirtilen değişkenin içine atanır.
Yapısı:
for degisken in koleksiyon:
# kod blokları
"""
# Basit Bir Örnek
meyveler = ["elma", "armut", "muz"]
for meyve in meyveler:
print(meyve)
# OUTPUT :
elma
armut
muz
# range() Fonksiyonu ile for
# range(start, stop, step): Belirli bir aralıkta sayı üretir
# i'ye ilk olarak 0 atanır ve 5 e kadar sırasıyla değerler atanır ve ekrana yazdırılır.
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# Burada ise ilk olarak i ye 1 atanır ve 1 değeri yazdırılır.Sonra 2 arttırılır ve i değeri 3 olur.Sonra 5,7,9 diye devam eder ve bu her değer ekran yazdırılır.
for i in range(1, 10, 2):
print(i) # 1, 3, 5, 7, 9
# String üzerinde dolaşmak
kelime = "Python"
for harf in kelime:
print(harf)
degerler = (10, 20, 30)
for sayi in degerler:
print(sayi)
# Burada Ali,Ayşe ve Mehmet anahtarlarından oluşan ve anahtarların değerleri sırasıyla 85,90,78 olan bir sözlük tanımlanır.
ogrenciler = {"Ali": 85, "Ayşe": 90, "Mehmet": 78}
# "ogrenciler" değişkenine atanan dictionary içindeki "Ali","Ahmet","Ayşe" anahtarları sırasıyla isim değişkenine atanır ve her isim değişkenine atanan değer ekran yazdırılır.
for isim in ogrenciler:
print(isim)
# Burada Ali,Ayşe,Ahmet anahtarlarından ve bu anahtarlara karşılık gelen 85,90,78 oluşan bir sözlüğü ogrenciler
# isimli değişkene atadık.
ogrenciler = {"Ali": 85, "Ayşe": 90, "Mehmet": 78}
# Anahtar ve Değerler
for isim, notu in ogrenciler.items():
print(f"{isim} adlı öğrencinin notu: {notu}")
# enumerate() kullanarak indeksli for döngüsü
# Dersler isimli değişkene içinde Matematik,Fizik,Kimya değerleri olan liste atanır...
dersler = ["Matematik", "Fizik", "Kimya"]
# Dersler isimli değişkene atanan listedeki her değer for döngüsüyle index numarası ile beraber alınır,index numarası index değişkenine,bu indexe karşılık gelen değer ise dersler değişkenine atanır.Bu atama işlemleri her değer için yapılır.Daha sonra her atama işleminden sonra dersler değişkenine atanan değerin listedeki index karşılığı ve değeri ekrana yazdırılır.
for indeks, ders in enumerate(dersler):
print(f"{indeks}. ders: {ders}")
# Dış döngü: i değişkeni 1'den başlar, 4'e kadar (4 hariç) artarak devam eder.
# Yani i sırasıyla 1, 2 ve 3 değerlerini alır.
for i in range(1, 4):
# İç döngü: j değişkeni de 1'den başlar ve 4'e kadar gider (4 hariç).
# Her i değeri için j tekrar 1, 2, 3 şeklinde çalışır.
for j in range(1, 4):
# Hem i hem de j değerlerini ekrana yazdır.
# Bu, iki seviyeli döngülerde her olası i-j eşleşmesini gösterir.
# Örnek çıktı: (1, 1), (1, 2), (1, 3), sonra (2, 1), (2, 2), (2, 3), ...
print(f"({i}, {j})")
# Bu satırda bir liste üretmek için "list comprehension" (liste kavraması) yapısı kullanılır.
# x, range(6) ifadesiyle 0'dan 5'e kadar olan sayıları sırasıyla alır: 0, 1, 2, 3, 4, 5
# Her x için x'in karesi (x**2) hesaplanır ve bu değerler listeye eklenir.
kareler = [x**2 for x in range(6)]
# Oluşan listeyi ekrana yazdırır.
# range(6) → [0, 1, 2, 3, 4, 5] olduğundan, her bir sayının karesi alınır:
# 0**2 = 0, 1**2 = 1, 2**2 = 4, 3**2 = 9, 4**2 = 16, 5**2 = 25
# Sonuç: [0, 1, 4, 9, 16, 25]
print(kareler) # [0, 1, 4, 9, 16, 25]
# İlk for döngüsü: 0'dan 4'e kadar sayılar üretir (range(5) ⇒ 0, 1, 2, 3, 4)
for sayi in range(5):
# Eğer sayı 3'e eşitse döngüyü tamamen durdurur (break komutu)
if sayi == 3:
break
# Eğer sayı 3 değilse, ekrana yazdırılır
print(sayi) # Çıktı: 0, 1, 2 (3 geldiğinde break ile döngü durur)
# İkinci for döngüsü: Yine 0'dan 4'e kadar sayılarla çalışır
for sayi in range(5):
# Eğer sayı 2'ye eşitse, o tur atlanır (continue komutu döngünün o turunu bitirip bir sonraki tura geçer)
if sayi == 2:
continue
# Sayı 2 olmadığında ekrana yazdırılır
print(sayi) # Çıktı: 0, 1, 3, 4 (2 atlandı)
# Üçüncü for döngüsü: 0, 1, 2 değerlerini üretir
for i in range(3):
print(i) # Çıktı: 0, 1, 2
# else bloğu: for döngüsü normal şekilde tamamlandığında (yani break ile kesilmeden) çalışır
# Bu örnekte döngü doğal biçimde sona erdiği için else içindeki kod da çalışır
else:
print("Döngü normal şekilde tamamlandı") # Bu satır yazdırılır
# NOT: Eğer yukarıdaki döngü break ile kesilseydi else çalışmazdı.
1. for döngüsüyle indeksli erisim için enumerate unutulur.
2. range() ile çalışırken start değeri verilmediğinde 0'dan başlar.
3. for döngüsü içinde çıkmak için break yerine return kullanılmaz.
4. Sözlüklerde doğrudan key, value erişimi için .items() unutulur.
5. for döngüsü sadece bir kez çalışacak şekilde yazılırsa while daha uygundur.
# Bu satırda 1'den 100'e kadar olan sayılar arasında sadece çift olanları seçip bir liste oluşturuyoruz.
# "i for i in range(1, 101)" kısmı: 1 dahil, 101 hariç olmak üzere 1'den 100'e kadar tüm sayıları sırayla alır.
# "if i % 2 == 0" kısmı: Her sayı için, 2'ye bölümünden kalan 0 mı diye kontrol eder (yani çift sayı mı?)
# Şart sağlanırsa o sayı listeye eklenir.
ciftler = [i for i in range(1, 101) if i % 2 == 0]
# Oluşan listeyi ekrana yazdırıyoruz.
# Bu liste 1 ile 100 arasındaki tüm çift sayılardan oluşur: 2, 4, 6, ..., 100
print(ciftler)
- for döngüsü koleksiyonlar üzerinde dolaşmak için kullanılır.
- range() sayılarla for döngüsü oluşturmak için kullanılır.
- enumerate(), items() gibi fonksiyonlar döngüyü daha esnek hale getirir.
- break, continue ve else ile döngüyü kontrol edebiliriz.
Python'da while döngüsü, belirli bir koşul doğru olduğu sürece kod bloğunu sürekli olarak çalıştıran bir döngü türüdür. Yani, döngü başladığında önce verilen koşul kontrol edilir. Eğer bu koşul doğruysa (True), döngü içindeki kod bloğu çalıştırılır ve ardından koşul tekrar kontrol edilir. Koşul hala doğruysa, kod bloğu bir kez daha çalıştırılır ve bu işlem döngü sona erene kadar devam eder. Ancak, koşul yanlış (False) olduğunda döngü çalışmayı durdurur ve program bir sonraki adıma geçer.
# while döngüsünün başlangıcı
while koşul: # 'koşul' her seferinde kontrol edilir. Eğer koşul doğru (True) ise döngü çalışır
# Döngü içerisinde yapılacak işlemler
# Bu kısmı, koşul doğru olduğu sürece sürekli çalıştırmak istediğiniz kodlarla doldurabilirsiniz
# Örneğin, bir sayaç artırma veya bir işlem gerçekleştirme gibi
pass # Bu, döngüde yapılacak işlemi temsil eder, burada bir işlem yok
sayi = 1 # İlk başta sayi değişkenini 1 olarak başlatıyoruz. Bu, döngü başladığında sayının ilk değeri olacak.
# while döngüsünün başlangıcı
while sayi <= 5: # Bu koşul, sayi değişkeni 5 veya daha küçük olduğu sürece döngünün çalışmaya devam edeceğini belirtiyor.
# Döngü her çalıştığında aşağıdaki işlemler yapılacak.
print(sayi) # Bu satır, sayi'nın mevcut değerini ekrana yazdırır. Yani döngü her çalıştığında,
# sayi'nın o anki değeri ekranda görünecek.
sayi += 1 # Bu satırda sayi'nın değeri 1 artırılır. Bu işlem, döngünün her turunda yapılır.
# İlk başta sayi 1'dir. Döngüde her bir adımda 1 eklenir, yani sayi 1'den 2'ye,
# sonra 2'den 3'e, 3'ten 4'e ve son olarak 4'ten 5'e çıkar.
# Eğer burada artırma işlemi yapılmazsa, döngü sonsuz döngüye girer çünkü koşul her zaman doğru olur.
# Sonsuz Döngü (Infinite Loop) örneği
# while döngüsü, parantez içindeki koşul True (doğru) olduğu sürece çalışır.
# Buradaki koşul "True" olduğu için döngü hiçbir zaman durmaz; çünkü True her zaman doğrudur.
while True:
# Bu satır döngü her çalıştığında ekrana aynı mesajı yazar.
# Çünkü döngü hiçbir zaman durmaz; bu nedenle bu satır sürekli tekrar eder.
print("Bu döngü sonsuza kadar çalışır!")
# Bu örnekte döngüyü durduracak hiçbir koşul veya 'break' ifadesi yok.
# Dolayısıyla program kullanıcı tarafından manuel olarak durdurulmadıkça çalışmaya devam eder.
# Sonsuz döngüler, bazı durumlarda kasıtlı olarak kullanılır:
# - Sürekli çalışan sunucular
# - Kullanıcıdan sürekli giriş bekleyen sistemler
# - Oyun döngüleri gibi uygulamalarda
# Ancak dikkat: Eğer sonsuz döngü yanlışlıkla yazılırsa, programınız donabilir ya da sistem kaynaklarını tüketebilir.
# Bu yüzden 'while True:' kullanırken dikkatli olunmalı, genellikle döngüyü durduracak bir 'break' ifadesi de eklenmelidir.
# Başlangıçta sayi değişkenine 1 değeri atanıyor
sayi = 1
# while True ifadesi ile sonsuz bir döngü başlatılıyor
# Bu döngü içinde bir 'break' komutu çalıştırılmadığı sürece durmadan devam eder
while True: # Sonsuz döngü başlatılıyor
# Her döngü adımında mevcut sayi ekrana yazdırılıyor
print(sayi)
# Eğer sayi değişkeni 3'e eşit olursa aşağıdaki koşul devreye girer
if sayi == 3: # sayi değişkeni 3 olduğunda döngü sona erdirilecek
break # 'break' komutu döngüyü anında sonlandırır
# Eğer yukarıdaki if koşulu gerçekleşmezse, sayi 1 artırılır ve döngü devam eder
sayi += 1 # sayi değerini 1 artır (örneğin 1 → 2, 2 → 3)
# Bu noktaya gelindiğinde döngü bitmiştir ve program sonlanır
# Başlangıçta sayi değişkenine 0 değeri atanıyor
sayi = 0
# sayi değeri 5'ten küçük olduğu sürece döngü devam edecek
while sayi < 5:
# Her döngü adımında sayi değişkeni 1 artırılıyor
sayi += 1
# Eğer sayi değeri 3'e eşitse, aşağıdaki blok çalışır
if sayi == 3:
# 'continue' komutu, bu döngü turunun kalan kısmını atlar ve bir sonraki tura geçer
# Yani aşağıdaki print(sayi) satırı bu turda çalışmaz
continue # sayi 3 olduğunda bu tur atlanır, ekrana yazdırılmaz
# Eğer 'continue' çalışmamışsa, sayi değeri ekrana yazdırılır
print(sayi)
# Döngü tamamlandığında ekranda şu sayılar görülür: 1, 2, 4, 5
# Başlangıçta sayi değişkenine 1 değeri atanıyor
sayi = 1
# Döngü, sayi değeri 3 veya daha küçük olduğu sürece çalışmaya devam eder
while sayi <= 3:
# Her döngü turunda sayi değişkeninin değeri ekrana yazdırılır
print(sayi)
# sayi her turda 1 artırılır (örneğin: 1 → 2 → 3 → 4)
sayi += 1
# while döngüsünün koşulu False (yani sayi > 3) olduğunda else bloğu devreye girer
else:
# Bu mesaj yalnızca döngü **break ile kesilmeden** normal şekilde tamamlanırsa yazdırılır
print("Döngü normal şekilde tamamlandı")
# Doğru şifreyi temsil eden değişken tanımlanıyor
dogru_sifre = "python123"
# Sonsuz bir döngü başlatılıyor; kullanıcı doğru şifreyi girene kadar devam edecek
while True:
# Kullanıcıdan şifre girmesi isteniyor
sifre = input("Şifreyi girin: ")
# Girilen şifre, doğru şifreyle karşılaştırılıyor
if sifre == dogru_sifre:
# Eğer kullanıcı doğru şifreyi girdiyse, başarılı mesajı verilir
print("Giriş başarılı!")
# 'break' komutu ile döngü sonlandırılır
# Artık program döngünün dışına çıkar
break # Doğru şifre girildiğinde döngü sona erer
else:
# Şifre yanlışsa kullanıcı bilgilendirilir
# Döngü tekrar başa döner ve yeniden şifre sorulur
print("Yanlış şifre, tekrar deneyin.")
# ❌ HATA 1: Sayaç değişkeni güncellenmezse döngü sonsuza kadar çalışır
i = 0 # Sayaç değişkeni başlangıçta 0 olarak tanımlanıyor
while i < 5: # Koşul: i 5'ten küçük olduğu sürece döngü devam eder
print(i) # i ekrana yazdırılır
# ? HATA: i artırılmadığı için i her zaman 0 kalır
# Bu da koşulun (i < 5) sonsuza kadar doğru kalmasına neden olur
# Sonuç: Sonsuz döngü oluşur ve program durmaz
# ✅ Çözüm: Döngü içinde i += 1 satırı eklenmelidir:
# i += 1
--------------------------------------------------------------------------------------------------------------------------
# ❌ HATA 2: Döngü koşulu en başta False ise, döngü hiç çalışmaz
x = 10 # Değişken başlangıçta 10 olarak ayarlanıyor
while x < 5: # Koşul: x 5'ten küçükse döngü çalışır
print("Bu döngü çalışmaz çünkü koşul baştan yanlış.")
# ? HATA: x zaten 10 olduğu için koşul False olur ve döngüye hiç girilmez
# Ekrana hiçbir şey yazdırılmaz
# ✅ Çözüm: Başlangıç değeri ve koşul birbiriyle uyumlu olmalıdır
# Örneğin: while x > 5: gibi bir koşul başlangıçta True olabilir ama sonsuz döngü tehlikesi vardır
# burada.Bu yüzden x+=1 ifadesi döngü içindeki kod bloğuna eklenmelidir.
# ✅ while döngüsü, koşul tabanlı çalışır:
# Belirttiğiniz mantıksal ifade (koşul) True olduğu sürece döngü çalışır.
# Örnek: 1'den 5'e kadar olan sayıları yazdıralım
sayi = 1 # Sayaç değişkeni tanımlanıyor
while sayi <= 5: # Koşul: sayi 5'e eşit veya küçük olduğu sürece devam et
print(sayi) # sayi ekrana yazdırılır
sayi += 1 # sayi her turda 1 artırılır (aksi halde sonsuz döngü olur)
# ✅ Koşul False olduğunda (sayi > 5), döngü sona erer
# ? Sonsuz döngü örneği:
# Eğer koşul daima True ise, döngü sonsuza kadar çalışır.
while True:
komut = input("Çıkmak için 'q' yazın: ") # Kullanıcıdan giriş alınır
if komut == 'q':
# Kullanıcı 'q' yazdıysa döngüyü sonlandır
break # break komutu döngüyü anında durdurur
# Eğer 'q' yazılmadıysa, bu mesaj gösterilir
print("Döngü devam ediyor...")
# ? Not: Sonsuz döngü yazarken mutlaka bir çıkış şartı (break gibi) olmalıdır,
# aksi halde program sonsuza kadar çalışmaya devam eder
# ⚠️ while döngüsünde dikkat edilmesi gerekenler:
# 1. Sayaç (counter) değişkeni unutulmamalı ve güncellenmelidir.
# Aksi takdirde döngü koşulu hep True kalır → sonsuz döngü olur.
# 2. Koşul doğru tanımlanmalıdır.
# Başlangıçta False ise döngü hiç çalışmaz; koşul mantıklı olmalı.
# 3. break ve continue gibi kontrol ifadeleriyle döngü yönetimi yapılabilir.
# - break → döngüyü tamamen bitirir.
# - continue → mevcut döngü turunu atlar, sonraki tura geçer.
Özet
while döngüsü, belirli bir koşul doğru olduğu sürece çalışır.
break komutu döngüyü sonlandırır, continue belirli bir turu atlar.
else bloğu, döngü sonlanınca (koşul sağlanmadığında) çalışır.
while döngüsü, koşulun sürekli doğruluğu üzerine çalışır, bu nedenle döngü kontrolü çok önemlidir.
# Operatörler, Python programlama dilinde temel yapı taşlarından biridir.
# Bir operatör, genellikle iki ya da daha fazla "operand" yani değer/değişken üzerinde işlem yapmak için kullanılır.
# Python’da operatörler sayesinde birçok işlem yapılabilir.
# Bu işlemler yalnızca matematiksel hesaplamalarla sınırlı değildir.
# Mantıksal karar verme, değer karşılaştırmaları, değer atamaları gibi işlemler de operatörlerle gerçekleştirilir.
# Örneğin:
# - 3 + 5 ifadesinde '+' bir aritmetik (toplama) operatörüdür ve operandlar 3 ile 5'tir.
# - x == y ifadesinde '==' bir karşılaştırma operatörüdür, x ve y operandlardır.
# - not True ifadesinde 'not' bir mantıksal (logical) operatördür.
# Python'daki operatörler birkaç ana gruba ayrılır:
# 1. Aritmetik Operatörler: Toplama (+), Çıkarma (-), Çarpma (*), Bölme (/), Mod (%), Üs (**), Tam bölme (//)
# 2. Atama Operatörleri: =, +=, -=, *=, /= gibi, değişkenlere değer atamak ve güncellemek için kullanılır.
# 3. Karşılaştırma (İlişkisel) Operatörler: ==, !=, >, <, >=, <= — iki değeri karşılaştırıp boolean sonuç verir.
# 4. Mantıksal Operatörler: and, or, not — birden fazla koşulu birleştirmek veya tersine çevirmek için kullanılır.
# 5. Kimlik Operatörleri: is, is not — iki değişkenin aynı nesne olup olmadığını kontrol eder.
# 6. Üyelik Operatörleri: in, not in — bir değerin bir koleksiyon içinde olup olmadığını kontrol eder.
# 7. Bit Düzeyi Operatörleri: &, |, ^, ~, <<, >> — ikilik (binary) düzeyde işlem yapar (ileri seviye kullanım).
# Bu operatörler, Python'da akıllı ve etkili kodlar yazmak için kritik öneme sahiptir.
# Doğru ve uygun operatörü seçmek, kodun okunabilirliğini ve verimliliğini artırır.
# ? Aritmetik Operatörler
# Bu operatörler, Python’da matematiksel işlemleri gerçekleştirmek için kullanılır.
# Sayılarla çalışırken toplama, çıkarma, çarpma, bölme gibi temel işlemler bu operatörlerle yapılır.
# ➕ Toplama Operatörü: +
# İki değeri birbirine ekler.
a = 5 + 3 # a'nın değeri 8 olur
# ➖ Çıkarma Operatörü: -
# İkinci değeri ilk değerden çıkarır.
b = 10 - 4 # b'nin değeri 6 olur
# ✖️ Çarpma Operatörü: *
# İki değeri çarpar.
c = 6 * 2 # c'nin değeri 12 olur
# ➗ Ondalıklı Bölme Operatörü: /
# Bölme işlemi yapar ve sonucu her zaman ondalıklı (float) verir.
d = 9 / 2 # d'nin değeri 4.5 olur
# ? Tamsayı Bölme Operatörü: //
# Sonucu en yakın küçük tamsayıya yuvarlar (float değil, int verir).
e = 9 // 2 # e'nin değeri 4 olur
# ➗ Modül (Kalan) Operatörü: %
# Bölme işleminden kalanı verir. Genellikle çift/tek kontrolü, döngü aralıkları gibi yerlerde kullanılır.
f = 9 % 2 # f'nin değeri 1 olur çünkü 9 ÷ 2 = 4 kalan 1
# ⬆️ Üs Alma Operatörü: **
# Bir sayının üssünü alır. Örneğin 2 üzeri 3 = 8
g = 2 ** 3 # g'nin değeri 8 olur
# ? NOT:
# Python'da bu operatörler hem tamsayı (int) hem de ondalıklı (float) verilerle çalışır.
# Ayrıca, `+` ve `*` gibi bazı operatörler diziler (list), metinler (str) ve diğer veri türleriyle de çalışabilir.
# Örnek:
metin = "Merhaba " + "Dünya!" # metin değişkeni: "Merhaba Dünya!"
tekrar = "Python " * 3 # tekrar değişkeni: "Python Python Python "
# ? Karşılaştırma Operatörleri
# İki değeri karşılaştırmak ve bu karşılaştırmanın sonucunu "True" ya da "False" (boolean) olarak döndürmek için kullanılır.
# Genellikle koşullu ifadelerde (if, while) kullanılır.
# ? Eşittir: ==
# İki değerin birbirine eşit olup olmadığını kontrol eder.
print(5 == 5) # True, çünkü iki değer eşit
print(5 == 3) # False
# ❗ Eşit Değildir: !=
# Değerler eşit değilse True döner.
print(5 != 3) # True
print(5 != 5) # False
# ➕ Büyüktür: >
# Sol taraftaki değer sağdakinden büyükse True döner.
print(7 > 4) # True
print(3 > 10) # False
# ➖ Küçüktür: <
# Sol değer sağ değerden küçükse True olur.
print(2 < 5) # True
print(9 < 4) # False
# ? Büyük Eşittir: >=
# Sol taraf, sağ taraftan büyük veya eşitse True olur.
print(5 >= 5) # True
print(6 >= 2) # True
print(3 >= 7) # False
# ? Küçük Eşittir: <=
# Sol taraf, sağ taraftan küçük veya eşitse True olur.
print(3 <= 5) # True
print(5 <= 5) # True
print(9 <= 4) # False
# ? Karşılaştırma operatörleri genellikle "if" koşulları ile birlikte kullanılır:
sayı = 7
if sayı >= 5:
print("Sayı 5 veya daha büyük.") # Bu satır çalışır çünkü koşul True
# ✅ Karşılaştırma sonucunda elde edilen True/False değerleri başka işlemlerde de kullanılabilir:
sonuç = 10 < 20
print(sonuç) # True
# ? Mantıksal Operatörler
# Mantıksal operatörler, birden fazla koşul ifadesini birleştirmek ya da bir koşulu tersine çevirmek için kullanılır.
# Bu operatörler "True" veya "False" döndüren ifadelerle çalışır.
# ?⚖️ AND Operatörü: and
# İki koşuldan her ikisi de True ise, sonuç True olur.
print(True and True) # True
print(True and False) # False
print(False and False) # False
# ?⚖️ OR Operatörü: or
# İki koşuldan en az bir tanesi True ise, sonuç True olur.
print(True or False) # True
print(False or False) # False
print(True or True) # True
# ?⚖️ NOT Operatörü: not
# Bu operatör, bir koşulun tersini alır. Yani True'yu False, False'u True yapar.
print(not True) # False
print(not False) # True
# ✅ Mantıksal operatörler, genellikle if koşullarında birden fazla durumu kontrol etmek için kullanılır:
a = 5
b = 10
# AND operatörü ile iki koşulun aynı anda sağlanıp sağlanmadığını kontrol edebiliriz:
if a < b and b < 20:
print("Hem a küçük b'den, hem de b 20'den küçük.") # Bu yazdırılır çünkü her iki koşul da True.
# OR operatörü ile bir koşulun sağlanıp sağlanmadığını kontrol edebiliriz:
if a > b or b < 15:
print("Büyükten küçük bir koşul var.") # Bu yazdırılır çünkü ikinci koşul (b < 15) True.
# NOT operatörü ile koşulu tersine çevirebiliriz:
if not (a == b):
print("a, b'ye eşit değil.") # Bu yazdırılır çünkü a != b.
# ? Kimlik Operatörleri
# Kimlik operatörleri, iki nesnenin birbirine "aynı nesne" olup olmadığını kontrol etmek için kullanılır.
# Yani, iki değişkenin değerleri aynı olabilir, ancak Python’da nesneler her zaman farklı bellek adreslerinde bulunabilir.
# Bu operatörler, bellek adreslerini karşılaştırır.
# ? is: Aynı Nesne mi?
# Bu operatör, iki nesnenin gerçekten aynı bellek alanında bulunup bulunmadığını kontrol eder.
x = [1, 2, 3]
y = [1, 2, 3]
z = x
# Burada x ve y'nin içerikleri aynı ancak bellek adresleri farklı.
print(x is y) # False, çünkü farklı bellek adreslerine sahiptirler.
# Burada x ve z aynı nesneye işaret ediyorlar.
print(x is z) # True, çünkü x ve z aynı nesneye işaret ediyor.
# ❌ is not: Aynı Nesne Değil mi?
# Bu operatör, iki nesnenin aynı bellek adresine sahip olup olmadığını kontrol eder ve tersine sonuç döner.
print(x is not y) # True, çünkü x ve y farklı nesnelerdir.
print(x is not z) # False, çünkü x ve z aynı nesneye işaret ediyor.
# ? NOT:
# `is` operatörü, genellikle nesne kimliklerini karşılaştırmak için kullanılır.
# Eğer değerlerin eşitliğini kontrol etmek istiyorsak, `==` karşılaştırma operatörü kullanılmalıdır.
# Kimlik operatörleri genellikle nesne karşılaştırmalarında, özellikle mutable (değiştirilebilir) veri tipleriyle çalışırken daha anlamlıdır.
# ? Üyelik Operatörleri
# Bu operatörler, bir öğenin belirli bir koleksiyonda (dizi, liste, set, vb.) bulunup bulunmadığını kontrol eder.
# ? in: Koleksiyonda var mı?
# Bu operatör, bir öğenin koleksiyonda olup olmadığını kontrol eder ve True/False döner.
liste = [1, 2, 3, 4, 5]
print(3 in liste) # True, çünkü 3 liste içinde var.
print(6 in liste) # False, çünkü 6 liste içinde yok.
# ? not in: Koleksiyonda yok mu?
# Bu operatör, bir öğenin koleksiyonda olup olmadığını tersine kontrol eder.
print(3 not in liste) # False, çünkü 3 liste içinde var.
print(6 not in liste) # True, çünkü 6 liste içinde yok.
# ? Üyelik operatörleri, koleksiyonlarda arama yapmak için oldukça kullanışlıdır.
# Bir öğenin bir koleksiyonda olup olmadığını kontrol etmek için `in` operatörü yaygın olarak kullanılır.
# Örnek olarak, bir string içinde belirli bir karakterin olup olmadığını kontrol edebiliriz:
metin = "Python programlama dili"
print("Python" in metin) # True, çünkü "Python" metin içinde var.
# Veya bir set içinde olup olmadığını kontrol edebiliriz:
kümem = {1, 2, 3, 4}
print(4 in kümem) # True
print(7 in kümem) # False
# ? Bit Düzeyinde Operatörler
# Bit düzeyinde operatörler, sayıların ikilik (binary) biçiminde işlem yapar.
# Bu operatörler genellikle ikilik sayı sistemini manipüle etmek için kullanılır.
# ? AND Operatörü: &
# Her iki bit de 1 olduğunda sonuç 1 olur, aksi takdirde 0.
a = 5 # 5'in binary karşılığı: 101
b = 3 # 3'ün binary karşılığı: 011
print(a & b) # 1, çünkü 101 & 011 = 001
# ? OR Operatörü: |
# Eğer herhangi bir bit 1 ise, sonuç 1 olur.
print(a | b) # 7, çünkü 101 | 011 = 111
# ? XOR (Exclusive OR) Operatörü: ^
# Eğer iki bit farklıysa 1, aynıysa 0 olur.
print(a ^ b) # 6, çünkü 101 ^ 011 = 110
# ? NOT Operatörü: ~
# Bit düzeyinde tersini alır. Bir sayının iki's complement'i hesaplanır.
print(~a) # -6, çünkü 5'in iki's complement'ini alır.
# ? Shift Operatörleri
# Bitleri sağa ya da sola kaydırma işlemi yapar.
# ? Sağ Kaydırma (Right Shift): >>
# Bu operatör, sayıyı sağa kaydırarak bölme işlemi yapar (bölme işlemine benzer, ancak daha hızlıdır).
print(a >> 1) # 2, çünkü 101'in bir basamağını sağa kaydırdık (5 // 2 = 2)
# ? Sol Kaydırma (Left Shift): <<
# Bu operatör, sayıyı sola kaydırarak çarpma işlemi yapar (çarpma işlemine benzer, ancak daha hızlıdır).
print(a << 1) # 10, çünkü 101'i bir basamağını sola kaydırdık (5 * 2 = 10)
# ? NOT:
# Bit düzeyinde operatörler, genellikle düşük seviyeli işlemler için ve belirli bir optimizasyon gereksinimi olduğunda kullanılır.
# Örneğin, sayılar üzerinde hızlı işlem yapmak ya da veri sıkıştırma algoritmalarında kullanılabilir.
# Python'da bu operatörlerin kullanımı sınırlı olsa da, bazı matematiksel ve sistemsel uygulamalarda faydalıdır.
# ? Aritmetik Operatörler
# Bu operatörler, matematiksel işlemler yapar.
a = 5 + 3 # ➕ Toplama: 5 + 3 = 8
b = 10 - 4 # ➖ Çıkarma: 10 - 4 = 6
c = 6 * 2 # ✖️ Çarpma: 6 * 2 = 12
d = 9 / 2 # ➗ Bölme (float): 9 / 2 = 4.5
e = 9 // 2 # ? Tam Bölme: 9 // 2 = 4 (kesirli kısım atılır)
f = 9 % 2 # ➗ Modül: 9 % 2 = 1 (kalan)
g = 2 ** 3 # ⬆️ Üs Alma: 2 ** 3 = 8
# ? Atama Operatörleri
# Bu operatörler, bir değişkene değer atamak için kullanılır.
x = 10 # = Değer atama: x = 10
# ? Toplamaya Atama
x += 5 # += Toplama ve atama: x = x + 5 → x = 15
# ? Çıkarmaya Atama
x -= 3 # -= Çıkarma ve atama: x = x - 3 → x = 12
# ? Çarpmaya Atama
x *= 2 # *= Çarpma ve atama: x = x * 2 → x = 24
# ? Bölmeye Atama
x /= 4 # /= Bölme ve atama: x = x / 4 → x = 6.0
# ? Tamsayı Bölmeye Atama
x //= 2 # //= Tam bölme ve atama: x = x // 2 → x = 3.0
# ? Modüle Atama
x %= 2 # %= Modül ve atama: x = x % 2 → x = 1.0
# ? Üs Almaya Atama
x **= 3 # **= Üs ve atama: x = x ** 3 → x = 1.0
# ? Karşılaştırma Operatörleri
# İki değeri karşılaştırır ve True/False döner.
a = 5
b = 3
print(a == b) # == Eşit mi?: False, çünkü 5 != 3
print(a != b) # != Eşit değil mi?: True, çünkü 5 != 3
print(a > b) # > Büyüktür: True, çünkü 5 > 3
print(a < b) # < Küçüktür: False, çünkü 5 > 3
print(a >= b) # >= Büyük veya eşit: True, çünkü 5 >= 3
print(a <= b) # <= Küçük veya eşit: False, çünkü 5 > 3
# ? Mantıksal Operatörler
# Koşulları birleştirir.
print(True and False) # and: False, çünkü her iki koşul da True değil
print(True or False) # or: True, çünkü en az bir koşul True
print(not True) # not: False, çünkü True'nun tersidir
# ?⚖️ Kimlik Operatörleri
# Nesnelerin aynı bellek adresine sahip olup olmadığını kontrol eder.
x = [1, 2, 3]
y = [1, 2, 3]
z = x
print(x is y) # is: False, çünkü farklı bellek adreslerine sahipler
print(x is z) # is: True, çünkü aynı nesneye işaret ediyorlar
# ? Üyelik Operatörleri
# Bir öğenin koleksiyon içinde olup olmadığını kontrol eder.
my_list = [1, 2, 3, 4, 5]
print(3 in my_list) # in: True, çünkü 3 listede var
print(6 not in my_list) # not in: True, çünkü 6 listede yok
# ? Bit Düzeyinde Operatörler
# Bit düzeyinde işlem yapar.
a = 5 # 5'in binary karşılığı: 101
b = 3 # 3'ün binary karşılığı: 011
print(a & b) # &: AND: 1, çünkü 101 & 011 = 001
print(a | b) # |: OR: 7, çünkü 101 | 011 = 111
print(a ^ b) # ^: XOR: 6, çünkü 101 ^ 011 = 110
print(~a) # ~: NOT: -6, çünkü 5'in iki's complement'ini alır
# ? Sağ ve Sol Kaydırma Operatörleri
# Bitleri sağa ya da sola kaydırır.
print(a >> 1) # >>: Sağ kaydırma: 2, çünkü 101'in bir basamağını sağa kaydırdık
print(a << 1) # <<: Sol kaydırma: 10, çünkü 101'i bir basamağını sola kaydırdık
# Fonksiyonlar ve Kullanım Amaçları
# Fonksiyon Nedir?
# Fonksiyon, belirli bir görevi yerine getiren, genellikle bir veya birden fazla girdi (parametre) alıp,
# bir çıktı (sonuç) döndüren bir yazılım bileşenidir. Python'da fonksiyonlar 'def' anahtar kelimesiyle tanımlanır.
# Fonksiyonlar, kodu daha modüler, okunabilir ve sürdürülebilir hale getiren önemli bir yazılım yapı taşır.
# Örnek Fonksiyon Tanımlama:
def selamla(isim):
"""Verilen isme göre bir selam mesajı yazdırır."""
print(f"Merhaba, {isim}!")
# Fonksiyonun Kullanımı
selamla("Ali") # "Merhaba, Ali!" mesajını yazdırır
selamla("Ayşe") # "Merhaba, Ayşe!" mesajını yazdırır
# Fonksiyonlar, genellikle bir değer döndürürler. Eğer değer döndürmesi istenmezse, işlem yalnızca yapılır.
# Örneğin, yukarıdaki 'selamla' fonksiyonu bir çıktı verir ama değer döndürmez.
# Kod Tekrarı Nedir?
# Kod tekrarı, aynı işlemin birden fazla kez yazılması anlamına gelir. Bu durum, kodun bakımını zorlaştırır
# ve hata yapma olasılığını artırır. Python fonksiyonları, aynı işlemi tekrar yazmak yerine bir fonksiyon ile
# sadece bir kez tanımlamamıza olanak tanır.
# Kod Tekrarı Örneği:
# Aşağıda aynı mesajı üç defa yazdırdık. Bu kodu fonksiyon kullanarak daha verimli hale getireceğiz.
print("Merhaba, Ali!")
print("Merhaba, Ayşe!")
print("Merhaba, Mehmet!")
# Bu şekilde kodun her parçası aynı işlemi tekrarlar ve kodun okunabilirliğini zorlaştırır.
# Fonksiyon ile Tekrarı Önlemek:
def selamla(isim):
"""Verilen isme göre bir selam mesajı yazdırır."""
print(f"Merhaba, {isim}!")
selamla("Ali")
selamla("Ayşe")
selamla("Mehmet")
# Artık kodu her seferinde tekrar yazmak zorunda kalmıyoruz. Aynı fonksiyonla farklı parametrelerle tekrar kullanabiliyoruz.
# Fonksiyonların Yazılımda Sağladığı Avantajlar:
# 1. Kodun Tekrarını Önler
# Fonksiyonlar, aynı kodu tekrar yazmak yerine yalnızca bir kez yazmamıza olanak tanır.
# Bu, hem zaman kazandırır hem de kodun bakımını kolaylaştırır.
# Örnek:
def topla(a, b):
"""İki sayıyı toplar."""
return a + b
def fark_al(a, b):
"""İki sayı arasındaki farkı alır."""
return a - b
# Bu fonksiyonları tek tek çağırarak işlemi gerçekleştirebiliriz.
print(topla(5, 3)) # 8
print(fark_al(5, 3)) # 2
# 2. Kodun Okunabilirliğini Artırır
# Fonksiyonlar kodu daha modüler hale getirir. Aynı zamanda hangi fonksiyonun ne iş yaptığını bilerek kodu
# daha rahat anlayabiliriz. Fonksiyon isimleri, işlevlerini belirttiği için kodun anlaşılması kolaylaşır.
# Örnek:
def hesapla_vergiler(miktar):
"""Verilen miktarın vergisini hesaplar."""
vergi_orani = 0.18
return miktar * vergi_orani
def hesapla_toplam_fiyat(miktar):
"""Vergi dahil toplam fiyatı hesaplar."""
vergi = hesapla_vergiler(miktar)
return miktar + vergi
# 3. Kodun Modülerliğini Artırır
# Fonksiyonlar yazılımın modülerliğini artırır. Her fonksiyon belirli bir işlemi yerine getirir.
# Bu sayede, farklı bölümleri birbirinden bağımsız olarak geliştirebilir ve güncelleyebiliriz.
def veri_ekle(ad, soyad):
"""Ad ve soyad bilgilerini kontrol eder ve ekler."""
if not ad or not soyad:
raise ValueError("Ad ve soyad boş olamaz.")
return f"{ad} {soyad} başarıyla eklendi."
# Burada, ad ve soyad kontrolü yapan fonksiyonu modüler bir şekilde yazdık.
# 4. Hata Ayıklamayı Kolaylaştırır
# Fonksiyonlar, belirli bir işlemin nerede yanlış gittiğini daha kolay anlamamızı sağlar.
# Çünkü her fonksiyonun sorumluluğu bellidir ve sadece o fonksiyonu kontrol ederek hatayı bulabiliriz.
def hesapla_ortalama(sayilar):
"""Bir liste içindeki sayıların ortalamasını hesaplar."""
if len(sayilar) == 0:
raise ValueError("Liste boş olamaz.")
return sum(sayilar) / len(sayilar)
# Buradaki fonksiyon, ortalama hesaplama işlemini tek bir fonksiyonda tutuyor ve hatayı bu fonksiyonda kontrol ediyor.
# 5. Test Edilebilirlik ve Bakım Kolaylığı
# Fonksiyonlar, yazılımın belirli kısımlarını bağımsız bir şekilde test etmemize imkan verir.
# Fonksiyonların her biri, belirli bir işlemi yerine getirdiği için bu parçaları bağımsız olarak test edebiliriz.
# Örnek:
def faktoriyel(n):
"""n sayısının faktoriyelini hesaplar."""
if n == 0:
return 1
else:
return n * faktoriyel(n - 1)
# Bu fonksiyon, her bir giriş için bağımsız bir test yapılabilir.
# 6. Performans ve Bellek Yönetimi
# Python fonksiyonları, kodun daha verimli çalışmasına yardımcı olabilir. Gereksiz tekrarlar engellenir ve
# belirli işlemler için fonksiyonlar tekrar kullanılabilir. Ayrıca, fonksiyonlar belleği daha verimli kullanmak için
# işlemleri gerektiği kadar yapar.
# Örnek:
def fibonacci(n):
"""Fibonacci serisinin n. elemanını döndürür."""
if n <= 1:
return n
else:
return fibonacci(n - 1) + fibonacci(n - 2)
# Yine, burada fibonacci hesaplama işlemi fonksiyon ile yapılmış ve sadece gerektiği kadar işlem yapılmıştır.
# Fonksiyonlarla Kodun Daha Düzenli, Okunabilir ve Sürdürülebilir Olmasını Sağlayabilirsiniz.
# Fonksiyonlar yazılım geliştirmede vazgeçilmez bir araçtır. Kodunuzu modülerleştirir, okunabilirliğini artırır,
# hata ayıklamayı kolaylaştırır ve yazılımın bakımını daha yönetilebilir hale getirir.
# ============================================================
# PYTHON: FONKSİYON TANIMLAMA VE ÇAĞIRMA - DETAYLI AÇIKLAMALI
# ============================================================
# ? 1. Fonksiyon Nedir?
# Fonksiyonlar belirli bir görevi yerine getiren, gerektiğinde tekrar tekrar çağrılabilen kod bloklarıdır.
# Fonksiyonlar sayesinde kod tekrarı azaltılır, yazılım daha düzenli ve okunabilir hale gelir.
# ? 2. Fonksiyon Tanımlama - def Anahtar Kelimesi
# Basit bir fonksiyon tanımlayalım:
def ornek_fonksiyon(): # 'def' anahtar kelimesi ile fonksiyon tanımlanır. Fonksiyonun adı 'ornek_fonksiyon'dur.
print("Bu bir örnek fonksiyondur.") # Fonksiyon çağrıldığında bu satır çalışır ve ekrana yazı yazdırır.
# Fonksiyonu çağıralım:
ornek_fonksiyon() # Bu satır, yukarıda tanımlanan fonksiyonu çalıştırır.
# ============================================================
# ? 3. Parametreli Fonksiyonlar
# Fonksiyonlara dışarıdan veri (parametre) gönderebiliriz.
def selamla(isim): # 'isim' adlı bir parametre alan bir fonksiyon tanımladık.
print(f"Merhaba, {isim}!") # Parametreyi kullanarak kişiye özel selamlama yapıyoruz.
selamla("Ayşe") # Fonksiyon 'Ayşe' parametresiyle çağrılıyor.
selamla("Mehmet") # Fonksiyon 'Mehmet' parametresiyle çağrılıyor.
# ============================================================
# ? 4. Birden Fazla Parametreli Fonksiyonlar
def topla(sayi1, sayi2): # İki parametre alan bir fonksiyon tanımladık.
toplam = sayi1 + sayi2 # Parametrelerin toplamı hesaplanıyor.
print("Toplam:", toplam) # Sonuç yazdırılıyor.
topla(5, 10) # Çıktı: Toplam: 15
# ============================================================
# ? 5. return Kullanımı
# Fonksiyonlar sadece işlem yapmakla kalmaz, sonuç döndürebilir.
def carp(a, b): # İki sayıyı çarpan fonksiyon
return a * b # Çarpım sonucu 'return' ile geri döndürülüyor.
sonuc = carp(3, 4) # Fonksiyon sonucu bir değişkene atanıyor.
print("Çarpım sonucu:", sonuc) # Çıktı: 12
# ============================================================
# ? 6. Varsayılan (default) Parametreler
# Fonksiyonlara varsayılan değerler atanabilir.
def mesaj_yaz(mesaj="Merhaba!"): # 'mesaj' parametresinin varsayılan değeri "Merhaba!" olarak ayarlandı.
print(mesaj)
mesaj_yaz() # Parametre verilmezse varsayılan değer kullanılır. Çıktı: Merhaba!
mesaj_yaz("Selam Dünya!") # Parametre verilirse o değer kullanılır. Çıktı: Selam Dünya!
# ============================================================
# ? 7. Anahtar Kelime Argümanları (Keyword Arguments)
def bilgi_yaz(ad, yas): # İsim ve yaş bilgisi alan fonksiyon
print(f"{ad} {yas} yaşında.") # Bilgiler ekrana yazdırılıyor.
bilgi_yaz(yas=30, ad="Zeynep") # Parametreler sırasız verilebilir, anahtar kelimeyle belirtilmelidir.
# ============================================================
# ? 8. Fonksiyonların İçinde Fonksiyon (Nested Functions)
def dis_fonksiyon(): # Dış fonksiyon tanımlanıyor
print("Dış fonksiyon çalıştı.") # Önce bu satır çalışır
def ic_fonksiyon(): # İç fonksiyon tanımlanıyor
print("İç fonksiyon çalıştı.")
ic_fonksiyon() # İç fonksiyon çağrılıyor
dis_fonksiyon()
# Çıktı:
# Dış fonksiyon çalıştı.
# İç fonksiyon çalıştı.
# ============================================================
# ? 9. Hatalı Fonksiyon Kullanımı - Örnekler
# selamla() # HATA: Gerekli parametre verilmediği için çalışmaz. TypeError oluşur.
# topla(1, 2, 3) # HATA: Fonksiyon 2 parametre alırken 3 verilmiş. TypeError.
# ============================================================
# ? 10. Docstring (Fonksiyon Açıklama Satırı)
def alan_dikdortgen(en, boy):
"""
Bu fonksiyon verilen en ve boy'a göre
dikdörtgenin alanını hesaplayarak döndürür.
"""
return en * boy
print("Alan:", alan_dikdortgen(4, 5)) # Çıktı: Alan: 20
# Docstring'ler otomatik yardım belgelerinde gösterilir (help() komutuyla)
# help(alan_dikdortgen)
# ============================================================
# SONUÇ:
# Fonksiyonlar yazılımda tekrar eden işlemleri toparlar,
# kodu daha kısa, düzenli ve okunabilir hale getirir.
# Her seviyedeki yazılımcı için vazgeçilmez bir araçtır.
# ================================================================
# PYTHON: PARAMETRELER ve ARGÜMANLAR - DETAYLI AÇIKLAMA ve ÖRNEK
# ================================================================
# ? PARAMETRE NEDİR?
# Fonksiyon tanımlanırken kullanılan değişkenlerdir.
# Yani, fonksiyonun içine hangi verileri alacağını belirtir.
# ? ARGÜMAN NEDİR?
# Fonksiyon çağrılırken parametrelere gönderilen gerçek değerlerdir.
# Örnek:
def selamla(isim): # 'isim' burada bir parametredir.
print(f"Merhaba, {isim}!")
selamla("Ahmet") # "Ahmet" burada bir argümandır.
# Çıktı: Merhaba, Ahmet!
# ================================================================
# ? PARAMETRE vs ARGÜMAN FARKI
# PARAMETRE (Parameter) → Fonksiyon tanımında yazılır (ör: isim)
# ARGÜMAN (Argument) → Fonksiyon çağrılırken verilen değer (ör: "Ahmet")
# ================================================================
# ? BİRDEN FAZLA PARAMETRELİ FONKSİYON
def topla(a, b): # 'a' ve 'b' parametrelerdir.
print("Toplam:", a + b)
topla(4, 6) # 4 ve 6 argümanlardır.
# Çıktı: Toplam: 10
# ================================================================
# ? VARSAYILAN (DEFAULT) PARAMETRELER
# Fonksiyon tanımlanırken bir parametreye varsayılan bir değer atanabilir.
# Bu sayede, fonksiyon çağrılırken o argüman verilmezse varsayılan değer kullanılır.
def selam(isim="Ziyaretçi"): # 'isim' parametresi için varsayılan değer "Ziyaretçi"
print(f"Hoş geldin, {isim}!")
selam() # Parametre verilmediği için varsayılan değer kullanılır.
selam("Elif") # Argüman verildiği için varsayılan değerin yerini alır.
# Çıktı:
# Hoş geldin, Ziyaretçi!
# Hoş geldin, Elif!
# ================================================================
# ? BİRDEN FAZLA VARSAYILAN PARAMETRE
def kullanici_bilgisi(ad="Bilinmiyor", sehir="Bilinmiyor"): # Her iki parametrenin de varsayılan değeri var.
print(f"Kullanıcı: {ad}, Şehir: {sehir}")
kullanici_bilgisi() # İkisi de varsayılan değeri kullanır.
kullanici_bilgisi("Ali") # Sadece 'ad' belirtilir, 'sehir' varsayılan kalır.
kullanici_bilgisi("Ayşe", "Ankara") # Her iki argüman da belirtilmiş.
# Çıktı:
# Kullanıcı: Bilinmiyor, Şehir: Bilinmiyor
# Kullanıcı: Ali, Şehir: Bilinmiyor
# Kullanıcı: Ayşe, Şehir: Ankara
# ================================================================
# ? POZİSYONEL vs ANAHTAR ARGÜMANLAR (Keyword Arguments)
# Pozisyonel argümanlar → sırasıyla parametrelere yerleştirilir.
# Anahtar (keyword) argümanlar → hangi parametreye ait olduğunu belirtir.
def bilgiler(ad, yas, meslek):
print(f"Ad: {ad}, Yaş: {yas}, Meslek: {meslek}")
# Pozisyonel argümanla çağırma
bilgiler("Mehmet", 30, "Mühendis")
# Anahtar kelimeyle çağırma
bilgiler(yas=22, meslek="Öğrenci", ad="Zeynep")
# Çıktı:
# Ad: Mehmet, Yaş: 30, Meslek: Mühendis
# Ad: Zeynep, Yaş: 22, Meslek: Öğrenci
# ================================================================
# ? HATA ÖRNEKLERİ
# Parametre eksik verilirse:
# bilgiler("Ali", 25) # HATA! → meslek eksik: TypeError oluşur.
# Fazla argüman verilirse:
# bilgiler("Ali", 25, "Doktor", "Ekstra") # HATA! Fazla argüman verildi.
# ================================================================
# ? DOCSTRING (FONKSİYON AÇIKLAMA YAZISI)
def kare_al(sayi=2):
"""
Bu fonksiyon verilen sayının karesini döndürür.
Eğer sayı verilmezse varsayılan olarak 2'nin karesini döndürür.
"""
return sayi ** 2
print("Sonuç:", kare_al()) # Varsayılan değeri kullanır → 4
print("Sonuç:", kare_al(5)) # 5'in karesi → 25
# ================================================================
# ? SONUÇ:
# Fonksiyonlar parametre alabilir.
# Bu parametreler fonksiyon çağrılırken argümanlara dönüşür.
# Varsayılan parametreler sayesinde fonksiyonlar esnek hale gelir.
# Anahtar kelimeyle çağırmak okunabilirliği artırır.
# ================================================================
# PYTHON: GERİ DÖNÜŞ DEĞERİ (return) - DETAYLI AÇIKLAMA ve ÖRNEK
# ================================================================
# ? return Nedir?
# 'return' ifadesi bir fonksiyondan değer döndürmek için kullanılır.
# Bu değer, fonksiyon çağrıldığı yerde kullanılabilir ve fonksiyonun çalışması burada sona erer.
# ? 1. return İfadesiyle Değer Döndürme
# Basit bir fonksiyon örneği: iki sayının toplamını döndüren bir fonksiyon.
def topla(a, b): # Fonksiyonun parametreleri 'a' ve 'b'
toplam = a + b # 'a' ve 'b' parametrelerinin toplamını hesaplıyoruz
return toplam # Hesaplanan toplam değeri fonksiyondan döndürüyoruz.
# Fonksiyon çağrısı ve sonucu bir değişkene atama
sonuc = topla(5, 3) # '5' ve '3' argümanları 'a' ve 'b' parametrelerine gönderiliyor.
print("Toplam:", sonuc) # Çıktı: Toplam: 8
# Fonksiyon çağrısında dönen değeri doğrudan yazdırmak
print("Toplam:", topla(7, 4)) # Çıktı: Toplam: 11
# ================================================================
# ? 2. Birden Fazla Değer Döndürme
# Python fonksiyonları, birden fazla değer döndürebilir.
# Bu değerler genellikle bir tuple içinde döndürülür.
def hesapla(x, y):
toplam = x + y # 'x' ve 'y' parametrelerinin toplamını hesapla
fark = x - y # 'x' ve 'y' parametrelerinin farkını hesapla
carpim = x * y # 'x' ve 'y' parametrelerinin çarpımını hesapla
bolum = x / y # 'x' ve 'y' parametrelerinin bölümünü hesapla
return toplam, fark, carpim, bolum # Birden fazla değeri tuple şeklinde döndürüyoruz.
# Fonksiyonu çağırmak ve dönen değerleri almak
toplam, fark, carpim, bolum = hesapla(8, 4) # Fonksiyonun döndürdüğü tuple'ı çözerek değişkenlere atıyoruz.
# Çıktı: Her bir değeri ekrana yazdıralım
print("Toplam:", toplam) # Çıktı: Toplam: 12
print("Fark:", fark) # Çıktı: Fark: 4
print("Çarpım:", carpim) # Çıktı: Çarpım: 32
print("Bölüm:", bolum) # Çıktı: Bölüm: 2.0
# ================================================================
# ? 3. Birden Fazla Değer Döndürme - Tuple ve Liste Kullanımı
# Dönen değerler bir tuple içinde olabilir, fakat liste de döndürülebilir.
# Ancak tuple genellikle daha yaygın bir kullanımdır çünkü verileri sabit tutmak amaçlanır.
def carpanlar(a, b):
return a, b # 'a' ve 'b' değerleri bir tuple olarak döndürülür.
carp, bolen = carpanlar(6, 3) # Dönen tuple çözülür ve 'carp' ile 'bolen' değişkenlerine atanır.
print("Çarpanlar:", carp, bolen) # Çıktı: Çarpanlar: 6 3
# ================================================================
# ? 4. Geri Dönüş Değeri ile Daha Karmaşık Hesaplamalar
# Birden fazla değer döndürülmesi, daha karmaşık işlemler için de kullanılabilir.
# Örneğin: Kredi kartı ödeme hesaplaması, faiz hesaplaması vb.
def faiz_hesapla(principal, faiz_orani, yil):
faiz = principal * (faiz_orani / 100) * yil # Faiz hesaplanır.
toplam = principal + faiz # Anapara + faiz toplamı.
return faiz, toplam # Faiz ve toplam döndürülür.
# Fonksiyonu çağırarak sonucu birden fazla değişkene atama
faiz, toplam_tutar = faiz_hesapla(1000, 5, 2) # 1000 anapara, %5 faiz oranı, 2 yıl
print(f"Faiz: {faiz}, Toplam Tutar: {toplam_tutar}")
# Çıktı: Faiz: 100.0, Toplam Tutar: 1100.0
# ================================================================
# ? 5. return ile Hata Durumu Yönetimi
# return ifadesi aynı zamanda hata durumu yönetimi için de kullanılabilir.
# Örneğin, negatif sayılara karşı doğrulama yaparak geri dönüş yapılabilir.
def faktoriyel(n):
if n < 0: # Eğer n negatifse, geçersiz bir değer döndürülür.
return "Geçersiz giriş, negatif sayılarla işlem yapılamaz."
elif n == 0: # 0 faktöriyel özel durumu: 1
return 1
else:
sonuc = 1
for i in range(1, n + 1):
sonuc *= i # faktöriyel hesaplama
return sonuc # Sonuç döndürülür
# Pozitif ve negatif değerlerle fonksiyon test edilir.
print(faktoriyel(5)) # Çıktı: 120
print(faktoriyel(-3)) # Çıktı: Geçersiz giriş, negatif sayılarla işlem yapılamaz.
# ================================================================
# ? 6. return ile Fonksiyonu Erken Bitirme
# return ifadesi fonksiyonun çalışmasını erken sonlandırmak için de kullanılabilir.
def sayi_kontrolu(sayi):
if sayi < 0:
return "Negatif sayı!" # Negatif sayı kontrolü, fonksiyonu sonlandırır.
return "Pozitif sayı!"
print(sayi_kontrolu(-5)) # Çıktı: Negatif sayı!
print(sayi_kontrolu(10)) # Çıktı: Pozitif sayı!
# ================================================================
# SONUÇ:
# 'return' ifadesi fonksiyonlardan değer döndürmek için kullanılır.
# Birden fazla değer döndürülebilir ve bu değerler genellikle tuple ya da liste olarak döner.
# Fonksiyonlar içinde return ifadesi ile hesaplamalar yapılabilir, hata durumu yönetimi sağlanabilir,
# ve fonksiyonlar daha verimli hale getirilebilir.
# ================================================================
# PYTHON: GLOBAL ve LOCAL DEĞİŞKENLER - DETAYLI AÇIKLAMA ve ÖRNEK
# ================================================================
# ? DEĞİŞKEN KAPSAMI (SCOPE) NEDİR?
# Değişkenlerin tanımlandığı ve erişilebildiği alanı ifade eder.
# Python'da değişkenler genellikle iki ana kapsamda yer alır:
# 1. Global Kapsam
# 2. Local Kapsam
# - Global değişkenler: Programın her yerinde erişilebilir.
# - Local değişkenler: Sadece bulundukları fonksiyon içinde erişilebilir.
# ================================================================
# ? LOCAL (YEREL) DEĞİŞKENLER
# Local değişkenler bir fonksiyon içinde tanımlanır ve sadece o fonksiyon içinde erişilebilir.
# Fonksiyon dışında, bu değişkene erişilemez.
def topla(a, b): # 'a' ve 'b' burada local (yerel) değişkenlerdir.
toplam = a + b # 'toplam' fonksiyon içinde tanımlanan yerel bir değişkendir.
return toplam # Bu değeri döndürüyoruz.
# Fonksiyonu çağırıp yerel değişkenlere erişemiyoruz.
sonuc = topla(3, 4) # 'a', 'b', ve 'toplam' sadece 'topla' fonksiyonu içinde geçerli.
print(sonuc) # Çıktı: 7
# Eğer aşağıdaki gibi bir işlem yapılırsa hata alırız:
# print(toplam) # HATA! 'toplam' fonksiyon dışında tanımlanmadığı için erişilemez.
# ================================================================
# ? GLOBAL DEĞİŞKENLER
# Global değişkenler, fonksiyonlar dışında tanımlanır ve programın her yerinde kullanılabilir.
# Global değişkenler, fonksiyonlar içinde de kullanılabilir.
global_degisken = "Bu bir global değişkendir." # Global değişken
def fonksiyon1():
print(global_degisken) # Global değişken fonksiyon içinde erişilebilir.
def fonksiyon2():
print(global_degisken) # Global değişken başka bir fonksiyonda da erişilebilir.
fonksiyon1() # Çıktı: Bu bir global değişkendir.
fonksiyon2() # Çıktı: Bu bir global değişkendir.
# ================================================================
# ? GLOBAL DEĞİŞKENLERİN LOCAL DEĞİŞKENLERLE İLİŞKİSİ
# Bir fonksiyon içinde global değişkenin değeri değiştirilemez,
# eğer değiştirilmek istenirse global değişkeni kullanabilmek için 'global' anahtar kelimesi gereklidir.
def fonksiyon3():
global global_degisken # Global değişkeni değiştirebilmek için 'global' anahtar kelimesi kullanılır.
global_degisken = "Global değişken değeri değiştirildi." # Değeri değiştiriyoruz.
fonksiyon3() # Fonksiyon çalıştırıldığında global değişkenin değeri değişir.
print(global_degisken) # Çıktı: Global değişken değeri değiştirildi.
# ================================================================
# ? GLOBAL ANAHTAR KELİMESİ KULLANIMI
# Global anahtar kelimesi, fonksiyon içinde bir global değişkeni değiştirmek için kullanılır.
# Eğer 'global' anahtar kelimesi kullanılmazsa, Python fonksiyon içinde yeni bir local değişken tanımlar.
def fonksiyon4():
global global_degisken # 'global' ile değişkeni global kapsamda tutuyoruz.
global_degisken = "Yine değiştirildi!" # Global değişkenin değeri burada değişir.
fonksiyon4() # Global değişkenin değeri değişir.
print(global_degisken) # Çıktı: Yine değiştirildi!
# Eğer 'global' anahtar kelimesi kullanılmazsa, fonksiyon kendi içinde bir 'global_degisken' adında yerel değişken oluşturur
# ve global değişkenin değeri değiştirilmez. Örnek:
def fonksiyon5():
global_degisken = "Yerel değişken" # Burada yeni bir local değişken oluşturuluyor.
print("Fonksiyon içindeki yerel değişken:", global_degisken)
fonksiyon5() # Çıktı: Fonksiyon içindeki yerel değişken: Yerel değişken
print(global_degisken) # Çıktı: Yine değiştirildi! (Global değişken değişmemiştir.)
# ================================================================
# ? GLOBAL VE LOCAL DEĞİŞKENLER ARASINDAKİ İLİŞKİ
# Local değişken, fonksiyon dışında erişilemezken, global değişken her yerden erişilebilir.
# Ancak, fonksiyon içinde global değişkeni değiştirebilmek için 'global' anahtar kelimesi gereklidir.
# ================================================================
# ? ÖRNEK: GLOBAL VE LOCAL DEĞİŞKENLERİN KARŞILAŞTIRILMASI
global_degisken2 = "Global 2"
def fonksiyon6():
global global_degisken2 # 'global' anahtar kelimesi ile global değişkeni kullanıyoruz.
global_degisken2 = "Global değişken 2 değiştirildi."
local_degisken = "Local değişken" # Bu sadece fonksiyon içinde geçerli.
print("Global değişken:", global_degisken2)
print("Local değişken:", local_degisken)
fonksiyon6() # Çıktı:
# Global değişken: Global değişken 2 değiştirildi.
# Local değişken: Local değişken
# Global değişkenin değeri fonksiyondan sonra değişmişken, local değişken fonksiyon dışında geçerli değildir.
# ================================================================
# SONUÇ:
# - Global değişkenler programın her yerinde kullanılabilir.
# - Local değişkenler sadece bulundukları fonksiyonda geçerlidir.
# - 'global' anahtar kelimesi ile fonksiyon içinde global değişkenin değeri değiştirilebilir.
# - Local değişkenler fonksiyon dışında erişilemez.
# ================================================================
# PYTHON: FONKSIYONLARDA DOKÜMANTASYON ve YARDIMCI FONKSIYONLAR
# ================================================================
# ? DOCSTRING NEDİR?
# Docstring, bir fonksiyonun, sınıfın veya modülün ne yaptığı hakkında bilgi sağlayan bir açıklamadır.
# Python'da docstring, fonksiyon, sınıf veya modül tanımının hemen altında yer alır.
# Genellikle üçlü tırnak işaretleri (""") ile başlar ve biter.
# Docstring, fonksiyonun ne işe yaradığını, hangi parametreleri kabul ettiğini ve hangi değeri döndürdüğünü açıklamak için kullanılır.
# ================================================================
# ? Docstring Kullanımı - Temel Örnek
def topla(a, b):
"""
Bu fonksiyon, iki sayıyı toplar.
Parametreler:
a (int veya float): İlk sayıyı temsil eder.
b (int veya float): İkinci sayıyı temsil eder.
Returns:
int veya float: a ve b'nin toplamını döndürür.
"""
return a + b # Fonksiyonun işlevi: 'a' ve 'b' sayılarının toplamını döndürmek
# Fonksiyon çağrısı
sonuc = topla(5, 3)
print(sonuc) # Çıktı: 8
# ================================================================
# ? Docstring ile Yardım Almak - help() ve __doc__ Kullanımı
# Python, fonksiyonların veya sınıfların docstring'ini görmek için birkaç yerleşik fonksiyon sağlar.
# Bu fonksiyonlardan ikisi 'help()' ve '__doc__' özellikleridir.
# `help()` fonksiyonu, bir fonksiyonun, modülün veya sınıfın belgelerini (docstring) gösterir.
# Bu fonksiyon, kullanıcının Python'daki bir fonksiyon veya sınıf hakkında bilgi edinmesine olanak sağlar.
help(topla) # Bu satır, 'topla' fonksiyonunun docstring'ini ekrana yazdırır.
# Çıktı:
# Help on function topla in module __main__:
#
# topla(a, b)
# Bu fonksiyon, iki sayıyı toplar.
#
# Parametreler:
# a (int veya float): İlk sayıyı temsil eder.
# b (int veya float): İkinci sayıyı temsil eder.
#
# Returns:
# int veya float: a ve b'nin toplamını döndürür.
# `__doc__` özelliği, bir fonksiyonun docstring'ini doğrudan döndürür.
print(topla.__doc__) # Bu satır da fonksiyonun docstring'ini ekrana yazdırır.
# Çıktı:
# Bu fonksiyon, iki sayıyı toplar.
#
# Parametreler:
# a (int veya float): İlk sayıyı temsil eder.
# b (int veya float): İkinci sayıyı temsil eder.
#
# Returns:
# int veya float: a ve b'nin toplamını döndürür.
# ================================================================
# ? Birden Fazla Satır İçeren Docstring Örneği
def carpma(a, b):
"""
Bu fonksiyon, iki sayıyı çarpar.
Parametreler:
a (int veya float): Çarpılacak ilk sayıyı temsil eder.
b (int veya float): Çarpılacak ikinci sayıyı temsil eder.
Returns:
int veya float: a ve b'nin çarpımını döndürür.
Örnekler:
carpma(2, 3) => 6
carpma(4.5, 2) => 9.0
"""
return a * b
# Fonksiyonu çağırma
sonuc2 = carpma(4, 5)
print(sonuc2) # Çıktı: 20
# ================================================================
# ? Docstring Yazım İpuçları
# 1. Açıklayıcı olun: Fonksiyon ne yapar? Hangi parametreleri kabul eder?
# 2. Parametrelerin türünü ve hangi türde değerler beklediğini belirtin.
# 3. Döndürülen değeri açıkça belirtin.
# 4. Eğer bir örnek varsa, örnek verin.
# ================================================================
# ? HELP() Fonksiyonunun Kullanımı
# `help()` fonksiyonu yalnızca docstring'i görüntülemekle kalmaz, aynı zamanda
# fonksiyon, sınıf veya modülün diğer özelliklerini de gösterir.
# Örneğin, 'list' sınıfına ait fonksiyonların nasıl çalıştığını görmek için:
help(list) # list sınıfının yardımcı dökümantasyonunu ekrana yazdırır.
# ================================================================
# ? Docstring ve help() ile Python Kütüphanelerini Keşfetme
# Python'da yerleşik kütüphanelerin kullanımını öğrenmek için 'help()' fonksiyonu çok faydalıdır.
# Örnek olarak, 'math' modülünü inceleyelim:
import math
help(math) # 'math' modülünün fonksiyonları ve açıklamaları gösterilir.
# ================================================================
# ? Fonksiyonlar Arası Yardımcı Fonksiyonlar
# Birçok durumda, bir fonksiyon başka bir fonksiyonun işlevini kullanabilir.
# Yardımcı fonksiyonlar, ana fonksiyonun iç işleyişini basitleştirmek için kullanılır.
# Örneğin, toplama ve çıkarma işlevlerini gerçekleştiren yardımcı fonksiyonlar:
def ekle(a, b):
"""
İki sayıyı toplar.
"""
return a + b
def cikar(a, b):
"""
İki sayıyı birbirinden çıkarır.
"""
return a - b
def hesapla(x, y):
"""
x ve y'yi toplar, sonra da farkını hesaplar.
Parametreler:
x, y: İki sayıyı temsil eder.
Returns:
tuple: (toplam, fark)
"""
toplam = ekle(x, y) # 'ekle' fonksiyonu çağrılır
fark = cikar(x, y) # 'cikar' fonksiyonu çağrılır
return toplam, fark # Her ikisini döndürüyoruz
# Fonksiyonu çağırma
toplam, fark = hesapla(10, 5)
print(f"Toplam: {toplam}, Fark: {fark}")
# Çıktı: Toplam: 15, Fark: 5
# ================================================================
# SONUÇ:
# - **Docstring**, fonksiyon, sınıf veya modüller hakkında bilgi sağlamak için kullanılır.
# - **help()** fonksiyonu, bir fonksiyon veya modül hakkında daha fazla bilgi edinmek için kullanılır.
# - **`__doc__`** özelliği, fonksiyonların docstring'ini doğrudan almak için kullanılır.
# - Yardımcı fonksiyonlar, büyük ve karmaşık fonksiyonları küçük, anlaşılır parçalara böler.
# ================================================================
# PYTHON: LAMBDA FONKSIYONLARI (ANONIM FONKSIYONLAR)
# ================================================================
# ? Lambda Fonksiyonları (Anonim Fonksiyonlar)
# Lambda fonksiyonları, Python'da bir fonksiyonun hızlı bir şekilde tanımlanabilmesini sağlayan
# "anonim" (isim verilmeyen) fonksiyonlardır. Genellikle kısa fonksiyonlar için kullanılırlar.
# Lambda fonksiyonları, 'lambda' anahtar kelimesi ile başlar ve bir ifade ile sonlanır.
# Lambda fonksiyonları, bir işlem yapacak fonksiyonları tek satırda tanımlamak için çok kullanışlıdır.
# ================================================================
# ? Lambda Fonksiyonu Tanımlama
# Basit bir lambda fonksiyonu örneği:
# Lambda fonksiyonu ile iki sayıyı toplayan bir fonksiyon yazalım.
topla = lambda a, b: a + b # 'lambda' ifadesi ile a ve b parametreleri toplanır.
# Lambda fonksiyonunu çağırma
sonuc = topla(5, 3)
print(sonuc) # Çıktı: 8
# Burada, lambda fonksiyonu 'a' ve 'b' parametrelerini alır ve toplamını döndürür.
# ================================================================
# ? Lambda Fonksiyonlarının Kullanımı
# Lambda fonksiyonları, özellikle aşağıdaki gibi yerleşik fonksiyonlarla birlikte kullanıldığında çok faydalıdır:
# - map(): Liste üzerindeki her elemana belirli bir fonksiyon uygular.
# - filter(): Liste üzerindeki elemanları belirli bir koşula göre filtreler.
# - reduce(): Liste üzerindeki elemanları birleştirerek tek bir değer döndürür.
# ================================================================
# ? map() Fonksiyonu ile Lambda Kullanımı
# map() fonksiyonu, bir fonksiyonu bir iterable (örneğin liste) üzerindeki her elemana uygular.
# Aşağıdaki örnekte, her sayıyı ikiyle çarpmak için lambda fonksiyonunu kullanacağız.
sayilar = [1, 2, 3, 4, 5]
# Lambda fonksiyonu ile sayıları ikiyle çarpma
carpilmis_sayilar = map(lambda x: x * 2, sayilar)
# map() fonksiyonu, sonuçları bir 'map' nesnesi olarak döndürür, bu nedenle bunu listeye dönüştürmek gerekir.
print(list(carpilmis_sayilar)) # Çıktı: [2, 4, 6, 8, 10]
# Burada, lambda fonksiyonu her bir 'x' değerini alır ve ikiyle çarpar.
# ================================================================
# ? filter() Fonksiyonu ile Lambda Kullanımı
# filter() fonksiyonu, bir fonksiyonu bir iterable (örneğin liste) üzerindeki her elemana uygular
# ve sadece True döndüren öğeleri filtreler.
# Aşağıdaki örnekte, yalnızca tek sayıları filtreleyeceğiz.
sayilar = [1, 2, 3, 4, 5]
# Lambda fonksiyonu ile sadece tek sayıları seçme
tek_sayilar = filter(lambda x: x % 2 != 0, sayilar)
# filter() fonksiyonu, sonuçları bir 'filter' nesnesi olarak döndürür, bu nedenle bunu listeye dönüştürmek gerekir.
print(list(tek_sayilar)) # Çıktı: [1, 3, 5]
# Burada, lambda fonksiyonu 'x' değerini alır ve sadece tek sayıları seçmek için True döndüren bir koşul kullanır.
# ================================================================
# ? reduce() Fonksiyonu ile Lambda Kullanımı
# reduce() fonksiyonu, bir iterable üzerinde bir işlemi iteratif olarak uygular ve
# sonuçları birleştirerek tek bir değer döndürür.
# reduce() fonksiyonu 'functools' modülünde yer alır.
# Aşağıdaki örnekte, tüm sayıları çarpan bir işlem yapacağız.
from functools import reduce # reduce() fonksiyonu functools modülünden gelir.
sayilar = [1, 2, 3, 4, 5]
# Lambda fonksiyonu ile sayıları çarpma
carpim = reduce(lambda x, y: x * y, sayilar)
print(carpim) # Çıktı: 120
# Burada, lambda fonksiyonu, iki değeri 'x' ve 'y' alır ve bunları çarpar. reduce, bu işlemi tüm liste elemanlarına uygular.
# ================================================================
# ? Lambda Fonksiyonlarının Kullanım Alanları
# - **Kısa ve geçici fonksiyonlar için** idealdir.
# - Kodun okunabilirliğini bozmadan küçük hesaplamalar yapılmasını sağlar.
# - Birçok fonksiyonun tek satırda tanımlanmasına olanak tanır.
# - Özellikle **map()**, **filter()**, ve **reduce()** gibi fonksiyonlarla kullanıldığında güçlüdür.
# ================================================================
# ? Lambda ve Diğer Fonksiyonel Programlama Yöntemleri
# Lambda fonksiyonları, fonksiyonel programlamada oldukça yaygındır.
# Python'da fonksiyonel programlama tarzında işlem yapmak için lambda, map, filter ve reduce fonksiyonları sıklıkla bir arada kullanılır.
# ================================================================
# SONUÇ:
# - **Lambda fonksiyonları**, kısa ve anonim fonksiyonlar yazmak için kullanılır.
# - **map()**, **filter()** ve **reduce()** fonksiyonları ile lambda fonksiyonları birleşerek daha güçlü ve kısa kodlar yazılmasını sağlar.
# ================================================================
# PYTHON: İÇ İÇE FONKSIYONLAR (NESTED FUNCTIONS) VE KAPSAM
# ================================================================
# ? İç İçe Fonksiyonlar (Nested Functions)
# İç içe fonksiyonlar, bir fonksiyonun içinde başka bir fonksiyon tanımlamaktır.
# Yani, bir fonksiyon başka bir fonksiyonu kapsayabilir. Bu özellik, fonksiyonel programlamada
# daha modüler ve organize kod yazmayı sağlayabilir.
# Aşağıda iç içe fonksiyon kullanımını ve kapsama (scope) nasıl etkileyeceğini gösteren bir örnek bulunmaktadır:
# ================================================================
# ? İç İçe Fonksiyon Tanımlama
def dis_fonksiyon():
"""
'dis_fonksiyon' adlı bir fonksiyon, içerisinde başka bir fonksiyon olan 'ic_fonksiyon' fonksiyonunu tanımlar.
"""
print("Dış fonksiyon çalışıyor.")
def ic_fonksiyon():
"""
İç fonksiyon sadece dış fonksiyon içinde çağrılabilir.
Dış fonksiyonun değişkenlerine erişebilir.
"""
print("İç fonksiyon çalışıyor.")
# İç fonksiyonu burada çağırıyoruz
ic_fonksiyon() # İç fonksiyon çağrılır
# Dış fonksiyonu çağırıyoruz
dis_fonksiyon() # Çıktı: Dış fonksiyon çalışıyor. İç fonksiyon çalışıyor.
# Burada, 'ic_fonksiyon' sadece 'dis_fonksiyon' fonksiyonu içinde çağrılabilir ve
# dış fonksiyonun içinde tanımlanan değişkenlere erişebilir. Ancak dışarıdan doğrudan 'ic_fonksiyon' çağrılamaz.
# ================================================================
# ? Kapsam (Scope) Kavramı
# Kapsam (Scope), bir değişkenin erişilebilir olduğu alandır.
# Python'da bir değişkenin kapsamı, hangi fonksiyonlar veya bloklar içinde o değişkenin erişilebilir olduğunu belirler.
# Fonksiyonlar içinde tanımlanan değişkenler, sadece o fonksiyon içinde geçerlidir. Bu, yerel kapsam (local scope) olarak adlandırılır.
# Fonksiyon dışındaki değişkenler ise küresel kapsam (global scope) olarak adlandırılır.
# Aşağıdaki örnekte yerel ve küresel kapsamın nasıl çalıştığını görebiliriz:
# Küresel değişken
x = 10
def fonksiyon():
# Yerel değişken
y = 20
print("Yerel değişken y:", y)
print("Küresel değişken x:", x)
fonksiyon()
# Çıktı:
# Yerel değişken y: 20
# Küresel değişken x: 10
# Burada, 'x' küresel bir değişken olduğu için fonksiyon içinde de kullanılabilir.
# 'y' ise yerel bir değişken olup sadece fonksiyon içinde geçerlidir ve dışarıdan erişilemez.
# ================================================================
# ? Closure Kavramı (Kapanış)
# Closure, iç içe fonksiyonların çalışma mantığıyla ilgilidir.
# Closure, bir iç fonksiyonun, dış fonksiyonun parametreleri ve değişkenleriyle birlikte
# hatırlanabilmesidir. İç fonksiyon, dış fonksiyonun değişkenlerine erişim sağladığı sürece
# dış fonksiyon bitse bile, dış fonksiyonun değişkenleri hafızada tutulur.
# Closure'ı daha iyi anlamak için aşağıdaki örneği inceleyelim:
def dis_fonksiyon_closure(x):
"""
'dis_fonksiyon_closure' fonksiyonu, 'x' parametresini alır ve içinde 'ic_fonksiyon' fonksiyonunu tanımlar.
İç fonksiyon, 'x' parametresini kullanarak bir işlem yapar.
"""
def ic_fonksiyon(y):
return x + y # İç fonksiyon, dış fonksiyonun 'x' parametresine erişiyor
# İç fonksiyonu döndürüyoruz
return ic_fonksiyon
# Closure kullanımı:
# Dış fonksiyon 'dis_fonksiyon_closure' çağrıldığında, içerideki 'ic_fonksiyon' fonksiyonu döndürülür.
# Burada, 'ic_fonksiyon' fonksiyonu, dış fonksiyonun 'x' parametresine erişim sağlar.
topla_10 = dis_fonksiyon_closure(10) # 'dis_fonksiyon_closure' fonksiyonu çağrıldı ve 'ic_fonksiyon' döndürüldü.
# 'topla_10' artık 'ic_fonksiyon' fonksiyonuna bir referans tutuyor.
# 'topla_10' fonksiyonunu kullanarak işlem yapalım
sonuc = topla_10(5) # 'x' değeri 10, 'y' değeri 5. Sonuç 15 olacaktır.
print(sonuc) # Çıktı: 15
# ================================================================
# ? Closure'ın Çalışma Mantığı
# Closure, dış fonksiyonun parametresini ve yerel değişkenlerini hatırlayarak,
# iç fonksiyonla birlikte çalışmasını sağlar. Yani, dış fonksiyon çalıştıktan sonra,
# iç fonksiyon hala dış fonksiyonun değişkenlerine erişebilir.
# Bu özellik, fonksiyonların "değer taşıyıcı" olarak kullanılmasına olanak tanır.
# ================================================================
# SONUÇ:
# - **İç içe fonksiyonlar** Python'da bir fonksiyon içinde başka bir fonksiyon tanımlamaya olanak tanır.
# - **Kapsam (scope)**, değişkenlerin hangi fonksiyonlarda erişilebilir olduğunu belirler.
# - **Closure**, iç fonksiyonların dış fonksiyonların değişkenlerini "hatırlaması" ve erişmesi özelliğidir.
# Bu, fonksiyonların esnekliğini artırır ve fonksiyonel programlamada oldukça kullanışlıdır.
# ================================================================
# PYTHON: *args ve **kwargs KULLANIMI
# ================================================================
# *args ve **kwargs, Python fonksiyonlarında esnek sayıda parametre almayı sağlayan özel sözdizimleridir.
# - *args, bir fonksiyona birden fazla konumsal parametre gönderilmesine izin verir.
# - **kwargs, bir fonksiyona anahtar-değer (keyword) parametreleri gönderilmesine olanak tanır.
# ================================================================
# ? *args: Esnek Sayıda Konumsal Parametre
# *args, fonksiyona gönderilen birden fazla konumsal parametreyi (pozisyonel argümanları)
# bir demet (tuple) içinde toplar.
# Yani, fonksiyona kaç parametre gönderildiğini bilmeden çalışabiliriz.
def toplam(*args):
"""
*args ile birden fazla parametre alarak, tüm parametrelerin toplamını hesaplayan bir fonksiyon.
"""
# args, bir tuple olarak gelir, bu yüzden onunla toplama işlemi yapılabilir.
toplam = 0
for sayi in args:
toplam += sayi
return toplam
# Fonksiyona farklı sayıda parametreler göndererek toplamını hesaplayalım:
print(toplam(10, 20, 30)) # Çıktı: 60
print(toplam(5, 15)) # Çıktı: 20
print(toplam(1, 2, 3, 4, 5)) # Çıktı: 15
# Burada, *args kullanarak fonksiyonumuza kaç parametre gönderildiğini bilmeden esnek şekilde işlem yapabiliyoruz.
# Yani, toplam fonksiyonu her zaman doğru çalışır, ne kadar sayıda parametre verilirse verilsin.
# ================================================================
# ? **kwargs: Esnek Sayıda Anahtar-Değer (Keyword) Parametre
# **kwargs, fonksiyona birden fazla anahtar-değer (keyword) parametresi gönderilmesini sağlar.
# Gönderilen parametreler, bir sözlük (dictionary) şeklinde toplanır.
def kisi_bilgileri(**kwargs):
"""
**kwargs ile bir kişiye ait bilgileri anahtar-değer (key-value) şeklinde alır
ve bu bilgileri yazdırır.
"""
for key, value in kwargs.items():
print(f"{key}: {value}")
# Fonksiyona anahtar-değer parametreleri ile bilgi gönderelim:
kisi_bilgileri(ad="Ali", yas=30, meslek="Mühendis")
# Çıktı:
# ad: Ali
# yas: 30
# meslek: Mühendis
# Burada, **kwargs kullanarak esnek sayıda anahtar-değer çifti alabiliyoruz.
# Bu, özellikle fonksiyona birçok parametre göndermemiz gerektiğinde ve hangi parametrelerin
# gönderileceği bilinmediğinde faydalıdır.
# ================================================================
# ? *args ve **kwargs'ı Birlikte Kullanma
# *args ve **kwargs'ı bir fonksiyonda birlikte de kullanabiliriz.
# Ancak, *args her zaman **kwargs'tan önce gelmelidir.
def bilgi_topla(*args, **kwargs):
"""
*args ile konumsal parametreleri ve **kwargs ile anahtar-değer parametrelerini alan bir fonksiyon.
"""
print("Konumsal Parametreler (*args):", args)
print("Anahtar-Değer Parametreleri (**kwargs):", kwargs)
# Hem *args hem de **kwargs kullanarak fonksiyonu çağıralım:
bilgi_topla(10, 20, 30, ad="Ayşe", yas=25)
# Çıktı:
# Konumsal Parametreler (*args): (10, 20, 30)
# Anahtar-Değer Parametreleri (**kwargs): {'ad': 'Ayşe', 'yas': 25}
# Burada, *args ile gönderdiğimiz sayılar bir tuple olarak, **kwargs ile gönderdiğimiz anahtar-değer
# çiftleri ise bir sözlük (dictionary) olarak alınmıştır.
# ================================================================
# ? Gerçek Hayattan Örnek: Öğrenci Bilgileri ve Notlar
# *args ve **kwargs kullanarak bir öğrencinin notlarını ve bilgilerini alalım.
def ogrenci_bilgi_notlari(isim, *notlar, **bilgiler):
"""
Öğrencinin ismini, notlarını ve diğer bilgilerini alarak yazdıran fonksiyon.
"""
print(f"Öğrenci İsmi: {isim}")
# Notların ortalamasını hesaplayalım
ortalama = sum(notlar) / len(notlar) if notlar else 0
print(f"Not Ortalaması: {ortalama}")
# Ekstra bilgiler varsa yazdıralım
for key, value in bilgiler.items():
print(f"{key}: {value}")
# Öğrencinin ismi, notları ve diğer bilgilerini girelim:
ogrenci_bilgi_notlari("Ahmet", 85, 90, 78, yas=20, okul="Üniversite", bolum="Bilgisayar Mühendisliği")
# Çıktı:
# Öğrenci İsmi: Ahmet
# Not Ortalaması: 84.33333333333333
# yas: 20
# okul: Üniversite
# bolum: Bilgisayar Mühendisliği
# Burada, *args kullanarak öğrencinin notlarını esnek sayıda parametre olarak alıyoruz ve
# **kwargs kullanarak öğrencinin diğer bilgilerini (yaş, okul, bölüm) anahtar-değer şeklinde alıyoruz.
# Bu sayede fonksiyon çok esnek bir hale geliyor.
# ================================================================
# SONUÇ:
# - **`*args`**, fonksiyona esnek sayıda konumsal parametre gönderilmesine olanak tanır.
# - **`**kwargs`**, fonksiyona esnek sayıda anahtar-değer parametresi gönderilmesini sağlar.
# - **Birlikte kullanıldıklarında**, *args konumsal parametreleri, **kwargs ise anahtar-değer parametrelerini alır.
# - Gerçek hayattan örneklerle, *args ve **kwargs'ın esnek ve güçlü kullanımını görebiliyoruz.
# ================================================================
# matematik.py
# Bu dosya matematiksel işlemleri yapan fonksiyonları içeriyor.
# Fonksiyonlar burada tanımlanır, başka dosyalarda kullanılmak üzere
# import edilerek tekrar kullanılabilir.
# ================================================================
def toplama(a, b):
"""
Bu fonksiyon iki sayıyı toplar.
:param a: İlk sayı
:param b: İkinci sayı
:return: İki sayının toplamı
"""
return a + b
def cikarma(a, b):
"""
Bu fonksiyon iki sayıyı çıkarır.
:param a: İlk sayı
:param b: İkinci sayı
:return: İlk sayıdan ikinci sayının çıkarılması
"""
return a - b
def carpma(a, b):
"""
Bu fonksiyon iki sayıyı çarpar.
:param a: İlk sayı
:param b: İkinci sayı
:return: İki sayının çarpımı
"""
return a * b
def bolme(a, b):
"""
Bu fonksiyon iki sayıyı böler.
:param a: İlk sayı
:param b: İkinci sayı
:return: İlk sayının ikinci sayıya bölümü
"""
if b == 0:
return "Bir sayıyı sıfıra bölemezsiniz!"
return a / b
# ================================================================
# main.py
# Bu dosya matematiksel fonksiyonları kullanmak için
# 'matematik.py' dosyasından import edilmiştir.
# ================================================================
# 'matematik' dosyasındaki fonksiyonları içe aktaralım:
import importt
# Toplama işlemini yapalım
toplam_sonuc = importt.toplama(10, 5)
print(f"Toplama Sonucu: {toplam_sonuc}") # Çıktı: 15
# Çıkarma işlemini yapalım
cikarma_sonuc = importt.cikarma(10, 5)
print(f"Çıkarma Sonucu: {cikarma_sonuc}") # Çıktı: 5
# Çarpma işlemini yapalım
carpma_sonuc = importt.carpma(10, 5)
print(f"Çarpma Sonucu: {carpma_sonuc}") # Çıktı: 50
# Bölme işlemini yapalım
bolme_sonuc = importt.bolme(10, 2)
print(f"Bölme Sonucu: {bolme_sonuc}") # Çıktı: 5.0
# Sıfıra bölme durumu:
bolme_sonuc_sifir = importt.bolme(10, 0)
print(f"Sıfıra Bölme Sonucu: {bolme_sonuc_sifir}") # Çıktı: Bir sayıyı sıfıra bölemezsiniz!
# 3. Adım Adım Açıklamalar ve Yorum Satırları
# matematik.py Dosyası:
# Bu dosyada çeşitli matematiksel işlemleri gerçekleştiren fonksiyonlar (toplama, cikarma, carpma, bolme) tanımlanmıştır.
# Her fonksiyon, ilgili işlemi yapar ve işlem sonucu döndürür. Örneğin, toplama fonksiyonu iki sayıyı toplar ve sonucu döndürür.
# Fonksiyonların her birinde açıklama metinleri (docstring) bulunmaktadır. Bu açıklamalar, fonksiyonun ne yaptığı hakkında bilgi verir.
# main.py Dosyası:
# main.py dosyasında, import matematik ifadesi ile matematik.py dosyasındaki fonksiyonlar içeri aktarılmaktadır.
# Daha sonra, bu fonksiyonlar matematik.<fonksiyon_adı> şeklinde çağrılır. Örneğin, matematik.toplama(10, 5) ifadesi ile toplama fonksiyonu kullanılır.
# Sonuçlar ekrana yazdırılır.
# Modüler Yapı:
# Fonksiyonlar farklı dosyalarda tanımlandığında, projedeki kodun tekrar kullanılabilirliği ve bakımı kolaylaşır.
# import komutu ile sadece ihtiyacınız olan fonksiyonları içeri alabilir ve kullanabilirsiniz.
# Bu yapı, yazılım projelerinde daha büyük ve daha yönetilebilir kodlar yazmamıza yardımcı olur.
# 4. Modüler Yapı Avantajları:
# Yeniden Kullanılabilirlik: Fonksiyonları ve kodları birden fazla dosyada yeniden kullanabilirsiniz. Örneğin, matematik.py dosyasındaki fonksiyonlar sadece bir dosyada tanımlandı ve main.py gibi başka dosyalarda tekrar kullanıldı.
# Kolay Bakım: Kodları modüller halinde ayırarak, bir dosyada yapılan değişikliklerin diğer dosyaları etkilemeden yapılmasını sağlayabilirsiniz. Bu, yazılım bakımını ve hata ayıklamayı kolaylaştırır.
# Daha Temiz ve Düzenli Kod: Modüler yapılar, projelerdeki kodun daha düzenli ve okunabilir olmasını sağlar.
# 5. Alternatif İthalat (Import) Yöntemleri:
# Python'da bir modülü farklı şekillerde içeri aktarabilirsiniz:
# Modül adı ile: import matematik şeklinde.
# Fonksiyonları tek tek: from matematik import toplama şeklinde. Bu durumda, sadece toplama fonksiyonunu içeri alırsınız.
# Modül için takma ad kullanma (alias): import matematik as mt şeklinde. Bu durumda, fonksiyonları mt.toplama(10, 5) şeklinde çağırabilirsiniz.
# ========================================================
# Nesne Tabanlı Programlamaya Giriş
# Prosedürel vs. Nesne Tabanlı Programlama
# ========================================================
# Prosedürel Programlama Yaklaşımı
# ---------------------------------
# Bu yaklaşımda program akışı sıralı adımlarla ve fonksiyonlarla yürütülür.
# Veriler genellikle global değişkenlerde saklanır ve bu verilere fonksiyonlar üzerinden erişilir.
# Bir kişinin bilgilerini ekrana yazdıran fonksiyon
def bilgileri_yazdir(ad, soyad, yas):
# Gelen parametreleri ekrana yazdırıyoruz
print("Ad:", ad)
print("Soyad:", soyad)
print("Yaş:", yas)
# Kullanıcıya ait bilgiler ayrı değişkenlerde saklanıyor
# Bu veriler daha sonra fonksiyona parametre olarak gönderilecek
ad = "Ali" # Kullanıcının adı
soyad = "Yılmaz" # Kullanıcının soyadı
yas = 30 # Kullanıcının yaşı
# Yukarıda tanımladığımız fonksiyonu çağırarak bilgileri ekrana yazdırıyoruz
bilgileri_yazdir(ad, soyad, yas)
# -----------------------------------------------
# Açıklama:
# - Bu yapı küçük programlar için yeterli olabilir.
# - Ancak projeler büyüdükçe veriler çoğalır ve fonksiyonlar karmaşık hale gelir.
# - Verilerin ve işlemlerin birbirinden ayrı olması, kodun okunabilirliğini ve sürdürülebilirliğini zorlaştırır.
# - Bu nedenle daha büyük ve karmaşık projelerde Nesne Tabanlı Programlama tercih edilir.
# ========================================================
# Nesne Tabanlı Programlama Yaklaşımı
# ========================================================
# Bu yaklaşımda veriler (özellikler) ve o verilere ait işlemler (metotlar)
# birlikte tanımlanır. Bunun için "class" (sınıf) yapısı kullanılır.
# Her sınıftan oluşturulan örneğe "nesne" (object) denir.
# Bir kişinin bilgilerini saklayan ve yazdıran bir sınıf tanımlıyoruz
class Kisi:
# Yapıcı metod (constructor)
# Bu metod, sınıftan yeni bir nesne oluşturulduğunda otomatik olarak çalışır
def __init__(self, ad, soyad, yas):
# self: sınıftan oluşturulan nesnenin kendisini temsil eder
# Yani kisi1 nesnesi için self → kisi1 olur
# Nesneye ait özellikleri (attribute) tanımlıyoruz
self.ad = ad # Nesneye ad bilgisini atıyoruz
self.soyad = soyad # Nesneye soyad bilgisini atıyoruz
self.yas = yas # Nesneye yaş bilgisini atıyoruz
# Nesneye ait bir metod (fonksiyon) tanımlıyoruz
# Bu metod, kişinin bilgilerini ekrana yazdırır
def bilgileri_yazdir(self):
# self üzerinden nesneye ait verilere erişilir
print("Ad:", self.ad)
print("Soyad:", self.soyad)
print("Yaş:", self.yas)
# --------------------------------------------------------
# Sınıftan bir nesne (object) oluşturuyoruz
# Kisi sınıfına ait bir örnek: kisi1
kisi1 = Kisi("Ali", "Yılmaz", 30)
# Bu işlem __init__ metodunu otomatik olarak çalıştırır
# Oluşturduğumuz nesneye ait metodu çağırıyoruz
# kişi bilgilerini ekrana yazdırır
kisi1.bilgileri_yazdir()
# --------------------------------------------------------
# Açıklama:
# - Aynı yapıyı başka kişiler için de kullanabiliriz.
# - Her kişi için ayrı bir nesne oluşturulur.
# - Kod daha düzenli, modüler ve okunabilir hale gelir.
# - Bu yapı, büyük projelerde kod tekrarını azaltır ve yönetimi kolaylaştırır.
# -----------------------------------
# Prosedürel vs. Nesne Tabanlı Karşılaştırması:
# -----------------------------------
# - Prosedürel: İşlem odaklıdır, küçük projelerde yeterlidir.
# Açıklama:
# Kodlar fonksiyonlar halinde yazılır ve işlem sırasına göre çalıştırılır.
# Veri ve işlemler birbirinden ayrıdır.
# Küçük projelerde bu yapı yeterlidir çünkü yönetilmesi kolaydır.
# Ancak proje büyüdükçe kod karmaşıklaşır, tekrarlar artar ve sürdürülebilirlik düşer.
# - Nesne Tabanlı (OOP): Modüler yapı sağlar, büyük projelerde tercih edilir.
# Açıklama:
# OOP'de veri (özellikler) ve bu verilere ait işlemler (metotlar) aynı yapı (sınıf) içinde tanımlanır.
# Böylece kod parçaları (nesneler) kendi sorumluluklarını taşır.
# Bu modüler yapı, büyük projelerde kodun daha kolay yönetilmesini sağlar.
# Sınıflar ve nesneler sayesinde kod yeniden kullanılabilir ve test edilebilir hale gelir.
# - OOP ile veri ve işlemler bir araya getirilir, kod daha okunabilir ve sürdürülebilir hale gelir.
# Açıklama:
# Nesne tabanlı yaklaşımda her şey bir sınıf yapısında toplanır.
# Veriye ait tüm işlemler aynı yerde tanımlandığı için kod okunması ve anlaşılması kolay olur.
# Değişiklik yapmak gerektiğinde sadece ilgili sınıf üzerinde düzenleme yaparak sistemi bozmadan güncelleme sağlanabilir.
# Bu da bakım ve genişletme süreçlerini kolaylaştırır.
# Özet:
# - Prosedürel programlama başlangıç seviyesinde hızlı sonuç verir ancak ölçeklenmesi zordur.
# - Nesne tabanlı programlama ise özellikle karmaşık sistemlerde uzun vadede verimli, düzenli ve sürdürülebilir bir çözüm sunar.
# ==========================================================
# 1. Sınıf Nedir?
# ==========================================================
# Bir sınıf (class), bir nesneye ait özellikleri (attributes)
# ve o verilere ait işlevleri (metotlar) tanımladığımız bir yapıdır.
# Python'da bir sınıf, benzer özelliklere ve işlevlere sahip nesneleri
# modellemek için kullanılır.
# ------------------------------------------
# Örnek 1: Sınıf Tanımlama
# ------------------------------------------
# Aşağıda, bir kişinin özelliklerini ve davranışlarını modelleyen
# basit bir sınıf örneği göreceğiz.
class Kisi:
# Sınıfın başlangıcında herhangi bir özellik tanımlanmamış olsa da,
# sınıfımız bir şablon olarak işlev görecektir.
pass
# Şu an sınıfımızın içinde herhangi bir özellik veya metot bulunmuyor.
# Ama bu sınıf üzerinden bir nesne oluşturabiliriz.Bu konuyu sonraki ders içeriğinde açıklayacağız.
# ------------------------------------------
# Örnek 1: Basit bir Sınıf Tanımlama
# ------------------------------------------
# "Kisi" adında bir sınıf tanımlıyoruz.
# Bu sınıf şu an için boş; sadece şablon olarak işlev görecek.
class Kisi:
pass # "pass" ifadesi, sınıfın henüz herhangi bir özelliği veya metodu olmadığını belirtir.
# Bu sınıfın, kişileri tanımlamak için bir şablon görevi gördüğünü unutmamalıyız.
# Şu an, Kisi sınıfını kullanarak nesne yaratabiliriz, ancak bu nesne
# sadece boş bir şablona sahip olacaktır. Nesneye ait özellikler veya metotlar
# şu an yok.
# Kisi sınıfından bir nesne oluşturuyoruz
kisi1 = Kisi() # Burada "kisi1" adında bir nesne oluşturduk. Ancak bu nesne henüz bir şey yapmaz.
# Burada sadece boş bir sınıf oluşturduk ve bir nesne türettik.
# Ama bu nesne şu an için herhangi bir özellik taşımıyor.
# ==========================================================
# Sınıf Tanımlaması
# ==========================================================
# Kisi adında bir sınıf tanımlıyoruz. Bu sınıf, kişilere ait
# bazı özellikleri (ad, soyad, yas) ve bu özellikleri tutan bir nesne oluşturur.
class Kisi:
# ==========================================================
# __init__ metodu: Sınıfın Yapıcı Metodu (Constructor)
# ==========================================================
# __init__ metodu, sınıfın her yeni örneği (nesnesi) oluşturulduğunda
# çağrılır. Bu metot, nesnenin başlangıç değerlerini (özelliklerini)
# belirlemek için kullanılır. Buradaki "self", oluşturduğumuz nesneyi temsil eder.
# self.ad, self.soyad ve self.yas nesnenin özellikleridir.
def __init__(self, ad, soyad, yas):
# self: "self" parametresi, oluşturduğumuz nesneyi temsil eder.
# Bu nesneye ait özellikleri tanımlarken kullanılır.
self.ad = ad # "ad" parametresi, oluşturduğumuz nesnenin adını tutar.
self.soyad = soyad # "soyad" parametresi, oluşturduğumuz nesnenin soyadını tutar.
self.yas = yas # "yas" parametresi, oluşturduğumuz nesnenin yaşını tutar.
# ==========================================================
# Yeni Nesne Oluşturma
# ==========================================================
# Kisi sınıfından bir nesne oluşturuyoruz. Burada "kisi1" isminde bir nesne oluşturduk.
# Bu nesnenin adını "Ali", soyadını "Yılmaz", yaşını ise 30 olarak belirliyoruz.
kisi1 = Kisi("Ali", "Yılmaz", 30)
# ==========================================================
# Nesne Özelliklerine Erişim
# ==========================================================
# Oluşturduğumuz nesneye ait özelliklere erişim sağlıyoruz.
# "kisi1" nesnesinin "ad" özelliğine erişiyoruz. "kisi1.ad" ifadesi,
# kisi1 nesnesinin adını döndürecektir.
print(kisi1.ad) # Ali
# "kisi1" nesnesinin "soyad" özelliğine erişiyoruz. "kisi1.soyad" ifadesi,
# kisi1 nesnesinin soyadını döndürecektir.
print(kisi1.soyad) # Yılmaz
# "kisi1" nesnesinin "yas" özelliğine erişiyoruz. "kisi1.yas" ifadesi,
# kisi1 nesnesinin yaşını döndürecektir.
print(kisi1.yas) # 30
# ==========================================================
# Sınıf ve Metot Tanımlaması
# ==========================================================
# Kisi adında bir sınıf tanımlıyoruz. Bu sınıf, bir kişiye ait özellikleri
# (ad, soyad, yas) tutarken, aynı zamanda bu kişiye ait bazı işlemleri
# (bilgileri yazdırmak gibi) gerçekleştiren metodları da içerebilir.
class Kisi:
# ==========================================================
# __init__ Metodu: Sınıfın Yapıcı Metodu (Constructor)
# ==========================================================
# __init__ metodu, sınıfın her yeni örneği oluşturulduğunda otomatik
# olarak çağrılır ve nesnenin başlangıç özelliklerini belirler.
def __init__(self, ad, soyad, yas):
self.ad = ad # Nesnenin adını atıyoruz.
self.soyad = soyad # Nesnenin soyadını atıyoruz.
self.yas = yas # Nesnenin yaşını atıyoruz.
# ==========================================================
# bilgileri_yazdir Metodu
# ==========================================================
# Bu metod, Kisi sınıfına ait bir nesnenin bilgilerini yazdırır.
# Metot, self parametresi ile nesnenin özelliklerine erişir.
def bilgileri_yazdir(self):
# Nesnenin ad, soyad ve yas özelliklerini yazdırıyoruz.
print(f"Ad: {self.ad}")
print(f"Soyad: {self.soyad}")
print(f"Yaş: {self.yas}")
# ==========================================================
# Yeni Nesne Oluşturma
# ==========================================================
# Kisi sınıfından yeni bir nesne (object) oluşturuyoruz. Bu nesnenin
# adını "Ali", soyadını "Yılmaz", yaşını ise 30 olarak belirliyoruz.
kisi1 = Kisi("Ali", "Yılmaz", 30)
# ==========================================================
# Nesneye Ait Metodun Çağrılması
# ==========================================================
# "kisi1" nesnesine ait "bilgileri_yazdir" metodunu çağırıyoruz.
# Bu metot, kisi1 nesnesinin ad, soyad ve yas bilgilerini ekrana yazdırır.
kisi1.bilgileri_yazdir()
# ==========================================================
# self Anahtar Kelimesi Nedir?
# ==========================================================
# Python'da, sınıf içindeki metodlar, bir nesneye ait özelliklere ve verilere erişmek için
# "self" anahtar kelimesini kullanır. self, sınıfın her bir örneğini (nesnesini) temsil eder.
# Yani self, sınıfın her örneğine (nesnesine) özel verilere ulaşmak için kullanılır.
# self, sadece sınıf içinde metodların tanımlandığı yerlerde kullanılabilir.
# Bu, metotların hangi nesne üzerinde çalıştığını belirtir.
# self Anahtar Kelimesinin Temel Amacı:
# 1. Nesneye ait özelliklere erişmek.
# 2. Nesne üzerinde işlem yapan metodlar tanımlamak.
# 3. Sınıfın her örneği için farklı verilere ulaşmak.
# ==========================================================
# self Anahtar Kelimesinin Kullanımı
# ==========================================================
# Bir sınıf içerisinde, self ile nesneye ait verilere ve metodlara erişiriz.
class Kisi:
def __init__(self, ad, soyad, yas):
# __init__ metodunda self, nesnenin özelliklerine erişmek için kullanılır.
# Bu metod nesne oluşturulurken otomatik olarak çağrılır.
self.ad = ad # self.ad ile nesnenin adını tutuyoruz.
self.soyad = soyad # self.soyad ile nesnenin soyadını tutuyoruz.
self.yas = yas # self.yas ile nesnenin yaşını tutuyoruz.
def bilgileri_yazdir(self):
# bilgileri_yazdir metodunda self, nesnenin ad, soyad ve yaşına erişir.
print(f"Ad: {self.ad}") # Nesnenin adını yazdırır.
print(f"Soyad: {self.soyad}") # Nesnenin soyadını yazdırır.
print(f"Yaş: {self.yas}") # Nesnenin yaşını yazdırır.
# ==========================================================
# Nesne Oluşturulması ve self Anahtar Kelimesinin Kullanımı
# ==========================================================
# Kisi sınıfından bir nesne (object) oluşturuyoruz. Bu nesneye ait
# özellikleri self ile ilişkilendiriyoruz.
kisi1 = Kisi("Ali", "Yılmaz", 30) # self, kisi1 nesnesi üzerinde işlem yapar.
# kisi1 nesnesine ait bilgileri yazdırıyoruz.
kisi1.bilgileri_yazdir()
# ==========================================================
# self ve Her Nesneye Ait Farklı Özellikler
# ==========================================================
# Sınıfın her nesnesi (örneği) kendine ait verilere sahip olabilir.
# self anahtar kelimesi sayesinde her nesneye ait veriler birbirinden bağımsızdır.
kisi2 = Kisi("Ayşe", "Demir", 25) # yeni bir nesne oluşturduk.
# kisi2 nesnesinin bilgilerini yazdırıyoruz.
kisi2.bilgileri_yazdir()
# ==========================================================
# self ve Metodlar Arasındaki İlişki
# ==========================================================
# Metodlar, self parametresini kullanarak nesneye ait verilere erişebilir ve bu verileri
# değiştirebilir. Örneğin, nesne üzerinde yapılan işlemler metodlar aracılığıyla yapılır.
# Metodlar nesneye özel çalışır; her nesne için farklı işlemler yapılabilir.
class Araba:
def __init__(self, marka, model, yil):
self.marka = marka
self.model = model
self.yil = yil
def araba_bilgileri(self):
# Bu metod, nesnenin marka, model ve yıl bilgilerini ekrana yazdırır.
print(f"Marka: {self.marka}")
print(f"Model: {self.model}")
print(f"Yıl: {self.yil}")
def yil_degistir(self, yeni_yil):
# Bu metod, nesnenin yıl bilgisini günceller.
self.yil = yeni_yil
print(f"Yeni Yıl: {self.yil}")
# ==========================================================
# self Kullanarak Nesneler Üzerinde İşlem Yapma
# ==========================================================
# Araba sınıfından bir nesne oluşturuyoruz.
araba1 = Araba("Toyota", "Corolla", 2020)
# araba1 nesnesinin bilgilerini yazdırıyoruz.
araba1.araba_bilgileri()
# Araba'nın yıl bilgisini değiştiriyoruz.
araba1.yil_degistir(2023) # Yeni yıl bilgisini güncelledik.
# ==========================================================
# Nesne Üzerinde İşlem Yapma ve Veri Erişimi
# ==========================================================
# Python'da nesne tabanlı programlama (OOP), nesneler ve bu nesneler üzerinde yapılan
# işlemlerle çalışmayı içerir. Bu bölümde, nesneler üzerindeki verilere nasıl erişileceğini
# ve nesneler üzerinde nasıl işlem yapılacağını öğreneceğiz.
# Bir nesne, sınıfın bir örneğidir ve sınıfın özelliklerine (attributes) ve metotlarına (methods) sahiptir.
# Nesneler üzerinde işlem yapabilmek için, nesneye ait verilere erişim sağlamak gerekir.
# ==========================================================
# Nesne Üzerinde Veri Erişimi
# ==========================================================
# Nesnelerin özelliklerine, o nesne oluşturulduktan sonra erişebiliriz.
# Nesne oluşturulduğunda, her nesnenin kendine ait özellikleri olacaktır.
# Bu verilere erişmek için, nesnenin özelliklerine dot notation (.) ile ulaşabiliriz.
# ==========================================================
# Sınıf ve Nesne Tanımlaması
# ==========================================================
# Kisi sınıfını tanımlıyoruz ve ad, soyad, yas gibi özellikler ekliyoruz.
class Kisi:
def __init__(self, ad, soyad, yas):
# __init__ metodu, nesnenin ilk oluşturulmasında çağrılır ve nesnenin başlangıç değerlerini alır.
self.ad = ad # self.ad, nesnenin "ad" özelliğini tutar.
self.soyad = soyad # self.soyad, nesnenin "soyad" özelliğini tutar.
self.yas = yas # self.yas, nesnenin "yas" özelliğini tutar.
def bilgileri_yazdir(self):
# bilgileri_yazdir metodu, nesnenin bilgilerini ekrana yazdırır.
print(f"Ad: {self.ad}") # Nesnenin "ad" özelliğini yazdırır.
print(f"Soyad: {self.soyad}") # Nesnenin "soyad" özelliğini yazdırır.
print(f"Yaş: {self.yas}") # Nesnenin "yas" özelliğini yazdırır.
# ==========================================================
# Nesne Oluşturma ve Veri Erişimi
# ==========================================================
# Kisi sınıfından bir nesne oluşturuyoruz. Bu nesnenin özelliklerini belirliyoruz.
kisi1 = Kisi("Ali", "Yılmaz", 30)
# Kisi sınıfına ait nesnenin "ad", "soyad" ve "yas" özelliklerine erişiyoruz:
print("Nesneye Ait Verilere Erişim:")
print(f"Ad: {kisi1.ad}") # kisi1 nesnesinin "ad" özelliğine erişim
print(f"Soyad: {kisi1.soyad}") # kisi1 nesnesinin "soyad" özelliğine erişim
print(f"Yaş: {kisi1.yas}") # kisi1 nesnesinin "yas" özelliğine erişim
# ==========================================================
# Nesne Üzerinde İşlem Yapma
# ==========================================================
# Nesneler üzerindeki verilere eriştikten sonra, bu verilere işlem yapabiliriz.
# Python'da nesne üzerinde işlem yapma, metodlar aracılığıyla gerçekleştirilir.
# Örneğin, bir "Kisi" nesnesine ait bilgileri yazdırmak için yazdığımız metod:
kisi1.bilgileri_yazdir()
# ==========================================================
# Nesne Özelliklerini Güncelleme
# ==========================================================
# Nesnelerin özelliklerini değiştirmek mümkündür. Özelliklere doğrudan erişim sağlayarak bu değişiklik yapılabilir.
# Kisi sınıfındaki bir nesnenin "yas" özelliğini değiştirelim.
print("\nYas Değiştirme:")
kisi1.yas = 35 # kisi1 nesnesinin "yas" özelliğini güncelledik.
print(f"Güncel Yaş: {kisi1.yas}")
# ==========================================================
# Nesne Üzerinden İşlem Yapma: Metodlarla Değişiklik
# ==========================================================
# Nesne özellikleri üzerinde değişiklik yapmak için metotlar kullanılabilir.
# Bir metod aracılığıyla nesnenin verilerini değiştirebiliriz.
# Yeni bir metod tanımlayalım: yas_degistir
class Kisi:
def __init__(self, ad, soyad, yas):
self.ad = ad
self.soyad = soyad
self.yas = yas
def bilgileri_yazdir(self):
print(f"Ad: {self.ad}")
print(f"Soyad: {self.soyad}")
print(f"Yaş: {self.yas}")
def yas_degistir(self, yeni_yas):
# Bu metot, nesnenin yas özelliğini değiştirir.
self.yas = yeni_yas
print(f"Yeni Yaş: {self.yas}")
# Yeni bir nesne oluşturalım
kisi2 = Kisi("Ayşe", "Demir", 28)
# kisi2 nesnesinin bilgilerini yazdıralım
print("\nKişi 2 Bilgileri:")
kisi2.bilgileri_yazdir()
# Metod aracılığıyla yaş bilgisini değiştirelim
print("\nYaş Değiştiriyoruz:")
kisi2.yas_degistir(32) # Yas değerini 32 olarak değiştiriyoruz.
# Son olarak, değişen yaş bilgisini kontrol edelim
print("\nGüncel Yaş Bilgisi:")
kisi2.bilgileri_yazdir()
# ==========================================================
# Sınıf Dışından ve İçinden Özelliklere Erişim
# ==========================================================
# Python'da sınıf içindeki verilere (özelliklere) ve metotlara,
# sınıf dışında ve içinde farklı şekillerde erişilebilir.
# Bu yazıda, sınıf içinden ve dışından nesne özelliklerine
# nasıl erişileceği ve nasıl manipüle edileceği anlatılacaktır.
# ==========================================================
# 1. Sınıf Dışından Özelliklere Erişim
# ==========================================================
# Bir nesnenin özelliklerine sınıf dışında, yani nesne oluşturulduktan sonra erişilebilir.
# Bu erişim için dot notation (nokta işareti) kullanılır.
# Nesne üzerinden doğrudan erişim yapılır.
# Sınıf Tanımlaması:
class Kisi:
def __init__(self, ad, soyad, yas):
# Nesnenin özelliklerini başlatıyoruz
self.ad = ad # Nesnenin "ad" özelliği
self.soyad = soyad # Nesnenin "soyad" özelliği
self.yas = yas # Nesnenin "yas" özelliği
def bilgileri_yazdir(self):
# Bu metot nesnenin bilgilerini yazdırır
print(f"Ad: {self.ad}")
print(f"Soyad: {self.soyad}")
print(f"Yaş: {self.yas}")
# Nesne oluşturuluyor
kisi1 = Kisi("Ali", "Yılmaz", 30)
# Sınıf Dışından Özelliklere Erişim:
print("Sınıf Dışından Erişim:")
print(f"Ad: {kisi1.ad}") # kisi1 nesnesinin "ad" özelliğine erişim
print(f"Soyad: {kisi1.soyad}") # kisi1 nesnesinin "soyad" özelliğine erişim
print(f"Yaş: {kisi1.yas}") # kisi1 nesnesinin "yas" özelliğine erişim
# ==========================================================
# 2. Sınıf İçinden Özelliklere Erişim
# ==========================================================
# Nesne özelliklerine sınıf içinde, yani sınıfın metotları içinde de erişilebilir.
# Bu, "self" anahtar kelimesiyle yapılır. "self", nesnenin kendisini ifade eder.
# Metod içinde özelliklere erişim:
class Kisi:
def __init__(self, ad, soyad, yas):
self.ad = ad # Nesnenin "ad" özelliği
self.soyad = soyad # Nesnenin "soyad" özelliği
self.yas = yas # Nesnenin "yas" özelliği
def bilgileri_yazdir(self):
# Bu metot nesnenin bilgilerini yazdırır
print(f"Ad: {self.ad}") # self.ad, nesnenin "ad" özelliğine erişim
print(f"Soyad: {self.soyad}") # self.soyad, nesnenin "soyad" özelliğine erişim
print(f"Yaş: {self.yas}") # self.yas, nesnenin "yas" özelliğine erişim
def yas_degistir(self, yeni_yas):
# Bu metot, nesnenin yaşını değiştirir
self.yas = yeni_yas
print(f"Yeni Yaş: {self.yas}")
# Nesne oluşturuluyor
kisi2 = Kisi("Ayşe", "Demir", 28)
# Sınıf İçinden Özelliklere Erişim:
print("\nSınıf İçinden Erişim (bilgileri_yazdir metodu):")
kisi2.bilgileri_yazdir() # Bu metod sınıf içinden nesne özelliklerine erişim sağlar
# Özelliği değiştirmek için metod kullanıyoruz:
print("\nYaş Değiştiriyoruz:")
kisi2.yas_degistir(32) # Yaş bilgisini değiştiren metodu çağırıyoruz
# Güncel bilgiyi yazdırıyoruz
print("\nGüncel Bilgiler:")
kisi2.bilgileri_yazdir() # Güncellenmiş yaş bilgisini yazdırır
# ==========================================================
# 3. Sınıf Dışından Özellik Güncelleme
# ==========================================================
# Sınıf dışından, nesnenin özelliklerini doğrudan değiştirebiliriz.
# Örneğin, nesnenin yaşını değiştirmek için aşağıdaki gibi erişebiliriz.
print("\nSınıf Dışından Özellik Güncelleme:")
kisi1.yas = 35 # kisi1 nesnesinin yaşını doğrudan güncelliyoruz
print(f"Güncellenmiş Yaş: {kisi1.yas}")
# ==========================================================
# 4. Özelliklerin Erişim Seviyesi
# ==========================================================
# Python'da, sınıf içindeki bazı özellikler özel (private) olarak tanımlanabilir.
# Bu özellikler dışarıdan doğrudan erişilemez. Ancak, Python'da özel erişim tamamen
# kısıtlanmamıştır, yalnızca bir "içsel kullanım" önerisi sunar.
# Özel özellikler tanımlama:
class Kisi:
def __init__(self, ad, soyad, yas):
self.ad = ad # Genel özellik
self.soyad = soyad # Genel özellik
self.__yas = yas # Özel özellik (çift alt çizgi ile tanımlandı)
def bilgileri_yazdir(self):
print(f"Ad: {self.ad}")
print(f"Soyad: {self.soyad}")
# private özelliğe metot içinde erişilebilir
print(f"Yaş: {self.__yas}")
def yas_degistir(self, yeni_yas):
# private özelliği değiştirebiliriz
self.__yas = yeni_yas
# Nesne oluşturuluyor
kisi3 = Kisi("Mehmet", "Çelik", 40)
# Sınıf Dışından Özel Özelliğe Erişim:
# Aşağıdaki kod hata verecektir, çünkü __yas özelliği özel olarak tanımlanmıştır.
# print(kisi3.__yas) # HATA: 'Kisi' nesnesi '__yas' özelliğine erişemez
# Ancak, sınıf içinde tanımlanan metodlar aracılığıyla özel verilere erişilebilir:
print("\nÖzel Özellik Erişimi:")
kisi3.bilgileri_yazdir() # private __yas özelliği metotla erişilebiliyor
# ==========================================================
# 5. Getter ve Setter Kullanımı (Private Özellikler için)
# ==========================================================
# Özel (private) özelliklere erişmek ve bu özellikleri değiştirmek için
# getter (alıcı) ve setter (ayarlayıcı) metodları kullanılabilir.
class Kisi:
def __init__(self, ad, soyad, yas):
self.ad = ad
self.soyad = soyad
self.__yas = yas # private özellik
# Getter metodu: Yaş bilgisini almak için
def get_yas(self):
return self.__yas
# Setter metodu: Yaş bilgisini güncellemek için
def set_yas(self, yeni_yas):
if yeni_yas >= 0:
self.__yas = yeni_yas
else:
print("Yaş negatif olamaz!")
# Nesne oluşturuluyor
kisi4 = Kisi("Fatma", "Koç", 25)
# Getter metoduyla özel özelliği alalım
print("\nGetter ile Yaş Erişimi:")
print(f"Yaş: {kisi4.get_yas()}") # getter metodu kullanarak özel yaş bilgisine erişiyoruz
# Setter metoduyla özel özelliği güncelleyelim
print("\nSetter ile Yaş Güncelleme:")
kisi4.set_yas(30) # setter metodu ile yaş bilgisi güncelleniyor
print(f"Güncellenmiş Yaş: {kisi4.get_yas()}") # Güncellenmiş yaş bilgisini alıyoruz
# ==========================================================
# KAPSÜLLEME (ENCAPSULATION) ve ERİŞİM BELİRLEYİCİLERİ
# ==========================================================
# Kapsülleme, Nesne Tabanlı Programlamanın (OOP) en önemli ilkelerinden biridir.
# Verilerin ve bu verilerle ilgili işlemlerin bir sınıf içinde bir arada tutulmasıdır.
# Python'da kapsülleme, özellikle nesneye ait verileri dış dünyadan gizlemek
# ve sadece belirli yollarla (metotlarla) erişilmesini sağlamak amacıyla kullanılır.
# ==========================================================
# 1. Temel Kapsülleme Nedir?
# ==========================================================
# Bir nesnenin özelliklerini (verilerini) doğrudan dışarıdan erişilemez hale getirip,
# bu özelliklere sadece sınıf içindeki metotlar aracılığıyla erişmektir.
# Amaç:
# - Veri güvenliği
# - Yetkisiz erişimin engellenmesi
# - Kontrol mekanizması (örneğin değer doğrulama) kurulması
# ==========================================================
# 2. Erişim Belirleyicileri (Access Modifiers)
# ==========================================================
# Python'da C++, Java gibi dillerdeki açıkça tanımlanmış erişim belirleyiciler (public, private, protected) yoktur.
# Ancak belirli kurallara dayalı şekilde simüle edilir:
# - PUBLIC (Genel): Her yerden erişilebilir.
# -> Özellik ya da metodun başında hiçbir alt çizgi (underscore) yoksa.
# -> Örn: self.ad
# - PROTECTED (Korumalı): Alt sınıflardan erişilebilir ama dışarıdan doğrudan erişim önerilmez.
# -> Özellik isminin başında bir alt çizgi (_) varsa.
# -> Örn: self._ad
# - PRIVATE (Özel): Yalnızca sınıf içinden erişilebilir.
# -> Özellik isminin başında iki alt çizgi (__) varsa.
# -> Örn: self.__ad
# ==========================================================
# 3. Örnek Uygulama: Public, Protected, Private
# ==========================================================
class Calisan:
def __init__(self, ad, maas):
self.ad = ad # public özellik
self._departman = "İK" # protected özellik
self.__maas = maas # private özellik
def bilgileri_goster(self):
print("Ad:", self.ad)
print("Departman:", self._departman)
print("Maaş:", self.__maas)
# Getter metodu: private veriye erişim sağlar
def get_maas(self):
return self.__maas
# Setter metodu: maaşı güncellemeden önce kontrol yapılabilir
def set_maas(self, yeni_maas):
if yeni_maas >= 0:
self.__maas = yeni_maas
else:
print("Geçersiz maaş değeri!")
# Nesne oluşturuluyor
calisan1 = Calisan("Ayşe", 15000)
# PUBLIC özelliğe doğrudan erişilebilir
print("\nPublic Özellik Erişimi:")
print(calisan1.ad) # Erişim mümkün
# PROTECTED özelliğe dışarıdan erişilebilir ama önerilmez
print("\nProtected Özellik Erişimi:")
print(calisan1._departman) # Erişim mümkün ama konvansiyon olarak önerilmez
# PRIVATE özelliğe doğrudan erişim HATA verir
print("\nPrivate Özellik Erişimi (Yanlış Yöntem):")
# print(calisan1.__maas) # AttributeError verir (erişim yasak)
# Doğru erişim: sınıf içindeki getter metodu aracılığıyla
print("\nPrivate Özellik Erişimi (Doğru Yöntem):")
print(calisan1.get_maas()) # 15000
# Private özellik güncelleme
print("\nMaaş Güncelleme:")
calisan1.set_maas(17000)
print("Yeni maaş:", calisan1.get_maas())
# Geçersiz güncelleme
print("\nGeçersiz Maaş Güncelleme:")
calisan1.set_maas(-5000) # Geçersiz
# ==========================================================
# 4. Python'da Name Mangling (İsim Karıştırma)
# ==========================================================
# __ozellik şeklinde tanımlanan private veriler, aslında _SınıfAdı__ozellik olarak yeniden adlandırılır.
# Bu sayede dışarıdan doğrudan erişim zorlaştırılır (tamamen engellenmez).
# Bu teknik "name mangling" olarak adlandırılır.
print("\nName Mangling ile Erişim (Önerilmez):")
print(calisan1._Calisan__maas) # Bu şekilde erişilebilir ama kesinlikle önerilmez!
# ==========================================================
# 5. Neden Kapsülleme Kullanmalıyız?
# ==========================================================
# - Kapsülleme, kodunuzu daha güvenli hale getirir.
# - Kullanıcının doğrudan nesne verilerine müdahale etmesini engeller.
# - Değer güncellemelerinde kontroller yapmanıza olanak tanır.
# - Nesneler arası tutarlılığı sağlar.
# - Daha okunabilir ve sürdürülebilir kod yazmanıza yardımcı olur.
# ==========================================================
# 6. Özet
# ==========================================================
# - Public: Her yerden erişilebilir.
# - Protected: Alt sınıflar erişebilir, dışarıdan erişilmesi önerilmez.
# - Private: Sadece sınıf içinden erişilebilir.
# - Getter ve Setter metotları, private verilere kontrollü erişim sağlar.
# - Kapsülleme ile veri güvenliği ve kod kontrolü sağlanır.
# ==========================================================
# SINIF İÇİNDE FONKSİYON TANIMLAMA (METHOD KAVRAMI)
# ==========================================================
# Nesne Tabanlı Programlama (OOP) yaklaşımında, sınıflar yalnızca veri tutmakla kalmaz,
# aynı zamanda bu verilerle ilgili işlemleri de içinde barındırır.
# Bu işlemler, sınıf içinde tanımlanan FONKSİYONLAR ile yapılır ve bunlara METHOD denir.
# ==========================================================
# 1. Method Nedir?
# ==========================================================
# Method, bir sınıf içinde tanımlanan fonksiyondur.
# Methodlar, nesnelere özgüdür ve genellikle 'self' parametresiyle tanımlanır.
# 'self' parametresi, metodun hangi nesne üzerinden çağrıldığını ifade eder.
# ==========================================================
# 2. Temel Method Kullanımı
# ==========================================================
class Araba:
# Yapıcı (constructor) metodumuz
def __init__(self, marka, model, hiz=0):
# Nesneye ait özellikleri tanımlıyoruz
self.marka = marka
self.model = model
self.hiz = hiz
# Bir method tanımlıyoruz (nesneye ait bir davranış)
def hiz_arttir(self, miktar):
# self: bu metodu çağıran nesneyi temsil eder
self.hiz += miktar
print(f"{self.marka} {self.model} hız arttırıldı. Yeni hız: {self.hiz} km/s")
# Başka bir method tanımı
def bilgileri_goster(self):
print("Marka:", self.marka)
print("Model:", self.model)
print("Hız:", self.hiz, "km/s")
# ==========================================================
# 3. Methodların Kullanımı (Nesne Üzerinden Çağırma)
# ==========================================================
# Araba sınıfından bir nesne (object) oluşturuyoruz
araba1 = Araba("Toyota", "Corolla")
# araba1 nesnesine ait bilgileri gösteriyoruz
araba1.bilgileri_goster()
# hız arttırma metodunu çağırıyoruz
araba1.hiz_arttir(20)
# yeniden bilgileri gösteriyoruz
araba1.bilgileri_goster()
# ==========================================================
# 4. Methodların Avantajları
# ==========================================================
# - Kod tekrarını azaltır.
# - Nesneye ait işlemleri kapsül içinde (sınıf) tutarak düzenli kod sağlar.
# - Sınıfın dışından yapılacak karışık işlemleri, sınıf içinde sadeleştirir.
# ==========================================================
# 5. self Parametresi Nedir?
# ==========================================================
# - Her sınıf methodunun ilk parametresi `self` olmalıdır.
# - Bu parametre, methodun hangi nesne (instance) üzerinden çağrıldığını belirtir.
# - self ile nesnenin özelliklerine erişebilir ve onları değiştirebiliriz.
# Örnek olarak: self.hiz -> o nesnenin hız değerini temsil eder
# ==========================================================
# 6. Methodlara Dışarıdan Parametre Göndermek
# ==========================================================
# - Methodlara dışarıdan parametre geçerek o methodun davranışını kontrol edebiliriz.
# - Örneğin `hiz_arttir(self, miktar)` methodu dışarıdan aldığı değeri kullanarak işlemi yapar.
# ==========================================================
# 7. Sınıf İçinde Farklı Türde Methodlar (İleri Seviye - Bilgi)
# ==========================================================
# - Örnek (instance) method: self parametresi alır. Nesneye özgüdür.
# - Sınıf (class) method: @classmethod ile tanımlanır, ilk parametresi cls olur. Tüm sınıfı ilgilendirir.
# - Statik (static) method: @staticmethod ile tanımlanır, self ya da cls almaz. Bağımsız çalışır.
# Bu dokümanda sadece örnek methodlara odaklandık. İleride diğerlerini de ele alacağız.
# ==========================================================
# 8. Kısa Özet
# ==========================================================
# - Method: Sınıf içinde tanımlanmış fonksiyondur.
# - self: O anki nesneye erişim sağlar.
# - Methodlar nesne üzerinden çağrılır: nesne.method_adi()
# - Methodlar sayesinde kod daha düzenli, okunabilir ve sürdürülebilir olur.
# ==========================================================
# 9. Ek Örnek
# ==========================================================
class Dikdortgen:
def __init__(self, genislik, yukseklik):
self.genislik = genislik
self.yukseklik = yukseklik
def alan_hesapla(self):
return self.genislik * self.yukseklik
def cevre_hesapla(self):
return 2 * (self.genislik + self.yukseklik)
# Nesne oluşturuluyor
dikdortgen1 = Dikdortgen(5, 10)
# Alan ve çevre hesaplama methodları çağrılıyor
print("Alan:", dikdortgen1.alan_hesapla())
print("Çevre:", dikdortgen1.cevre_hesapla())
# ==========================================================
# KALITIM (INHERITANCE) ve ÜST SINIF KULLANIMI
# ==========================================================
# Nesne Tabanlı Programlama'da (OOP) kalıtım (inheritance), bir sınıfın (alt sınıf)
# başka bir sınıfın (üst sınıf) özelliklerini ve metotlarını miras almasını sağlar.
# Bu sayede:
# - Kod tekrarını azaltırız.
# - Ortak özellikler üst sınıfa yazılarak daha sade ve düzenli yapı oluştururuz.
# - Gelişmiş sınıflar temel sınıfı genişleterek özel işlevler ekleyebilir.
# ==========================================================
# 1. Kalıtımın Temelleri
# ==========================================================
# Python'da kalıtım, bir sınıf tanımlanırken parantez içinde üst sınıfın yazılmasıyla yapılır:
# class AltSinif(UstSinif):
# Üst sınıf: Ortak özellik ve metotları içerir.
# Alt sınıf: Üst sınıfı miras alır ve isterse yeni özellikler/metotlar ekleyebilir.
# ==========================================================
# 2. Üst Sınıf Tanımı (Base Class / Superclass)
# ==========================================================
class Hayvan:
def __init__(self, ad, tur):
self.ad = ad
self.tur = tur
def ses_cikar(self):
print(f"{self.ad} bir ses çıkarıyor.")
def bilgileri_goster(self):
print("Ad:", self.ad)
print("Tür:", self.tur)
# ==========================================================
# 3. Alt Sınıf Tanımı (Derived Class / Subclass)
# ==========================================================
class Kedi(Hayvan):
def __init__(self, ad, renk):
# Üst sınıfın constructor'ını çağırmak için super() kullanılır
super().__init__(ad, "Kedi") # tür sabit olarak "Kedi" verildi
self.renk = renk # Alt sınıfa özgü yeni özellik
# Üst sınıftaki metodu override (geçersiz kılma)
def ses_cikar(self):
print(f"{self.ad} miyavlıyor.")
def bilgileri_goster(self):
# Üst sınıf metodunu da çağırabiliriz
super().bilgileri_goster()
print("Renk:", self.renk)
# ==========================================================
# 4. Kullanım: Nesneler Üzerinden Kalıtımı Test Etme
# ==========================================================
# Kedi sınıfından bir nesne oluşturalım
kedi1 = Kedi("Pamuk", "Beyaz")
# Hem üst sınıftan hem alt sınıftan gelen metodları kullanabiliriz
print("\n--- Kedi Bilgileri ---")
kedi1.bilgileri_goster()
print("\n--- Kedi Sesi ---")
kedi1.ses_cikar()
# ==========================================================
# 5. super() Fonksiyonu Nedir?
# ==========================================================
# - super(), alt sınıftan üst sınıfın metodunu veya constructor'ını çağırmak için kullanılır.
# - self yerine kullanılmaz; özellikle __init__ içinde üst sınıfı başlatmak için önemlidir.
# - Method override edildiğinde, üst sınıfın orijinal metoduna yine de erişmek istiyorsak super() kullanılır.
# ==========================================================
# 6. Method Override (Geçersiz Kılma)
# ==========================================================
# - Alt sınıf, üst sınıftaki bir metodun aynısını yeniden tanımlarsa buna override denir.
# - Böylece alt sınıf kendi özel davranışını tanımlayabilir.
# Örneğin:
# Hayvan sınıfındaki `ses_cikar()` metodu → genel ses
# Kedi sınıfında yeniden tanımlanarak → miyavlama sesi
# ==========================================================
# 7. Kalıtımın Avantajları
# ==========================================================
# - Ortak kodların tekrarını engeller.
# - Kodun okunabilirliğini ve sürdürülebilirliğini artırır.
# - Yazılım mimarisi daha modüler olur.
# - Genişleyebilir yapı: Yeni alt sınıflar kolayca eklenebilir.
# ==========================================================
# 8. Ek Örnek: Çoklu Alt Sınıflar
# ==========================================================
class Kopek(Hayvan):
def __init__(self, ad, cins):
super().__init__(ad, "Köpek")
self.cins = cins
def ses_cikar(self):
print(f"{self.ad} havlıyor.")
def bilgileri_goster(self):
super().bilgileri_goster()
print("Cins:", self.cins)
# Kopek nesnesi oluşturalım
kopek1 = Kopek("Karabas", "Golden Retriever")
print("\n--- Köpek Bilgileri ---")
kopek1.bilgileri_goster()
print("\n--- Köpek Sesi ---")
kopek1.ses_cikar()
# ==========================================================
# 9. Özet
# ==========================================================
# - Kalıtım (inheritance): Alt sınıf, üst sınıftan özellik ve metot miras alır.
# - super(): Üst sınıftaki yapı ve metodlara erişim sağlar.
# - Override: Alt sınıfın üst sınıftaki bir metodu yeniden tanımlamasıdır.
# - Avantaj: Kod tekrarı azalır, düzen artar, genişleyebilirlik sağlanır.
# ==========================================================
# ==========================================================
# OVERRIDE (ÜZERİNE YAZMA) ve super() FONKSİYONU
# ==========================================================
# Nesne Tabanlı Programlamada (OOP), alt sınıflar genellikle üst sınıflardan kalıtım yoluyla özellik ve metot alırlar.
# Ancak, alt sınıf kendi özel davranışını tanımlamak istediğinde, üst sınıftaki bir metodu AYNEN YENİDEN YAZABİLİR.
# Bu duruma "override" yani "üzerine yazma" denir.
# ==========================================================
# 1. Method Override Nedir?
# ==========================================================
# - Üst sınıfta tanımlı bir metodu, alt sınıfta aynı isimle yeniden tanımlarsak,
# alt sınıftaki yeni versiyon geçerli olur.
# - Bu şekilde, alt sınıf kendi ihtiyaçlarına uygun özel davranışlar sergileyebilir.
# - Override, çok biçimlilik (polymorphism) kavramının temelini oluşturur.
# ==========================================================
# 2. super() Fonksiyonu Nedir?
# ==========================================================
# - `super()`, alt sınıftan üst sınıfa erişmemizi sağlar.
# - Üst sınıfın metotlarını veya constructor (init) fonksiyonunu çağırmak için kullanılır.
# - Özellikle override edilen metotlarda, üst sınıfın orijinal metodunu da çalıştırmak istediğimizde işe yarar.
# ==========================================================
# 3. Örnek: Temel Kullanım
# ==========================================================
class Calisan:
def __init__(self, ad, pozisyon):
self.ad = ad
self.pozisyon = pozisyon
def bilgileri_goster(self):
print("Ad:", self.ad)
print("Pozisyon:", self.pozisyon)
# Alt sınıf: Yonetici
class Yonetici(Calisan):
def __init__(self, ad, pozisyon, departman):
# Üst sınıfın __init__ fonksiyonu çağrılıyor
super().__init__(ad, pozisyon)
self.departman = departman
# Üst sınıftaki bilgileri_goster metodunu override ediyoruz
def bilgileri_goster(self):
# Üst sınıfın metodunu da çalıştırmak istiyorsak super() kullanırız
super().bilgileri_goster()
print("Departman:", self.departman)
# ==========================================================
# 4. Kullanım
# ==========================================================
# Yonetici sınıfından nesne oluşturuluyor
yonetici1 = Yonetici("Ayşe", "Takım Lideri", "Yazılım")
# Override edilmiş metod çağrılıyor
print("\n--- Yöneticinin Bilgileri ---")
yonetici1.bilgileri_goster()
# Çıktı:
# Ad: Ayşe
# Pozisyon: Takım Lideri
# Departman: Yazılım
# ==========================================================
# 5. Neden Override Kullanılır?
# ==========================================================
# - Alt sınıfın kendine özgü davranışlar tanımlaması gerektiğinde
# - Üst sınıfın metodunu yetersiz veya genel bulduğumuzda
# - Çok biçimlilik sağlamak için (aynı isimli metodlar farklı davranabilir)
# ==========================================================
# 6. Override ve super() Birlikte Kullanmak
# ==========================================================
# - Bazı durumlarda alt sınıf metodunu tamamen baştan yazmak istemeyiz.
# - Üst sınıfın yaptığı işlemi kullanıp, üstüne kendi özel işlemlerimizi eklemek isteriz.
# - Bu gibi durumlarda super() kullanarak önce üst sınıf metodunu çağırır,
# sonra alt sınıfa özgü işlemleri ekleriz.
# Örnek:
class Arac:
def tanit(self):
print("Bu bir araçtır.")
class Otomobil(Arac):
def tanit(self):
# Üst sınıfın tanit metodunu çağır
super().tanit()
# Ardından alt sınıfa özgü tanımlama
print("Bu araç bir otomobildir.")
# Kullanım
otomobil1 = Otomobil()
print("\n--- Araç Tanıtımı ---")
otomobil1.tanit()
# Çıktı:
# Bu bir araçtır.
# Bu araç bir otomobildir.
# ==========================================================
# 7. Özet
# ==========================================================
# - Override: Alt sınıfın, üst sınıftaki bir metodu aynı isimle yeniden tanımlamasıdır.
# - super(): Alt sınıftan üst sınıfın metoduna veya constructor'ına erişim sağlar.
# - super(), kod tekrarını önler ve mevcut üst sınıf davranışlarını kullanmamıza izin verir.
# - Hem esneklik hem de genişletilebilirlik sunar.
# ==========================================================
# 8. Ekstra: override edilebilen yapılar
# ==========================================================
# - Metotlar override edilebilir.
# - Python'da bazı özel metotlar (örn. __str__, __len__, __eq__) da override edilebilir.
# - Yapıcı metot (__init__) override edilebilir ama super().__init__ ile üst yapı korunabilir.
# ==========================================================
# ==========================================================
# ÇOK BİÇİMLİLİK (POLYMORPHISM)
# ==========================================================
# Polymorphism (Çok Biçimlilik), nesne tabanlı programlamanın (OOP) temel özelliklerinden biridir.
# Aynı isimdeki bir metodun veya işlemin farklı nesnelerde farklı şekillerde davranabilmesini sağlar.
# Kısacası:
# Aynı isimli metod → farklı sınıflar → farklı davranış!
# Bu sayede:
# - Kod daha esnek ve genişletilebilir olur.
# - Farklı sınıflar ortak bir arayüzü paylaşabilir.
# - Nesneler birbirinin yerine kullanılabilir (interface benzeri davranış).
# ==========================================================
# 1. Polymorphism ile Metotların Farklı Davranması
# ==========================================================
# Önce ortak bir üst sınıf oluşturalım
class Hayvan:
def ses_cikar(self):
print("Hayvan bir ses çıkarıyor.")
# Alt sınıflar aynı isimde metotları farklı şekillerde tanımlar
class Kedi(Hayvan):
def ses_cikar(self):
print("Miyav!")
class Kopek(Hayvan):
def ses_cikar(self):
print("Hav hav!")
class Kus(Hayvan):
def ses_cikar(self):
print("Cik cik!")
# ==========================================================
# 2. Ortak Arayüzle Nesneleri Kullanma
# ==========================================================
# Polymorphism burada devreye girer.
# Farklı türden nesneler aynı metodu çağırır ama her biri kendine özgü tepki verir.
hayvanlar = [Kedi(), Kopek(), Kus()]
print("\n--- Hayvan Sesleri ---")
for hayvan in hayvanlar:
# Aynı metod ismi → farklı sınıflarda farklı davranış
hayvan.ses_cikar()
# Çıktı:
# Miyav!
# Hav hav!
# Cik cik!
# Bu, Python'da dinamik çok biçimliliğin (dynamic polymorphism) doğal örneğidir.
# ==========================================================
# 3. Fonksiyonlar ile Polymorphism
# ==========================================================
# Polymorphic fonksiyon: Farklı nesneleri aynı fonksiyonla işleyebiliriz.
def hayvan_sesi_çal(hayvan):
hayvan.ses_cikar()
print("\n--- Fonksiyon ile Polymorphism ---")
hayvan_sesi_çal(Kedi())
hayvan_sesi_çal(Kopek())
hayvan_sesi_çal(Kus())
# Bu, "nesneye göre davranış değişikliği" anlamına gelir.
# ==========================================================
# 4. Polymorphism + Kalıtım
# ==========================================================
# Polymorphism genellikle kalıtımla birlikte kullanılır.
# Üst sınıf (base class) ortak arayüzü sağlar.
# Alt sınıflar bu arayüzü kendi ihtiyacına göre özelleştirir (override yaparak).
# Örnek:
class Sekil:
def alan_hesapla(self):
print("Şeklin alanı hesaplanıyor...")
class Kare(Sekil):
def __init__(self, kenar):
self.kenar = kenar
def alan_hesapla(self):
print("Karenin Alanı:", self.kenar * self.kenar)
class Daire(Sekil):
def __init__(self, yaricap):
self.yaricap = yaricap
def alan_hesapla(self):
print("Dairenin Alanı:", 3.14 * self.yaricap * self.yaricap)
print("\n--- Şekil Alanları ---")
sekiller = [Kare(4), Daire(3)]
for sekil in sekiller:
sekil.alan_hesapla()
# Çıktı:
# Karenin Alanı: 16
# Dairenin Alanı: 28.26
# ==========================================================
# 5. Özet
# ==========================================================
# - Polymorphism: Aynı isimli metodun farklı sınıflarda farklı şekilde çalışmasıdır.
# - Kalıtım + Override ile çok biçimlilik sağlanır.
# - Python'da tüm sınıflar metotlarını override edebildiği için polymorphism doğal olarak desteklenir.
# - Kod tekrarını azaltır, genişlemeye açık mimari sağlar.
# Anahtar Faydaları:
# ✅ Aynı işlemi farklı nesnelerde farklı şekilde uygular.
# ✅ Genişletilebilir ve esnek yazılım tasarımı sağlar.
# ✅ Gerçek dünya modellemelerinde çok kullanışlıdır (hayvan sesleri, şekil hesaplamaları vb).
# ==========================================================
# ==========================================================
# SINIF METOTLARI ve STATİK METOTLAR
# ==========================================================
# Nesne tabanlı programlamada (OOP), Python sınıflarında sadece nesneye ait metotlar değil;
# sınıfa ait (class-level) ve nesneyle ilgisi olmayan (bağımsız) metotlar da tanımlanabilir.
# Bunun için iki özel dekoratör kullanılır:
# - @classmethod --> sınıfın kendisine erişim sağlar (cls)
# - @staticmethod --> sınıfa veya nesneye özel değildir, yardımcı fonksiyon gibi çalışır.
# ==========================================================
# 1. Normal Metotlar
# ==========================================================
# - Nesne üzerinden çalışır
# - self parametresiyle çalışır
# - Nesneye ait verilere (özelliklere) erişebilir
class Ogrenci:
def __init__(self, ad, soyad):
self.ad = ad
self.soyad = soyad
# Normal metot
def bilgileri_yazdir(self):
print(f"Ad: {self.ad}, Soyad: {self.soyad}")
ogr1 = Ogrenci("Ali", "Yılmaz")
ogr1.bilgileri_yazdir() # Ad: Ali, Soyad: Yılmaz
# ==========================================================
# 2. Sınıf Metotları (@classmethod)
# ==========================================================
# - Sınıf üzerinden ya da nesne üzerinden çağrılabilir.
# - self yerine cls parametresi alır (class'ı temsil eder).
# - Sınıf seviyesindeki verilerle çalışmak için kullanılır.
# - Özellikle alternatif yapıcı metodlar (fabrika fonksiyonları) için idealdir.
class Calisan:
zam_orani = 1.2 # sınıf seviyesi bir özellik (tüm nesneler için geçerli)
def __init__(self, ad, maas):
self.ad = ad
self.maas = maas
def maas_yazdir(self):
print(f"{self.ad} maaş: {self.maas}")
@classmethod
def zam_oranini_degistir(cls, yeni_oran):
cls.zam_orani = yeni_oran
print("Yeni zam oranı:", cls.zam_orani)
@classmethod
def string_ile_calisan_olustur(cls, bilgi_metni):
# "Ali-5000" gibi bir string alıp nesne oluşturur
ad, maas = bilgi_metni.split("-")
return cls(ad, int(maas))
# Sınıf üzerinden sınıf metodunu çağırabiliriz
Calisan.zam_oranini_degistir(1.5)
# Alternatif yapıcı fonksiyon ile nesne üretimi
calisan1 = Calisan.string_ile_calisan_olustur("Veli-6000")
calisan1.maas_yazdir() # Veli maaş: 6000
# ==========================================================
# 3. Statik Metotlar (@staticmethod)
# ==========================================================
# - Ne self ne de cls parametresi alır.
# - Sınıf veya nesneyle doğrudan ilişkili olmayan yardımcı metotlardır.
# - Genelde sınıf içinde anlamlı olan ama sınıf verisine ihtiyaç duymayan fonksiyonlar için kullanılır.
class Matematik:
@staticmethod
def topla(a, b):
return a + b
@staticmethod
def cikar(a, b):
return a - b
# Sınıf adı üzerinden doğrudan çağrılabilir
print("\nToplama:", Matematik.topla(10, 5)) # 15
print("Çıkarma:", Matematik.cikar(10, 5)) # 5
# Statik metotlar nesne oluşturmadan kullanılabilir
matematikci = Matematik()
print("Toplam (nesne ile):", matematikci.topla(3, 4)) # 7
# ==========================================================
# 4. Farklar ve Karşılaştırma
# ==========================================================
# 1. Normal Metot (self):
# - Nesne üzerinden çağrılır
# - self ile nesne verilerine erişebilir
# 2. Sınıf Metodu (cls):
# - Sınıf ya da nesne üzerinden çağrılır
# - cls ile sınıf verilerine erişebilir
# - Alternatif constructor olarak çok kullanılır
# 3. Statik Metot:
# - Ne sınıf verisine (cls) ne nesne verisine (self) erişir
# - Bağımsız yardımcı metot gibi davranır
# ==========================================================
# 5. Özet
# ==========================================================
# ✅ @classmethod → Sınıfa ait işlemler yapmak için kullanılır
# ✅ @staticmethod → Bağımsız, yardımcı işlemler yapmak için kullanılır
# ✅ Python OOP’de sınıf içi yapılandırmaları daha esnek ve anlamlı hale getirir
# İpucu:
# - Eğer metodunuz sınıf verisini değiştirecekse: @classmethod
# - Eğer metodunuz sadece işlem yapacaksa, veriyle işi yoksa: @staticmethod
# - Eğer metodunuz nesneyle ilgiliyse: normal metot (self)
# ==========================================================
# ==========================================================
# ÖZEL METOTLAR (DUnder Methods / Magic Methods)
# ==========================================================
# Python'da "__" (çift alt çizgi) ile başlayan ve biten özel metotlara "dunder" (double underscore) metotlar denir.
# Bu metotlar, sınıf nesnelerinin nasıl davrandığını belirler.
# Örnekler: __init__, __str__, __len__, __repr__, __add__, __eq__, __getitem__ vb.
# Bu metotlar sayesinde:
# ✅ Sınıflar, Python’un kendi yapıları gibi davranabilir
# ✅ Nesneleri daha okunabilir, esnek ve güçlü hale getiririz
# ==========================================================
# 1. __init__ Metodu
# ==========================================================
# Nesne oluşturulurken otomatik olarak çalışan yapıcı (constructor) metottur.
class Kitap:
def __init__(self, ad, yazar, sayfa_sayisi):
self.ad = ad
self.yazar = yazar
self.sayfa_sayisi = sayfa_sayisi
# Yeni bir nesne oluşturduğumuzda __init__ metodu çağrılır
k1 = Kitap("1984", "George Orwell", 328)
# ==========================================================
# 2. __str__ Metodu
# ==========================================================
# print() fonksiyonu çağrıldığında veya str(obj) yapıldığında çalışır.
# İnsan gözüyle okunabilir biçimde çıktı verir.
class Kitap:
def __init__(self, ad, yazar, sayfa_sayisi):
self.ad = ad
self.yazar = yazar
self.sayfa_sayisi = sayfa_sayisi
def __str__(self):
return f"Kitap: {self.ad}, Yazar: {self.yazar}, Sayfa: {self.sayfa_sayisi}"
k1 = Kitap("Hayvan Çiftliği", "George Orwell", 152)
print(k1) # __str__ metodu çağrılır
# ==========================================================
# 3. __repr__ Metodu
# ==========================================================
# Nesnenin geliştirici (debug) odaklı gösterimi içindir.
# repr(obj) çağrıldığında veya etkileşimli kabukta objeyi yazdırdığımızda çalışır.
# Mümkünse nesnenin tekrar oluşturulabileceği formatta bilgi verir.
class Kitap:
def __init__(self, ad, yazar, sayfa_sayisi):
self.ad = ad
self.yazar = yazar
self.sayfa_sayisi = sayfa_sayisi
def __repr__(self):
return f"Kitap('{self.ad}', '{self.yazar}', {self.sayfa_sayisi})"
k2 = Kitap("Bilinmeyen", "Yazar X", 250)
print(repr(k2)) # Kitap('Bilinmeyen', 'Yazar X', 250)
# ==========================================================
# 4. __len__ Metodu
# ==========================================================
# len(obj) çağrıldığında bu metot çalışır.
class Kitap:
def __init__(self, ad, yazar, sayfa_sayisi):
self.ad = ad
self.yazar = yazar
self.sayfa_sayisi = sayfa_sayisi
def __len__(self):
return self.sayfa_sayisi
k3 = Kitap("Zengin Baba Yoksul Baba", "Robert Kiyosaki", 305)
print(len(k3)) # __len__ çağrılır → 305
# ==========================================================
# 5. Diğer Özel Metotlara Kısaca Bakış
# ==========================================================
# __add__ → + operatörü ile nesneleri toplama davranışını belirler
# __eq__ → == ile eşitlik karşılaştırması
# __lt__, __gt__ → < ve > karşılaştırmaları
# __getitem__ → obj[i] erişimini özelleştirme
# __del__ → Nesne silinirken çalışır (genelde tavsiye edilmez)
# __call__ → obj() şeklinde nesneyi fonksiyon gibi çağırmayı sağlar
# ==========================================================
# 6. Özet
# ==========================================================
# ✅ __init__ → Nesne başlatılırken çalışır
# ✅ __str__ → print(obj) → kullanıcıya okunabilir çıktı
# ✅ __repr__ → repr(obj) → geliştirici odaklı, teknik gösterim
# ✅ __len__ → len(obj) → nesnenin uzunluğu tanımı
# Bu metotlar sayesinde nesnelerimizi Python'un kendi veri tipleri gibi davranacak şekilde özelleştirebiliriz.
# İpucu:
# __str__ kullanıcıya yöneliktir
# __repr__ geliştiriciye yöneliktir (debug için)
# ==========================================================
# ==========================================================
# İLERİ SEVİYE: ÇOKLU KALITIM ve MRO (Method Resolution Order)
# ==========================================================
# Kalıtım (inheritance), bir sınıfın başka bir sınıftan özellik ve metot almasını sağlar.
# Çoklu kalıtımda, bir sınıf birden fazla sınıftan miras alabilir.
# Python, çoklu kalıtımı destekler. Ancak bu durumda hangi sınıftaki metodun çalışacağını
# belirlemek için MRO (Method Resolution Order - Metot Çözümleme Sırası) devreye girer.
# ==========================================================
# 1. Temel Kalıtım Hatırlatma
# ==========================================================
class Hayvan:
def ses_cikar(self):
print("Bir hayvan ses çıkardı.")
class Kopek(Hayvan):
def ses_cikar(self):
print("Hav hav!")
k = Kopek()
k.ses_cikar() # "Hav hav!" → Alt sınıf üst sınıfın metodunu ezdi (override)
# ==========================================================
# 2. Çoklu Kalıtım (Multiple Inheritance)
# ==========================================================
# Bir sınıf birden fazla sınıftan miras alabilir.
class Ucan:
def hareket(self):
print("Uçarak hareket ediyor.")
class Yuruyen:
def hareket(self):
print("Yürüyerek hareket ediyor.")
# Kuş, hem Ucan hem Yuruyen sınıfından kalıtım alıyor
class Kus(Ucan, Yuruyen):
pass
serce = Kus()
serce.hareket() # "Uçarak hareket ediyor." → MRO sırasına göre Ucan sınıfındaki metot çağrılır
# ==========================================================
# 3. MRO (Method Resolution Order) Nedir?
# ==========================================================
# Python, çoklu kalıtımda hangi sınıftaki metodun çağrılacağını belirlemek için MRO kullanır.
# Yani, miras alınan sınıflar arasında hangi sırayla metotlara bakılacağı tanımlıdır.
# MRO sırasını görmek için: class.__mro__ ya da help(Class)
print(Kus.__mro__)
# (<class '__main__.Kus'>, <class '__main__.Ucan'>, <class '__main__.Yuruyen'>, <class 'object'>)
# Bu çıktı diyor ki: Kus → Ucan → Yuruyen → object
# Python metot ararken bu sırayla bakar, bulduğu ilk uygun metodu çalıştırır.
# ==========================================================
# 4. super() Kullanımı ile MRO
# ==========================================================
# super() fonksiyonu, MRO sırasına göre bir üst sınıfın metodunu çağırır.
class A:
def yazdir(self):
print("A sınıfı")
class B(A):
def yazdir(self):
print("B sınıfı")
super().yazdir()
class C(A):
def yazdir(self):
print("C sınıfı")
super().yazdir()
class D(B, C):
def yazdir(self):
print("D sınıfı")
super().yazdir()
d = D()
d.yazdir()
# Çıktı:
# D sınıfı
# B sınıfı
# C sınıfı
# A sınıfı
# Açıklama:
# D -> B -> C -> A sırasıyla yazdir metoduna bakılır. Bu sıra MRO’ya göre belirlenmiştir.
# MRO SIRASI:
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
# ==========================================================
# 5. Diamon Problem (Elmas Problemi)
# ==========================================================
# Aynı üst sınıftan birden fazla kez kalıtım alınması durumudur.
# Python MRO algoritması sayesinde bu problem çözülmüştür.
class Ortak:
def islem(self):
print("Ortak sınıf")
class Sol(Ortak):
def islem(self):
print("Sol sınıf")
super().islem()
class Sag(Ortak):
def islem(self):
print("Sağ sınıf")
super().islem()
class Alt(Sol, Sag):
def islem(self):
print("Alt sınıf")
super().islem()
a = Alt()
a.islem()
# Çıktı:
# Alt sınıf
# Sol sınıf
# Sağ sınıf
# Ortak sınıf
# Python, Ortak sınıfı yalnızca bir kez çağırdı. MRO sırası sayesinde çakışmalar önlenmiş olur.
# ==========================================================
# 6. Özet
# ==========================================================
# ✅ Çoklu kalıtım: Bir sınıfın birden fazla sınıftan miras almasıdır.
# ✅ MRO: Python’un çoklu kalıtımda metotların hangi sırayla çağrılacağını belirleme mekanizmasıdır.
# ✅ super(): MRO sırasına göre bir üst sınıf metodunu çağırmak için kullanılır.
# ✅ Python’un MRO algoritması, diamond problem gibi karışıklıkları önler.
# MRO Sırasını Görmek:
# print(SinifAdi.__mro__) veya help(SinifAdi)
# ==========================================================
# ==========================================================
# PROJE: OOP Kullanarak Basit Kitaplık Uygulaması
# ==========================================================
# Bu projede OOP ilkeleri kullanılarak bir kitaplık sistemi tasarlanacaktır.
# Kitap sınıfı ve Kitaplık sınıfı oluşturularak; kitap ekleme, silme ve listeleme işlemleri yapılacaktır.
# ==========================================================
# 1. Kitap Sınıfı (Book)
# ==========================================================
class Kitap:
def __init__(self, baslik, yazar, sayfa_sayisi):
# Kitap nesnesi oluşturulurken başlık, yazar ve sayfa sayısı girilir
self.baslik = baslik
self.yazar = yazar
self.sayfa_sayisi = sayfa_sayisi
def __str__(self):
# print() ile kitap nesnesi yazdırıldığında nasıl görüneceğini belirler
return f"{self.baslik} - {self.yazar} ({self.sayfa_sayisi} sayfa)"
# ==========================================================
# 2. Kitaplık Sınıfı (Library)
# ==========================================================
class Kitaplik:
def __init__(self):
# Kitapları saklayacağımız boş bir liste
self.kitaplar = []
def kitap_ekle(self, kitap):
# Kitap nesnesini listeye ekler
self.kitaplar.append(kitap)
print(f"Kitap eklendi: {kitap.baslik}")
def kitaplari_listele(self):
# Kitaplıkta kayıtlı tüm kitapları listeler
if not self.kitaplar:
print("Kitaplık boş.")
else:
print("Kitaplıktaki Kitaplar:")
for index, kitap in enumerate(self.kitaplar, 1):
print(f"{index}. {kitap}")
def kitap_sil(self, baslik):
# Verilen başlığa sahip kitabı kitaplıktan siler
for kitap in self.kitaplar:
if kitap.baslik.lower() == baslik.lower():
self.kitaplar.remove(kitap)
print(f"{baslik} adlı kitap silindi.")
return
print(f"{baslik} adlı kitap bulunamadı.")
# ==========================================================
# 3. Programın Çalışması (Simülasyon)
# ==========================================================
# Kitaplık nesnesi oluşturulur
kitapligim = Kitaplik()
# Kitap nesneleri oluşturuluyor
kitap1 = Kitap("Simyacı", "Paulo Coelho", 180)
kitap2 = Kitap("1984", "George Orwell", 328)
kitap3 = Kitap("Sefiller", "Victor Hugo", 700)
# Kitaplar kitaplığa ekleniyor
kitapligim.kitap_ekle(kitap1)
kitapligim.kitap_ekle(kitap2)
kitapligim.kitap_ekle(kitap3)
print("\n--- Kitapları Listele ---")
kitapligim.kitaplari_listele()
print("\n--- Kitap Sil ---")
kitapligim.kitap_sil("1984")
print("\n--- Güncel Liste ---")
kitapligim.kitaplari_listele()
# ==========================================================
# 4. Özet
# ==========================================================
# ✅ OOP kullanılarak Kitap ve Kitaplık nesneleri oluşturuldu.
# ✅ Kitap ekleme, listeleme ve silme işlevleri ayrı metotlar olarak tanımlandı.
# ✅ Kod modüler, okunabilir ve genişletilebilir hale getirildi.
# ==========================================================
Siber Güvenlik Nedir?
Siber güvenlik, dijital ortamda bulunan sistemlerin, ağların, cihazların ve verilerin güvenliğini sağlama sürecidir. Bu, siber saldırılara karşı korunmayı, yetkisiz erişimleri engellemeyi ve verilerin gizliliğini, bütünlüğünü ve erişilebilirliğini sağlamayı amaçlar. Günümüzde siber güvenlik, bireylerin, kurumların ve devletlerin dijital dünyadaki varlıklarını korumak için büyük önem taşımaktadır.
Siber Güvenliğin Temel Unsurları:
Gizlilik (Confidentiality): Bilgilerin yalnızca yetkilendirilmiş kişiler tarafından erişilmesi sağlanır. Gizliliğin sağlanması, verilerin başkaları tarafından izinsiz erişilmesini engellemeyi amaçlar. Örneğin, şifreleme teknikleri verilerin gizliliğini korur.
Bütünlük (Integrity): Verilerin doğruluğu ve bütünlüğü sağlanır. Bu, verilerin izinsiz bir şekilde değiştirilmemesini, eksik ya da yanlış bir biçimde kullanılmamasını sağlar. Bütünlüğün sağlanması, veri kaybını veya bozulmasını önlemeye yönelik önlemler almayı gerektirir.
Erişilebilirlik (Availability): Verilerin her zaman ve her yerden erişilebilir olmasını sağlar. Erişilebilirlik, verilerin ve sistemlerin kesintisiz bir şekilde kullanılabilir olmasına olanak tanır. Sistemlerin çökmemesi ve hizmetin sürekli sağlanması, erişilebilirliğin en önemli unsurudur.
Siber Güvenlikte Karşılaşılan Tehditler:
Hacker’lar: Hacker’lar, bilgisayar sistemlerine veya ağlarına izinsiz olarak erişmeye çalışan kişilerdir. Çoğu zaman kötü niyetlidirler ve amaçları, verileri çalmak, sistemleri bozmak ya da kötü amaçlı yazılımlar yerleştirmektir.
Etik Hacker’lar (White Hat Hackers): Etik hacker’lar, güvenlik açıklarını tespit etmek ve raporlamak amacıyla sistemlere sızan, ancak sadece izinli bir şekilde ve güvenlik için çalışan kişilerdir. Etik hacker’ların amacı, sistem güvenliğini güçlendirmektir.
Siber Güvenlik Türleri:
Siber güvenlik birden fazla bileşenden oluşur ve genellikle şu ana kategorilere ayrılır:
Ağ Güvenliği (Network Security): Ağ üzerinde gerçekleşebilecek tüm siber saldırılara karşı koruma sağlamak amacıyla kullanılan önlemleri kapsar. Bu tür saldırılar arasında DDoS (Distributed Denial of Service) gibi saldırılar yer alır.
Uygulama Güvenliği (Application Security): Yazılım ve uygulamalarda bulunan açıkları tespit ederek, bu açıkların kötüye kullanılmasını engellemeye yönelik tedbirleri içerir. Yazılımların güvenliğinin sağlanması, çoğu zaman şifreleme, kimlik doğrulama ve güvenlik duvarları kullanılarak yapılır.
Veri Güvenliği (Data Security): Verilerin gizliliğini ve bütünlüğünü sağlamak için kullanılan önlemleri içerir. Verilerin şifrelenmesi ve erişim kontrol mekanizmaları, veri güvenliğinin en önemli bileşenlerindendir.
Son Kullanıcı Güvenliği (End-User Security): Çalışanlar veya bireyler gibi son kullanıcıların güvenliğini sağlar. Bu, kötü amaçlı yazılımlardan korunma, güçlü şifreler kullanma ve güvenli internet alışkanlıkları geliştirmeyi içerir.
Siber Güvenlik Araçları ve Yöntemleri:
Firewall (Güvenlik Duvarı): Bir ağda, giden ve gelen trafiği kontrol ederek yetkisiz erişimi engeller. Güvenlik duvarı, bir nevi dijital güvenlik kapısı gibi çalışır.
Antivirüs Yazılımları: Bilgisayarları zararlı yazılımlardan (virüs, trojan, solucan vb.) korur. Antivirüs yazılımları, sistemdeki şüpheli aktiviteleri tespit eder ve engeller.
Şifreleme (Encryption): Verilerin şifreli hale getirilmesi, sadece yetkili kişiler tarafından okunabilmesini sağlar. Şifreleme, özellikle internet üzerinden gönderilen verilerin güvenliğini sağlamak için yaygın olarak kullanılır.
İki Faktörlü Kimlik Doğrulama (2FA): Kullanıcıların sisteme giriş yaparken yalnızca şifrelerinin değil, aynı zamanda ek bir doğrulama aracının (SMS, e-posta, doğrulama uygulaması vb.) kullanılması ile güvenliği artırır.
Siber Güvenlik Saldırı Türleri:
DDoS (Distributed Denial of Service) Saldırıları: Bir hizmeti, özellikle web sitelerini hedef alarak, aşırı trafikle çökertmeye yönelik saldırılardır. Saldırganlar, genellikle binlerce bot kullanarak web sitesinin erişilebilirliğini engellerler.
Phishing (Kimlik Avı): Kullanıcıları kandırarak kişisel bilgilerini (şifreler, banka hesap bilgileri vb.) çalmaya yönelik saldırılardır. Genellikle sahte e-postalar ve web siteleri kullanılır.
Malware (Zararlı Yazılımlar): Sisteme zarar vermek amacıyla yerleştirilen yazılımlardır. Bu yazılımlar, bilgisayarınıza gizlice zarar vererek, veri çalma, şifreleme veya sistem çökertme işlemleri yapabilir.
Ransomware (Fidye Yazılımları): Kullanıcıların verilerini şifreleyip, onları geri almak için fidye talep eden zararlı yazılımlardır. Bu tür yazılımlar genellikle kişisel bilgisayarlar veya büyük kurumları hedef alır.
Siber Güvenlik ile İlgili Örnekler:
Kimlik Avı (Phishing) Örneği: Bir şirketin e-posta adresinden gönderildiği izlenimi veren, ancak sahte olan bir e-posta, kullanıcıyı banka hesabı bilgilerini girmeye zorlar. Bu e-posta genellikle, kullanıcının acilen hesap bilgilerini güncellemesi gerektiğini belirten sahte bir uyarı içerir.
DDoS Saldırısı Örneği: Bir e-ticaret sitesinin web sunucusu, aynı anda binlerce isteğe cevap veremediği için çökertilir. Bu, siteye erişimi engeller ve iş kaybına yol açar.
Siber Güvenlikte Temel Terimler:
Gizlilik (Confidentiality): Verilerin sadece yetkilendirilmiş kişiler tarafından erişilebilmesi.
Bütünlük (Integrity): Verilerin doğru ve değişmeden kalması.
Erişilebilirlik (Availability): Verilerin her zaman, her yerden erişilebilir olması.
Şifreleme (Encryption): Verilerin korunarak yalnızca yetkili kişiler tarafından okunabilir hale getirilmesi.
Sonuç:
Siber güvenlik, dijital dünyanın önemli bir parçasıdır ve internetin her geçen gün daha fazla hayatımıza entegre olmasıyla birlikte bu alanın önemi artmaktadır. Siber güvenlik uzmanları, dijital ortamdaki tüm varlıkları koruyarak, bireylerin ve kurumların güvenliğini sağlamaya çalışır. Bu, yalnızca teknik bir konu değil, aynı zamanda bireylerin de dijital dünyada güvenli alışkanlıklar edinmesini gerektiren bir alandır.
Python ile Ağ Taramaları: Teorik ve Uygulamalı
Ağ taramaları, ağ yönetimi, güvenliği ve hata ayıklama amacıyla gerçekleştirilen önemli bir işlemdir. Bu işlem sayesinde ağdaki cihazlar, açık portlar, aktif bağlantılar ve potansiyel güvenlik açıkları tespit edilebilir. Ağ taraması, özellikle sızma testleri, ağ yönetimi ve güvenlik analizleri sırasında kritik bir rol oynar. Python, ağ taraması için güçlü ve esnek kütüphaneler sunarak, ağdaki cihazların ve portların kolayca taranmasına olanak tanır.
Bu dökümantasyonda, Python ile ağ taramalarını nasıl yapabileceğimizi, bunun teorik kısmını ve pratikte nasıl kullanılacağını anlatacağım.
1. Socket ile Port Taraması:
Teorik Açıklama:
Port taraması, ağ üzerinde belirli portların açık olup olmadığını belirlemek için yapılan bir işlemdir. Portlar, bir ağ cihazının üzerindeki iletişim kanallarını temsil eder. Bu portlar, genellikle internet protokolü (IP) adresi ile ilişkilidir ve her port belirli bir hizmeti (web, FTP, SSH vb.) barındırır.
Port taraması genellikle şunlar için yapılır:
Bir sistemin hangi servislerinin çalıştığını görmek.
Ağda güvenlik açıklarını tespit etmek.
Belirli bir servisle iletişim kurmak için doğru portu bulmak.
Python’un socket kütüphanesi, TCP/IP bağlantıları oluşturmak ve portları taramak için kullanılır. Aşağıda, socket ile yapılan port taramasının temel adımlarını göreceksiniz.
Uygulama:
import socket
def port_scan(target, port):
"""
Belirtilen IP adresindeki belirli portu kontrol eder.
:param target: Hedef IP adresi
:param port: Taranacak port
"""
# Socket nesnesi oluşturuluyor (IPv4, TCP bağlantısı)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bağlantı için zaman aşımı süresi belirleniyor (1 saniye)
socket.setdefaulttimeout(1)
# Portu kontrol etmek için bağlanma işlemi yapılıyor
result = sock.connect_ex((target, port))
# Bağlantı başarılı ise port açık demektir
if result == 0:
print(f"Port {port} açık!")
else:
print(f"Port {port} kapalı!")
# Socket bağlantısını kapat
sock.close()
# Hedef IP ve portlar belirleniyor
target_ip = "192.168.1.1" # Bu IP adresi hedef alınacak
ports = [22, 80, 443] # Taranacak portlar
# Her port için tarama işlemi yapılır
for port in ports:
port_scan(target_ip, port)
Açıklamalar:
socket.socket(): Yeni bir soket nesnesi oluşturur. AF_INET, IPv4 bağlantısını ifade eder. SOCK_STREAM ise TCP bağlantısını belirtir.
connect_ex(): Bu metod, hedef IP ve port ile bağlantı kurmayı dener. Bağlantı başarılıysa 0 döner.
setdefaulttimeout(): Bağlantı için zaman aşımı süresi belirler. Bu süre aşılırsa, bağlantı denemesi başarısız sayılır.
2. Scapy ile IP/ARP Taramaları:
Teorik Açıklama:
ARP (Address Resolution Protocol), IP adresi ile MAC adresi arasında bir eşleme yapar. Bir cihazın MAC adresine ulaşmak için ARP isteği gönderilir. Bu, ağdaki cihazların fiziksel adreslerinin (MAC) tespit edilmesine olanak sağlar.
Ağ taraması yaparken, özellikle ARP taraması kullanılarak, yerel ağdaki tüm cihazların IP ve MAC adresleri elde edilebilir. Bu tür taramalar, genellikle ağdaki aktif cihazları listelemek, ağ topolojisini anlamak veya olası güvenlik tehditlerini tespit etmek için yapılır.
Uygulama:
from scapy.all import ARP, Ether, srp
def arp_scan(target_ip):
"""
Belirtilen IP aralığındaki cihazların IP ve MAC adreslerini tarar.
:param target_ip: Taranacak IP adresi aralığı (örneğin: 192.168.1.1/24)
"""
# ARP isteği hazırlıyoruz (Ethernet çerçevesi ile)
arp_request = ARP(pdst=target_ip)
broadcast = Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast/arp_request
# ARP isteğini ağda yayınlıyoruz ve yanıtları alıyoruz
print("Ağ taraması başlatılıyor...")
answered_list = srp(arp_request_broadcast, timeout=1, verbose=False)[0]
# Yanıtları işliyoruz
for element in answered_list:
print(f"IP: {element[1].psrc} MAC: {element[1].hwsrc}")
# Hedef IP adresi
target_ip = "192.168.1.1/24" # Bu, ağdaki tüm cihazları taramak için kullanılan IP adresidir
arp_scan(target_ip)
Açıklamalar:
ARP(pdst=target_ip): Hedef IP aralığına ARP isteği gönderir.
Ether(): Ethernet çerçevesi oluşturur ve bu çerçeve aracılığıyla ARP isteği yayınlanır.
srp(): Scapy fonksiyonu, bu istekleri gönderir ve yanıtları toplar. Yanıtlar IP ve MAC adresiyle birlikte gelir.
3. Basit Ping Süiti:
Teorik Açıklama:
Ping, bir hedefe ICMP (Internet Control Message Protocol) mesajları göndererek, hedefin erişilebilir olup olmadığını kontrol eder. Bir ping yanıtı alındığında, hedefin aktif olduğu anlaşılır. Bu işlem, ağ bağlantılarının doğruluğunu test etmek için sıklıkla kullanılır.
Python ile ping süiti oluşturmak için, sistemin yerel ping komutunu çağırabiliriz. ping komutu, hedef cihazın IP adresine 4 adet ICMP paketi gönderir ve yanıt süresi ile birlikte erişilebilirlik bilgisini sağlar.
Uygulama:
import os
import platform
def ping_host(host):
"""
Ping komutunu çalıştırarak hedefin erişilebilirliğini kontrol eder.
:param host: Ping yapılacak hedef cihazın IP adresi
"""
# Sistem işletim sistemine göre uygun ping komutunu oluşturuyoruz
param = "-n" if platform.system().lower() == "windows" else "-c"
# Ping komutunu çalıştırıyoruz
command = f"ping {param} 4 {host}" # 4, 4 paket gönderileceğini belirtir
response = os.system(command)
# Ping yanıtına göre başarı mesajı basıyoruz
if response == 0:
print(f"{host} erişilebilir!")
else:
print(f"{host} erişilemiyor.")
# Hedef IP adresi
host = "192.168.1.1"
ping_host(host)
Açıklamalar:
os.system(): Sistemdeki komut satırını çalıştırmak için kullanılır. Burada ping komutunu çalıştırarak hedefin erişilebilirliğini kontrol ederiz.
platform.system(): Çalıştırılan sistemin işletim sistemini belirler. Windows ve Unix tabanlı sistemler için farklı ping komutları kullanılabilir.
Sonuç:
Bu doküman, Python ile ağ taramalarının nasıl yapılacağını hem teorik hem de uygulamalı olarak ele aldı. socket kütüphanesi ile port taraması, scapy ile IP ve ARP taramaları ve basit bir ping süiti oluşturma gibi işlemler, ağ güvenliği analizi ve yönetimi için temel araçlardır. Python'un esnekliği ve güçlü kütüphaneleri sayesinde, ağ tarama işlemleri daha verimli ve özelleştirilebilir hale getirilebilir.
Python ile 0'dan İleri Seviyeye Python Programlama Eğitimi – Sıfırdan Uzmanlığa Yolculuk
Python, günümüz yazılım dünyasının en güçlü ve çok yönlü programlama dillerinden biridir. Büyük teknoloji firmalarından startuplara, veri biliminden yapay zekaya, web geliştirmeden otomasyona kadar hemen her alanda Python kullanılmaktadır. İşte bu yüzden, yazılıma yeni başlayan birinin ya da mevcut bilgilerini ileri seviyeye taşımak isteyen bir geliştiricinin ilk durağı Python olmalıdır.
Bu kurs, hiçbir programlama bilgisi olmayan birini sıfırdan alarak, ileri seviyede Python geliştiricisi haline getirmeyi hedefleyen kapsamlı ve sistematik bir eğitim paketidir. Kurs içeriği sade, anlaşılır ve uygulamalı örneklerle doludur. Eğitim süreci boyunca sadece Python’un sözdizimini değil, aynı zamanda programlama mantığını, problem çözme becerilerini ve gerçek dünya uygulamalarını da öğreneceksiniz.
Kurs İçeriğinde Neler Var?
Kurs, mantıksal bir sıra izleyerek temel bilgilerden ileri düzey konulara geçiş sağlar:
Python’un kurulumu ve geliştirme ortamlarının tanıtımı
Temel sözdizimi: değişkenler, veri tipleri, operatörler
Karar yapıları: if, else, elif blokları
Döngüler: for ve while kullanımı, döngü kontrol ifadeleri
Fonksiyonlar: tanımlama, parametreler, geri dönüşler
Veri yapıları: listeler, demetler (tuple), sözlükler (dictionary), kümeler (set)
Dosya işlemleri: dosya açma, okuma, yazma, güncelleme
Hata yönetimi (try-except blokları) ve özel hata sınıfları
Nesne Yönelimli Programlama (OOP): sınıflar, nesneler, kalıtım, çok biçimlilik
Python modülleri ve paketleri
Standart kütüphaneler ve üçüncü parti modül kullanımı
Gerçek dünya problemlerinin çözümü
Mini projeler ile uygulamalı öğrenme
Bonus İçerikler:
Flask ile Web Uygulama Geliştirme Temelleri
Kivy ile Mobil Uygulama Geliştirmeye Giriş
Python ile otomasyon fikirleri ve örnek uygulamalar
Algoritma geliştirme ve problem çözme teknikleri
Bu Kurs Kimler İçin Uygun?
Yazılıma sıfırdan başlamak isteyen herkes
Python öğrenerek yazılım dünyasında kariyer yapmak isteyen öğrenciler
Veri analizi, yapay zeka veya makine öğrenmesi gibi alanlara giriş yapmayı planlayanlar
CV’sine Python eklemek isteyen profesyoneller
Kendi projelerini geliştirmek isteyen girişimciler veya freelance çalışmak isteyenler
Yazılım alanında kendini geliştirmek isteyen herkes
Neden Bu Kurs?
Hiçbir programlama bilgisi gerektirmez
Konular sade, anlaşılır ve sıfırdan anlatılır
Teorik bilgilerin yanı sıra uygulamalı örneklerle pekiştirme yapılır
Güncel Python sürümüne göre hazırlanmıştır
Eğitimi tamamladığınızda gerçek dünya problemlerini çözebilecek düzeye gelirsiniz
Python dilinin tüm yönlerini bir arada öğrenirsiniz – tek pakette tam çözüm!
Kursun sonunda neler yapabileceksiniz?
Python’da güçlü ve temiz kodlar yazabileceksiniz
Gerçek hayatta karşılaşılan problemleri Python ile çözebileceksiniz
Kendi otomasyon script’lerinizi, basit web ve mobil uygulamalarınızı yazabileceksiniz
Yazılım mülakatlarında teknik soruları rahatlıkla yanıtlayabilecek becerilere sahip olacaksınız
Veri bilimi, yapay zeka, siber güvenlik gibi alanlara sağlam bir altyapı ile geçiş yapabileceksiniz
Eğer sen de Python öğrenerek yazılım dünyasında yerini almak istiyorsan, daha fazla vakit kaybetmeden bu kursa katıl!
Adım adım ilerle, konuları özümse, uygulamalarla pratik yap ve kendi projelerini hayata geçirecek seviyeye ulaş!
Haydi, şimdi başla ve Python yolculuğuna güçlü bir adım at!