29 Eylül 2014 Pazartesi

PyQt Class Kullanımı

       Grafiksel kullanıcı arayüzüne sahip programlar genellikle bir çok pencere ve işlev içermektedir. Dolayısıyla bütün bu pencere ve işlevleri tek bir dosyada tutmak oldukça kafa karıştırıcı bir hale gelmeye başlar. Bu tür bir karmaşıklığı önlemek ve programımızı daha modüler bir hale getirmek için classları kullanırız.

Şimdi bir önceki konuda yazdığımız programı class kullanarak tekrar yazalım:
# !/usr/bin/env python
# -*- coding: cp1254 -*-
 
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class sinifProgrami(QDialog):
    def __init__(self, parent=None):
        super(sinifProgrami, self).__init__(parent)

        self.metin = QLabel('
PythonDersleri.com
') self.butonKirmizi = QPushButton('Kırmızı') self.connect(self.butonKirmizi, SIGNAL('pressed()'), self.kirmiziMetin) self.butonMavi = QPushButton('Mavi') self.connect(self.butonMavi, SIGNAL('pressed()'), self.maviMetin) izgara = QGridLayout() izgara.addWidget(self.metin, 0, 1, 2, 1) izgara.addWidget(self.butonKirmizi, 0, 0) izgara.addWidget(self.butonMavi, 1, 0) self.setLayout(izgara) self.setWindowTitle('PyQt Grid Layout') self.setFixedSize(450, 150) def kirmiziMetin(self): self.metin.setText('
Merhaba Dünyalı :)
') def maviMetin(self): self.metin.setText('
Uygar Köroğlu
') uygulama = QApplication([]) pencere = sinifProgrami() pencere.show() uygulama.exec_()

Bu kodu çalıştırdığımızda da çıktı değişmeyecektir:

PyQt classları QWidget nesnesi olabileceği gibi QDialog nesnesi de olabilir. Hangisinin nesnesi ise ona ait tüm özellikleri de taşıyacaktır. 
Yazmış olduğumuz kodları satır satır açıklamaktan ziyade bu koda baktığımızda farklı olarak gözümüze ilk şu satır çarpmaktadır:
super(sinifProgrami, self).__init__(parent)
Bu satırda parenttan bahsettik yani ebeveyn. Program alt pencerelerden oluşmaya başladığında, hangi pencerenin hangi pencereye ait alt pencere olduğunu ayırt etmek için bu yapı kullanılır. Biz bu pencerenin bir alt pencere olmadığını, bizim penceremizin bir ana pencere olduğunu parent=None ifadesiyle belirttik.
Bir class'ın başlamasını sağlamak için super() metodu kullanılmakta. super() metodu parametre olarak; ilk parametrede class'ın adını, ikinci parametrede ise self olarak kendisini alır. __init__() metoduna ise hangi pencerenin alt penceresi olduğunu parametre olarak yazarız.

28 Eylül 2014 Pazar

Bildiğiniz gibi Django'da veritabanı oluşturmak için ilk önce models.py dosyasında veritabanımınızın nasıl olacağına dair tanımlamaları yapıyoruz ve ardından
python manage.py syncdb
komutu ile tablolarımızı oluşturubiliyoruz. Peki ya tasarımını yaptığımız bir veritabanını model dosyası içerisine aktarmak istersek ne yapacağız. Bunun çözümüde yukarıdaki komut kadar basit. Vermemiz gereken komut şu şekikde.
python manage.py inspectdb > app/models.py
Bu şekilde app uygulaması içerisindeki models.py dosyası içerisine veritabanına uygun olan model tanımlamaları yapılacaktır. Şu tarz tanımlamalar görebilirsiniz.
class Message(models.Model):
    id = models.IntegerField(primary_key=True)
    message = models.CharField(max_length=30)
    class Meta:
        managed = False
        db_table = 'app_message'
Peki Django'nun kendi çekirdek tablolarını oluşturmak için ne yapacağız. Bunun için yine modelden tablo oluşturmamızı sağlayan komutu verebilirsiniz.
python manage.py syncdb
Kaynakça

