Ahmet Orsorlu
ABOUT THE AUTHOR

Ahmet Orsorlu

Matematik Mühendisliği lisans, Bilgisayar Mühendisliği yüksek lisans mezunu. Halen Logo Business Solutions'ta Yazılım Uzmanı olarak görev yapmakta. Basit ve temiz olan herşeyi seviyor. Galatasaraylı. Stephen King ve Metallica aşığı.

Java İpucu #3 – Java Konsoldan Veri Okuma

Java ile ilgili ipucu yazılarıma yine basit ama başlangıç seviyesinde (veya konsoldan çalışan programlar için) çok kullanımı olan bir konuyla devam etmek istiyorum. Bu sefer amacımız konsoldan veri okumak.

Bunun için birçok yöntem mevcut ancak ben sadece ikisinden bahsedeceğim.

İlki Scanner (JRE 1.5 ile geldi) sınıfını kullanarak basit bir kullanıcı girişi;

Scanner s = new Scanner(System.in);
System.out.print("Kullanıcı Adı: ");
String userName = s.nextLine();
System.out.print("Şifre: ");
String password = s.nextLine();

if (checkUserNameAndPassword(userName, password))
	System.out.println("Sisteme başarıyla giriş yaptınız.");

// Kullanıcı adı ve şifre kontrolü yapar
private static boolean checkUserNameAndPassword(String userName, String password) {
	// bilgileri kontrol et
	//
	return true;
}

Burada nextLine metodu konsoldayken klavyeden enter tuşuna basılana kadar olan tüm girdileri alır. Scanner sınıfının nextByte, nextInt gibi başka metotları da mevcut. Her zamanki gibi inceleme kısmı size ait 🙂

Diğer yöntem;

Console c = System.console();
if (c == null) {
	System.err.println("Konsol erişimi sağlanamadı.");
	System.exit(1);
}

String userName = c.readLine("Kullanıcı Adı: ");
char[] password = c.readPassword("Şifre: ");

if (checkUserNameAndPassword(userName, password)) {
	System.out.println("Sisteme başarıyla giriş yaptınız.");
}

Öncelikle bu yöntemin sadece konsoldan çalıştırılan java uygulamalarında çalışacağını söylemeliyim (örneğin, Windows’ta Komut İstemci’sinde veya Linux’ta Terminal’de). Aksi halde (örneğin, Netbeans’te çalıştırdığınızda), “Konsol erişimi sağlanamadı.” uyarısı gözükecektir.

Console (JRE 1.6 ile geldi) sınıfının güzel iki metodu readLine (Scanner sınıfındaki metot ile aynı işi yapıyor) ve readPassword (girilen verinin ekranda gözükmeden girilmesini sağlıyor). Kod parçasının diğer kısmı ilk örnekle aynı. Dikkat edin readPassword metodu karakter dizisi döndürüyor.

İpucu konusu olduğu için yine çok detaya girmemeye çalıştım. Diğer Java İpucu yazılarım için sitenin arama kısmına “Java İpucu”, Java makaleleri için “Java Makale” yazarak aratabilirsiniz. Site özellikleri kullanımına teşvik 🙂

Herkese iyi çalışmalar.

Proxy Server (Vekil Sunucu)

Proxy Server(vekil sunucu)lar, kullanıcı ile erişmek istediği ana sunucu arasında aracılık görevi edinen ara sunuculardır. Temel amaçları, cache (ön bellek) görevi görerek performans arttırıcı rol üstlenmektir. Şöyleki; uzaktaki sunucularda bulunan sık kullanılan web sayfalarının güncel halleri vekil sunucularda tutularak kullanıcı bu sayfalara erişmek istediğinde kullanıcıya vekil sunucudaki veriler gösterilir. Genellikle internet servis sağlayıcıları (örn. Türk Telekom) bu yöntemi kullanır.

Hemen bir örnekle açıklayayım;

Türkiye’de yaşayan Berk, Amerika’daki bir sunucuda bulunan cnn.com (aklıma bu adres geldi :)) sitesine erişmek istiyor. Berk’in servis sağlayıcısı Türk Telekom vekil sunucularında cnn.com adresindeki sayfaların güncel halini daha önce belleğine almış ise Berk’e taa Amerikalara gitmeye gerek kalmadan vekil sunucudaki bilgileri döndürüyor. Eğer istenilen sayfa vekil sunucuda bulunamaz ise o zaman vekil sunucu Amerika’da bulunan gerçek sunucudan sayfanın son halini istiyor ve Berk’e ana sunucudan dönen verileri döndürüyor.

