<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>söz uçar, yazı kalır</description><title>Fatih Erikli</title><generator>Tumblr (3.0; @fatiherikli)</generator><link>http://blog.fatiherikli.com/</link><item><title>Underscore.js ile hayatınızı kolaylaştıracak fonksiyonel programlama araçları</title><description>&lt;p&gt;&lt;a href="http://underscorejs.org/" target="_blank"&gt;Underscore.js&lt;/a&gt; javascript ile fonksiyonel programlamayı kolaylaştırmak amaçlı geliştirilen bir kütüphanedir. &lt;a href="http://documentcloud.github.com/backbone/" target="_blank"&gt;Backbone.js&lt;/a&gt;&amp;#8216;in de geliştiricisi olan &lt;a href="http://www.documentcloud.org/home" target="_blank"&gt;DocumentCloud&lt;/a&gt; tarafından yürütülen bir projedir. Hatta underscore.js için backbone dökümantasyonunda -hard dependency- olarak belirtilmekte. Yani backbone.js&amp;#8217;yi kullanırken projenize underscore.js&amp;#8217;i de dahil etmek zorundasınız.&lt;/p&gt;
&lt;p&gt;Underscore.js üzerinde çeşitli liste, nesne ve fonksiyon araçları bulunmakta. Bunların içinden en hoşuma gidenlerini buraya yazacağım.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;All &amp;amp; Any&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bu fonksiyonlar python&amp;#8217;da da built-in olarak bulunmakta. Bazen gerçekten çok faydalı olabiliyor.&lt;/p&gt;
&lt;p&gt;All fonksiyonu verdiğiniz listenin içindeki değerleri bakarak boolean kontrolü yapmakta. Eğer hepsi True ise fonksiyon True olarak dönüş yapar, değil ise False. Any ise listenin içinde en az bir tane True değer varsa True döndürmekte.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_.all([1,true,false], _.identity); // false&lt;br/&gt;_.all([1, true, true], _.identity); // true &lt;br/&gt;_.any([1, true, false], _.identity); // true &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;_.identity sizi yanıltmasın. Verdiğiniz değerin aynısını geri döndüren bir fonksiyondur. Bunun yerine kendi fonksiyonunuzu yazıp gelen parametreye göre boolean bir değer döndürebilirsiniz.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pluck&lt;br/&gt;&lt;/strong&gt;Map fonksiyonunun bir kısa yolu diyebiliriz. Diyelim ki içinde objeler olan bir listeniz var ve bu liste içindenki objelerden sadece bir özellik alarak yeni bir liste oluşturmak istiyorsunuz. Bunu ilk önce map, sonra da pluck ile yapalım;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var buddies = [ &lt;br/&gt;    {name: 'fatih', location: 'istanbul'}, &lt;br/&gt;    {name: 'ramazan', location: 'istanbul'}, &lt;br/&gt;    {name: 'yigit', location: 'istanbul'}, &lt;br/&gt;]&lt;br/&gt;_.map(buddies, function (item) { return item.name });&lt;br/&gt;&amp;gt;&amp;gt; ["fatih", "ramazan", "yigit"]&lt;br/&gt;_.pluck(buddies, 'name'); &lt;br/&gt;&amp;gt;&amp;gt; ["fatih", "ramazan", "yigit"]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gördüğünüz gibi map ile isimleri almak için ayrıdan bir fonksiyon yazdık. Pluck tam olarak bunun kısayolu. Ayrıdan bir fonksiyon yazmadan direk bir obje içinden attribute alarak liste oluşturabilmektesiniz. &lt;/p&gt;
&lt;p&gt;Ayrıca bunu python&amp;#8217;da operator.attrgetter metoduyla yapabilmekteyiz.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shuffle&lt;br/&gt;&lt;/strong&gt;Adından da anlaşılacağı üzere verdiğiniz listeyi randomize eden bir fonksiyondur. &lt;a href="http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle" target="_blank"&gt;Fisher–Yates shuffle&lt;/a&gt; algoritmasına göre sıralamaktaymış.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;_.shuffle(["fatih", "ramazan", "yigit"]);&lt;br/&gt;&amp;gt;&amp;gt; ["ramazan", "fatih", "yigit"]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bunlar liste ya da javascript&amp;#8217;teki terimiyle Array fonksiyonlarıydı. Şimdi ise biraz daha fonksiyonel programlama temelli olanlarından bahsedeceğim.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Memoize&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bir optimizasyon pattern&amp;#8217;ı olan &lt;a href="http://en.wikipedia.org/wiki/Memoization" target="_blank"&gt;Memoization&lt;/a&gt;&amp;#8216;ı kolaylaştıran bir fonksiyondur. Basit bir şekilde açıklayacak olursak; diyelim ki bir hesaplama fonksiyonunuz var. En klasik örneklerinden fibonacci. Memoize edilen bir fonksiyonda verdiğiniz parametreye göre hesaplama bir kere yapılır, belleğe alınır ve bir daha bu fonksiyonu aynı parametre ile çağırdığınızda tekrar hesaplamak yerinde direk bellektekini size döndürür. Bu işlemin adı &lt;a href="http://en.wikipedia.org/wiki/Lazy_evaluation" target="_blank"&gt;Lazy Evaluation&lt;/a&gt;&amp;#8216;dır.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var calculate = function (number) {&lt;br/&gt;    console.log('calculating...');&lt;br/&gt;    return number * number;&lt;br/&gt; }&lt;br/&gt;var lazy_calculate = _.memoize(calculate);&lt;br/&gt;lazy_calculate(10);&lt;br/&gt;&amp;gt;&amp;gt; calculating...&lt;br/&gt;&amp;gt;&amp;gt; 100&lt;br/&gt;lazy_calculate(10);&lt;br/&gt;&amp;gt;&amp;gt; 100&lt;br/&gt;lazy_calculate(10);&lt;br/&gt;&amp;gt;&amp;gt; 100&lt;br/&gt;lazy_calculate(20);&lt;br/&gt;&amp;gt;&amp;gt; calculating...&lt;br/&gt;&amp;gt;&amp;gt; 400&lt;br/&gt;lazy_calculate(20);&lt;br/&gt;&amp;gt;&amp;gt; 400 &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu fonksiyonun aynısını Django üzerinde &lt;a href="https://github.com/django/django/blob/master/django/utils/functional.py#L15" target="_blank"&gt;django.utils.functional&lt;/a&gt; paketinde bulabilirsiniz.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Debounce&lt;br/&gt;&lt;/strong&gt;Debouncing işlemini muhakkak ki herkes kendi yöntemleriyle yapmıştır. Açıklamak birazcık güç olacak; debounced yaptığınız bir fonksiyon çağırılmadan önce bir süre bekler. Bu süreyi siz belirlersiniz, örneğin 2 saniye. Eğer 2 saniye boyunca tekrar çağırılırsa bu süre sıfırlanır.&lt;/p&gt;
&lt;p&gt;Peki neden böyle bir şey yapayım ki diye soracak olursanız şöyle bir örnek verebilirim.&lt;/p&gt;
&lt;p&gt;Diyelim ki otomatik tamamlama özelliği olan bir arama kutusu yapıyorsunuz. Kullanıcı her tuşa bastığında bir ajax isteği gönderip uygun sonuçları getiriyorsunuz. Eğer burada ajax isteği yaparken debouncing işlemini yapmazsanız kullanıcı 8 karakterli bir kelime yazdığında sunucuya tam 8 adet ajax isteği göndermek durumunda kalırsınız.&lt;/p&gt;
&lt;p&gt;Bu problemi debouncing işlemi ile aşabilirsiniz. Debouncing yaptığınızda kullanıcının her yazdığı harf ile birlikte sunucuya istek yapmak yerine kullanıcının yazacağı kelime bittiğinde 2 saniye gibi bir süre bekleterek istek sayısını 1&amp;#8217;e indirebilirsiniz.&lt;/p&gt;
&lt;p&gt;Bir örnek yapalım;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var request = function () {&lt;br/&gt;   console.log("hello, this response from server"); &lt;br/&gt;}&lt;br/&gt;var debounced_request = _.debounce(request, 2000);&lt;br/&gt;debounced_request();&lt;br/&gt;debounced_request();&lt;br/&gt;debounced_request();&lt;br/&gt;debounced_request();&lt;br/&gt;// sonra 4 istek yapmamıza rağmen 2 saniye sonra 1 adet yanıt gelecek.&lt;br/&gt;&amp;gt;&amp;gt; 'hello, this response from server'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu işlem ile ilgili &lt;a href="http://www.illyriad.co.uk/blog/index.php/2011/09/javascript-dont-spam-your-server-debounce-and-throttle/" target="_blank"&gt;Don&amp;#8217;t spam your server&lt;/a&gt; ve &lt;a href="http://unscriptable.com/2009/03/20/debouncing-javascript-methods/" target="_blank"&gt;Debouncing javascript methods&lt;/a&gt; makalelerini okumanızı tavsiye edebilirim.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Throttle&lt;br/&gt;&lt;/strong&gt;Bu fonksiyon debouncing işlemine benzemektedir. Throttling işlemini bir fonksiyonun kullanımının zaman ile kısıtlanılması gerektiği yerlerde kullanmaktayız. Debounced edilmiş bir fonksiyon peş peşe çağırıldığında aradaki süre sizin belirlediğiniz süreden kısa ise belirttiğiniz sürenin dolmasını bekler.&lt;/p&gt;
&lt;p&gt;Örnek verecek olursak; bir refresh butonunuz var. Kullanıcı buraya tıkladığında sayfada bir bölüm refresh oluyor. Eğer buna kısıtlama getirmezseniz kullanıcı bu butona 30 kere peş peşe bastığında 30 tane istek ard arda yapılır. Bunu throttle ile aşabilirsiniz.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var request = function () {&lt;br/&gt;   console.log("hello, this response from server"); &lt;br/&gt;}&lt;br/&gt;var throttled_request = _.debounce(request, 2000);&lt;br/&gt;throttled_request();&lt;br/&gt;&amp;gt;&amp;gt; 'hello, this response from server'&lt;br/&gt;// 1 sn. bekliyoruz&lt;br/&gt;throttled_request();&lt;br/&gt;// cevap 1. sn sonra geliyor. çünkü throttle ederken 2 saniye süre verdik.&lt;br/&gt;&amp;gt;&amp;gt; 'hello, this response from server'&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Bind&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bu fonksiyon ECMAScript 5&amp;#8217;ten itibaren artık built-in olarak Javascript&amp;#8217;te bulunmakta. Ancak cross-browser bir javascript kodu yazmak istiyorsanız Underscore.js üzerinden kullanmanız daha faydalı olabilir.&lt;/p&gt;
&lt;p&gt;Diyelim ki  şöyle bir fonksiyonunuz var;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var hello = function () {&lt;br/&gt;   return "hello, " + this.name; &lt;br/&gt;}&lt;br/&gt;hello();&lt;br/&gt;&amp;gt;&amp;gt; 'hello undefined'&lt;br/&gt;window.name = 'fatih';&lt;br/&gt;hello();&lt;br/&gt;&amp;gt;&amp;gt; 'hello fatih'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gördüğünüz gibi ilk önce name öğesini istediğimizde undefined cevabını aldık. Global olarak tanımladığımız bir fonksiyonun scope&amp;#8217;u window&amp;#8217;dur. Window objesinde name tanımı olmadığı için yoktu. Tanımladıktan sonra fonksiyondan beklediğimiz cevabı alabildik.&lt;/p&gt;
&lt;p&gt;Karışık bir örnek oldu. Çünkü javascript&amp;#8217;teki this keyword&amp;#8217;u diğer dillerdeki this keyword&amp;#8217;üne hiç benzemiyor.&lt;/p&gt;
&lt;p&gt;Bunun gibi durumlarda fonksiyonları call ya da apply ile çağırarak scope&amp;#8217;unu değiştirebilmekteyiz. Call ve apply arasındaki fark call&amp;#8217;un parametreleri fonksiyon parametresi olarak, apply&amp;#8217;ın ise liste şeklinde almasıdır.&lt;/p&gt;
&lt;p&gt;Bind fonksiyonu bu işlemi daha da kolaylaştırmakta. Size apply işlemini yapan bir fonksiyon döndürmektedir. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var hello = function () {&lt;br/&gt;   return "hello, " + this.name; &lt;br/&gt;}&lt;br/&gt;hello();&lt;br/&gt;&amp;gt;&amp;gt; 'hello undefined'&lt;br/&gt;hello.apply({ name: 'fatih' });&lt;br/&gt;&amp;gt;&amp;gt; 'hello fatih'&lt;br/&gt;var binded_hello = _.bind(hello, { name: 'fatih' });&lt;br/&gt;binded_hello(); &lt;br/&gt;&amp;gt;&amp;gt; 'hello fatih'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gündelik hayattan başka bir örnek daha vermek istiyorum. Mesela backbone projelerini incelediyseniz bind ve bindAll fonksiyonlarının çok çok kullanıldığını görmüşsünüzdür. Çünkü bu işlemi yapmadan iç içe fonksiyonlar yazdığınızda this ile objeyi alıp başka bir değişkene atamak durumunda kalıyoruz. Örneğin &lt;em&gt;var self = this; &lt;/em&gt;gibi. Bu da bir hayli pis bir yöntem.&lt;/p&gt;
&lt;p&gt;Gündelik hayattan bir örnek demiştik;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var request = { &lt;br/&gt;    'result_text' : 'congratulations',&lt;br/&gt;    'post' : function () {&lt;br/&gt;       // callback fonksiyonuna scope atamasi yapiyoruz.&lt;br/&gt;       $.post('/send', _.bind(function (response) {&lt;br/&gt;           console.log(this.result_text);&lt;br/&gt;       }, this));&lt;br/&gt;       // bu sayede callback fonksiyonunda result objesini kullanabileceğiz.&lt;br/&gt;    }&lt;br/&gt;}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Burada apply ya da call kullanamazdık, çünkü callback fonksiyonunu biz değil jquery&amp;#8217;nin get methodu çağırmakta. Bind kullanmak en mantıklı çözüm.&lt;/p&gt;
&lt;p&gt;Ayrıca bu süpersonik çok amaçlı fonksiyon ile &lt;a href="http://en.wikipedia.org/wiki/Currying" target="_blank"&gt;currying&lt;/a&gt; işlemi de yapabilmekteyiz. Currying bir fonksiyonun parametrelerini önceden vererek başka bir fonksiyon oluşturmaktır.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var people = function (country, name) {&lt;br/&gt;   return 'hello ' + country + ', hello ' + name;&lt;br/&gt;}&lt;br/&gt;people('turkey', 'fatih');&lt;br/&gt;&amp;gt;&amp;gt; 'hello turkey, hello fatih'&lt;br/&gt;var turkey_people = _.bind(people, {}, 'turkey');&lt;br/&gt;turkey_people('fatih');&lt;br/&gt;&amp;gt;&amp;gt; 'hello turkey, hello fatih'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sadece bind fonksiyonunu için underscore.js&amp;#8217;yi yüklemek istemiyorsanız şu snippet&amp;#8217;i kullanabilirsiniz;&lt;br/&gt;&lt;a href="https://github.com/taylanpince/jquery-class/blob/master/src/bind.js" target="_blank"&gt;&lt;a href="https://github.com/taylanpince/jquery-class/blob/master/src/bind.js" target="_blank"&gt;https://github.com/taylanpince/jquery-class/blob/master/src/bind.js&lt;/a&gt;&lt;/a&gt;  &lt;/p&gt;
&lt;p&gt;Ayrıca Python Istanbul buluşmasında console.log&amp;#8217;u bind etme konusunda beni beni aydınlattığı için &lt;a href="http://blog.byk.im" target="_blank"&gt;Burak Yiğit Kaya&lt;/a&gt;&amp;#8216;ya teşekkürlerimi sunarım :)&lt;br/&gt;Bir de  kendisinin twitter üzerinden yazdığı bir öneri üzerine şuna da değinmek istiyorum;&lt;/p&gt;
&lt;p&gt;ECMAScript 5 ile Underscore.js üzerinde de göreceğiniz forEach, map, reduce, reduceRight, some, filter, every gibi bazı array fonksiyonları native bir şekilde gelmekte. Underscore.js bunların kontrolünü yapıp eğer browser destekliyorsa native olanı kullanmaktadır.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Önerebileceğim Underscore.js kaynakları&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://underscorejs.org/" target="_blank"&gt;&lt;a href="http://underscorejs.org/" target="_blank"&gt;http://underscorejs.org/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/" target="_blank"&gt;&lt;a href="http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/" target="_blank"&gt;http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://skilldrick.co.uk/2011/07/easy-functional-programming-in-javascript-with-underscore-js-part-1/" target="_blank"&gt;&lt;a href="http://skilldrick.co.uk/2011/07/easy-functional-programming-in-javascript-with-underscore-js-part-1/" target="_blank"&gt;http://skilldrick.co.uk/2011/07/easy-functional-programming-in-javascript-with-underscore-js-part-1/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.developerdrive.com/2012/04/an-introduction-to-underscore-js-%E2%80%93-part-1-arrays/" target="_blank"&gt;&lt;a href="http://www.developerdrive.com/2012/04/an-introduction-to-underscore-js-%E2%80%93-part-1-arrays/" target="_blank"&gt;http://www.developerdrive.com/2012/04/an-introduction-to-underscore-js-%E2%80%93-part-1-arrays/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Diğerleri&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://unscriptable.com/2009/03/20/debouncing-javascript-methods/" target="_blank"&gt;&lt;a href="http://unscriptable.com/2009/03/20/debouncing-javascript-methods/" target="_blank"&gt;http://unscriptable.com/2009/03/20/debouncing-javascript-methods/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.illyriad.co.uk/blog/index.php/2011/09/javascript-dont-spam-your-server-debounce-and-throttle/" target="_blank"&gt;&lt;a href="http://www.illyriad.co.uk/blog/index.php/2011/09/javascript-dont-spam-your-server-debounce-and-throttle/" target="_blank"&gt;http://www.illyriad.co.uk/blog/index.php/2011/09/javascript-dont-spam-your-server-debounce-and-throttle/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.digital-web.com/articles/scope_in_javascript/" target="_blank"&gt;&lt;a href="http://www.digital-web.com/articles/scope_in_javascript/" target="_blank"&gt;http://www.digital-web.com/articles/scope_in_javascript/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ejohn.org/blog/partial-functions-in-javascript/" target="_blank"&gt;&lt;a href="http://ejohn.org/blog/partial-functions-in-javascript/" target="_blank"&gt;http://ejohn.org/blog/partial-functions-in-javascript/&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://alternateidea.com/blog/articles/2007/7/18/javascript-scope-and-binding" target="_blank"&gt;&lt;a href="http://alternateidea.com/blog/articles/2007/7/18/javascript-scope-and-binding" target="_blank"&gt;http://alternateidea.com/blog/articles/2007/7/18/javascript-scope-and-binding&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.fatiherikli.com/post/24220247260</link><guid>http://blog.fatiherikli.com/post/24220247260</guid><pubDate>Sat, 02 Jun 2012 01:37:00 +0300</pubDate><category>underscore.js</category><category>debounce</category><category>throttle</category><category>lazy evaluation</category><category>bind</category><category>this</category><category>currying</category><category>partial application</category><category>memoize</category><dc:creator>lapslaps</dc:creator></item><item><title>Developer'lar için Türkçe podcast</title><description>&lt;p&gt;&lt;a href="http://ugur.ozyilmazel.com/" target="_blank"&gt;Uğur Özyılmazel&lt;/a&gt;&amp;#8216;in hazırladığı çok taze ve çok iyi başlamış bir podcast. Bugün (pazartesi) ikinci bölümü yayınlandı. Bölümün adının 001 olması sizi yanıltmasın. İlk bölüm 000&amp;#8217;dı. Podcast&amp;#8217;e giriş niteliğinde bir bölümdü.&lt;/p&gt;
&lt;p&gt;Podcast&amp;#8217;i dinlemek için devpod adındaki soundcloud hesabını takip edebilirsiniz. Ayrıca Itunes üzerinden de dinleyebilirsiniz.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://soundcloud.com/podcastmaster/sets/devpod" target="_blank"&gt;&lt;a href="http://soundcloud.com/podcastmaster/sets/devpod" target="_blank"&gt;http://soundcloud.com/podcastmaster/sets/devpod&lt;/a&gt;&lt;br/&gt;&lt;/a&gt;&lt;a href="http://itunes.apple.com/tr/podcast/devpod/id529938071" target="_blank"&gt;&lt;a href="http://itunes.apple.com/tr/podcast/devpod/id529938071" target="_blank"&gt;http://itunes.apple.com/tr/podcast/devpod/id529938071&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Eğer siz de benim gibi bir tumblr fanıysanız, tumblr üzerinden de takip edebilirsiniz;&lt;br/&gt;&lt;a href="http://devpod.tumblr.com/" target="_blank"&gt;&lt;a href="http://devpod.tumblr.com/" target="_blank"&gt;http://devpod.tumblr.com/&lt;/a&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Bu bölümde benim blogum hakkında da biraz bahsetmiş, buradan kendisine teşekkürlerimi sunuyorum. Blog post&amp;#8217;larımın okunduğunu görmek gerçekten sevindirici. Bundan sonra daha sık yazarım artık :)&lt;/p&gt;
&lt;p&gt;Bunun gibi girişimler gerçekten çok heyecan verici oluyor. Özellikle bölümün sonunda bahsedilen development içerikli türkçe blog&amp;#8217;ların tanıtımının hem herkes için çok faydalı hem de blog yazmaya teşvik edici bir şey olacağını düşünüyorum.&lt;/p&gt;
&lt;p&gt;Takipteyiz :)&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/23952871915</link><guid>http://blog.fatiherikli.com/post/23952871915</guid><pubDate>Tue, 29 May 2012 00:30:00 +0300</pubDate><category>devpod</category><category>podcast</category><dc:creator>lapslaps</dc:creator></item><item><title>Python İstanbul Mayıs buluşmasından notlar</title><description>&lt;p&gt;Bu ay da çok hareketli ve güzel geçen bir Python İstanbul buluşmasını 20 Python severin katılımıyla gerçekleştirdik. Geçen ay olduğu gibi bu buluşmada da &lt;a href="http://hipo.biz" target="_blank"&gt;Hipo&lt;/a&gt; ofisinde toplandık. Cumartesi günümüz python severlerle burada bir kahvaltı ile başladı, muhabbet ve sunumlarla devam etti. Gerçekten cumartesi günümü çok iyi değerlendirdim diyebilirim. &lt;/p&gt;
&lt;p&gt;Bu toplantıda 3 sunum yapıldı, sunumlardan birisini de benimdi. Sunumlar sırası ile şöyle yapıldı;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Pyİst geçmişi ve yön haritası (Metin Amiroff)&lt;/li&gt;
&lt;li&gt;Celery ve RabbitMQ (ben)&lt;/li&gt;
&lt;li&gt;PyPy &amp;amp; Just-in-time (JIT) compilation (&lt;a href="http://berkerpeksag.com/" target="_blank"&gt;Berker Peksağ&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Celery Sunumu&lt;br/&gt;&lt;/strong&gt;Sunumda bir &lt;a href="http://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol" target="_blank"&gt;AMQP&lt;/a&gt; protokolü implementation&amp;#8217;ı olan &lt;a href="http://www.rabbitmq.com/" target="_blank"&gt;RabbitMQ&lt;/a&gt;&amp;#8216;yu ve bunu message broker olarak kullanabilen &lt;a href="http://celeryproject.org/" target="_blank"&gt;Celery&lt;/a&gt;&amp;#8216;nin bize getirdiği kolaylıklardan bahsettik. Sunum için ayrıca bir de demo application hazırlama fırsatı olmuştu. Bununla birlikte bir de Onur Çelebi &lt;a href="http://en.wikipedia.org/wiki/Connect_Four" target="_blank"&gt;Connect 4&lt;/a&gt; oyunu için hazırladığı algoritmanın Celery halini hazırlayıp bizlere sundu. &lt;/p&gt;
&lt;p&gt;Celery sunumuna şuradan ulaşabilirsiniz;&lt;br/&gt;&lt;a&gt;&lt;a href="http://fatiherikli.com/pyist/pyist-celery.pdf" target="_blank"&gt;http://fatiherikli.com/pyist/pyist-celery.pdf&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;/a&gt;Demo uygulamayı incelemek isterseniz de;&lt;br/&gt;&lt;a href="https://github.com/fatiherikli/downforeveryoneorjustme" target="_blank"&gt;&lt;a href="https://github.com/fatiherikli/downforeveryoneorjustme" target="_blank"&gt;https://github.com/fatiherikli/downforeveryoneorjustme&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Onur Çelebi&amp;#8217;nin hazırladığı demo application&amp;#8217;a da ulaşır ulaşmaz buraya linkini koyacağım.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PyPy sunumu&lt;/strong&gt; &lt;br/&gt;Berker Peksağ hazırladığı sunumda ise &lt;a href="http://pypy.org/" target="_blank"&gt;PyPy&lt;/a&gt;&amp;#8216;ın sağladıkları, PyPy alternatifleri ve development sürecini anlattı. Ayrıca PyPy&amp;#8217;ın getirdiği avantajlardan ziyade dezavantajlarına da değindi. Hoş bir sunum olmuş gerçekten. PyPy hakında değişik bilgiler edindim. Kendisine buradan teşekkürlerimi sunuyorum :) &lt;br/&gt;Sunuma aşağıdaki linkten ulaşabilirsiniz;&lt;br/&gt;&lt;a href="http://berkerpeksag.github.com/slides/pypy-101-pyist/pypy-101-pyist.pdf" target="_blank"&gt;&lt;a href="http://berkerpeksag.github.com/slides/pypy-101-pyist/pypy-101-pyist.pdf" target="_blank"&gt;http://berkerpeksag.github.com/slides/pypy-101-pyist/pypy-101-pyist.pdf&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Python&amp;#8217;cuların kedi sevdası&lt;br/&gt;&lt;/strong&gt;Buluşma sadece sunumlardan ibaret değildi. Hatta sunumdan çok vakti hoş sohbet, geyik ve Nerd muhabbetiyle geçirdik :)&lt;br/&gt;Bunun dışında toplantıda bütün Python&amp;#8217;cuların gönlünü kazanan minik bir misafirimiz daha vardı. Daha doğrusu pek misafir denmez, ev sahibi demek daha doğru olur. Ona herkes hipo kedi diyor. Gerçi pek rahat durmadı ama olsun, toplantıya neşe kattı diyebiliriz. Ayrıca hipo kedi sayesinde community&amp;#8217;deki kedi severleri de tespit etmiş olduk. &lt;/p&gt;
&lt;p&gt;&lt;img src="http://img801.imageshack.us/img801/3453/aa1ba41816eb4f178c2a4a7.png"/&gt;&lt;/p&gt;
&lt;p&gt;Yine bir ay sonraki toplantıyı dört gözle bekliyorum. Haziranda bir Hack Day yapılması planlanıyor. Python ile uğraşan ya da merak salan herkese kaçırmamalarını tavsiye ederim :)&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/23814818783</link><guid>http://blog.fatiherikli.com/post/23814818783</guid><pubDate>Sat, 26 May 2012 23:06:00 +0300</pubDate><category>celery</category><category>pypy</category><category>python</category><category>python istanbul</category><category>rabbitmq</category><category>django</category><dc:creator>lapslaps</dc:creator></item><item><title>PyQuery: Python ile jQuery tadında html parse edin</title><description>&lt;p&gt;En sevdiğim kütüphanelerden bir tanesini daha sizinle paylaşmak üzereyim :)&lt;/p&gt;
&lt;p&gt;PyQuery elinizdeki html veriyi jQuery seçicileriyle ve fonksiyonlarıyla işlemenizi sağlıyor. Aşağıdaki gibi kullanabilirsiniz; &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from pyquery import PyQuery &lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; j = PyQuery(url="http://fatiherikli.com")&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; j("title").html()&lt;br/&gt;'Fatih Erikli'&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; j("p").length &lt;br/&gt;4 &lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; j("p").eq(0).parent() &lt;br/&gt;[&amp;lt;div.post&amp;gt;]&lt;br/&gt;&amp;gt;&amp;gt;&amp;gt; print j(".post").find("h3").html()&lt;br/&gt;short bio&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Kurulumu:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install pyquery&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dökümantasyona aşağıdaki linkten ulaşabilirsiniz;&lt;br/&gt;&lt;a href="http://packages.python.org/pyquery/api.html" target="_blank"&gt;&lt;a href="http://packages.python.org/pyquery/api.html" target="_blank"&gt;http://packages.python.org/pyquery/api.html&lt;/a&gt;&lt;/a&gt;  &lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/19644267705</link><guid>http://blog.fatiherikli.com/post/19644267705</guid><pubDate>Tue, 20 Mar 2012 23:58:27 +0200</pubDate><category>python</category><category>pyquery</category><dc:creator>lapslaps</dc:creator></item><item><title>Backbone.js, Django ve Tastypie üçlüsü ile bir scrum board uygulaması</title><description>&lt;p&gt;&lt;a href="http://img17.imageshack.us/img17/8313/d2c6a2aaa19e448c9a69d2a.png" target="_blank"&gt;&lt;img align="right" src="http://img17.imageshack.us/img17/8313/d2c6a2aaa19e448c9a69d2a.png" width="300"/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://documentcloud.github.com/backbone/" target="_blank"&gt;Backbone&lt;/a&gt; javascript ile mvc (model-view-controller) iskeleti üzerinde genişleyebilir (scalable) uygulama geliştirmenizi sağlayan bir kütüphanedir. Underscore.js ve jQuery ile birlikte kullanılmaktadır.&lt;/p&gt;
&lt;p&gt;Uzun zamandır backbone ile scrum board tarzı bir şey yapasım vardı. En sonunda yaptım, ve kodlarını github üzerinde açtım. Aşağıdaki linkten inceleyebilirsiniz;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://scrumboard.herokuapp.com/" target="_blank"&gt;&lt;a href="http://scrumboard.herokuapp.com/" target="_blank"&gt;http://scrumboard.herokuapp.com/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Heroku üzerinde free olarak yayınladığım için biraz yavaş olabilir. O yüzden siz en iyisi aşağıdaki gibi bilgisayarınıza kurupta çalıştırın :)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/fatiherikli/scrumboard.git&lt;br/&gt;$ cd scrumboard&lt;br/&gt;$ pip install -r requirements.txt &lt;br/&gt;$ python scrumboard/manage.py runserver &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;scrumboard/static/js/app dizini altındaki controllers.js, views.js ve models.js dosyalarını inceleyebilirsiniz.&lt;/p&gt;
&lt;p&gt;Ayrıca kodlara aşağıdaki linkten ulaşabilirsiniz. Hatta hoşunuza gider ve forklarsanız geliştirmeye birlikte devam edebiliriz :)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/fatiherikli/scrumboard" target="_blank"&gt;&lt;a href="https://github.com/fatiherikli/scrumboard" target="_blank"&gt;https://github.com/fatiherikli/scrumboard&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/19248054822</link><guid>http://blog.fatiherikli.com/post/19248054822</guid><pubDate>Tue, 13 Mar 2012 22:11:00 +0200</pubDate><category>python</category><category>django</category><category>backbone</category><category>scrum board</category><dc:creator>lapslaps</dc:creator></item><item><title>Python'da fonksiyonel programlama ve bir Internal DSL örneği</title><description>&lt;p&gt;Fonksiyonel programlama dilleri sadece fonksiyon kullanarak program geliştirmeye olanak tanır. Ayrıca fonksiyonların istenen değeri döndürmekten başka bir görevi de olmaz. &lt;a href="http://c2.com/cgi/wiki?FunctionalProgramming" target="_blank"&gt;Şurada&lt;/a&gt; daha da açıklayıcı bir tanım bulabilirsiniz.&lt;/p&gt;
&lt;p&gt;Python fonksiyonel bir programlama dili değildir ancak fonksiyonel programlamaya özgü bazı özellikleri desteklemektedir. &lt;/p&gt;
&lt;p&gt;Python üzerinde fonksiyonlar birer first-class objelerdir. Bu sayede fonksiyonu istediğiniz gibi saklayabilir, başka bir fonksiyon parametresi olarak alabilir, parametreleri üzerinde oynayabilirsiniz. Python&amp;#8217;da built-in olarak &lt;strong&gt;high-order functions&lt;/strong&gt; olarak bilinen verilen fonksiyon olarak parametre alan ve olarak başka bir fonksiyon veya verdiğiniz fonksiyone özgü sonuç döndüren fonksiyonlar bulunmaktadır.&lt;/p&gt;
&lt;p&gt;Aşağıda bir kaç tane teknik ve python&amp;#8217;da üzerinde html kod üretebilmek için bir Internal (embedded) &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language" target="_blank"&gt;DSL&lt;/a&gt; örneği verdim.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lambda&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lambda ile isimsiz fonksiyon (anonymous function) tanımlayabilmektesiniz. Bu size fonksiyonlarınızı çok daha kısa ve tek satırda oluşturmanıza olanak tanır. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrap_tags = lambda x, c : '&amp;lt;%s&amp;gt;%s&amp;lt;/%s&amp;gt;' % (x, c, x)&lt;br/&gt;print wrap_tags('strong', 'heey')
# &amp;lt;strong&amp;gt;heey&amp;lt;/strong&amp;gt; &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu fonksiyonu aşağıdaki gibi de yazabilirdiniz. İki fonksiyonun sonucu da aynıdır. Farkı ise Lambda ile tek satırda yazabiliyor olmanız.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def wrap_tags(x, c):
    return '&amp;lt;%s&amp;gt;%s' % (x, c, x)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Closures&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Closures bir fonksiyonun içinde verilen değere göre döndürülen başka fonksiyonlardır. Yukarıdaki örneğimizde wrap_tags adında fonksiyon yazdık. Bu fonksiyon bize verdiğimiz tag&amp;#8217;a ve text&amp;#8217;e göre html kodu yazdırıyor. fonksiyonu aşağıdaki gibi closure olarak kullanalım.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def tag_factory(tag):
    def inner(code):
        return wrap_tags(tag, code)
    return inner&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu fonksiyonun lambda şekli;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tag_factory = lambda tag : lambda code : wrap_tags(tag,  code)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tag_factory fonksiyonumuz tag parametresi almakta ve bu taga göre wrap_tags işlemini yaptıran bir fonksiyonun döndürmekte. Bu fonksiyonu aşağıdaki gibi kullanabiliriz.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print tag_factory('html')(
        tag_factory('head')(
            tag_factory('title')('SELAAM')
        )
      )&lt;br/&gt;# result is &amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;SELAAM&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;/html&amp;gt; &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Partial&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;functools kütüphanesindeki bu araç ile bir fonksiyonu önceden belirlediğiniz parametrelerle çağırıp kullanabilirsiniz. Bu işlemin adı &lt;a href="http://en.wikipedia.org/wiki/Currying" target="_blank"&gt;currying&lt;/a&gt;&amp;#8216;dir. Örnek olarak yukarıdaki closure örneğini partial methodu ile gerçekleştirelim.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from functools import partial