27 Eylül 2014 Cumartesi

PyQt Pencere Düzenleri

       Grafiksel arayüze sahip programlar genellikle birden çok pencereye sahiptirler. Ve bu pencereler de genellikle kendi içlerinde farklı parçacıklar bulundurmaktadırlar. Yani kendilerine ait butonları, labelları, text alanları gibi parçacıkları olmaktadır. Biz de programlarımızı yazarken kullandığımız parçacıkların sayısı arttığında, bunları penceremize nasıl yerleştireceğimiz konusunda birtakım pencere düzeni uygulama gereksinimi duymaktayız.

Örneğin; yerleştirmek istediğimiz bir label ve bir butonumuz olsun. Bunları yandaki şekildeki gibi yan yana veya alt alta koymak isteyebiliriz.

Bu yapılar Layout olarak isimlendirilirler. Biz burada kutu demeyi tercih ediyoruz. Bu şekillerden ilki dikey bir kutu (QVBoxLayout) diğeri ise yatay bir kutudur (QHBoxLayout). Bu kutulara eleman eklemek istediğimizde (addWidget) dikey kutuda her eklenen eleman alta gelecek şekilde, yatay kutuda ise sağ tarafa gelecek şekilde ekleme işlemi gerçekleşmektedir. Bir parçacık eklemek için addWidget() metodu kullandığımız için penceremizin de QWidget() nesnesi olması gerekir.

Şimdi bu bahsettiklerimiz hakkında bir örnek yazalım ve bu örnek üzerinden kodları açıklayalım.

# !/usr/bin/env python
# -*- coding: cp1254 -*-
from PyQt4.QtGui import *

uygulamam = QApplication([])
pencere = QWidget()
etiket = QLabel('PythonDersleri.com')
buton = QPushButton('Butonum')

yatayKutu = QHBoxLayout()
yatayKutu.addWidget(etiket)
yatayKutu.addWidget(buton)

pencere.setLayout(yatayKutu)
pencere.setWindowTitle('Programım')
pencere.show()

uygulamam.exec_()

1. Satır = Yazdığımız kodların Python kodu olduğunu ve Python'un dizinini belirtiyoruz. (Linux için)
2. Satır = Türkçe karakterlerin desteklenmesini istediğimizi belirtiyoruz.
3. Satır = Grafiksel arayüz için gerekli modülü programımıza dahil ettik.
5. Satır = Bir QApplication nesnesi oluşturuyoruz.
6. Satır = Bir tane Widget oluşturduk.
7. Satır = İçeriği "PythonDersleri.com" olan bir Label oluşturduk.
8. Satır = Üzerinde "Butonum" yazan bir buton oluşturduk.
10. Satır = Yatay şekilde eleman ekleyebileceğimiz bir kutu oluşturduk.
11. Satır = Oluşturduğumuz yatay kutunun içine Labelımızı ekledik.
12. Satır = Yine yatay kutunun içine butonumuzu da ekledik.
14. Satır = Pencere düzenimizin oluşturduğumuz yatay kutu olacağını belirttik.
15. Satır = Program penceremizin başlığında "Programım" yazmasını belirttik.
16. Satır = Penceremizin görüntülenmesini istedik.
18. Satır = Uygulamamızın çalışmasını istedik.

       Kodu çalıştırdığımızda ise bize şöyle bir çıktı verecektir:

       Çalışma Sorusu: Yukarıda yatay bir kutu için yazmış olduğumuz kodu dikey bir kutu için yeniden yazın; ancak bu kez üstte buton altta label bulunsun.

PENCERE BOYUTLARI VE YERİ

       Yukarıda yazmış olduğumuz gibi bir kod yazdığımızda programımız parçacıkları yerleştirebildiği minimum boyutlarda açılacaktır. Biz istersek bu boyutları değiştirebiliriz (resize). Ancak bu değiştirme işlemi küçültme yönünde değil, büyütme yönünde yapılabilmektedir. Küçültmeye çalıştığınızda ise parçacıkların yerleştirildiği minimum boyutlarda açılacaktır. Boyutları değiştirebileceğimiz gibi programın sol üst köşeden itibaren kaç piksel uzaklıkta başlayacağını da belirleyebiliriz (move). Bu değişikliklerin nasıl olduğunu görmek için ise yukarıda yazmış olduğumuz koda pencere.setWindowTitle('Programım') satırından sonra aşağıdaki kodları ekleyin ve değişikliği görmek için çalıştırın.