Bu durumda iki yönlü bir fayda olmuş oluyor aslında;

  • Berk web sayfasına daha hızlı erişmiş oluyor
  • İnternette önemli sorunlardan birisi olan servis sağlayıcılar arası (anlaşılır olması için ülkeler arası diyebiliriz. Tam öyle değil ama benzer) trafik azalmış oluyor.

Vekil sunucuların diğer bir kullanım amacı da gizlilik. Vekil sunucu kullanıldığı zaman ana sunucu isteğin vekil sunucudan geldiğini düşünüyor. Yani ana sunucu için kullanıcı vekil sunucu olmuş oluyor. Asıl kullanıcının bilgilerine hiçbir şekilde erişemiyor.

Bu kullanımı da gündelik hayat analojisi ile açıklayayım;

Tankut, hoşlandığı kız Beril’in yaşının kendisine uygun olup olmadığını çok merak ediyor. Ama tabii ki gidip doğrudan Beril’e soramıyor (bayanların yaşını sorma durumu). Çareyi Beril’in yakın arkadaşı Münevver’e danışmakta buluyor. İşin kötü yanı Münevver de Beril’in yaşını bilmiyor (bu noktada Münevver Beril’in yaşını biliyor ise ilk kullanıma örnek olmuş oluyor. Pek performans durumu yok ama idare edin :)). Münevver’in Beril’e yaşını sorması kabalık olmayacağı için, Münevver Beril’den yaşını öğrenip Tankut’a söylüyor. Görüldüğü üzere Beril bilgiyi aslen kimin edindiğini bilmemiş oluyor 🙂

Bu yöntemi, örneğin sadece Almanya içinde videolarını gösteren bir video sitesine Almanya’da bulunan bir vekil sunucuya bağlanarak kullanabilirsiniz. Evet, bu sayede videoları da izlemiş oluyorsunuz. Bu tarz vekil sunucu görevi gören bir sürü vekil sunucu mevcut (örn. vtunnel, ktunnel vb.). (Laf aramızda yasaklı siteler için de kullanılabilir 🙂 ).

Proxy Server (vekil sunucu)ları genel ve yüzeysel olarak basit bir şekilde anlatmaya çalıştım. Umarım anlaşılır olabilmişimdir.

Herkese iyi çalışmalar.

Java İpucu #2 – Java Konsola Yazı Yazdırma

Biraz da Java’ya yeni başlayan arkadaşlarımız için kısa bilgilendirme amaçlı yazılar yazmak istedim. Bir programlama dilini öğrenirken ilk öğrendiğimiz konudan başlayalım: Konsola yazı yazdırma.

Bir yazıyı ekrana nasıl basacağımızı gösteren küçük bir kod parçası yazalım;

System.out.println("Konsola basılacak ilk yazı");
String printTxt = "Konsola basılacak ikinci yazı";
System.out.println(printTxt);
System.out.print("Bundan sonra yazılacak yazı yanına gelecek - ");
System.out.print("Bir önceki yazının yanına gelecek yazı");

1. satırda println metodu doğrudan stringi argüman alarak konsola basıyor ve alt satıra geçiriyor. İngilizce açılımını print line (satır yaz) olarak düşünebiliriz. 3. satırda println metoduna 2. satırda oluşturduğumuz string nesnesini argüman olarak veriyoruz. 1. satırla benzer sonuç doğuruyor. 4 ve 5. satırlardaki print metodunun println metodundan farkı, gelen argümanı konsola bastıktan sonra alt satıra geçmeden bir sonraki ekrana yazma işleminin aynı satırdan devam etmesi.

Kod parçasının konsol çıktısı şu şekilde;

Konsola basılacak ilk yazı
Konsola basılacak ikinci yazı
Bundan sonra yazılacak yazı yanına gelecek - Bir önceki yazının yanına gelecek yazı