wrap_tags = lambda x, c : '&amp;lt;%s&amp;gt;%s&amp;lt;/%s&amp;gt;' % (x, c, x)&lt;br/&gt;HTML = partial(wrap_tags, 'html')
BODY = partial(wrap_tags, 'body')
HEAD = partial(wrap_tags, 'head')
STRONG = partial(wrap_gas, 'strong')&lt;br/&gt;UL = partial(wrap_tags, 'ul')
LI = partial(wrap_tags, 'li')

print HTML(        
          BODY(
              UL(
                 LI('Selamlar')
              )
          )        
      )&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Reduce&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yukarıdaki örneğimizde basitçe python üzerinde html kod üretmek için mini bir Internal DSL yazdık :) Ancak bir eksiği var. Html fonksiyonları yalnız bir adet parametre alıyor. Yani yukarıdaki örnekte iki adet ya da daha fazla liste öğesi içeren bir liste çıkaramıyoruz. Bunu reduce ile aşabiliriz. &lt;/p&gt;
&lt;p&gt;Reduce bir dizideki elemanların tümünü tek tek belirttiğiniz fonksiyona verip tüm elemanlarla ilgili bir sonuç çıkarmanızı sağlayan araçtır. Reduce&amp;#8217;a ilk vereceğiniz parametre iki adet parametre alan bir fonksiyon, ikincisi bir liste, üçüncüsü de sonucun başlangıç (initial) değeridir. Reduce işlemi &lt;a href="http://en.wikipedia.org/wiki/Fold_(higher-order_function)" target="_blank"&gt;folding&lt;/a&gt; olarakta bilinmektedir.&lt;br/&gt;&lt;br/&gt;Basir bir örnek yapalım;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from operator import add&lt;br/&gt;print reduce(add, range(1,10))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;operator.add fonksiyonu python&amp;#8217;daki toplama işlemidir. İki adet parametre alır ve bunları toplar. Bunu biliyoruz :) biz bu fonksiyonu reduce parametresi olarak kullanıp 1&amp;#8217;den 10&amp;#8217;a kadar olan sayıların toplamını aldırdık.&lt;/p&gt;
&lt;p&gt;Şimdi DSL örneğimize geri dönelim. wrap_tags fonksiyonumuzu aşağıdaki gibi değiştirelim.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from operator import concat
wrap_tags = lambda x, *c : '&amp;lt;%s&amp;gt;%s&amp;lt;/%s&amp;gt;' % (x, reduce(concat, c), x)&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Çıktı aşağıdaki gibidir;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print DIV(STRONG('heey '), 'selam')
# &amp;lt;div&amp;gt;&amp;lt;strong&amp;gt;heey&amp;lt;/strong&amp;gt; selam&amp;lt;/div&amp;gt; &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;operator modülündeki concat python&amp;#8217;daki string birleştirme işleminin fonksiyonudur. Reduce üzerinde bu fonksiyonu ilk parametre, *c ile aldığımız kod listesini de ikinci parametre olarak verdik. Ve problemimiz çözüldü. Bunu string fonksiyonu olan join ile aşabilirdik ama konumuz bu değil. Maksat örnek olsun :)&lt;/p&gt;
&lt;p&gt;Biraz daha geliştirelim. Fonksiyonuza keyword arguments olarak html tag&amp;#8217;ının parametrelerini aldıralım. Bu işlemi yapmak için ise bir başka fonksiyonel programlama aracı olan map&amp;#8217;i kullanacağız.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Map&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;İki adet parametre alır. Birinci parametre fonksiyondur. İkincisi ise listedir. Map listeki her elemanı verdiğiniz fonksiyon&amp;#8217;dan geçirir ve size tekrar liste döndürür. Aşağıdaki örnekle daha iyi anlaşılacaktır. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print map(lambda x : x*x, range(1,10))&lt;br/&gt;&lt;/code&gt;# [1, 4, 9, 16, 25, 36, 49, 64, 81]  &lt;/pre&gt;
&lt;p&gt;Parametre olarak verdiğimiz fonksiyon verilen sayının karesini döndürmekte. Gördüğünüz üzere 1&amp;#8217;den 10&amp;#8217;a kadar olan sayıların karesi liste şeklinde elimizde artık. Şimdi tekrar DSL örneğimize geçelim. Html tagları için parametre örneğini yapalım. Bu işlemi lambda yerine klasik fonksiyon ile yapalım.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def parameters(**p):
    def _build_parameters(parameter):
        key, value = parameter
        return ' %s="%s"' % (key, value)
    return reduce(concat, map(_build_parameters, p.items() ) , '')