pencere.resize(300, 100) # Yeni boyutlar
pencere.move(50, 50) # Sol üst köşeden uzaklık

25 Eylül 2014 Perşembe

Numpy: Dizi Oluşturma

Bu bölümde sayısal verilerin depolandığı dizileri oluşturma yöntemlerini öğreneceğiz. Python programlama dili Fortran ve C türevi dillerden farklı olarak veri bloğu için fiziksel bellekteki hafıza ayarlama işini otomatik olarak yapar. Dolayısıyla biz sadece dizimizin niteliğini ve niceliğini belirtip oluşturabiliriz. Diziyle işimiz bittiğinde Python yine bizim ek bir komut çalıştırmamıza gerek kalmadan hafızada ayrılmış yeri boşaltır. Böylece diğer programlar için de yer açılmış olur.
 
Dizi Nesnesi
Python nesne tabanlı bir programlama dilidir. Bu yüzden herbir modül veya kütüphane bir sınıf olarak düşünülebilir. Bu sınıfların nesneleri temelde constructor adı verilen inşa fonskiyonları ile oluşturulur. İnşa fonksiyonlarının parametrelerini inceleyerek nesnelerimizin temelde hangi özelliklerini barındırdığını öğrenebiliriz. Aşağıdaki örneğe göz atalım.
>>> from numpy import * # Numpy kütüphanesini ad alanı ön eki olmadan ekliyoruz
>>> ndarray(shape=(2,3), dtype=float32)
array([[  3.77839489e+22,   9.18355102e-39,   1.38829441e-40],
       [ -3.76174156e-37,   7.62234898e-39,   7.00649232e-45]], dtype=float32)
İnşa fonksiyonunun bazı parametreler aldığını görüyoruz. Bunlardan shape, oluşturmak istediğimiz boyutu bildiren bağlı sıralılardır (tuples). Yukarıdaki örnekte de bu parametreyle birlikte 2x3'lük yani iki satırdan 3 sütundan oluşan bir dizi oluşturmak istediğimiz belirtmiş olduk. dtype özelliği ise bu dizide hangi tip verilerin saklanacağını belirtir. Biz burada standart 'float32' tip veri (varsayılan) türünden bir diziyi tercih ettik. Farklı tip Python veril tipleri ('int', 'float64' vb.) de dizilerde depolanabilir.
ndarray sınıfı hafızanın elverdiği ölçüde keyfi boyutlu dizileri destekler. Örneğin; aşağıda tamsayılardan oluşan 2x2x2x2'lik bir dizi oluşturulmuştur. 
>>> ndarray((2,2,2), 'int32')
array([[[ 50398851, 505910976],
        [505910976, 505910976]],
       [[ 68431072, 657601396]]]),
        [   657961,  48016344]]])
Yazımızın bundan sonraki bölümlerinde ise anlatımı kolaylaştırmak amacıyla genelde tek boyutlu dizilerle çalışılacaktır.

Elemanlara Erişim
Dizinin herhangi bir elemanına erişmek için köşeli parantez '[ ]' operatörünü kullanabiliriz. Python'da ilk indis '0'dan başlar, ve diğer programlama dillerinden farklı olarak negatif indisleri destekler. Negatif indislerde ise ilerleme yönü sondan başa doğrudur.
>>> dizi = ndarray(5) 
>>> print(dizi)
[  3.83049187e+238   3.45262638e-316   0.00000000e+000   3.83711926e+238
   6.35862486e-321]
>>> dizi[1] = 5.0  # baştan ikinci elemana değer atandı
>>> dizi[-1] = 5.0 # en sondaki elemana değer atandı
>>> print(dizi)
[  3.83049187e+238   5.00000000e+000   0.00000000e+000   3.83711926e+238
   5.00000000e+000]
