Twisted - wprowadzenie: generatory (0)

We wpisie "reactor i deferred" przedstawiłem koncepcje programowania asynchronicznego z wykorzystaniem obiektu Deferred w którym kolejkowane były zadania. Taki sposób pisania może być jednak bardzo niewygodny, jeśli okaże się, że w swoim kodzie mamy wiele miejsc oczekujących na dane. Każdorazowe pojawienie się nowych informacji wymaga napisania nowej funkcji która je obsłuży. Drugie tyle, jeśli chcemy oprogramować możliwe wystąpienia błędów.

Generatory

Jaki jest generator, każdy widzi. Najprostszym przykładem może być generowanie kolejnych liczb:

>>> def gen_number(start):
...     while True:
...         start += 1
...         yield start
...         
>>> g = gen_number(2)
>>> g.next()
3
>>> g.next()
4
>>> g.next()
5

Jeśli chcesz dowiedzieć się o nich więcej, polecam prezentację "Generator Tricks for Systems Programmers".

Generatory, aż do Pythona 2.5 miały bardzo poważną wadę - były hermetyczne. Utworzony ...

Twisted - wprowadzenie: implementacja protokołu (0)

W poprzednim wpisie przedstawiłem obiekt reaktora oraz klasę Deferred. Kolejnym krokiem będzie napisanie serwera, który używając prostego protokołu będzie zwracał kod strony której adres został przesłany przez klienta.

Implementacja protokołu

Bazową klasą każdego protokołu, implementującą jedynie IProtocol jest internet.protocol.Protocol. Podstawową klasą dla wszystkich serwerów jest internet.protocol.ClientFactory:

>>> from twisted.internet import protocol, reactor
>>> 
>>> class WebGetProtocol(protocol.Protocol):
...     pass
... 
>>> class WebGetFactory(protocol.ServerFactory):
...     protocol = WebGetProtocol
...     
>>> reactor.listenTCP(9000, WebGetFactory())
<<class 'twisted.internet.tcp.Port'> of __main__.WebGetFactory on 9000>
>>> reactor.run()

Po utworzeniu instancji fabryki, przekazuję ją wraz z numerem portu jako parametr metody listenTCP obiektu reaktora. Wszelkie dane które pojawią się na tym porcie, obsłużone zostaną przez moją fabrykę.

Do połączenia z serwerem, można użyć na przykład ...

Twisted - wprowadzenie: reactor i deferred (0)

Śledząc portale i blogi o treści programistycznej, trudno nie zauważyć wzmożonego ostatnio zainteresowania "nowymi" asynchronicznymi frameworkami napisanymi w Pythonie. Osobiście staram się jednak nie podniecać każdą nowością i aby się przekonać do biblioteki, potrzebuję czegoś więcej niż 10 linijek kodu, wyświetlających Hello world. Okazało się, że nie ja jedyny.

Od jakiegoś czasu czytam o twisted i w miarę możliwości staram się napisać trochę działającego kodu. Niestety, oprócz tutoriala w którym opisane zostały podstawy, do dyspozycji jest jeszcze tylko dokumentacja API.

Ponieważ sam dużo czasu spędziłem na gromadzeniu informacji, postaram się w miarę przystępnie opisać podstawy twisted.

Reaktor

Ponieważ twisted jest asynchronicznym frameworkiem, posiada własny obiekt odpowiedzialny za zarządzanie główną pętlą programu i wywoływanie obsługi zdarzeń:

>>> from twisted.internet import reactor ...
txChat (0)

txChat to napisany w twisted i jQuery czat. Kiedyś, ktoś napisał w twisted podobną aplikację, której działanie polegało na wymuszaniu ciągłego przeładowywania strony. Kod miał być wydajnościowym PoC twisted. Uruchomiony na słabej maszynie, obsługiwał całkiem sporą liczbę zapytań. Pomyślałem, że napiszę coś podobnego, ale uproszczę sobie i serwerowi zadanie, używając Javascript.

surround.vim i django templates (0)

surround.vim to wtyczka pozwalająca na szybsze wstawianie znaczników otaczających tekst w określony sposób. Sam skrypt zawiera skróty tylko dla nawiasów oraz tagów XML (ponieważ korzysta z text-objects), ale znając wyrażenia regularne, można spróbować napisać własne definicje (:h surround-customizing).

Ponieważ wiele inclusion tagów w Django otacza fragmenty szablonu, dobrym pomysłem może być użycie do ich pisania funkcjonalności surround . Niestety nie udało mi się tego osiągnąć bez pisania paru linijek patcha. Autor w bardzo specyficzny sposób napisał ten skrypt i na pewno nie zamierzał ułatwiać jego rozszerzania, dlatego w pół godziny nie udało mi się osiągnąć niczego więcej poza obsługą wstawiania tagów. Parametrem który dostajemy po nałożeniu łatki jest d (lub D).

Ajax w Django (ver. 2) (1)