wrap_tags = lambda x, *c, **p : '&amp;lt;%s%s&amp;gt;%s&amp;lt;/%s&amp;gt;' % (x, parameters(**p), reduce(concat, c), x)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu fonksiyonun lambda şekli ise;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;parameters = lambda **p : \
             reduce(concat,
                # build parameters from dict with mapping.
                map(lambda k: ' %s="%s"' % (k[0], k[1]) , p.items() ),
                '') # empty string for reduce initial.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Artık keyword-arguments olarak html parametreleri belirtebiliyoruz;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print DIV('selamlar', id='container', style='font-size:15px')
# &amp;lt;div style="font-size:15px" id="container"&amp;gt;selamlar&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Html tag&amp;#8217;ının parametreleri bize keyword-arguments olarak Dictionary şeklinde gelmekte. Biz bu dictionary objesini items metoduyla (key, value) şeklinde tuple içeren bir listeye dönüştürdük. Key parametremiz, value ise parametremizin değeri. Biz listedeki parametrelerimizi html&amp;#8217;e uygun olacak şekilde döndürüp Reduce ile düz bir string haline getirdik.&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Filter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bu işleme DSL&amp;#8217;de ihtiyaç duymadık ancak çok kullanışlı fonksiyonlardan bir tanesidir. Map ve Reduce&amp;#8217;deki gibi ilk parametre fonksiyon, ikincisi de liste olacak şekilde kullanmaktasınız. Fonksiyonunuz boolean (true/false) bir değer döndürmelidir. Filter işlemi verdiğiniz bu fonksiyona göre listenizde filtreleme yapacaktır. Aşağıdaki örnekle çok daha iyi anlaşılacaktır.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print filter(lambda x : x % 2 == 0, range(1,10))
# [2, 4, 6, 8]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bir sayının 2&amp;#8217;ye bölünüp bölümediğini kontrol eden bir fonksiyon yazdık. Ve bu fonksiyone göre sonucu False dönenleri filtreledik.&lt;br/&gt;&lt;br/&gt;Ve son olarak DSL örneğini tam olarak vereyim. Ancak bir şey belirtmek istiyorum;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dikkat. Ofiste denemeyin&amp;#160;!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Aşağıdaki örneği tamamen fantazi olsun diye veriyorum :) Zira aşağıdaki gibi partial&amp;#8217;ı partial olarak çağıran, lambda kullanıcam diye ortaya anlaşılmaz karman çorman bir kod çıkaran, yerden tasarruf olsun diye değişkenleri packing şeklinde tanımlayan bir iş arkadaşım olsa herhalde boğardım ben. Fonksiyonlar arasında hoplayıp zıplamak ne kadar eğlenceli olsa da abartmamak gerekir. pep-8&amp;#8217;e ve diğer kod standartlara küfür niyetinde bir kod yazdık :) &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# -*- coding:utf-8 -*-
from functools import partial
from operator import concat