Dizinin boyutu shape fonksiyonuyla elde edilir. Tek boyutlu diziler için standart kütüphanedeki len fonksiyonu da kullanılabilir. 
>>> shape(dizi)
(5,)
>>> len(dizi)
5
Diziye ait elde edilmek istenen en önemli bilgilerden biri de maximum ve minimum değerleri, ve bunların indis konumlarıdır. max/min fonksiyonları bu değerleri, argmax/argmin fonksiyonları da bu değerlerin bulunduğu indisleri bize bildirir.
>>> min(dizi)
0.0
>>> argmin(dizi)
2
>>> max(dizi)
3.837119259946211e+238
>>> argmax(dizi)
3

Ön Tanımlı Dizi Oluşturma
Numpy dizilerini oluşturmanın aslında birçok yolu vardır. İlk olarak standart liste tipindeki verilerin nasıl diziye dönüştüğünü görelim.
>>> liste = ([1,2,3])
>>> dizi = array(liste, 'float32')  # tam sayı yerine ondalıklı olarak depolar
>>> print(dizi)
[ 1.  2.  3.]
Dizileri de tolist fonksiyonuyla tekrardan listeye dönüştürebiliriz.
>>> liste = ([4,6,7])
>>> dizi = array(liste, 'int32')
>>> liste2 = dizi.tolist()
>>> print(liste2)
[4, 6, 6]
Dizi elemanlarını baştan '0' veya '1' atayarak, veya inşa fonksiyonunda olduğu gibi varsayılan değer atayarak oluşturabiliriz.
>>> dizi = zeros(4)
>>> print(dizi)
[ 0.  0.  0.  0.]
>>> dizi = ones(4)
>>> print(dizi)
[ 1.  1.  1.  1.]
>>> dizi = empty(4)
>>> print(dizi)
[  7.35794000e-295   7.01521574e-295   7.01647004e-295   7.01440942e-295]
Dizileri önceden belirli aralıklarla da oluşturabiliriz. arange fonksiyonu sırasıyla başlangıç, bitiş ve adım aralığını parametre olarak alıp bitiş noktasının dahil olmadığı bir dizi oluşturur. linspace başlangıç ve bitiş değerleri arasındaki istenilen sayıda eş aralıklı değer türetir. arange'ten farklı olarak linspace'te adım aralığı değil örnek sayısı parametre olarak girilir ve bitiş noktası da türetilen değerler içindedir. 
>>> arange(1,10,1)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> linspace(1,10,3)
array([1., 5.5, 10.])
logspace ise eş aralıklı örnek değerleri, istenilen tabanda logaritmik olarak verir.
>>> logspace(1, 10, N=2) # varsayılan taban değeri '10' kullanıldı
array([  1.00000000e+01,   1.00000000e+10])
>>> logspace(1, 10, N=3, base=2)
array([2., 45.25, 1024.]) # log2(2)=1, log2(45.25)=5.5, log2(1024)=10

Rastgele Dizi Oluşturma
Numpy kütüphanesindeki random sınıfı ve alt fonksiyonlarını kullanarak rastgele değerlerle doldurulmuş diziler elde edebiliriz.
>>> random.random(3)
array([ 0.5878516 ,  0.01153192,  0.84747563])
Değerler görüldüğü gibi [0,1) aralığında türetilmiştir. Eğer keyfi aralıkta olması istenirse bu uniform alt fonksiyonu kullanarak sağlanabilir
>>> # [a=3,b=5) yarı açık aralıkta rastgele N=4 adet değer
>>> random.uniform(3,5,4)
array([ 4.37716131,  3.04042835,  3.08056492,  4.89028642])

Kaynaklar:
[1] Langtangen H. P., A Primer on Scientific Programming with Python, Springer, 2009

24 Eylül 2014 Çarşamba

Numpy & Scipy