Półtora roku temu opisałem jak zastosować AJAX w aplikacji napisanej w Django. Wybrałem wtedy tworzoną w Pythonowym stylu bibliotekę mochikit i Django 0.96. Opis cieszy się dużą popularnością, ale bogatszy o ponad rok doświadczeń wiem, że teraz zrobiłbym to wszystko o wiele lepiej.

Kiedyś jako przykład użycia ajax stworzyłem proste wiki, ale nie chciało mi się tego opisać. Tym razem wyjaśnię jak napisać prymitywny blog w Django (a jakże!). Pominę jednak kwestię przyjemnego interfejsu i skupię się na jak największej ilości JavaScriptowych wodotrysków.

Wybór biblioteki JavaScript

Swój pierwszy kod w JavaScript napisałem chyba ponad trzy lata temu. Jedyne co pamiętam to biblioteka której użyłem - mootools. Potem zacząłem używać mochikit, bo wydawało mi się, że nic wygodniejszego nie znajdę.

Obecnie ...

Generator zapytań dla Solra (0)

Ostatnie dni spędzam na nauce Solra i rozwijaniu Djangowego kodu wykorzystującego właśnie z ten indekser. Ponieważ tworzenie zapytań może być naprawdę męczące i generować wiele błędów, napisałem w wolnym czasie parę linijek które powinny pomóc. API jest oczywiście wzorowane na Django ORM. Komunikacją z Solr zajmuje się moduł pysolr.

Oto przykład zapytania:

q = Query()
q.filter(OR(title='Hello world!', description='Hello world!'), date__lt=dt)
q.exclude(photo=True, video=False)
q[:2]
print q.pprint()

które generuje następujący kod:

((description:"Hello world!") OR (title:"Hello world!")) 
 AND (date:"LESS_THAN(to_sorl_format)") 
 AND (NOT (contains_photo:"true") OR (contains_video:"true"))
Cscope (0)

Czytając kod który napisał ktoś inny, największym problemem jest podążanie za kolejnymi wywołaniami funkcji. Zdarza się też tak, że znam nazwę lub jej fragment i chcę znaleźć wszystkie odwołania. Jak sobie z tym poradzić? Do tej pory używałem grepa uruchamianego przez odpowiedni Vimowy plugin. Rozwiązanie sprawdza się dla projektów z niewielką ilością kodu. Gorzej jeśli na wynik trzeba czekać parę sekund, bo architektura Vima nie pozwala w tym czasie robić cokolwiek innego.

Konkurencyjnym rozwiązaniem jest ctags, który jakoś nie przypadł mi do gustu. Trafiłem jednak na narzędzie o nazwie cscope, które ponoć potrafi jeszcze więcej.

Instalacja

Miłą niespodzianką jest fakt, że aby Vim był w stanie korzystać z cscope, wystarczy skompilować go z flagą --enable-cscope.

Przygotowanie bazy

Aby móc skorzystać ...

Map na procesach (0)

Z braku lepszego zajęcia, napisałem funkcję map działającą na procesach

import time
import itertools

# python 2.4
from processing import Queue, Process

def procmap(target, args, proc_nr):
    """Processes powered map function

    Acts like build-in `map` function, but result is in random order.
    """
    def _sub_procmap(target, args, resultbox):
        resultbox.put(map(target, args))
    step = len(args) / proc_nr
    q = Queue()
    processes = []
    for i in xrange(proc_nr):
        arg = itertools.islice(args, i * step, i * step + step)
        p = Process(target=_sub_procmap, args=[target, arg, q])
        processes.append(p)
    for p in processes:
        p.start()
    for p in processes:
        p.join()
    result = []
    while not q.empty():
        result.extend(q.get())
    return result

def _test():
    _test1()
    _test2()
    _test3()

def _test1():
    def double(value):
        return value * 2 ...
virtualevn i hg vs git (6)

Virtualenv

Ponieważ lubię testować różne, często mało popularne Pythonowe biblioteki, zazwyczaj zamiast domyślnego menadżera pakietów używam easy_install lub pip. Nie zawsze pamiętam o usuwaniu niepotrzebnych pakietów, do tego dochodzą zależności i powoli robi się w systemie syf. Sytuację ratuje jednak virtualenv, który pozwala szybko zbudować piaskownicę.

Ponieważ na zaliczenie mam napisać grę sieciową, jako główny język wybrałem Pythona. Z racji tego, że na docelowym komputerze nie ma ani twisted ani pyglet, zbudowałem własne środowisko w którym rozwijam projekt.

piotrek@archbook# mkdir pysandbox
piotrek@archbook# cd pysandbox
piotrek@archbook# virtualenv .
New python executable in ./bin/python
Installing setuptools............done.
piotrek@archbook# source bin/activate
(pysandbox)piotrek@archbook# easy_install twisted
...
(pysandbox)piotrek@archbook# easy_install pyglet
...

Hg vs Git

Jakiś czas temu google ...

« 2 1 /4 0 »