parameters = lambda **p : \
             reduce(concat,
                # build parameters from dict with mapping.
                map(lambda k: ' %s="%s"' % (k[0].replace('_',''), k[1]) , p.items() ),
                '') # empty string for reduce initial.

wrap_tags = lambda x, *c, **p : \
            '&amp;lt;%s%s&amp;gt;%s&amp;lt;/%s&amp;gt;' % (
                x, # open tags
                parameters(**p), # tag parameters
                reduce(concat, c), # content
                x)  # close tags

HTML, HEAD, TITLE, BODY, H1, UL, LI, FOOTER, DIV = map(\        
    partial(partial, wrap_tags),
    ['html', 'head', 'title', 'body', 'h1', 'ul', 'li', 'footer', 'div']
)


print HTML(
        HEAD(
            TITLE('Python üzerinde fonksiyonel programlama')
        ),
        BODY(
            H1('Fonksiyel programlama nedir ?', style="margin:0px;", id="title"),
            UL(
                LI('Lambda Calculus', _class="first"),
                LI('High-order Functions'),
                LI('Functions as First-class Objects'),
                LI('Closures'),
                LI('Currying', _class="last"),
            )
        ),
        FOOTER(
            DIV("Her hakkı saklıdır.", id="footer")
        )
     )&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Evet, fonksiyonel programlama araçları sayesinde tüm kodumuzda sadece iki adet ismi olan fonksiyon tanımladık. Fonksiyonel programlama dillerindeki esneklik olmasa da python&amp;#8217;da gayet tatlı bir şey çıkardık :)&lt;/p&gt;
&lt;p&gt;Aşağıdaki bağlantıları da incelemenizi tavsiye ederim.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?FunctionalProgramming" target="_blank"&gt;&lt;a href="http://c2.com/cgi/wiki?FunctionalProgramming" target="_blank"&gt;http://c2.com/cgi/wiki?FunctionalProgramming&lt;/a&gt;&lt;br/&gt;&lt;/a&gt;&lt;a href="http://en.wikipedia.org/wiki/Functional_programming" target="_blank"&gt;&lt;a href="http://en.wikipedia.org/wiki/Functional_programming" target="_blank"&gt;http://en.wikipedia.org/wiki/Functional_programming&lt;/a&gt;&lt;br/&gt;&lt;/a&gt;&lt;a href="http://www.slideshare.net/adambyrtek/functional-programming-with-python-516744" target="_blank"&gt;&lt;a href="http://www.slideshare.net/adambyrtek/functional-programming-with-python-516744" target="_blank"&gt;http://www.slideshare.net/adambyrtek/functional-programming-with-python-516744&lt;/a&gt;&lt;br/&gt;&lt;/a&gt;&lt;a href="http://www.slideshare.net/newmedio/introduction-to-functional-programming" target="_blank"&gt;&lt;a href="http://www.slideshare.net/newmedio/introduction-to-functional-programming" target="_blank"&gt;http://www.slideshare.net/newmedio/introduction-to-functional-programming&lt;/a&gt;&lt;br/&gt;&lt;/a&gt;&lt;a href="http://burcudogan.com/2009/03/08/functional-programing-for-beginners/#more-46" target="_blank"&gt;&lt;a href="http://burcudogan.com/2009/03/08/functional-programing-for-beginners/" target="_blank"&gt;http://burcudogan.com/2009/03/08/functional-programing-for-beginners/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/18468195548</link><guid>http://blog.fatiherikli.com/post/18468195548</guid><pubDate>Wed, 29 Feb 2012 03:20:00 +0200</pubDate><category>python</category><category>fonksiyonel programlama</category><category>internal dsl</category><category>dsl</category><category>map</category><category>filter</category><category>reduce</category><category>partial</category><dc:creator>lapslaps</dc:creator></item><item><title>Django'da admin üzerinde çalışırken hayatınızı kolaylaştıracak iki decorator</title><description>&lt;pre&gt;&lt;code&gt;def allow_tags(func):&lt;br/&gt;    """&lt;br/&gt;    Bir ModelAdmin uzerinde yazdiginiz fonksiyonun html olarak cikti verebilmesini saglar.&lt;br/&gt;    """&lt;br/&gt;    func.allow_tags = True
    return func

def short_description(description):&lt;br/&gt;    """&lt;br/&gt;    ModelAdmin uzerinde yazdiginiz fonksiyonlara short_description atamasi yapar.&lt;br/&gt;    """
    def wrap(func):&lt;br/&gt;        func.short_description = description
        return func            
    return wrap&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Şu şekilde kullanabilirsiniz;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class FooBarAdmin(admin.ModelAdmin):&lt;br/&gt;    list_display = ('__unicode__', 'my_method')&lt;br/&gt;&lt;br/&gt;    @allow_tags&lt;br/&gt;    @short_description('Benim bold kolonum')&lt;br/&gt;    def my_method(self, obj):&lt;br/&gt;        return '&amp;lt;strong&amp;gt;selamm !&amp;lt;/strong&amp;gt;' &lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.fatiherikli.com/post/18448347621</link><guid>http://blog.fatiherikli.com/post/18448347621</guid><pubDate>Tue, 28 Feb 2012 21:57:00 +0200</pubDate><category>django</category><category>admin</category><category>modeladmin</category><category>python</category><category>decorator</category><dc:creator>lapslaps</dc:creator></item><item><title>Heroku'daki uygulamanız için SQL konsolu</title><description>&lt;p&gt;Aşağıdaki plugin sayesinde konsol üzerinden heroku uygulamanızın veritabanında sql sorguları çalıştırabilir ve sonuçlarını görebilirsiniz.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ddollar/heroku-sql-console" target="_blank"&gt;&lt;a href="https://github.com/ddollar/heroku-sql-console" target="_blank"&gt;https://github.com/ddollar/heroku-sql-console&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kurulum&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Heroku projenizin dizinine gidin ve şu şekilde plugin&amp;#8217;i ekleyin.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;heroku plugins:install git://github.com/ddollar/heroku-sql-console.git&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plugin&amp;#8217;i yüklediniz. Konsola da şöyle erişebilirsiniz.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ heroku sql&lt;br/&gt;SQL&amp;gt; select count(*) from users;&lt;br/&gt;+-------+