pythondersleri.com yeni bir yazı dizisi "Numpy ve Scipy : Bilimsel Hesaplamalar İçin Python" ile karşınızda! Bu yazı sayesinde akademik çalışmalar ve endüstriyel uygulamalardaki hesaplamalar için Python programlama diline bir miktar vakıf olabilmeyi amaçlıyoruz. Meselenin kapsamı geniş olduğu için ilk yazımızda içerik hakkında özet bilgi vermeyi uygun gördük.
Python'un günümüzdeki popülerliğinin en önemli sebeplerinden biri de hesaplamalı bilimlerdeki işlevselliğidir. Üst seviye bir programlama dili olan Python bu işlevselliği sayesinde; alt seviye programa dillerinde (C, C++, Fortran) yapılabilen karmaşık büyük çaptaki hesaplamaları kıyaslanabilir bir performansta, kullanıcıya büyük kolaylıklar sağlayarak (Matlab vb.) gerçekleştirebilmektedir. Python aslında bu fonksiyonelliğini biraz da modül, paket veya kütüphane olarak adlandırılan eklentilere borçludur. Bu paketlerden en meşhurları yazı dizimizin kapsamını da oluşturan Numpy ve Scipy kütüphaneleridir. Numpy genel olarak dizi/vektör/matris hesaplamaları için özelleşmiş bir kütüphane olup, büyük çaptaki veri kümeleri üzerinden işlem yapmayı kolaylaştırır. Scipy ise bünyesinde, sık kullanılan matematiksel rutinleri ve fiziksel problemlerinin bilgisayar ortamında ifade edilmesine yönelik fonksiyonları barındırmaktadır. Dersler kapsamında yeri geldiğinde ayrıca, işlenilen ve sonuç olarak elde edilen verilerin görselleştirilmesi amacıyla Matplotlib kütüphanesinde bahsedilip pratik bilgiler verilmeye çalışılacaktır.

?

Yazılardaki örnekler, Python 3.3 sürümünde çalışan kodlar olup Numpy 1.8 ve Scipy 0.13 kütüphaneleri uyumludur. Ancak ilgili kütüphanelerin kurulu olduğu herhangi bir Python 3x sürümü kullanılmasının bir sıkıntı oluşturmayacağı kanaatindeyiz. Paketlerin yüklenmesi ile ilgili yönergeler için http://www.scipy.org sitesine göz atabilirsiniz. Windows kullanıcılarına kolaylık sağlamak amacıyla üçüncü şahıslar tarafından ikili(binary) dosyalar hazırlanıp ücretsiz olarak dağıtılabilmektedir. Bunların içerisinde, diğer pek çok eklentiyi de bulabileceğiniz http://www.lfd.uci.edu/~gohlke/pythonlibs adresini tavsiye edebiliriz.
Scipy kütüphanesi arka planda Numpy dizilerinden istifade etmektedir. Bu yüzden derslerimizde öncelikle Numpy anlatılacak ardından Scipy'e geçilecektir. Numpy kapsamında aşağıdaki konulara değinilecektir.
  • Dizi oluşturma
  • Vektörleştirme ve dilimleme
  • Matrisler ve basit lineer cebir
  • Veri dosyaları
Scipy kapsamında ise aşağıdaki konu başlıkları takip edilmeye çalışılacaktır.
  • Lineer cebir
  • İnterpolasyon ve eğri uydurma
  • Sayısal integral ve türev alma
  • Fourier dönüşümü
  • Özel fonksiyonlar
  • Fizksel büyüklükler ve sabitler
  • Sembolik matematik
  • Dosya okuyup yazma

22 Eylül 2014 Pazartesi

Daha önce Django Projesini Apache ve Mod_WSGI ile Yayınlamak yazısında Apache sunucusu üzerinde nasıl proje yayınlanacağından bahsetmiştik. Bu yazıda ise çok basit bir şekilde bir apache sunucu üzerinde birden fazla Django projesi nasıl çalıştırılır bundan bahsedeceğiz. Çözümü oldukça basit. Yapmamız gereken Apache VirtualHost tanımlaması yaparken projeleri process'lere bölmek. Bu şekilde diğer projenin süreçleri projemizi hataya sürüklemeyecek ve birden fazla proje tek bir sunucuda sorunsuz bir şekilde çalışabilecektir.
Birinci proje için VirtualHost tanımlaması :