print ve println metodları String parametresinin yanında, diğer tüm primitive (int, char vb.) tipleri parametre olarak alabiliyor. Ayrıca bu metodlara Java kütüphanelerinde bulunan ya da kendi oluşturduğunuz tüm sınıfları da argüman olarak verebiliyorsunuz. Nasıl mı? Java’da tüm sınıfların ata sınıfı Object sınıfıdır. Ve bu sınıf çok sihirli bir metoda sahiptir: toString. Yani, tüm sınıflarınızın bir String karşılığı var. Bu metodu isterseniz kendi sınıfınızda override ederek içeriğini siz yazabilirsiniz. Bu işlemi yapmazsanız Object sınıfı sizin için bir gösterim yapıyor. Çok da anlamlı olmayabilir sizin için tabi 🙂

Hemen örnek kod;

Object o = new Object();
System.out.println(o);

ve konsol çıktısı;

java.lang.Object@42e816

Çıktının içeriği çok da önemli değil (meraklıları için söyleyeyim; sınıfın paket ismiyle beraber ismi ve hash kodu). Ama her sınıfın bir String karşılığı var bunu bilin yeter 🙂

Uyarı!

Bu noktadan sonrası tamamen meraklı ve usta kullanıcılar içindir. Uyarmadı demeyin 🙂

Örnek kod parçalarındaki

System.out.println

satırını irdeleyelim biraz. Bu satırda aslında, System sınınıfın out alanının println metodunu çağırıyoruz. System sınıfı nesnesi oluşturulamayan ve türetilemiyen bir sınıf  (final class). out, System sınıfının static bir alanı (değişkeni) ve PrintStream tipinde. print ve println metotları ise aslında PrintStream sınıfının metodları. Kendileri de static tabii ki 🙂

Uyarı Sonu

Basit bir konuyu çok da karmaşıklaştırmamak için daha detaya girmek istemiyorum. Diğer yazılarda yeri geldikçe yeniden değinmeye çalışırım. Herkese iyi çalışmalar.

Java Makale #2 – HashMap vs HashTable

HashMap sınıfı, Map arayüzünün tüm özelliklerini hashing (bir nevi verileri tekil integer değerlere dönüştürme işlemi) özelliğiyle gerçekleyen Java sınıfıdır. Hemen terimleri ayrı ayrı açıklayalım.

Map arayüzü, ikili verilerinizi (key ve value) tutmanızı sağlayacak kuralları belirler. HashMap sınıfı ise key verilerinizin hash değerlerini (ki bu değer  Java’da tüm sınıfların atası olan Object sınıfının hashCode metodundan gelir) Map‘in key verisi olarak tutar (HashMap‘ten başka TreeMap ve AbstractMap gibi Map türleri de mevcuttur). Örneğin, bir gruptaki kişilerin yaşlarını <isim,yaş> ikilisi şeklinde tutabilirsiniz. Bir nevi indeks değeri istediğiniz bir nesne olabilen dizi diyebiliriz.

HashMap sınıfının en büyük özelliği put ve get işlemlerini yani bir key değerine ait value değerini tutma ve istenilen zamanda okuma işlemlerini birim zamanda yapabilmesidir. Deminki örnek üzerinden gidersek, gruptaki Hakan’ın yaşı 24, Melis’in yaşı 21 ise, Hakan ve Melis’in yaşlarını birim zamanda edinebiliyoruz.

Şimdi de kod üzerinden nasıl kullanıldığına bakalım;

HashMap ages = new HashMap();

ages.put("Hakan", new Integer(24));
ages.put("Melis", new Integer(21));

Integer ageOfHakan = (Integer) ages.get("Hakan");
Integer ageOfMelis = (Integer) ages.get("Melis");

Kullanımı bu kadar basit. Kod parçasının 6. ve 7. satırlarında dikkat ederseniz veriyi alırken Integer cast işlemi yapmak zorunda kaldık. Çünkü, HashMap nesnesi her tipten value değerine sahip olabilir. get metodu da aslında bir Object nesnesi döndürüyor. Buradaki cast işleminin sakıncaları büyük ama konumuz o değil tabii ki. Başka bir yazıda da buna değinelim.

Şimdi gelelim HashTable sınıfına. Zaten söylenmesi gereken birçok şeyi HashMap ile birlikte söyledik 🙂 Hemen HashTable sınıfı ve HashMap sınıfı arasındaki farkları sıralayalım (HashMap sınıf tanımında belirtildiğine göre):

  • HashTable sınıfı synchronized, HashMap sınıfı unsynchronized şekilde çalışmaktadır. Benzer fark, StringBuffer ve StringBuilder sınıfları arasında da mevcuttur. Bu konu hakkındaki daha önceki yazıma bakabilirsiniz.
  • HashMap sınıfı null key ve value değerlerine izin vermektedir. HashTable sınıfı null değerlere izin vermez.