| count |
+-------+
|    13 |
+-------+ &lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.fatiherikli.com/post/18346691586</link><guid>http://blog.fatiherikli.com/post/18346691586</guid><pubDate>Mon, 27 Feb 2012 01:45:00 +0200</pubDate><category>heroku</category><dc:creator>lapslaps</dc:creator></item><item><title>Python üzerinde Design Patterns (Tasarım Desenleri) örnekleri</title><description>&lt;p&gt;Bu blog post&amp;#8217;unda kendi projelerimde ya da çalıştığım şirkette development sürecinde kullandığımız design pattern&amp;#8217;ları ve bu konudaki python&amp;#8217;un avantajlarına değineceğim.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design Patterns&lt;br/&gt;&lt;/strong&gt;Bu kavramın henüz türkçesi bulunmadı :) Genelde tasarım örüntüleri ya da tasarım desenleri denmekte.&lt;/p&gt;
&lt;p&gt;Design pattern&amp;#8217;lar development sürecinde sıkça rastlanan problemleri çözmek için kullanılan desenlerdir. Bunların bir -desen- olmasının sebebi problemi çözmekten ziyade probleme object-oriented&amp;#8217;ın temel felsefelerinden olan reusable (yeniden kullanılabilir) çözümler getirmektir. &lt;/p&gt;
&lt;p&gt;Gang of Four (dörtlü çete) olarak bilinen 4 kafadar 1994 yılında &lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Design_Patterns_(book)" target="_blank"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt;&lt;/strong&gt; isimli kitaplarında 3 farklı kategoride 23 farklı tasarım deseni derlemiştir. Bu kategoriler;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Creational patterns: Objelerin oluşturulması ile ilgili desenlerdir&lt;/li&gt;
&lt;li&gt;Structural patterns: Sınıflar arasındaki bağlantıları &lt;a href="http://en.wikipedia.org/wiki/Loose_coupling" target="_blank"&gt;gevşek tutmak&lt;/a&gt; ve projenin genişletebilmesini sağlayan desenlerdir.&lt;/li&gt;
&lt;li&gt;Behavioral patterns: Sınıflar ya da objeler arasında &lt;a href="http://en.wikipedia.org/wiki/Object_composition" target="_blank"&gt;composition&lt;/a&gt; ya da &lt;a href="http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)" target="_blank"&gt;inheritance&lt;/a&gt; kullanılarak iletişim kurmak için kullanılan desenlerdir.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Desen örnekleri vermeden design pattern ve object-oriented prensiplerine göre bir kaç şeyden bahsetmek istiyorum.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Design pattern&amp;#8217;lar ezberlenmemelidir. Bütün desenleri inceledikten sonra zaten ortaya çıkan problem sizi design pattern kullanmaya itecektir.&lt;/li&gt;
&lt;li&gt;Design pattern&amp;#8217;ların kullanımı abartılmamalıdır. Problem sizi zaten gerekli yerlerde design pattern kullanmaya itecektir. Zira çözümünüz bir &lt;a href="http://blog.fatiherikli.com/post/16555455350/anti-patterns" target="_blank"&gt;anti-pattern&lt;/a&gt;&amp;#8216;e dönüşebilir.&lt;/li&gt;
&lt;li&gt;Kullandığınız platformu ya da programlama dilininin getirtiği avantajları tam anlamıyla bilmeden bir deseni uygulamamak gerekir.&lt;/li&gt;
&lt;li&gt;Her sınıfın sadece &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle" target="_blank"&gt;tek bir sorumluluğu&lt;/a&gt; olmalıdır. Bunu desen örneklerinde bolca göreceksiniz. Başka sorumluluklar ayrı sınıflara dağıtılmalıdır. Bu yol inheritance değil, composition olmalıdır. Aksi takdirde object-oriented kasıcam diye ileride kodlara dönüp baktığınızda bir &lt;a href="http://en.wikipedia.org/wiki/God_object" target="_blank"&gt;god-object&lt;/a&gt; görebilirsiniz :)&lt;/li&gt;
&lt;li&gt;Burada listelediğim bir kaç desen size yetmeyecektir. Blog post&amp;#8217;unun altında bu konu ile ilgili bolca link yazdım. Ayrıca django, pika, sqlalchemy, tornado gibi tonlarca open-source yazılımların kaynak kodlarını okumanızı tavsiye ederim. Desen yuvalarıdır onlar :) buradaki kuru örnekler yerine onları okumak daha faydalı olacaktır.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;3. maddeyi biraz daha açıklamak istiyorum. Örnek olarak python&amp;#8217;da zaten built-in gelen iterator pattern&amp;#8217;ini kendimiz yazmamız aptalca olur. Diğer bir örnek ise örnek python&amp;#8217;da fonksiyonların &lt;a href="http://en.wikipedia.org/wiki/First-class_function" target="_blank"&gt;first-class&lt;/a&gt; objeler olmasıdır. Yani fonksiyonları istediğimiz saklayabilir, çalışma zamanında olarak programın akışına göre değiştirebiliriz. Bu bize çoğu pattern&amp;#8217;i uygularken inanılmaz kolaylıklar sağlamaktadır. Wikipedia&amp;#8217;daki &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern" target="_blank"&gt;strategy pattern&lt;/a&gt;&amp;#8216;in açıklamasında bunu görebilirsiniz.&lt;/p&gt;
&lt;p&gt;Python üzerinde en sık kullanılan 8 pattern&amp;#8217;in örneğini vereceğim. Bu 8 pattern&amp;#8217;in 8 pattern olmasının sebebi tamamen zannımca, kendi gözlemlerimdir.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Creational Patterns&lt;/strong&gt;     
&lt;ul&gt;&lt;li&gt;Singleton Pattern&lt;/li&gt;
&lt;li&gt;Factory Pattern&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structural patterns&lt;/strong&gt; 
&lt;ul&gt;&lt;li&gt;Decorator Pattern&lt;/li&gt;
&lt;li&gt;Proxy Pattern&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Behavioral patterns&lt;/strong&gt; 
&lt;ul&gt;&lt;li&gt;Iterator Pattern&lt;/li&gt;
&lt;li&gt;Observer Pattern&lt;/li&gt;
&lt;li&gt;Strategy Pattern&lt;/li&gt;
&lt;li&gt;Null-object Pattern&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Singleton Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bu desende bir class&amp;#8217;ın sadece bir tane instance&amp;#8217;ı olması gerekmektedir. En çok kullanılan ve en basit desenlerden biridir. Amacı aynı işi yapan bir sürü instance&amp;#8217;ın bellekte ayrı ayrı yer işgal etmesi yerine tek bir instance üzerinden iş yapmasını sağlamaktır. Genellikle database&amp;#8217; bağlanmak gibi bir kere yapılması gereken yerlerde kullanılır. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def singleton(klass):
    if not hasattr(klass, 'instance'):
        klass.instance = klass()
    return klass.instance

class Connection(object):
    def __init__(self):
        print "init..." # sadece bir kez calismali.

a = singleton(Connection)
b = singleton(Connection)
print a is b # True&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Factory Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Factory pattern&amp;#8217;i programın akışına göre belirlediğiniz sınıf ya da objeleri getiren fabrika olarak düşünebilirsiniz. Örneğin kullanılan database türüne göre bir database client&amp;#8217;i getirmek için kullanılabilir. Ya da eğer makina linux ise şu modülü, windows işe şu modülü yükle gibi&amp;#8230;&lt;/p&gt;
&lt;p&gt;Django üzerinde formset&amp;#8217;lerle işlem yaparken kullandığımız formset_factory, modelformset_factory birer factory pattern&amp;#8217;ına örnektir;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
                    can_delete=False, max_num=None):    
    attrs = { &lt;br/&gt;          'form'      : form, &lt;br/&gt;          'extra'     : extra,
          'can_order' : can_order, &lt;br/&gt;          'can_delete': can_delete,
          'max_num'   : max_num&lt;br/&gt;    }
    return type(form.__name__ + 'FormSet', (formset,), attrs)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu desende çağırırken verdiğiniz forma göre ve belirlediğiniz miktara göre form içeren bir FormSet sınıfı döndürülmektedir. Daha da basit bir örnek verecek olursak; tumblr gibi bir servis üzerindeki post tiplerine göre bize model döndüren bir factory method yazalım. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def post_model_factory(model):
    return {
        'dialog' : Dialog,
        'quote'  : Quote,
        'link'   : Link,
        'video'  : Video,
        'audio'  : Audio,
    }.get(model) or Post # eger bulunmazsa, default olarak Post modeli donduruluyor.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Decorator Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Decorator pattern&amp;#8217;i bir sınıfa onu türetmeden ya da temel yapısında değişiklik yapmadan çalışma zamanında ek özellikler eklememizi sağlayan bir desendir. &lt;/p&gt;
&lt;p&gt;Aslında Singleton Pattern örneğinde bir decorator pattern&amp;#8217;i uyguladık. Singleton olmasını istediğimiz sınıf üzerinde birazcık oynama yaptık. Decorator pattern&amp;#8217;i yaptığımız işlemin ta kendisidir&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def singleton(klass):
    if not hasattr(klass, 'instance'):
        klass.instance = klass()
    return klass.instance
&lt;br/&gt;class Connection(object):
    def __init__(self):
        print "init..." # sadece bir kez calismali.&lt;br/&gt;&lt;br/&gt;connection = singleton(Connection)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ayrıca bildiğiniz üzere python&amp;#8217;da built-in olarak decorator desteği var. Örneğin singleton pattern örneğini şu şekilde yapabilirdik.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def singleton(klass):
    if not hasattr(klass, 'instance'):
        klass.instance = klass()
    return klass.instance

@singleton # Connection artik bir class degil, instance.&lt;br/&gt;class Connection(object):
    def __init__(self):
        print "init..." # sadece bir kez calismali.&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Proxy Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Proxy Pattern orijinal class&amp;#8217;a dokunmadan, başka bir class oluşturup yeni özellikler eklememizi sağlayan bir desendir. Bunun için en iyi örnek olarak django&amp;#8217;daki &lt;a href="https://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models" target="_blank"&gt;proxy model&amp;#8217;leri&lt;/a&gt; gösterebilirim.&lt;/p&gt;
&lt;p&gt;Django dökümantasyonundan bir örnek vermek istiyorum;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from django.contrib.auth.models import User
class MyUser(User):
    class Meta:
        proxy = True

    def do_something(self):
        pass&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Iterator Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bu pattern python üzerinde built-in olarak gelmektedir. Iterator Pattern bir listedeki elemanların içerisinde dolaşmak, sonraki ve önceki elemanı bulmamızı sağlar. Bu liste sonsuz bir liste olabilir. Örneğin fibonacci serisinin tüm değerlerini bir listeye atamazsınız, ama iterator ile yaptığınızda sadece bir sonraki fibonacci sayısını istediğinizde size o sayıyı hesaplar ve getirir. &lt;/p&gt;
&lt;p&gt;En basit şekilde bir iterator deseni;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def iterator():
    yield "hey"
    yield "selam"
    yield "naber"&lt;br/&gt;&lt;br/&gt;for item in iterator():
    print item&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bir örnek yapacak olursak; bir model&amp;#8217;deki kayıtlar üzerinde hesaplama yapıp sonuçlarından bir liste oluşturmak gerekmekte.&lt;/p&gt;
&lt;p&gt;Kötü örnek;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def orders():
    result = []
    for item in Orders.objects.all():
        result.append(item.calculate()) # uzun suren bir islem
    return result &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu şekilde listenin oluşabilmesi için bütün kayıtların hesaplanması ve listeye eklenmesi gerekiyor. Ama bize sadece ilk 10 kaydın hesaplamaları gerekli. Fail :)&lt;br/&gt;Bunu aşağıdaki gibi yapmamız gerekiyor;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def orders():    
    for item in Orders.objects.all():
        yield item.calculate() # uzun suren bir islem  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ayrıca iterator&amp;#8217;lerin aşağıdaki gibi bir kullanımı da mümkündür. &lt;a href="https://bitbucket.org/chris1610/satchmo/" target="_blank"&gt;Satchmo&lt;/a&gt;&amp;#8216;nun cart modelinden örnek veriyorum;&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Cart(models.Model):    
    site = models.ForeignKey(Site, verbose_name=_('Site'))
    desc = models.CharField(_("Description"), blank=True, null=True, max_length=10)
    date_time_created = models.DateTimeField(_("Creation Date"))
    customer = models.ForeignKey(Contact, blank=True, null=True, verbose_name=_('Customer'))

    objects = CartManager()

    # her hangi bir sinifa asagidaki gibi iteration ekleyebiliyoruz.
    def __iter__(self):
        return iter(self.cartitem_set.all())&lt;br/&gt;    # ... &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu sayede sepete ait ürünleri aşağıdaki kolayca alabiliyoruz.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cart = Cart.objects.from_request(request)&lt;br/&gt;for item in cart:&lt;br/&gt;    print item # artik item bir CartItem instance'ı...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Observer Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Publish/subscribe olarakta bilinmektedir. Temel anlamda sınıflarımıza event, yani olay atamamızı sağlayan desenlerdir. Bu desende bir objenin durumunun değişmesi durumunda, dinlemekte olan belirlediğiniz gözlemcilere haber gitmektedir.&lt;/p&gt;
