31-12-2011, 10:38 ö.ö. //
//
python
, java
, lisp
Bugün çok fantastik birşey gördüm, anlatmazsam ölürüm(uygun bir başlık düşünmem tüm yazıyı yazmamdan daha uzun sürdü o yüzden idare edin hehe).
Diyelim ki bir veri yapısı tasarlıyoruz, bir nodedan bir sürü başka nodea veya elemana pointerlar olacak. Bir yandan da bellek kullanımını minimum tutmak istiyoruz. Pointerları tutan arrayimizde hiç boş yer olmamalı.
Bir bitmap tutuyoruz. Büyük ihtimalle integer oluyor(Java primitive int tipi 32bit olmak zorunda mesela). Diyelim ki bu node'un n. indexine bir eleman/pointer ekleyeceksiniz. Bitmap ilk başta 0 tabii. Şu şekilde bitmap'de ilgili elemanı 1 yapıyoruz:
Buraya kadar herşey çok basit. Bu noktadan sonra bu bitmape göre 30. elemanın arrayde nereye denk geldiğini bulmamız lazım. Bunun için şu formülü kullanıyoruz:
ctpop, population count fonksiyonu, yani bir sayının iki tabanında gösterilişindeki 1 bitleri sayıyor. Bu Java'da Integer.bitCount fonksiyonu(öhm, static methodu) ile bulunabilir.
Birkaç deneme yaparak nasıl yaptığını anlayabilir ve kendimizi ikna edebiliriz:
In [2]: bmp = 0
In [3]: bmp |= 1 << 15
In [4]: ctpop(bmp & ((1<<15)-1))
Out[4]: 0
In [5]: bmp |= 1 << 21
In [6]: bmp |= 1 << 10
In [7]: ctpop(bmp & ((1<<10)-1))
Out[7]: 0
In [8]: ctpop(bmp & ((1<<15)-1))
Out[8]: 1
In [9]: ctpop(bmp & ((1<<21)-1))
Out[9]: 2
Eğer arraydeki n. yere bir eleman ekliyorsak, n'den itibaren arrayi bir kaydırmamız lazım. En büyük index her zaman arrayde de daha sonda oluyor.
Ne yaptığına bakalım. 25. elemanın arraydeki yerine bakarken, 1 << 25i hesaplıyorum ki bu aslında (2 tabanında) 1 ve yanına 25 tane 0 koymak demek. Daha sonra bu sayıdan 1 çıkararak, en sağdan itibaren(en anlamsız bitten itibaren) tüm 0ları 1 yapıyorum, ilk gördüğüm 1'i 0 yapıyorum, gerisine dokunmuyorum(bu şartlar altında geriye kalan tüm bitler 0 oluyor). Daha sonra bu sayı ile bitmap'i logical and(bazı yerlerde bitwise and diyor, aynı şeyler sanırım?) işlemine sokup ctpop yaptığımda, bitmap'de (1 << n)'den itibaren kaç tane 1 olduğunu saymış oluyorum ve bu da bana array'deki indeximi veriyor. Çok mantıklı.
Bu arada kullandığınız dile göre bu işlemi daha kolay bir şekilde yapabilirsiniz. Bazı diller(Java'da Integer.bitcount, Common Lisp'de logcount gibi) direkt olarak bitCount gibi fonksiyonlar sunuyor. Bir de ben Common Lisp'de hiç kaydır 1 çıkart falan demeden direkt "şu bitle şu bit arasında kaç 1 olduğunu say" şeklinde bir fonksiyon yazdım, bitwise trickler yapmadan, şöyle:
(defun ctpop (bitmap &key (start 0) (end 32))
(logcount (ldb (byte (- end start) start) bitmap)))
22-5-2011, 1:08 ö.s. //
//
python
, java
, ödev
, vim
, lisp
Son birkaç gündür yoğun bir şekilde GUI programlama ve Java ile uğraştım. İlk başta 2 arkadaşımla beraber basit bir chat sunucu/istemcisi yazmaya başladık(kaynak koda github depomuzdan erişebilirsiniz). Daha önceki tecrübelerimden (lisede web tasarım, daha sonra Python + GTK/QT ile arayüz denemelerim) arayüz tasarımından ne kadar nefret ettiğimi bildiğimden, bu projede ben sunucu ve istemci altyapısını hazırlamakla uğraştım. Fakat sonra bir ödev gereği, arayüz tasarımıyla da kendim uğraşmam gerekti.
Ödev Java ile yapılacaktı ve dolayıyısla arayüz olarak Swing kullandım. Başlangıç için Eclipse için WindowBuilder eklentisi ile ana çerçeve + layoutları oluşturup daha sonra elle yazdım. Bu süreçte şunu farkettim, adam gibi bir IDE, işleri daha önce tahmin edemeyeceğim kadar kolaylaştırıyor. Asıl olarak Python ile yazan biri olarak, birkaç gün öncesine kadar her işimde VIM kullanıyordum ve çok da memnundum(arayüz tasarımı yapmıyorum). Şu birkaç gün(sadece ödev için 1460 satır kod) bazı şeyleri farketmemi sağladı.
Onlarca sınıf, her sınıf için onlarca method, ve bu sınıflar arasında karışık ilişkilerin olduğu bir işle uğraşıyorsanız, iyi bir IDE şart. Dökümantasyonda geçirdiğiniz çok kısaltıyor.
Static typing çok hoş bir olay. Okula başladıktan sonra bol miktarda C(programlama yarışması) ve Java(ödevler) uğraşmam gerekti. Henüz sadece birkaç dili birşeyler üretebilecek seviyede biliyorum ve bu konuda çok da bilgili değilim, ama Python ile en çok dökümantasyon ve IDE sıkıntısı çekiyorum. Ücretli IDEleri denemedim ama denediğim tüm ücretsiz Python IDEleri Autocomplete konusunda çaresiz kalıyorlar. Python'da aşağıdaki gibi birşey görebilmek için herşeyimi(?!) verirdim:

