“Matrisler ve Kriptoloji” üzerine de biraz Python

Geçtiğimiz cuma günü, matematik dersinin sonlarına doğru hocamız bakın matrisler aynı zamanda şu işe de yarıyormuş diye “Matrisler ve Kriptoloji” adlı matematik kitabında bir bölüm okudu. Okan’a baktım, o da bana baktı. Beyinde kıvılcımlar, düşünmeler … bir anda EVET! dedim.(tabi içimden) Hemen koşuldu kitabın o bölümü ele geçirildi.

Neyse meğerse soruları çok kolay olan matrislerin ciddi işe yaradığı bir nokta varmış o da kriptoloji. Çok köklü bir araştırma yapmadan okuduğuma ve anladığıma göre şu an anlatacaklarım kriptoloji teknolojisinin belki de ilk adımlarıdır. Hatta kesin kırma yolları da vardır. Ama sizin de eğleneceğinizi düşünüyorum. (Oturup bundan esinlenmek gerek, kendinizi tekrar etmek yerine)

Mantık aslında çok basit. Her karakter için bir integer belirliyorsunuz. Aynen şöyle:

A B C D …
0  1  2 3 …   gibi

Sonra göndereceğiniz yazıyı belirliyorsunuz:

Y -> 27
O -> 17
K -> 13
U -> 24
Ş  -> 22

betiğimiz bu sayı dizisini oluşturuyor otomatik, sonra bunu bir matris yapıyor. Şöyle:

[ 27 13  22 ]
[ 17 24  34 ] (satırın 2 gelmesi için 34 otomatik eklenmeli.)

Sonra bir anahtar matrisi ile bunu çarpıyorsunuz:

[1  2]
[3  5] gibi

Matris çarpımı için 11. sınıf Matematik kitabınız duruyorsa bakabilirsiniz. :) Ya da vikiye:

Her birimi toplam karakter sayısının bir fazlasının moduna alırsanız (örneğin 35), elinize şifrelenmiş bir matris kalacaktır. Bunu geri sayı dizisine çevirebilirsiniz.

Gelelim şifreyi çözmeye!

Bildiğiniz gibi matrisleri çarptıktan sonra tersi ile çarparsanız eski haline döner. Biz de aynısı yapıp anahtar matrisin tersi ile şifrelenmiş matrisi çarpacağız bir daha moddaki değerini bulursak elimize ilk girdiğimiz sayı dizi kalır. Artık geri çevirebilirsiniz.

Oynaması çok eğlenceliydi. Derseniz ki nasıl yapılır Python ile şurada benim yaptığım, şurada ise Okan’ın bir sürü karakter destekli sürümüne(benim betiği modifiye etti. :) ) ulaşabilirsiniz. (Bu arada kodlar tamamen 1 saatlik uğraşmanın ürünüdür, saçma berbat kodlama olabilir.)

Bu peki nasıl geliştirilir ? Oturup düşünmek gerek(anahtar matrisi büyütmek, karmaşıklaştırmak), bunun üzerine hayatını adayan uğraşan bir sürü profesyonel insanlar olduğunu unutmayın!

 

 

Apache + Django + mod_python

Bu 3′lüyü yan yana getirmek benim için zordu. Fakat en sonunda bunu başardım. Diğer sitelerdeki gibi sadece konfigürasyonu yazıp, bırakmayacağım. Hepsini tek tek adımlar şeklinde yazdım. Süreç kısacası Django projesi oluşturup bunu Apache ile ilişkilendirmeniz.

1. Edinmek:

Django, Apache ve mod_python üçlüsünü indirmemiz gerek. (Bu adımlar sadece Pardus içindir. Diğer dağıtımlar hakkında bir şey diyemeceğim.)

sudo pisi it Django apache mod_python

2. Django işine başlamak ve bitirmek:

Dikkat: Projeyi oluşturmadan önce lütfen django projenizi koyacağınız bir klasör oluşturun ki Apache’de sıkıntı yaşamayın.