Yine bir reçete vermek gerekir bu noktada değil mi? 🙂

  • Multithread çalışıyorsanız ve senkronizasyon işlemi sizin için önemliyse (ve senkronizasyın işlemini elle yapmaya üşeniyorsanız) HashTable sınıfını
  • Diğer hemen tüm durumlarda HashMap sınıfını kullanabilirsiniz.

Python Görüntü İşleme ve Düzgün Resim Küçültme Örneği

from PIL import Image

No module named PIL diye bir hata veriyorsa aşağıdaki şekilde python image kütüphanesini yükleyiniz. Kütüphaneyi yükleme ile değil de, doğrudan dosyaları kopyalarak sisteminize attıysanız alabilirsiniz. Kütüphanenin olduğu (PIL) dizinde çalışırsanız da hata almayaacksınız, çünkü python default olarak pythonu çalıştırdığınız dizini sys.patch e ekliyor. bu yüzden yine de aşağıdaki gibi yüklemenizde yarar var.

Yüklemek için;

sudo apt-get install python-imaging

apt-get yoksa;

yum install python-imaging

ile yükleyebilirsiniz.

Bir resim dosyası açın. tam yol girmeniz her zaman daha sağlıklı olur (.bmp,.jpg,.png,.gif)

imageFile = "/root/emre/snake.jpg"
imageObj = Image.open(imageFile)

Örnek bir resmi şu adresten indirebilirsiniz : snake.jpg

Resmin boyutlarını almak için .size diyoruz. bu bize 2 li bir dizi (array) döndürüyor.

data = imageObj.size
print "width(en) %s , height(boy) %s" %(data[0], data[1])

Bunları ileride kullanacaksak ayrı değişkene verebiliriz

imageWidth=data[0]
imageHeight=data[1]

Yeni en ve boy degerlerinin disaridan girilmesini isteyelim.

width = float(raw_input("En giriniz"))
height = float(raw_input("Boy giriniz"))

Aşağıda 4 farklı yeniden boyutlandırma algoritması var, 4 ü de resmi verilen boyutlarla yeniden boyutlandırıyor. Deneyip görebilirsiniz (algoritmaların türkçeleri biraz saçma oldu 🙂 )

im2 = imageObj.resize((int(width), int(height)), Image.NEAREST) # en yakın komşuluk metodu.
im3 = imageObj.resize((int(width), int(height)), Image.BILINEAR) # 2x2 lik ortamda lineer interpolasyon metodu
im4 = imageObj.resize((int(width), int(height)), Image.BICUBIC) # 4x4 ortamda Kübik interpolasyon metodu
im5 = imageObj.resize((int(width), int(height)), Image.ANTIALIAS) # aşağı ölçeklendirme filtreleme metodu (antialias)

Bu yeniden boyutlandırılmış resimleri çalıştığımız dizine kayıt edebiliriz.

im2.save("NEAREST.jpg")
im3.save("BILINEAR.jpg")
im4.save("BICUBIC.jpg")
im5.save("ANTIALIAS.jpg")

Resmin ilk hali üzerinden doğru ölçeklendirmek için bir resim algoritması aşağıdadır. Bu resmi eğip büzmez mevcut oranları korur, eski resmi girilen en boy oranları şeklindeki bir hayali diktörgenin içine sığdırır. Çarpma bölme ve oran işlemleri için float değerlere ihtiyacımız olduğundan integer olabeilcek verileri float() tan geçirmeyi unutmuyoruz.

if imageWidth>width or imageHeight > height :
	if imageWidth > imageHeight :
		finalWidth = width
		percent = float(width)/float(imageWidth)
		finalHeight = float(percent) * float(imageHeight)
	elif imageHeight >= imageWidth :
		finalHeight = height
		percent = float(height)/float(imageHeight)
		finalWidth = float(percent) * float(imageWidth)
elif imageWidth < = width and imageHeight < = height : 
	finalWidth = imageWidth
	finalHeight = imageHeight

Resim objesi resize işleminde integer değer aldığından oluştururken float olan verileri int() ten geçiriyoruz ve resmi kaydediyoruz.

print "yeni boyutlar %s %s" % (finalWidth,finalHeight)
newImage = imageObj.resize((int(finalWidth),int(finalHeight)), Image.NEAREST)
newImage.save("newImage.jpg")