<?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>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>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>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></channel></rss>