&lt;p&gt;Django&amp;#8217;daki &lt;a href="http://pydispatcher.sourceforge.net/" target="_blank"&gt;signal dispatcher&lt;/a&gt; kullanımı observer pattern&amp;#8217;ine bir örnektir. Django&amp;#8217;daki signals kullanımı ilgili bir örnek veriyorum;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def create_user_profile(sender, instance, created, **kwargs):
    if created:
       profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Strategy Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Strategy pattern&amp;#8217;i bir işin yapılmasının yöntemini çalışma zamanında belirlemenizi sağlar. Benim en sevdiğim desendir :)  Örneğin bir servisiniz için bir importer yazacaksınız diyelim. Yazacağınız sınıfta verileri import ettiğiniz ve nereden import edeleceği kısımlarının ayrı tutulması gerekir. Import ettiğiniz servis bir rss ya da tamamen standart dışı bir xml olabilir. Bu gibi durumlarda komple import servisiniz yerine, import edeceğiniz yere özel strategy sınıfı düzenleyip o şekilde import etmeniz gerekir. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://pika.github.com/" target="_blank"&gt;Pika&lt;/a&gt;&amp;#8216;nın connection sınıfında bu deseni görebiliriz.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ReconnectionStrategy super sinifi bos bir interface sinifidir.&lt;br/&gt;class NullReconnectionStrategy(ReconnectionStrategy):
    pass&lt;br/&gt;
class SimpleReconnectionStrategy(ReconnectionStrategy):
    can_reconnect = True
    def __init__(self, initial_retry_delay=1.0, multiplier=2.0,
                 max_delay=30.0, jitter=0.5):       
        # implement edilen yerler onemli degil, kirptim.        
&lt;br/&gt;class Connection(object):
    def __init__(self, parameters=None, on_open_callback=None,
                 reconnection_strategy=None):&lt;br/&gt;        # ...       
        self.reconnection = reconnection_strategy or NullReconnectionStrategy()&lt;br/&gt;        # ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Connection sinifinda re-connection işleminin strategy olarak alındığını görüyoruz. Burada yapılan işlemin adı &lt;a href="http://en.wikipedia.org/wiki/Object_composition" target="_blank"&gt;composition&lt;/a&gt;&amp;#8216;dur. Connection sınıfında re-connection işlemlerinin yapılması yerine re-connection işlemi yapılacak yerlerde buradaki tanım üzerinden yapılacaktır.&lt;/p&gt;
&lt;p&gt;Ayrıca zorunda olmadıkça buradaki gibi uzun uzun strategy tanımları yapmamıza gerek yok. Zaten python&amp;#8217;daki fonksiyonlar first-class objelerdir. Birazcık pitonik olmak lazım :) Aşağıdaki örnekle daha iyi anlaşılacağını umuyorum.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def urllib_strategy(url):
    import urllib2
    return urllib2.urlopen(url).read()

def requests_strategy(url):
    import requests
    return requests.get(url).content

def get_html_source(url, opener_strategy=urllib_strategy): # default urllib_strategy
    return opener_strategy(url)

print get_html_source("http://fatiherikli.com")
print get_html_source("http://fatiherikli.com",
                      opener_strategy=requests_strategy)
print get_html_source("http://fatiherikli.com",
                      opener_strategy=lambda url : "fake html source.")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bu deseni çoğu yerde görebilirsiniz. Bir örnek daha; Django&amp;#8217;daki User application&amp;#8217;ının view&amp;#8217;larındaki login view&amp;#8217;ında bu pattern uygulanmış durumda.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def login(request, template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm):
    redirect_to = request.REQUEST.get(redirect_field_name, '')
    form = authentication_form(data=request.POST)&lt;br/&gt;    # ... &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gördüğünüz üzere AuthenticationForm &amp;#8216;u view&amp;#8217;da parametre olarak almaktadır. Varsayılan olarak kendi formunu kullanıyor, ancak siz view&amp;#8217;ı çağırırken urls.py&amp;#8217;nizde kendi login formunuzu verebilmektesiniz.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;br/&gt;Null Object Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Null object pattern&amp;#8217;i olmayan bir obje üzerinde işlem yaparken programın hata vermemesini sağlamaktır. Ayrıca bu desen sayesinde gereksiz null kontrollerinden kurtulmuş oluyoruz.&lt;/p&gt;
&lt;p&gt;Bunun örneğini yine django üzerinden vereceğim. Bildiğiniz üzere django bize request.user dediğimizde bize aşağıdaki User sınıfını döndürmekte; &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class User(models.Model)&lt;br/&gt;    # ...&lt;br/&gt;    def is_anonymous(self):&lt;br/&gt;        return False

    def is_authenticated(self):
        return True&lt;br/&gt;   # ... &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gördüğünüz üzere User sınıfında is_authenticated ve is_anonymous method&amp;#8217;ları direk true-false döndürecek şekilde implement edilmiş. Bunun sebebi eğer kullanıcı login olmuşsa bu sınıf kullanılacak, login olmamış ise aşağıdaki AnonymousUser sınfı kullanılmasıdır. AnonymousUser sınıfında is_anonymous ve is_authenticated methodları tam ders durumda olacaktır. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class AnonymousUser(object):
    id = None
    username = ''
    is_staff = False
    is_active = False
    is_superuser = False    &lt;br/&gt;    # ...
    def __unicode__(self):
        return 'AnonymousUser'

    def is_anonymous(self):
        return True

    def is_authenticated(self):
        return False&lt;br/&gt;    # ... &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gördüğünüz gibi bu sınıfta bir model instance&amp;#8217;ı taklit edilmiş durumda. Bu sayede &lt;em&gt;request.user.is_authenticated&lt;/em&gt; dediğimizde None type bla bla hatasını almadan kullanıcının login olup olmadığını anlayabiliyoruz.&lt;/p&gt;
&lt;p&gt;Ayrıca bu desenin örneğini strategy pattern&amp;#8217;inin örneklerinde verdiğim pika kütüphanesinin NullReconnectionStrategy sınıfında da görebilirsiniz. &lt;/p&gt;
&lt;p&gt;Bu desenin başka bir örneğini satchmo&amp;#8217;nun cart modelinde görebilirsiniz. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class NullCart(object):
    desc = None
    date_time_created = None
    customer = None
    total = Decimal("0")
    numItems = 0

    def add_item(self, *args, **kwargs):
        pass

    def remove_item(self, *args, **kwargs):
        pass

    def empty(self):
        pass

    def __str__(self):
        return "NullCart (empty)"

    def __iter__(self):
        return iter([])

    def __len__(self):
        return 0

    def save(self):
        pass&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Bağlantılar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Software_design_pattern" target="_blank"&gt;&lt;a href="http://en.wikipedia.org/wiki/Software_design_pattern" target="_blank"&gt;http://en.wikipedia.org/wiki/Software_design_pattern&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.python.org/workshops/1997-10/proceedings/savikko.html" target="_blank"&gt;&lt;a href="http://www.python.org/workshops/1997-10/proceedings/savikko.html" target="_blank"&gt;http://www.python.org/workshops/1997-10/proceedings/savikko.html&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sourcemaking.com/design_patterns" target="_blank"&gt;&lt;a href="http://sourcemaking.com/design_patterns" target="_blank"&gt;http://sourcemaking.com/design_patterns&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.javacamp.org/designPattern/" target="_blank"&gt;&lt;a href="http://www.javacamp.org/designPattern/" target="_blank"&gt;http://www.javacamp.org/designPattern/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://c2.com/cgi/wiki?DesignPatterns" target="_blank"&gt;&lt;a href="http://c2.com/cgi/wiki?DesignPatterns" target="_blank"&gt;http://c2.com/cgi/wiki?DesignPatterns&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.blackwasp.co.uk/GofPatterns.aspx" target="_blank"&gt;&lt;a href="http://www.blackwasp.co.uk/GofPatterns.aspx" target="_blank"&gt;http://www.blackwasp.co.uk/GofPatterns.aspx&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ayrıca türkçe olarak python üzerinde design pattern&amp;#8217;lerle ilgili &lt;a href="http://yasararabaci.tumblr.com" target="_blank"&gt;Yaşar Arabacı&lt;/a&gt;&amp;#8216;nın bir yazısı bulunmakta;&lt;br/&gt;&lt;a href="http://yasararabaci.tumblr.com/post/14873752371" target="_blank"&gt;&lt;a href="http://yasararabaci.tumblr.com/post/14873752371" target="_blank"&gt;http://yasararabaci.tumblr.com/post/14873752371&lt;/a&gt;&lt;/a&gt;&lt;strong&gt;&lt;br/&gt;&lt;br/&gt;Sunumlar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.slideshare.net/guest46da5428/application-of-software-design-pattern" target="_blank"&gt;&lt;a href="http://www.slideshare.net/guest46da5428/application-of-..." target="_blank"&gt;http://www.slideshare.net/guest46da5428/application-of-&amp;#8230;&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.slideshare.net/saurabh.net/design-patterns-for-70-of-programmers-in-the-world" target="_blank"&gt;&lt;a href="http://www.slideshare.net/saurabh.net/design-patterns..." target="_blank"&gt;http://www.slideshare.net/saurabh.net/design-patterns&amp;#8230;&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/17796282445</link><guid>http://blog.fatiherikli.com/post/17796282445</guid><pubDate>Sat, 18 Feb 2012 03:32:00 +0200</pubDate><category>python</category><category>django</category><category>design patterns</category><category>singleton</category><category>factory</category><category>decorator</category><category>proxy</category><category>iterator</category><category>observer</category><category>null-object</category><dc:creator>lapslaps</dc:creator></item><item><title>Python konsolunda en son evaluate edilen değere ulaşmak</title><description>&lt;p&gt;Bildiğiniz üzere Python konsolu üzerinde bir expression yazdığınızda size sonucunu döndürmekte. Eğer sonuç üzerinde bir işlem yapmak isterseniz onu bir değişkene atamanız gerekir normal şartlarda. Ama bazen işe yaramayabiliyor. Örneğin httplib kütüphanesindeki &lt;a href="http://docs.python.org/library/httplib.html#httplib.HTTPConnection.getresponse" target="_blank"&gt;getresponse&lt;/a&gt; metodunu bir kere çağırmak durumundasınız.&lt;/p&gt;