Bir Django projesi oluşturmamız gerek.

django-manage.py startproject newsite

“/home/tdgunes/django/mysite”‘da duruyor diyelim.

Ve Django Test Sunucusu’nun çalışıp çalışmadığını kontrol edebilirsiniz..

python manage.py runserver

3.  Apache’yi Ayarlamak:

Konsola tek tek yazın:

cd /etc/apache2/modules.d/

sudo nano 16_mod_python.conf

Sonra alttakileri dosyanın en sonuna yazın.

<Location “/”>

SetHandler python-program

PythonHandler django.core.handlers.modpython

PythonPath “['/home/yourname/django/] + sys.path ”

SetEnv DJANGO_SETTINGS_MODULE newsite.settings

PythonDebug On

</Location>

4. Apache’yi çalıştırmak:

Yazın:

sudo service apache start

Her açılışta çalışmasını istiyorsanız:

sudo service apache on

ya da servis yöneticisinin plasmoidini kullanabilirsiniz.

Hepsi bu kadar. Tüm bu parçaları yerine koymak zordu fakat şu an bu yöntem ile sunucunuz sorunsuz bir şekilde çalışmalı.

Python’da Liste Mantığı

Geçen günlerde  bir e-posta aldım. E-posta’da bir listenin kopyasının nasıl yapıldığı soruluyordu. Ve ‘a=b’ gibi bir yöntemin işe yaramadığı belirtiliyordu. Birkaç deneme ve Osman Karagöz ile konuşmamdan sonra işin mantığını bir de buradan açıklamak istedim.

#İlk önce iki liste belirleyelim

a = ['1','2','3','4']
b = [ ] #bu liste boş

#Şimdi b'yi a'ya eşitleyelim

b=a

#Çıktılarını alalım

print b
print a

#Şimdi a'daki tüm elemanları silelim

for i in range(4):
    a.pop(0)

# Bir daha çıktı alalım

print b
print a

Sorun bu son çıktıların ne olacağı idi. İlk cevap a’nın boş, b’nin dolu olması olarak düşünebilirsiniz. Fakat iki liste de boş olacaktır.

b=a dediğimizde a’nın verilerine bağlantı açmış oluyoruz. Yani ikisinden birinden bir veri silersek o zaman ikisinden de silinmiş olacaktır. Eğer bir veri eklersek ikisine de eklenmiş olacaktır. Peki tam bir kopyalama istersek ne yapmalıyız ?

for i in a:
    b.append(i)

dersek a’nın tam bir kopyasını b’de sahip olacağız.

İyi Pythonlamalar!

Süpriz!

Evet, süpriz!

Geçen yıl PyGuguk adında bir guguklu saat yaptığımı hatırlıyorum. Tabi amatör bir uygulamaydı. Beklerken ana döngüyü bölemediği için donup kalıyordu ve kapatmak imkansızdı. Kontrolcu projesi ile uğraşırken öğrendiğim QThread ve Guguk için gereken QTimer ile artık guguklu saatimiz donmuyor, güzelce ötüyor.

Ses çalmak için Phonon kütüphanesini kullanıyorum. Fakat nedense Pardus’daki PyQt’de Phonon desteği yok. O yüzden Pardus için eğer Phonon kütüphanesini bulamazsa PyGame’e geçebilecek.

Guguk projesi ne yapıyor, her saat başı saat kadar ötüyor ve bir pencere çıkarıp size ‘Guguk!’ diyip saati söylüyor. Ayrıca guguklama işlemini durdurup susup oturmasını sağlayabilirsiniz.  Başlattığınızda siyah G harfi kırmızı oluyor ve çalışmaya başladığını haber veriyor.

Guguk projesini şuradan bulabilirsiniz.

Ve diğer süpriz:

Artık yazılarımın aynısı İngilizce olarak da bulabilrsiniz. Tamamen kendim çevirmeye çalıştım. Kelime kelime olmasa da anlamlarının aynı olduğundan emin olabilirsiniz.

Dil bölümünden dil değişikliği yapabilirsiniz.

__init__.py Nedir ?

Uğraştığım projelerimde genellikle yazdığım kütüphaneleri Python’un bulabilmesi bir zorluk haline geliyordu. Eğer  zorluk olmasın diye tüm kütüphanelerimi aynı klasöre atarsam o zaman da büyük bir karmaşa oluyordu. Ve karşıma “__init__.py” dosyası çıktı.

“__init__” adını Nesne Tabanlı Programlama yazımdan hatırlayacaksınız, orada bizim için nesnemizin parametrelerini tutan aynı zamanda belirlemeler yaptığımız bir tür içindekiler listesiydi. Şimdi ise “__init__.py” dosyası bizim için aynı işi görecek.

Diyelim ki ben matematik hesapları yaptırdığım bir projem var. Ve kütüphanelerim şöyle:

  • Kare için kare.py
  • Dikdörtgen içeren dikdortgen.py
  • Daire içeren daire.py
  • Küp içeren  kup.py
  • Prizmalar içeren prizma.py
  • Küre içeren kure.py

Ve biz elimizde bu tüm geometrik cisimleri 2 ve 3 boyut olmak üzere ayıralım. 2 boyutluları ikiboyut klasörüne koyalım, 3 boyutluları ucboyut klasörüne koyalım. Ve şimdi bu klasörlerin yanına “main.py”(başlangıç betiğimiz) oluşturduktan sonra dosyamızdan klasörlerden çağırmak için bu oluşturduğumuz iki klasörün içine “__init__.py” dosyayı oluşturalım ve içine hiçbir şey yazmalayalım.*

Şimdi main.py’dan “from ikiboyut.kup import *” ya da “import ucboyut.prizma as prizma” diyebiliriz. Böylece klasörlerin içinden kütüphanelerimizi rahatça çağırmış olduk.

Bu işin aynısını sys modülü ile yapabiliriz anca büyük bir karmaşa oluşabilir. Sys için ise “sys.path.append(os.getcwd()+”/ucboyut/”)” demeniz gerekiyor. Böylece başlangıç betiğiniz kütüphanelerinizi bulabilir.

Kısacası “__init__.py” ile klasörlerinizi bir kütüphane gibi düşünebilirsiniz. Kütüphanenin içindeki kütüphaneyi çağırıp, düzenli bir şekilde rahatça programınızı geliştirebilirsiniz.

Not*: Gördüğünüz üzere “__init__.py” dosyasını boş bıraktık. Eğer çok isterseniz belirlemelerinizi orada da yapabilirsiniz. “deneme = 10″ diyip, klasörün adından çağırdığınız da “import ucboyut.deneme as deneme”, “print deneme” size 10 diyerek geri dönecektir. İsterseniz nesne belirlemelerinizi de orada yapabilirsiniz.

Python’da Glob ile Dosya Yakalamak

Şu günlerde bazı açık kaynak projelerin kurulum dökümanlarına ve başlangıç betiklerine bakarken karşıma ‘glob’ isimli bir modül geldi. Meğerse ne şahane bir şeymiş, haberim yok. Efendim glob ile istediğiniz dosyaları uzantılarına göre dosya yakayalabiliyorsunuz. Nasıl mı ? Şöyle:

import glob
pdfdosya = glob.glob('/home/tdgunes/*.pdf')

ile pdf dosyalarınızı bulabilirsiniz. Eğer betiği çalıştırdığınız noktadaki dosyaları bulacaksanız yapmanız gereken

import glob, os
pdfdosya = glob.glob(os.getcwd() + '/*.pdf')

Kurulum betiklerinde genellikle .ui, .qrc gibi dosyaların derlenmesinden önce dosyaların bulunması için kullanılıyormuş. İsterseniz güzel bir betikle tüm diskteki .pdf dosyalarını da bulabilirsiniz.

Python ile dosya bulmakta böylece kolay oldu.

Python’da ‘Finally’!

İnternet’ten Python öğrenenlerde genellikle bazı konular eksik kalabiliyor. Örneğin ‘Finally’ gibi. ‘Finally’, hata yakalarken yaptığınız işlemde son adım olarak ortaya çıkan verilerin temizlenmesi olarak kullanabileceğimiz kullanışlı bir komut. Klasik ‘try:’, ‘except:’ yazdıktan sonra ‘finally:’ koyabiliyoruz demek oluyor bu. Peki nasıl uyguluyoruz bir bakalım.

a = 10
try:
    a += "10"
except TypeError:
   print 'Tipler uyuşmadı.'
finally:
   print 'Veriler sıfırlanıyor'
   a = 0

‘finally’inin kullanımı böyle. Bu kodu tanımlarsak sırasıyla:

  1. Bir a değeri belirledik ve buna 10 dedik.
  2. Sonra bir de üstüne string(yazı) olan “10″ eklemeye çalıştık.
  3. Bunun sonucunda bir ‘TypeError’ aldık.
  4. Sonra a’yı sıfırladık.

Burada merak edeceğiniz mevzu eğer ‘TypeError’ oluşmasaydı ne olacağıydı. Eğer bu hata oluşmasaydı, veriler gene sıfırlanacaktı. Finally işlemini temizleme olarak görebilirsiniz. Ama çok isterseniz, bu ifadenin altına da temizleme komutunu yazabilirsiniz. Bu tercih size kalmış.

Python ile Konsoldan Tıklanan Tuşları Yakalamak!

Nesne tabanlı programlamadan sonra bir başka merak ettiğim konu ise: Konsol tabanlı bir program yaptığımda ona verdiğim komutları, hep uzun uzun yazmam gerekiyordu. Mesela bir oyun yaptınız. Konsoldaki haritanızda ileri,geri,sağ ve sola gitmesi için durmadan “ileri,geri …” yazmanız gerekiyor.

Fakat artık direk “WASD” tuşları olsun klavyedeki her tuşla programa komutlar gönderebileceksiniz. Yapmanız gereken “tty” modülünü kullanmak fakat bu modül çok ilginç ki, programı kapattıktan sonra bile sizin klavye komutlarınızı alıyor.  Bunun yerine hem Linux, hem Windows, hem de Macintosh’larda çalışacak bir yöntem ve sadece “tty” modülüyle değil de başka modülleri de kullanmalı. Çünkü tty modülü sadece Linux’da çalışıyor ve stabil değil.

Küçük bir google araması yaptığınızda karşınıza şöyle bir site geliyor. (Macintosh desteğini denemediğim için örneklere yazmayacağım ama o siteden Macintosh desteğine bakabilirsiniz.)

İlk önce tane .py dosyası oluşturun ve onun içine şunları yazın.

# -*- coding: utf-8 -*-
class _Getch(object):
    """Gets a single character from standard input.
       Does not echo to the screen."""
    def __init__(self):
        try:
            self.impl = _GetchWindows()
        except ImportError:
            self.impl = _GetchUnix()

    def __call__(self):
        return self.impl()

class _GetchUnix(object):
    def __init__(self):
        import tty, sys

    def __call__(self):
        import sys, tty, termios
        fd = sys.stdin.fileno()
        old_settings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
            ch = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
        return ch

class _GetchWindows(object):
    def __init__(self):
        import msvcrt

    def __call__(self):
        import msvcrt
        return msvcrt.getch()

getch = _Getch()

Bunu sonra ana programınıza “form dosyanız import *” şeklinde ekleyin. Sonra kullanırken:

from alici import *
while True:
    karakter = getch().upper()
    print "Tıklanan tuş: %s"  % karakter

şeklinde yazabilirsiniz. Burada “getch().upper()” yazarken “upper()” yazmamızdaki mantık, gelen karakterin büyük ya da küçük problemi yaşamamak için hepsini büyük yapıp öyle işlemektir.  Bu yazdığınız “.getch()” bu haliyle Linux’da ve Windows’da çalışabilir.

Ayrıca bu olay PyGame gibi başka kütüphanelerle yapılabilir fakat eğer tamamen konsol tabanlı bir programda bunu istiyorsanız tek çözüm bu.

Not: Son örnekteki döngüden kurtulamazsanız kurtarıcınız “CTRL-C” olsun.

Python ile şifre oluşturmak/kullanmak

Geçenlerde bir arkadaşım bana “random” ile ilgili bir örnek gönderdi. Hatalı olan minik betiği düzeltirken aklımdan, yaptığı oyuna bir şifreli hile açan bir şey koymak geldi. Ve şifreyi kodlarda görmemesini istiyordum. “raw_input” kullanırsam başkaları tarafından görülebilecekti. Ben biraz daha profesyonel bir şey düşünüyordum. Aynı zamanda aldığı şifreyi, bir seri numaraya dönüştürüp önceki kayıt ile karşılaştıracaktı.  Kodlamaya oturduğum da benim için yaratılmış iki modül karşıma geldi. Bunlar: “getpass” ve “hashlib” idi.

	elif cevap == "sayiyigoster":
	  a = getpass.getpass()
	  b = hashlib.md5()
	  b.update(a)
          toplam = b.hexdigest()
	  print toplam
          if toplam == "d8383ab2db089aed597fc628990caa69":
	      print "Tutulan sayı: %s" % rnumber

Yukarıdaki betik arkadaşımın oynuna eklediğim bir betik. Buradan basitçe “getpass.getpass()” ve altındaki “md5″ oluşturucuyu görebilirsiniz.

İyi pythonlamalar!

Python ile .mp3 ve .midi dosyalarını açmak/dinlemek

Python ile MySQL bağlantısı yaptık bakalım şimdi python ile nasıl .mp3 ve .midi dosyalarını dinleyebiliriz. Öncelikle yapmanız gereken pygame paketini Pardus deposundan indirmek. Neden pygame’i kullanıyoruz diye bir soru sorarsanız cevabım ise Pardus deposundaki bir paket olduğu ve ek olarak başka büyük kütüphaneleri kullanmayacağımızdır. Aslında .mp3 ve .midi dosyalarını açarken pygame yerine direk “os.system(“play dosyadi”) ” şeklinde bir komut da kullanabilirsiniz ama python içinden bu işi yapmak daha mantıklı olduğunu söylemeliyim.

PyGame modülünü edindikten sonra kod yazımına sıra geldi. Basitçe internetten nasıl yapabilirim diye kendime sorduğumda şu sitede aşağıdaki kodlar yer alıyordu.

# -*- coding: utf-8 -*-
import pygame
dosya = raw_input("Dosya adı:n")
def baslat(dosya):
    clock = pygame.time.Clock()
    try:
	print "- Dosya yüklendi -"
        pygame.mixer.music.load(dosya) #dosyayı yükler
    except pygame.error:
        print "%s adlı dosya bulunamadı.n(%s)" % (dosya, pygame.get_error())
        return
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        clock.tick(30)

freq = 44100     # audio CD kalitesi
bitsize = -16    # 16 bit
channels = 2     # 1 mono, 2 stereo
buffer = 2048
pygame.mixer.init(freq, bitsize, channels, buffer)
# 0 'dan 1.0 kadar ses seviyesi
pygame.mixer.music.set_volume(0.75)

try:
    baslat(dosya)
except KeyboardInterrupt:
    # CTRL-C ile kapanırsa
    pygame.mixer.music.fadeout(1000)
    pygame.mixer.music.stop()
    raise SystemExit

Kodları sitedekine göre Türkçeleştirip, bir de “raw_input” ekledim. Ama arada bir bir daha programı açarsanız, bazen susmayı ve hata vermemeyi tercih edebiliyor.

İyi Pythonlamalar!