Hatta mesela şöyle birşey yapabilseydim:

Ama yok, örneğin PyDev daha aşağıdaki kodda çakılıyor:
Daha burda bile, Class1'in methodlarını gösteremiyor. Direkt olarak Class1. şeklinde yazıp, autocomplete çalıştırırsak, methodları gösteriyor, bu iyi, fakat bu sefer de bound-unbound method farkını anlayamıyor ve bound methodları da gösteriyor. Ki bound methodlar bu şekilde çağırılamaz. Fail.
WingIDE diyenler için, personal sürümü, sanki "öyle gerekli özellikler çıkaralım ki, kimse almasın" diye düşünülerek hazırlanmış. O kısıtlı özellikleri çıkardığımızda, Vim ile de yapıyorum zaten geri kalanları. Burdan bakın. Professional sürümü de çok pahalı.
PyCharm diyenler için, Open Source lisansı ücretsiz, fakat Open Source Definition'a uyan bir projeniz olmalı. Benim yok.
Eclipse, Java'nın verdiği acıyı inanılmaz derecede hafifletiyor. Yoksa sınıflar arasındaki saçma derecede karmaşık ilişkiler başka türlü çözülemez. Python'da ise, benzer karışıklıkta tasarlanmış(muhtemelen başka bir dilde, örneğin QT için C++) bir kütüphane ile çalışıyorsanız, acınızı hafifletecek hiçbir şey yok.
Konudan biraz sapacağım ama, Python hakkında beni sinirlendiren bir başka konu da, threading ve socket olayları. Ne zaman socket veya threading kullansam, mutlaka bir problemle karşılaşıyorum ve bunu ne zaman IRC'de sorsam, mutlaka birileri Twisted kullanmamı söylüyor. Kötü alışkanlıklardan, yanlış programlamadan vs bahsedip duruyorlar. Sanki Freenode #python kanalında, içinde şöyle bir kod olan bir sürü bot varmış gibi:
if "socket" in msg or "thread" in msg:
self.reply(msg, "Use twisted!!1 bad habits good code debugging bla bla bla")
Java'da yaklaşık bir hafta kadar önce kullanılabilr bir hale getirdiğimiz chat istemci/sunucusu, dilin kendi thread ve socketlerini kullanıyor. Thread ve socket kullanımı ile alakalı dökümantasyon hariç hiçbir yere baktığımı hatırlamıyorum. Python'dan gelen birisi olarak şaşırtıcı derecede kolay ve stabil oldu.
Bir süredir kafamda kendi IRC istemcimi yazma fikri var. Şu anda yazabilmek için gerekli herşeyi biliyorum. Dün oturdum, Java ve Python'da IRC sunucusuna bağlanabilmek için gerekli en küçük kodu yazmaya karar verdim(arayüz ile beraber). Java'da, kendi socket ve thread sınıfları ve Swing ile kolayca yazdım(bu arada Swing'in ne kadar kötü gözüktüğüne dikkat, platform bağımsız olarak iğrenç gözüken bir arayüz kütüphanesi kendisi, ehehe):

Python'da QT kullandım. Fakat garip bir şekilde, ne zaman sunucudan bir mesaj gelse, QT segmentation fault veriyor:
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
Segmentation fault
IRC'de sorduğumda aldığım yanıtı tahmin edersiniz zaten.
Şimdi oturup düşünüyorum, bir yanda Java, sadece dilin kütüphaneleri ile sunucuya bağlanıp, mesaj gönderip aldığım kod, arayüz ile beraber hazır bile. Elimin altında Eclipse gibi bir IDE var. Python ile yapmak istersem, ekstra olarak uğraşmam gerekecek şeyler: PyQT'nin dökümantasyonu, Twisted'ın dökümantasyonu, Twisted'ı öğrenmek, QT Designer ile tasarımı koda çevirmek için ekstra bir işlem yapmak, daha sonra bir daha QT Designer ile değişiklik yapamamak(Eclipse + WindowBuilder ile tasarım/kod arasında değiştirmek tek tuş).
Adil olmak lazım, Java ile başta bahsettiğim projeye girişmeden önce, bunların farkında değildim. Python ile ise bu boyutta bir proje yapmadım. Küçük küçük bir sürü script(ki her biri, yazdığım satır sayısına göre işimi abartı derecede kolaylaştırıyor), en büyük projem kendi blogum.
Python bana programlamaya ilk başladığım günlerde bile birşeyler üretme imkanı verdi. Programlamaya başladığım sene(lisede yaptığım web tasarım + programlamayı saymıyorum), ilk önce kendi blogumu, daha sonra arşiv düzenleyiciyi yapabildim. Başka bir dille yapamazdım.
Şu anda static typed bir dilin bana sağladıklarını biliyorum(en azından bu projeleri yapmaya başlamadan öncekine göre çok daha iyi biliyorum). Şimdi dynamic typed bir dilin avantajlarını görmem lazım.
O yüzden IRC istemcimi her şeye rağmen Python ile yazacağım. Java ile yazarsam, kendimi tekrar etmekten başka birşey yapmamış olacağım. Twisted'ı ihtiyacım olduğu kadarıyla öğrenmeye bugün başlıyorum. Çalıştırılabilir bir hale gelir gelmez yorumlarımı buraya yazacağım.
(Bu arada Twisted'da IRC istemci protokolü hazır olarak var)
VIM hakkında
Vim hakkında da birkaç birşey söyleyeyim hazır IDE/Editor muhabbetine girmişken. Yaklaşık 7-8 aydır(sanırım) Vim kullanıyorum, ve şu dakikadan sonra Vim'siz hiçbir şey yazamaz oldum. Maillerimi Vim ile yazıyorum(sylpheed), bloga yazıları Vim ile giriyorum(kendi eklentim), Eclipse'de Vim eklentisi kullanıyorum(o olmasa Eclipse kullanamazdım), Lisp ile uğraştığımda, Emacs kullanmam gerekiyor ve Emacs'i vimpulse ile kullanıyorum. Şöyle iyi böyle güzel diye anlatmayacağım, resmen bağımlı oldum. Arkadaşların, normal IDE/Editorlerde nasıl yazdıklarını görünce duygulu anlar yaşıyorum.
Bu yüzden IDE seçerken dikkat ettiğim konulardan biri de Vim desteği(veya eklentileri) oluyor. Eclipse o açıdan(viPlugin sağolsun) çok başarılı. Söz konusu Java olduğunda düşünüyorum da, Eclipse olmasa herhalde hiçbir şey yazamazdım.(bu arada WingIDE Vim tuşlarını destekliyormuş, ne kadar başarılıdır bilmiyorum)
13-3-2011, 2:12 ö.s. //
//
python
, java
Çarşamba ve perşembe günleri kardan dolayı tatildi, cuma günü 2 saat derse girdim, cumartesi ve pazarla beraber 5 gün tatil yapmış gibi oldum. Birkaç fikrimi koda dökmek için fazlasıyla zamanım vardı.
Arşiv düzenleyiciye klasör dinleme özelliğini sonunda ekledim. Bir süredir üzerinde düşünüyordum ama birkaç şeyden dolayı bir türlü başlayamamıştım. Birincisi, kaynak kod aşırı derecede karışık, yeniden geliştirilebilir bir şekilde yazılmamıştı. Birşey eklemeyi bırak, birkaç gün sonra kendim okuduğumda kodda ne olup bittiğini anlamıyordum. Tüm programı neredeyse yeniden yazdım.
Çok daha esnek ve anlaşılabilir bir yapı oluşturdum. Büyük ihtimalle bundan sonraki güncellemeler çok daha kolay olacak. Tüm yapıyı değiştirmemin bir sebebi de klasör dinleme özelliğinin bazı şeylere ihtiyaç duymasıydı.
Klasör dinleme demişken, bu konuda şaşırtıcı derecede fazla alternatif var. inotify, fam, gamin, watchdog, fsmonitor, pyfilesystem .. Bunların hepsini az çok kurcaladım. En son istediğim basitlikte/yeterlilikte fsmonitor kullandım.(FF'de yardımcı olan herkese teşekkürler. İlgili feed.)
Yeni sürümde henüz arayüz yok, tüm yapıyı değiştirince arayüz kısmı problem oldu bu sefer. Eğer arayüz yaparsam, gtk ile değil de wx ile yapacağım sanırım. gtk'da arkaplanda bir işlem yaparken arayüzü güncelleme konusunda çok sıkıntı yaşadım. Çalışan fonksiyon arayüzü güncellemek için başka fonksiyonları çağırsa bile, fonksiyon çalışmasını bitirmeden arayüz güncellenmiyor. Arayüzü güncellemek için, belirli aralıklarla fonksiyonu durdurmak gerekiyor(örneğin döngüdeki her bir adımda, yield ile bir değer döndürüp, gobject.idle_add(task) ile döngünün ilerlemesi sağlanabilir). Belki wx'de daha kolaydır.
Github alanımdan indirebilirsiniz. System tray'de duracak basit bir arayüzden sonraki adım, yanlış etiketleri düzenlemek ve eksik etiketleri tamamlamak olacak sanırım.
Design patterns
Öğrenmek istediğim birkaç konu, başlamak istediğim birkaç kitap vardı. Hazır esnek, geliştirilebilir, anlaşılabilir program yazmakta sıkıntı yaşıyorken, Head First Design Patterns'a başladım ve şunu farkettim, OOP belki yeni başlayanlar için FP kadar zor değil fakat yeterince esnek/anlaşılır/geliştirilebilir bir yapı kurmak zor bir olay. Design patterns ile ilgilendikçe şunu farkettim, bu patternlar OOP'de çok karşılaşılan problemler için üretilmiş* ve aslında heryerdeler(böyle mi yazılıyor). Örneğin daha önce birkaç blog/feed'de sövdüğüm java.io decorator dolu. Twisted factory/reactor kullanıyor vs. Ben de son arşiv düzenleyicinin dosya izleme ve gerekli sinyalleri gönderme kısmında observer kullandım(daha çok öğrenme amaçlıydı ama güzel oldu).
Fonksiyonel programlamaya karşı sebebini açıklayamadığım bir ilgim var. Neredeyse her gün OO programlama yapmama rağmen(dersler gereği, halbuki hiç FP yapmıyoruz) OOP bilmiyormuşuz bunu farkettim. Aynı FP gibi, prensipleri vs. varmış. C ile uğraştığımız bu dönem OOP'in bir teknoloji değil, teknik olduğunun az da olsa farkına varmıştım ama design patterns ile küçük çaplı bir aydınlanma yaşadım resmen.
Design patterns, oop vs. demişken, python'da tip kontrolleri ver encapsulation ile alakalı: differences between isinstance() and type() in python, what is the best way to check the type of a python variable?, alex martelli'nin design patterns in python sunumu.
Vim için markdown önizleme
Vim için python ile eklenti yazma olayını biraz kurcalamıştım, geçen aklıma geldi, bloga vim ile yazı nasıl ekleyebilirim?
Aslında genel olarak, vim ile subprocess.Popen() fonksiyonunu çağırabildikten ve vim.current.buffer[:] ile buffer'ı alabildikten sonra, gerisi Python. Şimdilik yazı eklemeyi yapamadım ama markdown için önizleme eklentisi yaptım.
Henüz kurulum için hazır değil ama, so: markdownpreview.vim ile ekledikten sonra, :call MarkdownPreview() ile önizlemeyi görebilirsiniz. Birkaç problem var, birincisi, buffer'dan türkçe karakterler garip bir şekilde geliyor. Onunla uğraşmak lazım. İkincisi de, bir preview ekranını kapatmadan bir daha çalıştırırsanız, bir ekran daha açılıyor. Bir ara düzelteceğim. Önizleme ekranı gtk ile yapıldı.
Kaynak kod github alanımda. Bu arada, vim'e python ile eklenti yazma hakkında resmi kaynak.
Bunların dışında blogda da birkaç iyileştirme yaptım ama önemli bir değişiklik yok.
Bundan sonra yazmayı planladıklarım: Editor(vim) vs. IDE muhabbeti ve Pardus pisi paket yapımı ile alakalı birkaç şey.
Okunacaklar: A Curious Course on Coroutines and Concurrency(evet hala okuyamadım), Before you start learning Lisp, Code like a pythonista: Idiomatic Pytohn, Intermediate and Advanced Software Carpentry in Python, Why why functional programming matters matters.
23-12-2010, 5:11 ö.s. //
//
java
, ödev
Bugün bil113 final için birkaç satır birşeyler yazdım, Deitel'den Java: How to Program'a baktım biraz. Deitel'in Python kitabı rezaletti, ama bu iyiymiş(Amazon'dan da çılgın puanlar almış zaten). Recursion, searching and sorting bölümlerinin alıştırmalarını falan çözdüm. Kağıt üzerinde yine bildiğimizden çok az puanlar alacağız ama, neyse..
Hazırlık için çözülebilecek bazı klasik basit problemler:
Aksini belirttiklerim hariç, çözümlerim bu ve şu dosyalarda(main methodları testlerim için). Sort.java dosyasındaki düzenleme methodların ilk bakışta arrayi değiştirmesi gerekirken aslında neden değiştirmediği(ya da hangi arrayi değiştirdiği) de düşünülebilir. İlk başta anlam verememiştim. Tam sınav sorusu bence.
Bunların dışında, codingbat'deki sorular güzel. Hepsi bittikten sonra çözümlerini yazacağım buraya.
Bu arada, biraz konu dışı olacak ama, Python'da tek satırda quicksort, ibretlik:
def qsortr(list):
return [] if list==[] else qsortr([x for x in list[1:] if x < list[0]]) + [list[0]] + qsortr([x for x in list[1:] if x >= list[0]])
Bu arada(2), bu yazıyı aşağıda ekran görüntüsünü görebileceğiniz programla ekliyorum:

Bunu da yine fizik finalinden önce yazmıştım. Burda, adres satırı Django admin'de olduğu gibi, yazı başlığından otomatik olarak üretiliyor. Henüz bazı durumlarda yanlış sonuçlar verebiliyor. Tek tuşla yazılı django development server'da ekliyorum, kontrol edip, web'e tıklıyorum ve bir daha gönderiyorum. Çok pratik oldu. Normalde localde admin panelinden yazıyı ekleyip, herşey tamamsa, webe kopyalıyordum. Şimdilik sadece benim yönetici panelimde çalışsa da, biraz düzenlemeyle istediğim esnekliğe getireceğim programı. Daha sonra birkaç ekleme daha yapıp burada yayınlayacağım yine.(örneğin dosya upload işini daha kolaylaştıracak birşeyler ekledikten sonra)
Yazı eklemeyi daha da kolay hale getirebilmek için önceki projelerimden bkz. nautilus için ftp upload scripti
16-12-2010, 7:25 ö.s. //
//
java
, ödev
Ödevi kısaca başlıktaki gibi özetleyebiliriz. Bir yol haritamız var, verilen iki nokta arasındaki tüm yolları bulup, yolun ne kadar sürdüğünü hesaplamamız istendi.
Ödev hakkında daha detaylı bilgi, girdi formatı, vs. için föyü şurdan indirebilirsiniz.
Benim uyguladığım iki yöntem vardı, iki şekilde çözdüm yani ödevi. Bir tanesi, breadth-first search algoritmasıydı. Wikipedia'daki kodu ödeve uyarladım. İkinci yöntem de, kendi "recursive" yöntemdi.
Ödevi asistanlara gönderdiğim haliyle burdan indirilebilir.
Onun dışında, 2. lab sınavındaki 4. sorunun çözümü de burda. Bence bu sınavdaki en/tek zor ve zevkli soruydu. Kısaca, belirtilen dosyanın içinden belirtilen kelimelerin kaç kere geçtiğini bulan bir program. Girdi formatı tam olarak sorudaki gibi olmalı, fakat soru elimde olmadığından formatı yazamıyorum, hueahea.
Bu arada unutmadan, kullanılan dil Java.