&lt;p&gt;Her neyse, python konsolunda en son evulate edilen değere&lt;strong&gt; _ (underscore) &lt;/strong&gt;diyerek ulaşabilmekteyiz. Örnek;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; from myads.adserver.models import Advertisement
&amp;gt;&amp;gt;&amp;gt; Advertisement.objects.get(title='Adsense')
&amp;lt;Advertisement: Adsense&amp;gt;
&amp;gt;&amp;gt;&amp;gt; _
&amp;lt;Advertisement: Adsense&amp;gt;
&amp;gt;&amp;gt;&amp;gt; _.__class__
&amp;lt;class 'myads.adserver.models.Advertisement'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; _.__class__
&amp;lt;class 'django.db.models.base.ModelBase'&amp;gt;
&amp;gt;&amp;gt;&amp;gt; _.__class__
&amp;lt;type 'type'&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ayrıca &lt;a href="http://ipython.org/" target="_blank"&gt;IPython&lt;/a&gt; kullanıyorsanız aşağıdaki gibi bir kullanımlar da mümkün;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;In [1]: 9 * 9
Out[1]: 81
In [2]: 9 * 9 * 9
Out[2]: 729
In [3]: 9 * 9 * 9 * 9
Out[3]: 6561
In [4]: _1 # ilk output
Out[4]: 81
In [5]: _2 # ikincisi
Out[5]: 729
In [6]: _3 # felan
Out[6]: 6561
In [7]: _oh # output history
Out[7]: {1: 81, 2: 729, 3: 6561, 4: 81, 5: 729, 6: 6561}
In[8]: __ # son output'tan onceki output
Out[8]: 6561
In[9]: _i1 # ilk girilen input'un unicode hali
Out[9]: u'9 * 9\n'
In [10]: _.__class__? # son output'un class'ının dokumantasyonu
Type:           type
Base Class:     &amp;lt;type 'type'&amp;gt;    
String Form:    &amp;lt;type 'unicode'&amp;gt;  
Namespace:      Interactive
Docstring:      bla bla bla...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Blog post&amp;#8217;unun konusu IPython&amp;#8217;a dönüşmeden burada keseyim. &lt;/p&gt;
&lt;p&gt;Kolay gelsin :)&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/17741224652</link><guid>http://blog.fatiherikli.com/post/17741224652</guid><pubDate>Fri, 17 Feb 2012 03:28:00 +0200</pubDate><category>python</category><category>ipython</category><dc:creator>lapslaps</dc:creator></item><item><title>sosyate.com</title><description>&lt;p&gt;&lt;img align="right" height="100" src="http://sosyate.com/static/img/logo.png" width="220"/&gt;Ruby ya da Ruby on Rails&amp;#8217;in community&amp;#8217;si hep ilgimi çekmiştir. Bu framework adına yapılmış gerçekten çok eğlenceli ve düzgün işler var. Ayrıca bu community&amp;#8217;nin yaptığı siteler tam bir görsel şölen niteliğinde kanımca. Özellikle &lt;a href="http://railsforzombies.org/" target="_blank"&gt;Rails for zombies&lt;/a&gt;&amp;#8216;i çok beğenmiştim.&lt;/p&gt;
&lt;p&gt;Aylardır elimde olan sosyate.com adında bir domain vardı. Hem boş boş durmasın, hem de &lt;a href="http://heroku.com" target="_blank"&gt;heroku&lt;/a&gt; üzerinde benim de bir çarkım dönsün diye bir şeyler yapmaya çalıştım :)&lt;/p&gt;
&lt;p&gt;Uygulama kullanıcı adınızı girdiğinizde twitter&amp;#8217;da en çok kullandığınız kelimelerin analizini yapıyor. Şuanda analiz&amp;#8217;den ziyade sadece en çok kullanılan kelimeleri listeliyor. Boş vakitlerimde canım rails çektiğinde geliştireceğim bir proje olarak görüyorum. Eğer uğraşmak isteyen olursa kodlarım açık, projeyi github&amp;#8217;da public olarak tutuyorum. Her zaman beklerim :)&lt;/p&gt;
&lt;p&gt;Şuradan siteye ulaşabilir;&lt;br/&gt;&lt;a href="http://sosyate.com/" target="_blank"&gt;&lt;a href="http://sosyate.com/" target="_blank"&gt;http://sosyate.com/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Şuradan da repository&amp;#8217;e erişebilirsiniz.&lt;br/&gt;&lt;a href="https://github.com/fatiherikli/sosyate" target="_blank"&gt;&lt;a href="https://github.com/fatiherikli/sosyate" target="_blank"&gt;https://github.com/fatiherikli/sosyate&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div id="-chrome-auto-translate-plugin-dialog"&gt;
&lt;div&gt;
&lt;div class="translate"&gt;&lt;/div&gt;
&lt;div class="additional"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://www.google.com/uds/css/small-logo.png"/&gt;&lt;/div&gt;</description><link>http://blog.fatiherikli.com/post/17686075203</link><guid>http://blog.fatiherikli.com/post/17686075203</guid><pubDate>Thu, 16 Feb 2012 03:13:00 +0200</pubDate><category>ruby</category><category>ruby on rails</category><category>projects</category><dc:creator>lapslaps</dc:creator></item><item><title>12 Şubat - Python İstanbul buluşması</title><description>&lt;p&gt;Pyist&amp;#8217;e ilk defa bugün katıldım. Şansıma bugün diğer buluşmalara nazaran beklenenden daha kalabalık bir toplantı olmuş. Yaklaşık 20 kişiydik. Gerçekten çok zevkli ve heyecan verici bir buluşmaydı.&lt;/p&gt;
&lt;p&gt;Her ne kadar projeksiyon cihazı bulamasakta konuşmacı arkadaş (&lt;a href="http://taylanpince.com/" target="_blank"&gt;Taylan Pince&lt;/a&gt;) sunum konusunu çok başarılı bir şekilde anlattı. Sunumun konusu django ile RESTful API&amp;#8217;ler geliştirmemizi kolaylaştıran &lt;a href="https://github.com/toastdriven/django-tastypie" target="_blank"&gt;django-tastypie&lt;/a&gt; idi. Bu zamana kadar REST API için &lt;a href="https://bitbucket.org/jespern/django-piston/wiki/Home" target="_blank"&gt;piston&lt;/a&gt; kullanmaktaydım. Zannedersem bugünkü buluşmadan sonra tastypie kullanacağım :)&lt;/p&gt;
&lt;p&gt;Böyle bir organizasyonu düzenlediği için başta &lt;a href="http://cihanokyay.com/" target="_blank"&gt;Cihan Okyay&lt;/a&gt;&amp;#8216;a ve diğer emeği geçen herkese teşekkürlerimi sunuyorum. &lt;/p&gt;
&lt;p&gt;Sunum dosyaları github&amp;#8217;taki &lt;a href="https://github.com/pyist" target="_blank"&gt;pyist&lt;/a&gt; organizasyonu altında yayınlanacaktır.&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/17503312542</link><guid>http://blog.fatiherikli.com/post/17503312542</guid><pubDate>Sun, 12 Feb 2012 21:37:00 +0200</pubDate><category>python</category><category>django</category><category>meetup</category><category>meetup</category><category>pyist</category><dc:creator>lapslaps</dc:creator></item><item><title>MongoDB database yapısı üzerinde MapReduce işlemleri</title><description>&lt;p&gt;Bildiğiniz üzere &lt;a href="http://mongodb.org" target="_blank"&gt;MongoDB&lt;/a&gt; document-oriented bir &lt;a href="http://en.wikipedia.org/wiki/NoSQL" target="_blank"&gt;NoSQL&lt;/a&gt; veritabanıdır. Verileri JSON şeklinde saklayıp, JSON şeklinde erişiyoruz. Daha doğrusu &lt;a href="http://bsonspec.org/" target="_blank"&gt;BSON&lt;/a&gt; (Binary JSON) şeklinde. &lt;/p&gt;
&lt;p&gt;NoSQL database sistemleri üzerinde group, distinct gibi işlemler ilişkisel veritabanlarına (mysql, postgresql) nazaran biraz daha karmaşık. Bunun gibi sorgular fonksiyonel programlama&amp;#8217;nın temellerinden olan MapReduce işlemi ile yapılmaktadır. MapReduce MongoDB üzerinde built-in olarak gelmektedir. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Map ve Reduce fonksiyonları&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sorgular için iki adet fonksiyon yazıyorsunuz; map ve reduce. Şimdilik MongoDB üzerinde sadece javascript ile yazılabiliyor.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Map: parametre olarak her bir dökümanı (ilişkisel veritabanlarındaki satır) alır ve key, value şeklinde dönüş yapar.&lt;/li&gt;
&lt;li&gt;Reduce: map fonksiyonundan gelen key, value değerlerini parametre olarak alır ve verilerinizi bu fonksiyonda işlersiniz.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Bir örnek yapalım&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://myadslot.com" target="_blank"&gt;Myadslot.com&lt;/a&gt; üzerinden örnek vermek istiyorum; istatistik dataları benim üşengeçliğimden dolayı MySQL database üzerinde diğer kayıtlar ile birlikte saklanmaktaydı. Bu gece vaktimi eski verileri MongoDB&amp;#8217;ye aktarmak için data-migration yazarak geçirdim. MongoDB üzerinde saklanan datalar şu şekilde;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    "last_visit_date": "2012-01-26 18:05:41",
    "slot_id": 9,
    "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) ",
    "last_visit_url": "http://dbdsgnr.appspot.com/",
    "visit_count": 2,
    "ip_address": "72.179.56.244",
    "advertisement_id": 7
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Problem şu;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Slot istatistikleri sayfasında slota ait tüm reklamların görüntülenme sayısının toplamının alınması gerekiyor. Aslında bu data zaten slot üzerinde denormalize edilmiş durumda, maksat örnek olsun :)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Örnekte MongoDB client&amp;#8217;i olarak pymongo kullanacağız. Veritabanına bağlanmak için şöyle bir fonksiyon kullanabiliriz;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import pymongo
def get_db(db_name="myadslot"):
    return pymongo.Connection()[db_name]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Map ve reduce fonksiyonlarımızı yazalım. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;map_slots = """
function () {
    emit(this.slot_id, this.visit_count);
}
"""&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gördüğünüz üzere map edilen dökümana (row) this keyword&amp;#8217;ü ile ulaşabilmekteyiz. slot_id&amp;#8217;sini key, visit_count&amp;#8217;u ise value olarak belirledik. Şimdi reduce fonksiyonumuzu yazalım.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;reduce_slots = """
function (key, values) {
    var total = 0;
    for (var i in values) {
        total += values[i]
    }
    return total
}
"""&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reduce fonksiyonumuza slot_id ve visit_count parametre olarak geliyor. Biz burada slota ait tüm reklamların visit_count&amp;#8217;unun toplamını döndürüyoruz. Python içinde javascript birazcık pis oluyor gördüğünüz üzere. Ancak MongoDB&amp;#8217;nin sonraki versiyonlarında ek olarak &lt;a href="https://jira.mongodb.org/browse/SERVER-699" target="_blank"&gt;başka script dilleri&lt;/a&gt; kullanabileceğiz. Şimdi bu fonksiyonlarımızı MongoDB üzerinde çalıştıralım.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;db = get_db()
result = db["visitors"].map_reduce(map_slots, reduce_slots, "slot_stats")
for item in result.find():
    print item&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Map reduce işleminden sonra bize geçici bir koleksiyon oluşturulmakta. Geçici koleksiyonumuzun adını slot_stats olarak belirledik. Bu koleksiyon üzerinden tekrar filtreleme yapabilmekteyiz ancak biz hepsini yazdırdık. İşlemin sonucu şu şekilde olacaktır;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{u'_id': 4L, u'value': 17.0}
{u'_id': 5L, u'value': 335909.0}
{u'_id': 6L, u'value': 3L}
{u'_id': 9L, u'value': 3736.0}
{u'_id': 10L, u'value': 4.0}&lt;br/&gt;... &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ayrıca django ile birlikte MongoDB kullanımı için aşağıdaki bağlantıları göz atmanızı tavsiye ederim.&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://django-mongodb.org/" target="_blank"&gt;&lt;a href="http://django-mongodb.org/" target="_blank"&gt;http://django-mongodb.org/&lt;/a&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/mdirolf/mongodb-lt3s-django-django-nyc" target="_blank"&gt;&lt;a href="http://www.slideshare.net/mdirolf/mongodb-lt3s-django-django-nyc" target="_blank"&gt;http://www.slideshare.net/mdirolf/mongodb-lt3s-django-django-nyc&lt;/a&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.montylounge.com/2010/02/11/integrating-mongodb-and-django/" target="_blank"&gt;&lt;a href="http://blog.montylounge.com/2010/02/11/integrating-mongodb-and-django/" target="_blank"&gt;http://blog.montylounge.com/2010/02/11/integrating-mongodb-and-django/&lt;/a&gt;&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.fatiherikli.com/post/17467479191</link><guid>http://blog.fatiherikli.com/post/17467479191</guid><pubDate>Sun, 12 Feb 2012 05:50:00 +0200</pubDate><category>django</category><category>map</category><category>mongodb</category><category>nosql</category><category>pymongo</category><category>python</category><category>reduce</category><category>django</category><dc:creator>lapslaps</dc:creator></item><item><title>Birazcık scaling: Python ve Django uygulamalarında asenkron işler (RabbitMQ)</title><description>&lt;p&gt;Konuya girmeden önce; artık blog post&amp;#8217;larım &lt;a href="http://django.org.tr" target="_blank"&gt;django.org.tr&lt;/a&gt; gezegeninde yayınlanmakta. Bu yüzden bana tumblr&amp;#8217;ın getirtiği baştan salma yazı yazma alışkanlığımı sonlandırmak istiyorum. Başlıksız ya da içeriksiz post atmak her ne kadar güzel olsa da post&amp;#8217;lar sadece tumblr üzerinden okunmuyor. Artık özen göstererek yazmak gerekecek :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Distributed Computing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.rabbitmq.com" target="_blank"&gt;RabbitMQ&lt;/a&gt;,  zaten dağıtık hesaplama (distributed computing) konusunda ünlü olan &lt;a href="http://www.erlang.org" target="_blank"&gt;Erlang&lt;/a&gt; dili ile geliştirilmiş &lt;a href="http://en.wikipedia.org/wiki/AMQP" target="_blank"&gt;AMQP&lt;/a&gt;(Advanced Message Queuing Protocol) protokolü üzerinde çalışan open-source bir message broker (mesaj kuyruğu diyebiliriz) yazılımıdır. Bu ve bunun gibi message broker yazılımları sayesinde kullandığımız dilden bağımsız bir şekilde yapılması uzun süren işlemleri (hesaplamalar, email vb.) çeşitli makinalara ya da aynı makina üzerindeki birden fazla worker&amp;#8217;a dağıtabiliriz.&lt;/p&gt;
&lt;p&gt;Gerçek hayattan bir örnek verecek olursak; scale edilmesi gereken bir django uygulamasında request ve response arasında uzun süren işlemler ya da web ile alakası olmayan ayrı bir katmanda yapılan bir iş olmaması gerekmektedir. Misal kullanıcılara bir ya da birden fazla email göndermek, uzun süren hesaplamalar yapmak, kullanıcıya yeni bir demo site açmak gibi &amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Requirements&lt;/strong&gt;;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Erlang platformu (Linux üzerindeyken RabbitMQ kendisi yüklemekte. Eğer windows üzerinde iseniz &lt;a href="http://www.erlang.org/download.html" target="_blank"&gt;şuradan&lt;/a&gt; indirip kurabilirsiniz.)&lt;/li&gt;
&lt;li&gt;RabbitMQ Server (Windows&amp;#8217;ta iseniz &lt;a href="http://www.rabbitmq.com/download.html" target="_blank"&gt;şuradan&lt;/a&gt; indirebilirsiniz)&lt;/li&gt;
&lt;li&gt;Kullanacağımız programlama dili için RabbitMQ client kütüphanesi. Örneklerde python için &lt;a href="http://pypi.python.org/pypi/pika" target="_blank"&gt;pika&lt;/a&gt; kullanacağız. Diğer diller için kütüphaneler &lt;a href="http://www.rabbitmq.com/devtools.html" target="_blank"&gt;şurada&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Paket manager&amp;#8217;ımız ile rabbitmq-server&amp;#8217;ı yükleyelim.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt-get install rabbitmq-server&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Kurulum bittiğinde server otomatik olarak başlatılacaktır. Şimdi de python kütüphanemizi yükleyelim.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install pika&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Bu işlem de bittikten sonra yükleyeceğimiz başka bir şey kalmıyor. Örneklere geçebiliriz.&lt;/p&gt;
&lt;p&gt;Bir mesaj kuyruğu uygulamasında üç temel yapı vardır; Consumer, Queue ve Publisher.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Consumer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Publisher&amp;#8217;dan gelecek olan mesajlar için sürekli dinlemede olan bir nevi sunucudur. Aynı anda birden fazla consumer çalıştırabilirsiniz. RabbitMQ tüm consumer&amp;#8217;lara eşit miktarda iş yükü dağıtmaya çalışacaktır. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Queue&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Task yani görevlerin saklandığı kuyruktur. Eğer tek consumer var ise bu yapı &lt;a href="http://en.wikipedia.org/wiki/FIFO" target="_blank"&gt;FIFO&lt;/a&gt; (First in First out) yani -ilk giren ilk çıkar- şeklindedir. Zira birden fazla consumer olduğunda RabbitMQ işleri dağıtmaktadır.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Publisher&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Consumer&amp;#8217;a işleri gönderen uygulamadır. Bu bir django application&amp;#8217;ı olabilir.&lt;/p&gt;
&lt;p&gt;Şimdi örneğimize geçelim; peş peşe email gönderen bir uygulama simüle edelim. İlk olarak receiver yani consumer uygulamamızı yazalım. &lt;/p&gt;
&lt;p&gt;consumer.py içeriği;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import pika, time

def callback(ch, method, properties, body):
    print "email gonderiliyor; ", body
    time.sleep(1) # gercekci olsun diye 1 saniye bekletiyoruz :)
    print "email gonderildi."

def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    channel = connection.channel()
    channel.queue_declare(queue='mailing')
    channel.basic_consume(callback, queue='mailing', no_ack=True)
    channel.start_consuming()

if __name__ == "__main__":
    main()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;br/&gt;Örnekte mailing adında bir kuyruk oluşturduk ve o kuyruk üzerinde consuming işlemini başlattık. Örneği çalıştırdığınızda program dinlemeye geçecektir. Bir mesaj geldiğinde ise oluşturduğumuz callback fonksiyonu mesaj parametresi ile birlikte işlemeye başlayacaktır. Consumer uygulamamızı aşağıdaki gibi başlatalım;&lt;/p&gt;
&lt;p&gt;python consumer.py&lt;/p&gt;
&lt;p&gt;Şimdi ise publisher&amp;#8217;ımızı yazalım.&lt;/p&gt;
&lt;p&gt;publisher.py içeriği;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import sys
import pika

def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    channel = connection.channel()
    channel.queue_declare(queue='mailing')
    channel.basic_publish(exchange='', routing_key='mailing',body=sys.argv[1])
    connection.close()

if __name__ == "__main__":
    main()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Consumer uygulamamızdaki gibi aynı kuyruğa bağlandık ve bu sefer kuyruğa mesaj göndermesini istedik. Publisher uygulamamızı aşağıdaki gibi çalıştırdığımızda dinlemede olan consumer&amp;#8217;ımız üzerine görevi yapacaktır.&lt;/p&gt;
&lt;p&gt;python publisher.py fatiherikli@gmail.com&lt;/p&gt;
&lt;p&gt;Burada önemli olan kısım publisher&amp;#8217;dan ziyade consumer uygulamamızın yapılandırmasıdır. Örnekte biz tek bir consumer uygulaması çalıştırdık. Peş peşe publisher.py üzerinden komut göndermeye çalıştığınızda Consumer&amp;#8217;ınız sırasıyla gönderdiğiniz komutları çalıştıracaktır.&lt;/p&gt;
&lt;p&gt;Şimdi ise consumer.py &amp;#8216;nizi farklı terminallerde aynı anda çalıştırın. Örnek olarak 3 tane consumer&amp;#8217;ınız dinlemede olsun. Publisher&amp;#8217;ınız üzerinden peş peşe mesaj göndermeye çalıştığınızda her consumer&amp;#8217;da aynı görev sayısı olacak şekilde işlemlerin dağıtıldığını göreceksiniz.&lt;/p&gt;
&lt;p&gt;Ayrıca Django ve RabbitMQ etkileşimini daha da kolaylaştıran celery projesini incelemenizi tavsiye ederim;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://celeryproject.org/" target="_blank"&gt;&lt;a href="http://celeryproject.org/" target="_blank"&gt;http://celeryproject.org/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div id="-chrome-auto-translate-plugin-dialog"&gt;
&lt;div&gt;
&lt;div class="translate"&gt;&lt;/div&gt;
&lt;div class="additional"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;img src="http://www.google.com/uds/css/small-logo.png"/&gt;&lt;/div&gt;</description><link>http://blog.fatiherikli.com/post/17342249281</link><guid>http://blog.fatiherikli.com/post/17342249281</guid><pubDate>Fri, 10 Feb 2012 01:54:00 +0200</pubDate><category>amqp</category><category>distributed computing</category><category>django</category><category>pika</category><category>python</category><category>queue</category><category>rabbit mq</category><category>erlang</category><dc:creator>lapslaps</dc:creator></item><item><title>obfuscated c code contest</title><description>&lt;p&gt;20 senedir devam eden en ufak ve en anlaşılmaz c kodu yazma yarışması;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.ioccc.org/" target="_blank"&gt;&lt;a href="http://www.ioccc.org/" target="_blank"&gt;http://www.ioccc.org/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;preprocessor kullanılarak mors alfabesiyle yazılmış bir örnek; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.ioccc.org/1986/hague.c" target="_blank"&gt;http://www.ioccc.org/1986/hague.c&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/16838146465</link><guid>http://blog.fatiherikli.com/post/16838146465</guid><pubDate>Wed, 01 Feb 2012 00:26:53 +0200</pubDate><dc:creator>lapslaps</dc:creator></item><item><title>anti-patterns  </title><description>&lt;p&gt;anti pattern; analyze, management ya da development sürecinde sıklıkla yapılan hatalardır. amacı yazılımcıları ya da yöneticileri yapılan hatalardan uzaklaştırmaktır.&lt;/p&gt;
&lt;p&gt;örnek olarak analyze konusunda &lt;strong&gt;analysis paralysis,&lt;/strong&gt; management konusunda &lt;strong&gt;escalation of commitment&lt;/strong&gt; (battı balık yan gider), development sürecinde &lt;strong&gt;god object&lt;/strong&gt; gibi&amp;#8230;&lt;br/&gt;&lt;br/&gt;işte size hayvan gibi bir anti-pattern listesi;&lt;br/&gt;&lt;a href="http://c2.com/cgi/wiki?AntiPatternsCatalog" target="_blank"&gt;&lt;a href="http://c2.com/cgi/wiki?AntiPatternsCatalog" target="_blank"&gt;http://c2.com/cgi/wiki?AntiPatternsCatalog&lt;/a&gt;&lt;/a&gt;  &lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/16555455350</link><guid>http://blog.fatiherikli.com/post/16555455350</guid><pubDate>Fri, 27 Jan 2012 04:09:00 +0200</pubDate><category>anti pattern</category><category>design pattern</category><dc:creator>lapslaps</dc:creator></item><item><title>Joel Spolsky'nin eski işyeri ile problemleri</title><description>&lt;a href="http://joelonsoftware.com/articles/fog0000000043.html"&gt;Joel Spolsky'nin eski işyeri ile problemleri&lt;/a&gt;: &lt;p&gt;&lt;strong&gt;The Joel Test&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Do you use source control?&lt;/li&gt;
&lt;li&gt;Can you make a build in one step?&lt;/li&gt;
&lt;li&gt;Do you make daily builds?&lt;/li&gt;
&lt;li&gt;Do you have a bug database?&lt;/li&gt;
&lt;li&gt;Do you fix bugs before writing new code?&lt;/li&gt;
&lt;li&gt;Do you have an up-to-date schedule?&lt;/li&gt;
&lt;li&gt;Do you have a spec?&lt;/li&gt;
&lt;li&gt;Do programmers have quiet working conditions?&lt;/li&gt;
&lt;li&gt;Do you use the best tools money can buy?&lt;/li&gt;
&lt;li&gt;Do you have testers?&lt;/li&gt;
&lt;li&gt;Do new candidates write code during their interview?&lt;/li&gt;
&lt;li&gt;Do you do hallway usability testing?&lt;/li&gt;
&lt;/ul&gt;</description><link>http://blog.fatiherikli.com/post/16549565716</link><guid>http://blog.fatiherikli.com/post/16549565716</guid><pubDate>Fri, 27 Jan 2012 02:37:00 +0200</pubDate><category>The Joel Test</category><dc:creator>lapslaps</dc:creator></item><item><title>kank.im'in kodları artık açık</title><description>&lt;p&gt;şuradan göz atabilirsiniz;&lt;br/&gt;&lt;a href="https://github.com/fatiherikli/kankim" target="_blank"&gt;&lt;a href="https://github.com/fatiherikli/kankim" target="_blank"&gt;https://github.com/fatiherikli/kankim&lt;/a&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; denemek için;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;git clone git://github.com/fatiherikli/kankim.git&lt;/li&gt;
&lt;li&gt;cd kankim&lt;/li&gt;
&lt;li&gt;python manage.py syncdb&lt;/li&gt;
&lt;li&gt;python manage.py runserver&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;kankim&amp;#8217;i ise &lt;a href="http://kank.im" title="şurada" target="_blank"&gt;şurada&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/16540119790</link><guid>http://blog.fatiherikli.com/post/16540119790</guid><pubDate>Fri, 27 Jan 2012 00:03:00 +0200</pubDate><category>kankim</category><category>django</category><category>python</category><dc:creator>lapslaps</dc:creator></item><item><title>open source lisanslar (gpl, ccl, osl vs..) hakkında güzel bir tartışma</title><description>&lt;a href="http://forum.ceviz.net/genel-programlama/96638-creative-commons-benzeri-yazilim-lisansi.html"&gt;open source lisanslar (gpl, ccl, osl vs..) hakkında güzel bir tartışma&lt;/a&gt;</description><link>http://blog.fatiherikli.com/post/16534349473</link><guid>http://blog.fatiherikli.com/post/16534349473</guid><pubDate>Thu, 26 Jan 2012 22:20:00 +0200</pubDate><category>ccl</category><category>gpl</category><category>open source</category><category>ben çünkü unutucam bunları. onun için yazıyorum.</category><dc:creator>lapslaps</dc:creator></item><item><title>şunu bir incele;</title><description>&lt;p&gt;&lt;a href="http://code.google.com/p/django-simple-captcha/" target="_blank"&gt;&lt;a href="http://code.google.com/p/django-simple-captcha/" target="_blank"&gt;http://code.google.com/p/django-simple-captcha/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://blog.fatiherikli.com/post/16518264431</link><guid>http://blog.fatiherikli.com/post/16518264431</guid><pubDate>Thu, 26 Jan 2012 14:33:00 +0200</pubDate><category>kendime not</category><category>captcha</category><category>gapcük</category><dc:creator>lapslaps</dc:creator></item></channel></rss>