ServerAdmin info@proje1.com
ServerName proje1.com
DocumentRoot /var/www/proje1


Alias /static/ /var/www/proje1/static/
WSGIDaemonProcess proje1
WSGIScriptAlias / "/var/www/proje1/proje1/wsgi.py" process-group=proje1
ErrorLog /var/log/apache/proje1/error_log
TransferLog /var/log/apache/proje1/access_log
...

İkinci proje için VirtualHost tanımlaması :

ServerAdmin info@proje2.com
ServerName proje2.com
DocumentRoot /var/www/proje2


Alias /static/ /var/www/proje2/static/
WSGIDaemonProcess proje2
WSGIScriptAlias / "/var/www/proje1/proje1/wsgi.py" process-group=proje1
ErrorLog /var/log/apache/proje1/error_log
TransferLog /var/log/apache/proje1/access_log
...

Burada öenmli olan 8 ve 9. satırlar. 8. satırda proje için bir Process tanımlaması yapıyoruz. 9. satırda ise bu processi projemize atama işlemini yapıyoruz. Eğer bu tanımlamaları yaparsanız bir sunucu üzerinden istediğiniz kadar projeyi çalıştırabilirsiniz.

18 Eylül 2014 Perşembe

Pushover Kullanımı

Pushover, Telefona bildirim almanızı sağlayan bir servistir. Bunun için kullanımı oldukça basit olan bir api sağlamaktadır. Bu yazıda pushover apisinin Python ile nasıl kullanıldığından bahsedeceğiz?
Yapmamız gereken ilk önce https://pushover.net/ adresini ziyaret ederek üye olmak. Üye olduktan sonra ana sayfada size bir key verildiğini göreceksiniz.
Bize verilen keyi birazdan kullanacağız. Ama ondan önce resmin altında gördüğünüz Register an Application linkinden bir uygulama oluşturmamız gerekiyor. Zorunlu olan alanları doldurduktan sonra Create Application diyerek uygulamayı oluşturuyoruz.
Ve bize bu uygulamayı kullanabilmek için bir token veriliyor.
İşte bize gerekli olan kullanıcı key'ini ve uygulama token'ini elde ettik. Bundan sonra Device Clients sayfasından uygulamayı telefonumuza indirip kullanıcı girişi yapıyoruz. Şimdi apiyi kullanabiliriz. Pushover için Python ile yazılı kütüphane mevcut. İlk önce onu kurmalıyız.
sudo pip install python-pushover
Pushover kullanabilmek için bu kütüphaneyi kullanmak zorunda değilsiniz. requests kütüphanesini kullanarak isteği kendiniz de yapabilirsiniz. Ama kullanımı daha basit olduğu için bu kütüphaneyi kullanacağız. Basit bir şekilde kullanımı şöyle:
from pushover import Client

client = Client("User Key", api_token="Api Token")
client.send_message("Test içeriği", title="Test Başlığı")
Eğer her şey yolunda ise bu programı çalıştırdığınızda telefonunuza bildirim gelmiş demektir. Eğer gelmedi ise adımları tekrar gözden geçiriniz. Daha ayrıntılı bilgiye https://pushover.net/api adresinden ulaşabilirsiniz.

Kaynakça

3 Eylül 2014 Çarşamba

Django 1.7 ve Migrations

Ve Django'nun 1.7 sürümü yayınlandı. Bu bizim için çok anlam ifade ediyor. Çünkü artık biz de Migration özelliğine sahibiz. Veritabanımızda oluşturmuş olduğumuz tablolara sütünlar ekleyebilir veya silebiliriz. Bildiğiniz gibi Django'nun 1.7'den önceki sürümünde bir tablo sadece bir kere oluşturuluyordu. Yani projeyi yaptıktan bir süre sonra tablo üzerinde değişiklik yapmanız demek tablo içerisindeki verileri kaybetmeniz demektir. Güncellenmiş halini yeniden oluşturmak için tabloyu silerek tekrardan oluşturmanız gerekiyordu. İşte bu sorun 1.7 ile birlikte gelen Migration ile ortadan kalktı.