Friday, December 26, 2008

Python - gdy Gruszka jest Pomarańczą

W tym wpisie chciałbym przybliżyć działanie metody __new__(). Jest to metoda statyczna wywoływana w trakcie tworzenia obiektu, zanim sam obiekt jeszcze powstanie. Jej zadaniem jest właśnie zwórcenie obiektu. Czyli co ? Co to dla nas oznacza ? Oznacza na przykład to iż istnieje metoda, którą mogę zaimplementować (coś w niej zrobić) wywoływana zanim jeszcze istnieje obiekt. Mogę więc wpłynąć na to jak ten obiekt będzie na prawdę tworzony i co więcej ! To ja mogę zdecydować jaki obiekt będzie stworzony i zwrócony.Tworząc obiekt jednego typu mogę zwrócić obiekt innego ? Na przykład. Możesz przekazać troszkę inną listę parametrów jego metodzie __init__ albo zainicjalizować jakieś elementy przed jego stworzeniem. Zobaczymy przykład.
class Pomarancz(object):
    pass

class Gruszka(object):

def __new__(type):
    return Pomarancz()

if __name__ == '__main__':
    gruszka = Gruszka()
    print type(gruszka)
Co tu się dzieje. Stworzyliśmy sobie dwie klasy: Pomarancz i Gruszka. Gruszka jest jakaś podejżana, ale to zaraz do tego wrócimy. Co w ramach programu ? Tworzomy obiekt gruszka klasy Gruszka. Na razie na tym się zatrzymajmy. W każdym "normalnym" języku programowania gdy tworzymy obiekt jakiejś klasy dostajemy ... tak instancję tej klasy :) Jak tworzymy obiekt klasy Samolot dostajemy samolot. Jak dostajemy obiekt klasy Dziecko dostajemy dziecko. Tak samo na codzień zachowuje się Python możemy jednak, dzięki metodzie __new__ zwrócić podczas tworzenia obiektu "coś innego".Sprawdźmy co my zwróciliśmy podczas tworzenia Gruszki. print type(gruszka) (funkcja type podaje typ obiektu, klasę obiektu który jest jej parametrem) zwróciło nam pomarańcz Pomarancz ? Wow :D To prawie jak kamień alchemiczny. Teraz zamieniamy Gruszki w Pomarańcze (to jak Ołów w Złoto).

Przyjżyjmy się metodzie __new__(). Skoro to ona ma zwracać obiekt klasy :) to znaczy, że to co zwróci nam przez return to dostaniemy przy użyciu Gruszka(). Jak byk stoi tam zwrócenie świerzo stworzonego obiektu pomarańczy :) Teraz wszystko się zgadza.

Już słyszę głosy oburzonych programistów: "przecież Python miał być czytelny. A tu takie konstrukcje ?". Z mojego skromnego punktu widzenia służą one językowi. Jak ?
Wyobraź sobie, że chciałbyś mieć klasę UlubionyOwoc, która w zależności do tego jaki użytkownik tworzy jej instancję dostaje to co lubi najbardziej. Dzięki metodzie __new__() możesz tego w prosty sposób dokonać nie tracąc przy tym na elegancji składni i prostocie kodu (po prostu tworzysz obiekt), gdzie bez takiego rozwiązania musiałbyś tworzyć jakąś metodę statyczną w stylu UlubionyOwoc.zwroc_owoc().

Teraz jeszcze kilka szczegółów. W naszym przykładzie jak tylko interpreter natrafi na instrukcję return Pomarancz() zacznie tworzyć instancję klasy Pomarańcz. Dla nas oznacza to iż zostanie wywołane Pomarancz.__new__(), które jest domyśle a po nim Pomarancz.__init__() :) Być może dla wielu z was to już jest oczywiste :] ale piszę.

A co z argumentami, które są przekazywane podczas tworzenia obiektu. Powiedzmy Gruszka(2, jasio='imie') ? Metoda w postaci
def __new__(type, *args, **kwargs)
Pytania może rodzić kwestia: "No dobrze. A jak w metodzie __new__ klasy gruszka zwrócić obiekt klasy Gruszka ? Przecież jak zapiszę Gruszka() znowu wyląduję w __new__ i zacznę kręcić się w kółko". Słuszna uwaga. Uniwersalna metoda to:
def __new__(type, *args, **kwargs):
    return object.__new__(type, *args, **kwargs)

Gdzie type oznacza typ klasy, który chcemy "stworzyć". Przy użyciu formy Gruszka() czy Pomarancz() jest on przekazywany automatycznie jednak można tworzyć obiekty również tak object.__new__(tutaj_podaj_typ, argumenty, argumenty nazwane).

Na koniec dodam tylko, że jak już nasza klasa zwróci obiekt swojego typu to wywoływana jest metoda Gruszka.__init__ z całym kompletem parametrów przekazanym do __new__ czyli przekazanym podczas tworzenia obiektu :)

I to by było na tyle. Miłej zabawy.

Python - wywoływanie obiektu

Python umożliwia potraktowanie obiektu jak funkcji, czyli ... wywołania obiektu :) Każdy z was może sam rozważyć taką potrzebę. Widząc jak łatwo obiekt może udawać inne typy (takie jak int, complex czy nawet słownik lub listę), można się zastanowić: skoro obiekt stworzony przez nas tak dobrze może udawać najróżniejsze inne obiekty - dlaczego nie miałby móc udawać funkcji ? To w sumie też obiekt. Tutaj właśnie zaczynają prześwitywać paradygmaty programowania funkcyjnego języka Python :)

A wszystko to w kilku linijkach:
class Klasa(object):

    def __call__(self):
        print "Wywolalem sie ! z wiadomoscia :)"

if __name__ == '__main__':
    obiekt = Klasa()
    obiekt()
Co wynika z powyższego kodu ? Wyposażyliśmy nasz obiekt w metodę __call__. Gdy potem próbujemy wywołać nasz obiekt, potraktować go jak funkcję (fragment obiekt()) python sprawdzi czy istnieje metoda __call__ i jeżeli tak wywoła ją. Metoda ta zachowuje się pod wieloma względami tak jak każa inna funkcja: może przyjmować parametry lub zwracać jakąś wartość :)

Thursday, December 25, 2008

Pylons - generowanie formularzy z użyciem form alchemy

W którejś z prezentacji na Matrix eXtreme II narzekałem na to, że Pylons (niestety) nie potrafi generować formularzy. Postanowiłem w końcu sprawdzić to na kanale #pylons. Co się okazało ? Na google code rezyduje sobie spokojnie :) projekt o nazwie formalchemy. Jest to biblioteka, na dzień dzisiejszy w wersji 1.1, która potrafi generować formularze dla modeli sqlalchemy :] Fantastczna wiadomosć :) Dodatkowo w dokumentacji projektu prześwitują już informacje o admin panelu co szalenie cieszy :) Życzę powodzenia i czekam na oficjalne wieści z PylonsHQ :P

Walt Disney - mistrzostwo w antropomorfizacji

Wczoraj miałem okazję obejrzeć w telewizji bajkę "Auta", o czerwonej wyścigówce :) Film szalenie mi się podobał, naprawdę dobrze się bawiłem oglądając go. Największe wrażenie zrobił na mnie świetny polski dubbing, byłem naprawdę dumny z naszych polskich aktorów.

Równocześnie przypomniał mi się film WALL.E. Czy Wy też zauważyliście, że Walt Disney, jakby, że im przestaje wystarczać robienie zwykłych bajek, filmów, ale że celowo sobie "utrudniają". Utrudniają obierając za cel postaci zupełnie nieożywione i jakby ambicjonalnie mówili "teraz my ... tak je ożywimy, że to będzie musiało być coś niesamowitego". Auta były naprawdę dobre, ale kto oglądał WALL.Ego pamięta, że tam ... tam to było już mistrzostwo. Te roboty praktycznie nic nie mówiły, kwestie wygłaszali przedewszystkim ludzie - a ... ta cała mimika, zachowanie, czytelność gestów i ich przesłanie ... to wszystko było robione po mistrzowsku. Film o robotach, które były tak ludzkie ... coś niemożliwego.

Zastanawiam się czym jeszcze zaskoczy nas Disney. Może teraz będzie film o kamieniach, którym rzucą nas na kolana ;) Nie wiem, ale cele jakie sobie wyznaczają to dla mnie z góry nudne filmy, z których robią hity. Tylko tak dalej !

Tuesday, December 23, 2008

Python - przeciążanie operatorów z punktu widzenia programisty C++

Cała prostota przeciążąnia operatorów w Pythonie względem C++ wynika z podanych już wcześniej zalet definiowania funkcji. Przeciążenie jakiegoś operatora w tworzonej przez nas klasie polega wyłącznie odnalezieniu nazwy funkcji za nią odpowiedzialnej, wymyśleniu jak ma działać dla naszego obiektu i zaimplementowaniu jej w naszej klasie. Z puli operatorów opisanych w dokumentacji języka PythonWeźmy na przykład operator dodawania +. Jak widzimy wystarczy w naszej klasie zdefiniować dwuargumentową metodę o nazwie __add__ i nasza klasa będzie rozumiała dodawanie. Załóżmy, że będzie to zawsze suma elementów modulo 5 (pierścień modulo pięć - dla osób pamiętających jeszcze coś z matematyki dyskretnej lub algebry liniowej).

Klasa będzie musiała przetrzymywać w sobie wartość liczby. Będziemy ją zapisywać do __value. Dodatkowo aby ułatwić sobie obliczenia nauczymy naszą klasę "konwertować się do inta" :) Bo przecież bądź co bądź chodzi o obliczenia na liczbach. 


class Mod5(object):

    def __init__(self, value):
        self.__value = value

    def __int__(self):
        return self.__value

    def __add__(self, b):
        return ((int(self) + int(b)) % 5)

if __name__ == '__main__':
    a = Mod5(5)
    b = Mod5(7)
    print a + b

Metoda __init__ pobiera jeden argument, liczbę którą jest nasz obiekt. Oczywiście nie sprawdzamy mnóstwa różnych rzeczy. czy liczba jest w naszym zakresie, czy to na pewno liczba całkowita itd... Metoda __int__ wywoła się w momencie, w którym nasz obiekt będzie konwertowany na int.  Wykorzystujemy to w metodzie __add__. Jako pierwszy argument przyjmuje samego "siebie" oraz drugi obiekt ten po symbolu "+". Konwertujemy obia te obiekty (siebie i ten drugi) na inta. Otrzymujemy więc nie obiekt klasy Mod5, ale liczbę :) dodajemy je i robimy modulo 5. Linijki poniżej to już tylko test - czy działa :)

Jak widać przeładowywanie operatorów, czy nawet modelowanie klasy, która będzie miałą możliwość rzutowania na najróżniejsze inne typy (naprawdę tutaj są ogromne możliwości, może być rzutowana na complex, long nawet na listę czy krotkę), wszystko to jest banalnie proste i łatwe :) Wystarczy zajrzeć do odpowiednigo działu dokumentacji Pythona :) i 

Monday, December 22, 2008

Python - polimorfizm z punktu widzenia programisty C++

Właściwie temat był już poruszany w wątku, w którym napisałem kilka słów o wyłapywaniu wyjątków.

Ponieważ zarówno w przypadku metod jak i funkcji nie trzeba definiować typu obiektów, które są do nich przekazywane wszystkie metody zachowują się tak jakby były wirtualne. Choć ciężko o tym mówić przy braku deklaracji typu parametru - po prostu są wywoływane na obiekcie przekazanym do funkcji czy metody jaki by ten obiekt nie był. Tak zwany polimorfizm najlepiej zobaczyć we wspomnianym już powyżej przykładzie wyłapywania wyjątków. Wyłapując wyjątek klasy bazowej możemy obsługiwać tym samym blokiem również wszystkie wyjątki klas pochodzących od niej (pochodnych). W C++ wymaga to użycia funkcji wirtualnych :] (jak można zobaczyć tutaj). Python po prostu - tak działa :) Jest to jego naturalne zachowanie, o które nie musimy w żaden sposób zabiegać.

Python - hermetyzacja, enkapsulacja z punktu widzenia programisty C++

W C++ kiedy chcieliśmy ukrywać informacje w klasach pisaliśmy po prostu metody (settery i gettery), które ustawiały lub pobierały wartości konkretnych parametrów. Właściwie - tworząc prywatny atrybut klasy (zaczynający się od dwóch podkreśleń) i pisząc do niego gettery i settery możemy dosłownie przekopiować rozwiązanie znane nam z C++. Możesz nadal pisać
obiekt.setX(10)
obiekt.getX()

Jednak :) Python umożliwia Ci używanie obiektu tak jakby był publiczny:
obiekt.x = 10
obiekt.x

dopisując do nich funkcje, wywoływane w trakcie przypisywania wartości lub odwoływania się do niej. Wszystko dzięki strukturze property.
Stwórzmy więc naszą klasę :) chowając w niej prawdziwe zmienne.
class Klasa(object):
    def __init__(self):
        self.__x = None

    def getx(self):
        return self.__x

    def setx(self, value):
        self.__x = value

    def delx(self):
        del self.__x

    x = property(getx, setx, delx, "I'm the 'x' property.")
Podczas tworzenia obiektu zostanie powołany do życia prywatny atrybut __x. Nie ma do niego dostępu z zewnątrz. Teraz - piszemy normalne metody takie jak w C++ :) getx, która zwróci jego wartość, setx, która ustawi jego wartość oraz dodatkowo delx, która skasuje atrybut :]
Cała "sztuczka" opiera się na końcowym stworzeniu atrybutu klasy "x" i przypisania do niego stworzonego gettera, settera, "delletera" oraz docstringa - opisu zmiennej. Od teraz możemy korzystać z "x" tak jakby był to atrybut klasy faktycznie jednak wywoływały się będą stworzone przez nas funkcje :)
obiekt = Klasa()
obiekt.x = 10 # Wywoła się tak naprawdę setx(10) self.__x = 10
print obiekt.x # Wywoła się tak naprawdę getx() return self.__x
del obiekt.x # Wywoła się tak naprawdę delx() del self.__x
Bardzo przyjemna i użyteczna metoda :] kontrolowania dostępu do atrybutów z zewnątrz przy niekomplikowaniu elegancji oraz prostoty składni :)

Python - klasy z punktu widzenia programisty C++

Kiedy tworzyliśmy klasę w C lub C++ używaliśmy słowa kluczowego class lub struct (od tego zależał domyślny tryb widoczności dla elementów klasy). Trzeba było zapisać co jest private, co protected a co public. Czasami potrzebowaliśmy aby jakaś metoda lub atrybut klasy był statyczny. Do wszystkiego używaliśmy specjalnych słów kluczowych. Jeżeli chcieliśmy stworzyć konstruktor tworzyliśmy metodę o nazwie naszej klasy a destruktor - podobnie, tyle tylko, że nazwę tą poprzedzaliśmy tyldą.

Wszystko omówię na podstawie przykładowej klasy Pythona.

class MojaKlasa(object):
    zmienna_statyczna = 12

    def __init__(self):
        self.zwykla_zmienna = 'a'
        print 'Ja się wywołam przy toworzeniu'

    def __del__(self):
        print 'Ja się wywołam przy usuwaniu'

Powyższa klasa dziedziczy po object. Dalej w ciele klasy definiujemy zmienną o nazwie zmienna_statyczna i przypisujemy jej wartość 12. W języku Python wszystkie zmienne definiowane w ciele klasy zachowują się jak zmienne statyczne. Metoda __init__ (nazwa zaczyna się i kończy od dwóch podkreślników) wywoła się zaraz po utworzenia obiektu :) Zaś metoda __del__  podczas jego usuwania. Piszę celowo "wykona się zaraz po utworzeniu", a nie "jest konstruktorem" ponieważ jest to stwierdzenie bliższe prawdzie.

Metody statyczne oznaczamy podając przed ich deklaracją @staticmethod:

class Klasa(object):
    zmienna = 12

    @staticmethod
    def mojaStatycznaMetoda():
        return Klasa.zmienna
Metoda jak widać nie przyjmuje parametru self (nie miałoby to sensu skoro jest statyczna i może być wywołana dla klasy bez tworzenia jej instancji). Aby odwołać się w niej do zmiennej statycznej możemy użyć Klasa.zmienna gdzie klasa to nazwa klasy a zmienna to nazwa zmiennej zadeklarowanej w jej ciele. Podobnie wygląda wywołanie metody statycznej Klasa.mojaStatycznaMetoda().

Wszystkie metody przyjmują jako pierwszy parametr self, czyli "samego siebie". Jest to jawny zapis tego co w C++ jest ukryte w mechanizmach języka i traktowane "domyślnie" (wszak możesz w metodach klasy C++ odwoływać się do obiektu z użyciem słówka this chociaż nigdzie go nie przekazujesz). Wszystkie atrybuty zdefiniowane w metodzie __init__ z użuyciem self.nazwa_zmiennej są jak widać zmienny obiektu nie klasy co po przeanalizowaniu znaczenia zmiennej self (ja, moja instancja, aktualnie tworzony obiekt) ma rzeczywiście sens :) Zmienne należą do obiektu (self), są definiowane dla niego (konkretnej instancji) nie zaś w ciele samej klasy.

A co z atrybutami: prywatny, publiczny. Domyślnie wszystkie metody i atrybuty w Pythonie są publiczne. I tutaj, aby zdefiniować elementy prywatne, zrezygnowano ze słów kluczowych na rzecz konwencji. Aby element klasy był prywatny jego nazwa musi zaczynać się od dwóch podkreślników to jest od __.  Tak więc atrybuty:


class KolejnkaKlasa(object):
    __zmienna_statyczna
    def __init__(self):
        self.__top_secret

    def __nie_wywolasz_mnie(self):
        pass
    pass
Wszystko czego nazwa zaczyna się od dwóch podkreślników będzie prywatne, ze swojej natury.
Co można powiedzieć o wartościach protected ? Są - ale istnieją jedynie z umowy. Umownie - wszystko czego nazwa rozpoczyna się od jednego znaku podkreślenia jest parametrem chronionym. Umowanie - ponieważ faktycznie ma się do niego nadal publiczny dostęp. Czy to znaczy, że Python nie wspiera metod i atrybutów chronionych w klasach. Tak - w Pythonie nie zaimplementowano tego mechanizmu. Zrobiono to celowo. Zainteresowanych odsyłam do wątku "Protected Methods and Python" na grupie dyskusyjnej języka. Jak widać po dyskusji, ufając intuicji autorytetu jakim jest Bjarne StrouStrup (twórca języka C++) atrybty i metody chronione to zły, zbędny mechanizm :) Więc nie martw się nic nie tracisz :)

Python - funkcje i zmienne z punktu widzenia C++

Będąc pod wrażeniem Thinking in Python chciałem tym wpisem rozpocząć pewne rozważania, które powinny być spostrzeżeniami programisty C/C++ po zderzeniu się z językiem Python.

Języki C/C++ wymagały od nas definiowania funkcji w bardzo restrykcyjny sposób. Musieliśmy podać dokaładnie typ i kolejność przekazywanych parametrów. Zmiana, którejś z tych dwóch powodowało przeładowywanie funkcji. Dodatkowo wymagane było od nas podanie wartości, którą miała zwracać nasza funkcja. Przez co czasami musieliśmy pisać kilka wersji naszej funkcji.

W języku Python wszystko wygląda znacznie prościej. Dlaczego ? Otóż tak jak w języku C/C++ zmienne posiadały konkretny typ - taki a nie inny, w języku Python spotykamy się z pewną szczególną cechą zmiennych. Po pierwsze nie definiujemy explicite ich typów. Są one "rozpoznawane" a może raczej "przyjmowane" przez język programowania na podstawie wartości jakie im przypiszemy.

Co to dla nas oznacza ? Aby w C/C++ stworzyć jakąś uniwersalną funkcję działającą dla różnych typów przekazywanych do niej obiektów musieliśmy używać mechanizmu szablonów. Ponieważ tutaj tworząc funkcję nie podajemy typów parametrów jakie przekazujemy - nasza funkcja działa dla wszystkich danych dla niej przekazanych - o ile operacje, które w niej wykonujemy mają dla tych zmiennych sens.

Dobrym przykładem prezentującym jest na przykład operacja "dodawania" (+).
Dla zmiennej typu string oznacza ona konkatencję (połączenie dwóch napisów).
Dla liczb oznacza to naturalnie ich dodanie.

Rozważmy funkcję dodającą dwie wartości:


def add(a, b):
    return a + b


Nigdzie nie podaliśmy typu zmiennej. Super spróbujmy więc podać wartości różnych typów - zobaczymy co dostaniemy:

add(2,3)

zwróci nam na pewno 5. No dobrze, ale czy zadziała dla liczb zmiennoprzecinkowych ? Oczywiście - jedyny wymaganiem Pythona jest tutaj aby operator, którego używamy (u nas +) był dobrze zdefiniowany dla obiektów, które przekazujemy do funkcji :) z liczbami rzeczywistymi nie ma tutaj problemu.

add(0.1,7.4)

da nam 7.5 :] pięknie. Ba więcej !

add((3 + 2j), (7 + 1.7j))

da nam równie dobry wynik - (10 + 3.7j) :] zgodnie z zasadą - jeżeli dla jakiegoś typu przekazanego do funkcji operacje, które na nim wykonujemy są dobrze określone - wszystko zadziała.
Do tej pory używaliśmy tylko parametrów liczbowych :) Jednak gdyby tak pomyśleć - to operator + jest równie dobrze określony dla napisów - oznacza on po prostu ich konkatenację. Czyli "Merry" + " Christmas" powinno nam wyprodukować "Merry Christmas". Sprawdźmy.

add('Marry', ' Christmas')

Działa :)

Jak widać Python pozawala na tworzenie funkcji, których zachowanie jest bardziej naturalne a wyniki dokładnie takie jakie się spodziewamy :] Specjalne mechanizmy, które służyły nam do osiągnięcia podobnego efektu w C++ zostały jakby "wchłonięte" w naturalne zachowanie się języka programowania.
Zasada iż operatory i działania jakie wykonujemy na obiektach przekazywanych do funkcji tyczy się również tworzonych przez nas typów. Python pozwala na przeładowywanie i definiowanie całego grona operatorów pozwalających nam sterować zachowywaniem się tworzonym przez nas typów danych. Jedną z dostępnych w dokumentacji list takich operatorów znajdziesz pod adresem http://docs.python.org/library/operator.html

Polimorfizm w Pythonie

Ostatnio programując w C++ walczyłem z polimorficznymi wyjątkami. Sytuacja zgrała się z trafieniem po drodze na lekturę Thinking in Python, gdzie zauważyłem bardzo ciekawe podejście autora, który czasami pisze "w C++ musiałeś to i to a w Pythonie - po prostu działa". Szalenie mi to podejście odpowiada :) Tak więc w myśl tej idei postanowiłem sprawdzić jak ma się polimorfizm wyjątków w Pythonie i czy dużo więcej się namęcze. Po raz kolejny :) punkt za prostotę dla Pythona - po prostu działa :]
class MyException(Exception):
    def __init__(self, message):
        self.message = message
    def __str__(self):
        return repr(self.message)

class MySocketException(MyException):
    pass

class MyOtherException(MyException):
    pass

def f():
    raise MyOtherException("Moj wyjatek: Wystapil straszny blad !")

if __name__ == '__main__':
try:
    f()
except MyException, e:
    print e



Czy to nie jest piękne :)

Sunday, December 21, 2008

Polimorficzne wyjątki w C++

Dziś pisałem zaliczenie z Interfejsów Programowania Systemów Operacyjnych. Zadanie na kolejne laboratorium polegało na opakowaniu w klasę prostej komunikacji opartej na socketach uniksowych. Może się komuś przyda :) Programik znajdziecie tutaj. Najwięcej namęczyłem się z obsługą wyjątków :) Nie jest to wyjście idealne, ale :) jeżeli ktoś nie ma lepszego pomysłu to można podejrzeć jak to jest wykonane. Przy okazji szukania trafiłem dziś na ciekawą informację o polimorficznych wyjątkach w FAQ LITE C++.

Python - od czego zacząć

Dziś zostało mi zadane pytanie od czego zacząć z Pythonem na start :)
Ponieważ  było to pytanie w kontekście "Windowsa" będę pisał głównie o nim.

Na początek potrzebny jest sam język Python. Możemy go ściągnąć z oficjalnej strony
Po zajerzeniu do działu Download możemy się ciut zagubić. Proponuję ściągnąć wersję pythona zaczynającą się od cyferki 2. Wszystkie samouczki opisują składnię kompatybilną z tą właśnie gałęzią. I nie ma się co martwić. Python 3 wyszedł stosunkowo nie dawno jest do niego niewiele bibliotek i chyba niemalże brak samouczków, a ucząc się Pythona 2 wcale nie uczysz się czegoś nieużytecznego. Opanowując Pythona 2 dasz sobie radę i z Pythonem 3 wspierając się dokumentacją :) opisującą zmiany pomiędzy tymi dwoma gałęziami.

Ściągamy więc ze strony http://www.python.org/download/ wersję Pythona 2, instalujemy w systemie :) Super. Połowa sukcesu za nami.

Przydałoby się jeszcze środowisko programistyczne. Sporo o edytorach dla języka Python można znaleźć w wątku http://forum.python.org.pl/index.php?topic=54.0 PPCG lub na oficjalnym Wiki Pythona . Wybór należy do Ciebie. Jeżeli lubisz proste, działające programy polecam Geany. Zaś dla miłośników poważny środowisk programistycznych wtyczkę do Eclipse o nazwie PyDev. W gruncie rzeczy bardzo dobrze z Pythonem radzi sobie Vim. Wiedząc, że kombinacja klawiszy [ctrl]+[x] [o] uzupełnia składnię wielu funkcji pythona (choć niestety są tutaj zauważalne braki) podając również w okienku nad kodem jej dokumentację (brawo !) a [ctrl]+[n] uzupełnia na podstawie wpisanego już w kodzie lub plikach tekstu - można śmiało używać Vima. Przy odpowiednich ustawieniach wcięcia :) i kolorowanie - no niemalże nic nie brakuje.
Znacznie bardziej rozbudowany jest na przykład Eclipse, który zaznacza nam na "marginesie" kodu wszystkie linijki nie zgodne ze standardem kodowania PEP-8, posiada znacznie bardziej wyrafinowane uzupełnianie składni oczywiście moc funkcji konfiguracyjnych.

Należałoby tutaj wspomnieć o pewnej wciąż drażniącej mnie przypadłości Windows. Konsola i PATH :| Wieczne utrapienie. Problem polega między innymi na tym, że programy uruchamia się na przykład wpisując:

python moj_program.py
Po pierwsze żeby konsola była zjadliwa wypadałoby użyć Windows PowerShell i zmienić w niej czcionkę na coś bardziej zjadliwego. Ja używam Lucida Console 14 bez pogrubienia. Zaletą tej konsoli jest fakt iż można w niej stosować polecenia takie jak na przykład ls nie walcząc z Uniksowymi nawykami. Jednak nadal uruchomienie konsoli Pythona czy wykonanie w niej programu w którymś momencie spowoduje odpaleniem go w zwykłej konsoli cmd i cały urok gdzieś znika :| nie udało mi się jeszcze zmusić całego systemu aby używał wszędzię PowerShella.
Kolejny frustrujący, tym razem już prostszy do rozwiązania problem, to fakt, że domyślnie polecenie Python nie jest wrzucone do zmiennej PATH. Możemy to zmienić wchodząc we Właściwości Mojego Komputera (Właściwości Systemu), wybierając w zakładce Zaawansowane opcje Zmienne środowiskowe ... i modyfikując  lub dodając zmienną użytkownika PATH na przykład:

%PATH$:%ProgramFiles%\Python26\

Przynajmniej tak to wygląda pod Vistą w przypadku instalacji w domyślnym katalogu Program Files.
Oczywiście to nie rozwiązuje poprzedniego problemu i nadal mamy totlotek, z której konsoli będziemy korzystać :| Jeżeli ktoś potrafi rozwiązać rzeczone problemy :) to byłbym szalenie wdzięczny za uwagi w komentarzach. Jednak z mojego doświadczenia nic nie równa się z wygodą używania Pythona w Linuksie. Więc jeżeli masz dostęp do jakiegoś shella lub możliwość używania Linuksa ad hoc - skorzystaj z niego :) Pod Windows najwygodniej pracować jest w jakimś edytorze, który posiada swój własny shell i wyjście programu tak aby nie musieć używać linii poleceń Windows (o zgrozo).

Gdzie zacząć szukać. Ja zacząłem od kursu Jakuba Swachy - był przyjemny. Polecam również moje wykłady. Jeżeli zaś chodzi o dobrą literaturę - natknąłem się w sieci na draft Thinking In Python. Już programujący i niebojącym się języka Angielskiego - bardzo polecam. Mnóstwo materiałów znajdziecie rownież na stronie Polish Python Coders Group szczególnie w dziale artykuły i wykłady.

Powodzenia !

Saturday, December 20, 2008

web2py - wymiękłem

Jeszcze tydzień temu zachwalałem, w swojej prezentacji, na konferencji w Warszawie Pylons. Prezentowałem jego cechy, zalety oraz braki. No właśnie braki. Po obejrzeniu prezentacji Webhosting.pl o wdrożeniu Pylons oraz "Pylons - Demonstracja możliwości" Tomasza Nazara. Można je znaleźć na stronie materiałów PyCon2008 PL zaczęło do mnie docierać, że Pylons nie jest niczym - fenomenalnym.

Zacząłem analizować ... porównania. Porównania z innymi frameworkami. W Merb zachwyciła mnie modularność, wydajność i czytelność kodu. Przyznaję się. Nie napisałem w tym frameworku nawet pół linijki kodu. Cały podziw dla kunsztu przedkładam wyłącznie z wypowiedzi z jakimi spotykam się w sieci. Przeglądając pluginy znalazłem ciekawą opcję walidacji danych wchodzących do datamapeera jednak zabrakło mi gdzieś generowania formulrzy czy chociażby samej obecności admin panelu. Wiem, że ma być obecny w wersji 2.0 :) To cieszy. Być może coś przeoczyłem jednak przy moich obecnych obserwajach Merb w porównaniu do Pylons ma fantastyczne validowanie, z tłumaczeniami błędów i to w kilku języka... I do tego ta elegancja składni dekoratorów - miodzio.

No właśnie. Skoro już przy tym jesteśmy. Pylons tak jak merb nie posiada admin panelu. Tutaj na tle frameworków Pythonowych króluje Django. Nie ma mowy o scaffoldingu czy czymkolwiek takim. Nic z tych rzeczy. Modularność może cieszyć, jednak niestety nie znajdujemy mechanizmów do generowania formularz (znowu) ... Co prawda jest FormBuild ale wygląda bynajmniej podejrzanie, pomimo tego że jest opisana w PylonsBook, i jakoś ... nie o takim generowaniu marzę.

No więc może Django. Posiadania rozbudowane generowanie formularzy oraz admin panel. Pomimo tego nie dorasta do pięt Pylons w walidowaniu formularzy o braku możliwości testowania kodu (co często jest krytczne) nie wspomnę.
Sprostowanie
Od wersji 1.0 Django posiada możliwość pisania zarówno unittestów (z użyciem Pythonowej biblioteki unittest) jak i functional testów. Jest temu poświęcony poddział dokumentacji.

Co do Railsów - wydają się tutaj rozsądne. Posiadają na przykłąd mailer, którego na próżno szukać w jakimkolwiek pythonowym frameworku. Jest konsola (jak w Pylons), Scaffolding. Może brak admin panelu (chociaż może ktoś zna takowy), ale nie ma co narzekać: mailer, rack do testowania, migracje. HAML, SASS, spory wybór możliwych do podpięcia ORMów ... bomba.
A co gdybyśmy chcieli programować w Pythonie ? HAML i SASS oczywiście nie zagościł tutaj, mailerów nie można się spodziewać (choć szkoda, bo przydałaby się dobrze przetesowana biblioteka odporna na MailInjection) .

Wszystkie frameworki są do siebie jednak podobne. Generowany jest jakiś kod, używa się poleceń skryptowych i konsoli...
Dziś trafiłem na ten screencast pokazujący możliwości frameworka web2py



Nie wiem jakie macie podejście do tego co jest na nim pokazane. Wszystko co jest tam zaprezentowane to prawda, choć bardziej przypomina to "klikanie" aplikacji, niż jej tworzenie. Na prawdę. Nie otworzyłem ani przez sekundę edytora. Konsola też w gruncie rzeczy jest zbędna (chyba, że chcesz w niej odpalić serwer). Jest scaffolding (wow). Co prawda nie zauważyłem, żeby można było sobie wygenerować jego kod do pliku "od tak" jak w Rails, ale jest ! i to nie lada. Formularzy się "nie generuje" po prostu ... są :) i walidowanie jest ... bajecznie proste.
Wydaje mi się troszkę, że tak zautomatyzowany framework będzie podpadał pod zarzuty pod jakimi padał Django w ogniu Grono.net jednak ... to co dziś widziałem robi na mnie wrażenie. Web2Py to coś ... innego, coś co zmienia myślenie o tworzeniu aplikacji internetowych. Zobaczymy co jeszcze :)

Monday, December 1, 2008

Python Wykłady - uaktualnienie

Moja wiedzy o Pythonie wciąż się poszerza a wraz z nią zmieniają się wykłady.
W części pierwszej zmieniłem troszkę "wypunktowanie" pythona na jego korzyść - doszedłem do wniosku, że Python posiada dobry edytor po tym jak zobaczyłem pydev w Eclipse oraz usłyszałem opinie o Komode IDE - jest to moim zdaniem porównywalne z programem Zenda oraz PDT.

Poprawiłem kilka błędów, które zauważyli moi znajomi. Dodałem opis or, not i and w części drugiej zaraz przy omówieniu ifów.

W części trzeciej dodałem do klas informacje o tym jak enkapsulować zmienne w Pythonie :) Coś czego dopiero nie dawno się nauczyłem.

Thursday, November 27, 2008

Ruch na pylonshq.com

Od czasu do czasu wpadam na http://www.pylonshq.com/ i buszuję odrobinkę po stronce aby zobaczyć co się pozmieniało :) W sumie ruch jest duży, którego dnia bym nie wszedł wciąż pojawiają się jakieś nowe uaktualnienia lub komentarze do artykułów. PylonsBook od jakiegoś czasu jest już zamknięte, a treść wysłana do wydawnicta. Ostatnio pojawiło się sporo propozycji buttonów i logo Pylons dostępnych na stronie: http://wiki.pylonshq.com/display/pylonscommunity/Pylons+Logo

Myślę, że widać iż wydanie 0.9.7 oraz .0.9.8 zbliżają się dużymi krokami. To cieszy :)

Wednesday, November 12, 2008

Google gadgets - po prostu strona

Dzisiejsze popołudnie poświęciłem na przyjżenie się ciut bliżej tworzeniu gadgetów dla gmail. Na starcie wziąłem pod lupę rtm.xml - gadget Remember The Milk. Okazało się, że jest to plik XML opisujący kilka własności obiektu, który pojawi się w panelu gmaila z linkiem do strony wstawianej "w ramkę". Tak więc wszystko opiera się na napisaniu normalnie działającej witryny i włożenia jej w "ramkę" gmaila. :) Super !

Kilka ciekawych informacji można znaleźć na http://code.google.com/apis/gadgets/docs/reference.html lub wzorować się na innych :] Tak czy owak - rozwiązanie jest genialne w swej prostocie i ogranicza nas wyłącznie nasza wyobraźnia i umiejętności towarzyszące naszej personie przy tworzeniu stron internetowych.

Tuesday, November 11, 2008

Jython - przydatny, bez szału

Wczoraj musiałem napisać malutką, multiplatformową aplikacyjkę. Chodziło o niewielką ikonkę w trayu, podpięte do niej menu z opcją "&Zamknij". Ikonka w zależności od zawartości pewnej witryny miała się zmieniać na kolorową lub czarnobiałą.

Z jednej strony chciałem napisać to w Pythonie: przenośność, prosta składnia, czytelność - po części znane mi biblioteki. Z drugiej nie chciałem użerać się z wxWidgets, którego w ogóle nie znam. Muszę przyznać, że moim faworytem do interfejsów jest zdecydowanie Java. Już samo Swing jest bardzo dobrze zaprojektowanym rozwiązaniem jednak jeżeli dorzucić do tego możliwość pisania kodu z SWT - bije chyba wszystkie inne rozwiązania na głowę. Ponieważ zależało mi na estetyce aplikacji pod wieloma systemami - Java wygrywała przede wszystkim na tym polu.

I tutaj pojawia się właśnie pomysł na użycie jythona. Idea okazała się bardzo prosta. Używanie składni Pythona do modułów Java. Na początku bardzo miłe zaskoczenie:

from org.eclipse.swt.widgets import *

po prostu szok. Normalna biblioteka Java a ja tu sobie ją importuję po pythonowemu. Super ! Zaraz potem mogłem sobie zrobić:

import urllib

i wszystko działało :) Zmiana implementacji pojawiła się przede wszystkim przy listenerach - gdzie nie mogłem tworzyć klas "in place" jak w Javie, ale musiałem tworzyć własne - dziedziczące po tych mi potrzebnych. Jednak to raczej wpłynęło na Pythonowo rozumianą czytelność programu. Co do struktury początkowej ten kto pisał w SWT na pewno się połapie:

class App(object):

    def __init__(self):

        """Główny kod aplikacji."""

        self.display = Display()
        self.shell = Shell(self.display)

self.setTrayIcon()
self.createMenuItems()

        self.timer = Timer(self.display, self.image, self.tray, self.trayItem)
        self.timer.checkIsUndoneTickets()
        self.display.timerExec(5 * 1000, self.timer)

        while not self.shell.isDisposed():
            if not self.display.readAndDispatch():
                self.display.sleep()
                
        self.display.dispose()
        
if __name__ == '__main__':
    App()

Moim zdaniem banalne i genialne zarazem :] Właściwie - to samo co w języku Java tylko zapisane z użyciem innej składni.

Niestety nawet w tak banalnym programiku odczułem kilka podstawowych rzeczy. Na początku chciałem użyć Timera Pythonowego. Nie mógł on jednak komunikować się  z wątkiem głównego programu - SWT. Cóż, zmuszony byłem wykorzystać ten SWTowy.

Kolejna rzecz. Mój program wymaga otworzenia domyślnej przeglądarki systemu. Po trafieniu na moduł webbrowser Pythona już się cieszyłem, gdy zauważyłem, że niestety w Jythonie jest on niedostępny. Tak więc zmuszony byłem po raz kolejny użyć Javy.

Desktop.getDesktop().browse(URI(ratunkuAdminURL))
Dodatkowo powyższy kod działa tylko po części tak jak chciałem. Otwiera mi firefox-a w systemie, w którym domyślną jest Chrome. Powyższy kod bazuje na składnikach przestażałej już w wielu miejscach biblioteki awt. Jestem ciekaw czy nie istnieje możliwość zrobienia tego samego lepiej w Java :]

Friday, November 7, 2008

Konfigurujemy VPS - komentarz

Dziś natrafiłem na szalenie ciekawą serię artykułów zatytułowaną Konfigurujemy VPS

Bardzo ciekawy temat, z przykładowymi obrazkami i rzetelnymi wyjaśnieniami. Szalenie zainteresowało mnie php-fpm. Muszę się mu przyjrzeć.

Odniosę się tutaj do Shared Hostingu. Zastanawiam się, czy ktoś bawi się w VPS na Apache. O ile w przypadku Shared Hostingu Apache jest po prostu - najlepszym wyborem o ile dla mnie wybór na VPSa jest oczywisty (na pewno nie Apache).

Fantastycznie zareklamowane postawienie na wejściu nginxa z przekierowywaniem ruchu do Apache - trzeba spróbować :) Co do PHP - wspomniał bym o kilku drobiazgach. Primo. Przyśpieszyć go można używając np. XCache lub APC. Do VPSa są po prostu świetne (APC okazuje się słabsze przy serwerze, z kilkoma tysiącami kont, na których po prostu wysiada).

Jeżeli o spawnowanie procesów FastCGI chodzi - dla wielu kont zżerają znacznie więcej pamięci niż mod_php na Apache i niestety przy użyciu do nich dodatkowo suexec po prostu serwer musiałby być maszyną rodem z TASKu, żeby móc to obsłużyć.

Gdyby chcieć mieć shared hosting ze spawnowanym PHP vis user z XCachem dla każdego usera z osobna - potrzebna byłaby POTWORNA maszyna.

Merb - i propaganda Railsowców

To już kolejny raz kiedy napatocza mi się ktoś ze znajomych, który mówi "Widziałeś Railsy jaaa - fantastyczne !", albo "Będę się uczył Railsów", albo "Właśnie skończyliśmy projekt w Railsach, który robiliśmy z kolegami.". Kurcze belek. Bawiłem się w Railsach, używałem też kilku innych frameworków takich np. jak CakePHP, CodeIgniter, Symfony czy Pylons a także jestem wciąż naocznym świadkiem wszystkich odkryć współlokatora, który zgłębia Django i nie rozumiem - czym się ludzie zachwycają. Rails - przereklamowany, z tego co czytałem, bezmyślnie zaimplementowany, niewydajny, posidający błędy framework, który jak widać pomimo swoich wad wciąż robi wielki show więc do listy dodałbym jeszcze podkreślając  po raz kolejny przereklamowany framework.

W przyszłym miesiącu premiera Merba. Śledzę jego karierę od czasu gdy wpisy zaczęły pojawiać się na blogu Zabiello, później zaimportowałem sobie kanał RSS z Merbist, przeszukałem sieć pod kątem materiałów na jego temat, pooglądałem slajdu z MerbCamp... i wciąż zastanawiam się co jest z ludźmi zafascynowanymi Railsami nie tak.  Żadne argumenty nie przemawiają do osób, które zamierzają się uczyć Railsów, aby spróbować z Merbem. Nie ważne czy powiem: "jest szybszy", "jest przemyślanie zaimplementowany", "uczy się na błędach railsów", "jest napisany przez fachowców od Rubego" - argument zawsze jest ten sam: "Do Railsów jest więcej książek, Railsów jest się łatwiej nauczyć". Ludzie - co z tego, że jest do nich 2,5 miliona książek. Do Merba jest kilka 5,3 GB filmów. Natrafiłem również na ciekawy - wyglądało na to całościowy - kurs Merba [http://merb.4ninjas.org/] choć jeszcze nie dokończony  - cóż więcej można chcieć ?

Nadal będę próbował propagować ideę Merba, przekonywać do niego railsowców. Może zrobię do niego slajdy. Uważam, że jest to fantastyczny framework. Używałem w nim wyłącznie templatów i kontrolerów, ale już samo HAML i SASS mnie tak użekło iż stwierdziłem, że ten framework to numer 1 :) i basta !

Z pozdrowieniami dla wszystkich railsowców jadących wciąż lokomtową parową w czasach ażewe :) Merb propagator :P

Ruby on Rails vs .... series

Dziś kolega, zafascynowany Ruby on Rails, pokazał mi filmiki z serii Ruby on Rails vs .... http://pl.youtube.com/results?search_query=Ruby+On+Rails+vs&search_type=&aq=f

Na starcie zapytałem: "A jak wygląda filmik z Django" [http://pl.youtube.com/watch?v=PLUS00QrYWw] Chyba musieli się naprawdę wysilić żeby coś takiego wymyślić. Moim zdaniem - śmiech na sali. W momencie, w którym to obejrzałem twórcy wydali mi sie śmieszni i w gruncie rzeczy - sami ośmieszyli Railsy.

Przy informacjach, jakie można znaleźć na blogach, w których zarzutami przeciwko railsom jest wydajność (tutaj Django pokazuje klasę że hoho) czy też błędy znane od lat, czy chociaż kiepski sposób implementacji porównywanie siebie z Django z góry z założeniem "Railsy muszą wypaść na plus" - jest bez sensowne.

Friday, October 31, 2008

Windows Vista - Twoja decyzja

Mniej więcej rok temu na gwiazdkę dostałem laptopa. Zrzuciła się cała rodzina. Prezentem był Fujitsu-Siemens Amilo Pro V3525.
Ponieważ był to prezent nie miałem żadnego wpływu na to co dostanę. Oczywiście na pierwszy ogień poszedł Ubunciak - Vista, po pewnym czasie, szalenie wolno zaczęła działać. Po zainstalowaniu Linuksa - zaczęło się. Karta graficzna intela nie potrafiła udźwignąć gier 3D, a raczej słabo sobie radziła zaś karta dźwiękowa - poza tym, że w ogóle jest cicha to choć firmuje się jako realtek, okazało się, że niestety w Linuksie nie mam co marzyć o tym aby wkładając słuchawki alsa wyłączała mi głośniczki i na odwrót, szalenie irytujące. Choć nie zgłosiłem buga na bugtrackerze ALSY to wciąż mnie to denerwowało.

Z zazdrością patrzyłem na kolegów, którzy kupili sobie Asusy z NVIDIĄ i Realtekiem. Coż poradzić - darowanemu koniowi nie zagląda się w zęby. "Następnym razem kupię sobie już za swoje pieniąze Maczka, i tyle."

Z całą historią wiąrze się jeszcze jedna rzecz. Na rok pojawił się kolega z Maciem. Patrzę ! A On używa na nim Windowsa. Oczywiście się wzburzyłem! Jak można zrezygnować z Leoparda ?! Na którymś seminarium ten kolega miał problemy (chociaż może w końcu mu się udało), z podpięciem rzutnika pod Laptop. Pomyślałem sobie ... hmm ... A więc nie wszystko działa.

Wczoraj moja głowa zaczęła pracować. Gdybym kupił sobie Maca to oczywiście - wiedziałby, że jest na nim Mac OS X i używał tego właśnie systemu. Czy dziwiłbym się gdyby coś nie działało, wciskając temu komputerowi Windows ? Chyba raczej nie. Kupiłem go, jest na nim Leopard, wiem, że z nim komputer będzie działał dobrze a jak chcę mieć coś innego - trzeba było sobie kupić lapka z Windows, a nie teraz cudować - ktoś mógłby mi powiedzieć.

Zacząłem się zastanawiać czy nie podobnie jest w moim przypadku. Dostałem laptopa, współpracuje z Windows Vista i wiem, że z nim działa dobrze i co !Jak próbuję mu wcisnąć Linuksa to powinienem się dziwić, że nie wszystko działa ? Chcę mieć Ubuntu - powinienem sobie kupić DELLa a nie Fujitsu-Siemens.

Tak więc od wczoraj jestem ponownie szczęśliwym użytkownikiem Windows Vista Businnes i to się nie zmieni. Doszedłem do wniosku, że wyzwaniem będzie dla mnie nauczyenie się obsługi tego systemu. Zacząłem jednak zauważać u siebie bardzi dziwne, ciekawe syndromy. Otóż - pogodzony z tym iż będę już siedział w tym systemie zacząłem go ciut ulinuksawiać. Działam już na PowerShell, wciąż nie wiem jak zmusić skrypty Pythona aby odpalały się wew. tego samego okna PoweShell a nie w cmd.exe. Zainstalowałem sobie openSSH (jedyny mój problem to to, że nie mogę używać kluczy bez haseł dla autoryzacji). Na uczelni dowiedziałem się, że Windows Vista jest zgodny z POSIX tak więc kwestią czasu jest znalezienie takich poleceń jak chmod czy wszystkich innych ps, bg, fg itd... przypominających pracę z powłoką Linuksową.

Muszę szukać po grupach ? Tak - to prawda, jak każdy użytkownik Linuksa. Pomęczę się (jak w Linuksie) i nagnę po pewnym czasie system do moich wymagań, choć czuję, że dołoże laptopowi chyba jeszcze z 2 GB ramu :) dla pewności.

Aha i na koniec. System mi jeszcze nie muli, jak zacznie zmienię zdanie, ale jak wyłączy się automatyczne instalacji aktualizacji to Vista nie jest zła i naprawdę zdziwilibyście się jak Microsoft zmienił politykę i jak wiele dobrych aplikacji do Windows jest za darmo. Np. Pash :] - choć to akurat nie zasługa MS :)

Wnioski - skoro kupujesz MacBooka - nie zrzymasz się na Apple, że działa świetnie z Mac OS X, skoro kupuję coś Microsoftu - nie zamierzam się zrzymać na to, że działa świetnie z Windows Vista (bo działa !). Mam dwie drogi, albo się wściekać i toczyć walkę albo zaakceptować rzeczywistości. Przez rok przyjmowałem postawę pierwszą, czas na drugą i czuję, że zmienie ją dopiero kupując innego laptopa.

@edit
Niestety w Windows Vista Business nie zaświadczę zgodności z POSIX ponieważ istnieje ona dopiero od wersji Enterprise w górę (czyli jeszcze tylko Ultimate)

Wednesday, October 29, 2008

Python introspekcje funkcji

Nie wyobrażacie sobie jak byłem zdziwiony kiedy wczoraj na kanale IRC python.pl zobaczyłem, pierwszy raz w życiu - na oczy, implementację introspekcji funkcji.

Funkcja może być potraktowana jak obiekt o zbiorze jakiś właściwości. Weźmy sobie funkcję:

def fun(a,b=1,c='defc'):
"""DOCSTRING"""
print '{0} {1} {2}'.format(a,b,c)

O bebechach samej definicji funkcji może nam dużo powiedzieć już samo:

dir(fun)

func_doc
Zwróci nam dokumentację funkcji # 'DOCSTRING'

func_name
To nic innego jak nazwa funkcji # 'fun'

func_defaults
Krotka podające wartości domyślne funkcji # (1, 'defc')

func_code
Zwróci nam obiekt reprezentujący ciało funkcji. Możemy spróbować go wykonać używając metody exec. Oczywiście próba zakończy się niepowodzeniem ponieważ nie przekazaliśmy do kodu argumentów.

Obiekt ten jest o tyle ciekawy iż sam posiada kilka własności, które mogą pomóc nam dalej diagnozować funkcję. Na przykład:

func_code.co_argcount
Poinformuje nas o tyle ile funkcja przyjmuje parametrów

func_code.co_filename
Powie w jakim pliku została zdefiniowana funkcja

func_code.nlocals
Ilość lokalny zmiennych (łącznie z argumentami)

func_code.co_varnames
Krotka z nazwami lokalnych zmiennych (rozpoczyna się od argumentów funkcji)

Bardzo ciekawą własnością jest func_code.co_flags. Sprawdzając czy zostały dla niej ustawione konkretne bity możemy szybko dowiedzieć się kilku interesujących rzeczy.

Jeżeli w co_flags został ustawiony bit 0x04 Funkcja posługuje się parametrem *arguments. Bit 0x08 oznacza iż nasze obiekt posługuje się **kwarguments zaś 0x20 gdy funkcja jest generatorem.

Pierwszym sposobem, aby sprawdzić czy funkcja posiada, którąś z tych właściwości jest wykonanie ilorazu bitowego z poszukiwaną wartością. Tak np. jeżeli

fun.func_code.co_flags & 0x04

wyjdzie 0 oznacza iż nasza funkcja nie korzysta z *args, jeżeli otrzymamy 0x04 - korzysta.

Więcej szczegółów:
http://docs.python.org/reference/datamodel.html#index-1940
http://docs.python.org/reference/datamodel.html#index-1965

Tuesday, October 28, 2008

Python singletone

Dziś na okienku przed angielskim usiadłem na chwilkę, żeby zaimplementować w Pythonie singletonea :) Wygląda to w tym języku szalenie oryginalnie:

#!/usr/bin/python

class Klasa(object):
    pass

class Singletone(object):

    __instance = None

    def __new__(self):

        if Singletone.__instance == None:
            Singletone.__instance = self
        return Singletone.__instance

if __name__ == '__main__':
    s1 = Singletone()
    s2 = Singletone()
    k1 = Klasa()
    k2 = Klasa()

    print 'Singletone: ' + repr(s1 is s2)
    print 'Klasa: ' + repr(k1 is k2)


Python coraz bardziej mi się podoba :)

Monday, October 27, 2008

Zmiany w wykładach Pythona

Od jakiegoś już czasu poprawiam znalezione literówki, dodaję niektóre slajdy, zmieniam kolejność itd... Dzisiaj poprowadziłem dla jednoosobowej widowni próby wykład i wprowadziłem kilka znaczących zmian w slajdach, które sprawiają iż wszystko jest bardziej spójne i zaczyna wynikać jedno z drugiego. Zmiany pojawiają się codziennie - więc proponuję zainteresowanym śledzić pliki. Nie pojawia się w nich na razie żadna nowa treść, są to tylko zmiany np kolejności slajdów, dodania komentarza, usunięcia czegoś tak aby wykład stanowił jakąś "całość".

Framework Web 2.0++ ?

Dzisiaj, jadąc autobusem, zastanawiałem się nad różnicami pomiędzy chmurami obliczeniowymi a zwykłymi aplikacjami. Dokładniej nad tym czy można byłoby zrobić małą rewolucję w stworzeniu framerowka, który zrewolucjonizowałby tworzenie witryn Web 2.0. Pierwsze co mi przyszło do głowy to stworzenie helpera ajax_link_to(source_link, destination_element), który zwróconą zawartością aktualizowałby jakiegoś na przykład diva. Oczywiście odpowiednie konfigurowywalne. Taki gotowy mechanizm do tworzenia statycznych witryn Web 2.0.

Problem pojawia się gdy musimy np. zapisać newsa czy dodać użytkownika. W aplikacjach webowych obiekty przecież giną, w zwykłej aplikacji wszystko dzieje się w jakiejś dużej pętli, której zakończenie oznacza wyjście z programu. Co można byłoby tutaj zmienić ?

Może to co przyjść do głowy to próba zapętlenia skryptu działającego na serwerze. Hmm :) Z jednej strony oczywiste jest, że jak długo nie zakończy się skrypt tak długo nie wyświetli się witryna. Możemy tutaj spekulować z użyciem buforowania i flushowania buforów. Wtedy nawet gdyby wszystko działało w pętli trzeba byłoby uporać się jeszcze z timeoutami.

Ktoś inny mógłby wpaść na pomysł trzymania wszystkich obiektów w sesjach. I jest to chyba najprostsze rozwiązanie. Framework mógłby wspierać również jakąś inteligentną metodę przekazywania do zapytań ajaxowych obiektów, z którymi będzie pracować i odbieraniu zmodyfikowanych form oraz nadpisywanie obecnych.

Pomysł zastosowania obiektowej bazy danych byłby jeszcze lepszy :) bo pozwalałby na zachowanie stanu witryny również po jej wyjściu.

Jak widać bezstanowość protokołu HTTP sprawia nie lada problemy. Istnieje oczywiście jak widać kilka rozwiązań, które mogłyby nam pomóc jednak sprawdzenie wydajności i wykonywalności ich zastosowań trzeba byłoby sprawdzić.

Friday, October 24, 2008

Python - wykłady

Dziś ukończyłem pierwszy etap przygotowywania wykładów z języka Python.

Wstęp
Cały ten fragment ma być zachętą do rozpoczęcia przygody z językiem Python. Przedstawione są w nim cele i historia języka. Na koniec pozwoliłem sobie na porównanie Python i PHP oraz Python i Rubego.

Podstawy
Bardzo ogólnikowe omówienie języka. Prezentacja ma na celu zaprezentowanie podstaw języka, ułatwiając jego późniejsze zrozumienie. Wyszedłem tutaj z założenia, że omówienie pewnych elementów dwukrotnie (wpierw pobieżnie, ponownie - dokładniej) jest właściwym podejściem. Po zakończeniu tej części będziesz miał ogólne pojęcie o języku i jego składni, czy strukturze.

Wprowadzenie
Tutaj wiele obiektów, które pojawiły się w części Podstawy omawiam już dokładniej. Te które pojawią się kolejnych, tematycznych działach wykładu - pomijam (na przykład matematykę).

Matematyka
Omówienie części matematycznej Pythona. Liczby zespolone i biblioteka math, a także rozwinięcie tematu w postaci kilku przykładów wykorzystania SciPy.

Tuesday, October 14, 2008

Przewodnik po Pylons 0.9.7

W ostatnich dniach postanowiłem usytematyzować swoją wiedzę związaną z frameworkiem Pylons. W wolnym czasie tworzyłem kolejne części przewodnika, z myślą o opublikowaniu go na łamach python.org.pl. Na "całość" składają się cztery części. Ponieważ niestety uczelnia daje się we znaki postanowiłem opublikować ich szkice a w miarę ich dopracowywania publikować oficjalnie opracowane wersje na wyżej wymienionym portalu.

Część 1 0.0.1

Część 2 0.0.1

Część 3 0.0.1

Część 4 0.0.1

Saturday, September 6, 2008

7digital.com i Visa Electron z Chipem

Otóż, od jakiegoś już czasu staram się posiadać wyłącznie legalną muzykę. Na początku zalogowałem się na lastfm.pl Jednak tam to czego mogłem słuchać było losowe. Pomimo to zauważyłem, że obok opcji buy istnieje download from 7digital. No to dawaj http://www.7digital.com/ i jedziemy. Przypadkiem piosenka, którą chciałem mieć znalazła się w zbiorze 7digital i mogłem ją kupić za 0,72 funta - co w dniu pisania tego posta jest to 3,38 zł. Po wypełnieniu wszystkich danych dla karty Visa Debet - piosenka była do ściągnięcia.

Plik jest "DRM Free" :) kodowany 192kbps - kawałek zajmował 10 MB (normalnie około 4 MB). Minus jest taki, że plik można ściągnąć wyłącznie trzy krotnie, dodatkowo idzie jak krew z nosa - jednak muzyka jest i to jest fajne. Nie musiałem kupować całego albumu i dobrze. Może to jeszcze nie jest to o co się Polska biła, ale nie jest źle ... to jedyny znany mi dostawca muzyki w takiej formie. Zobaczę jeszcze ile ściągną mi z karty :]

@edit:
Tak :) Pobrali z karty dokładnie 3,59 zł :D

Z mbanku do WBK

Sytuacja się powtórzyła. Znowu - zablokowałem sobie dostęp przez internet do konta. Jak zwykle pojechałem od rana, w poniedziałek do punktu obsługi klienta. Zacząłem od odnowienia telekodu. Oczywiście nic nowego - na zgłoszenie się operatora, trzeba było czekać długo. Kiedy już zamówiłem rozmowę, czekałem ... czekałem, czekałem. Chciałem odebrać rozmowę ustalić nowe hasło dostępu przez internet i dalej ! Jednak nic się nie działo. Postanowiłem zamówić kolejną rozmowę. Dowiedziałem się, że rozmowy są realizowane w kolejności zgłoszeń więc zgłoszenie kolejnej nic nie zmieni. Pomyślałem więc, że skoro jestem już na starówce to chociaż wpłacę sobie coś na koncie. Co prawda pieniądze będą dopiero za parę dni dostępne na karcie, ale w sumie również po to tu przyszedłem. Podszedłem do wpłatomatu i był - nieczynny. Od Pana w środku dowiedziałem się, że "pewnie przepełnił się i będzie czynny dopiero po 12 taj". Czyli co ? To, że pofatygowałem się tutaj w poniedziałek rano, nic nie zmieniło ? Ponieważ sytuacja nie powtórzyła się po raz pierwszy, a zapomnieć hasła zdarza mi się często powiedziałem dość - zmieniam bank. Podpytałem się kolegi o jego bank, używał WBK < 30. No to ok. Poszedłem do WBK, wystarczył dowód. Założyłem konto. Wpłaciłem szybko pieniążki w oddziale. Cieszyło mnie to, że mogę coś załatwić z człowiekiem, nie jestem zmuszony do interakcji z maszyną, która jak nie działa, albo jest w jakimś stanie, w którym nie może zrealizować moich rządań - to nie jest w stanie mi nikt pomóc. Po założeniu konta w WBK zrobiłem wpłatę własną i byłem po prostu zachwycony - po powrocie do domu (7 minut), pieniądze były na koncie do mojej dyspozycji. Marzenie. Dodatkowo musiałem jeszcze zmienić po założeniu konta kod pocztowy - 10 s, żadnej maszyny po prostu powidziałem gościowi o co chodzi on zmienił i wsio :) Było zmienione.

Dodatkowo po około 10 dniach doszła do mnie karta Visa Electron - jednak z chipem, a co w związku z tym przeczytajcie w dalszym poście.

Tuesday, September 2, 2008

Google Chrome on Linux - 437 MB żywych źródeł (aktualizacja)

Postanowiłem sprawdzić czy uda mi się odpalić google chrome na Linuksie. Trafiłem na stronkę: http://dev.chromium.org/developers/how-tos/build-instructions-linux gdzie pokazane było jak zbudować przeglądarkę ze źródeł. Na początku zdziwiło mnie, że snapshot mega wolno się ściąga ... Myślę sobie 400 coś KB ... hmm ... pewnie serwery są zapchane... Spróbuję przez svn. Przez svn leciało szybko, jednak zacząłem mieć po 3 minutach wrażenie, że ściągam całe google: cygwin, jakieś webkity ... do licha co jest. Wtedy przyjrzałem się jednostce stojącej przy liczbie danych ściągniętego snapshotu. CO ?! 437 MB - źródeł ...Po prostu zwaliło mnie z nóg. Nie wiem jak długo się to cudo będzie budować, ale chyba pierwszy raz poczuję na sobie oddech użytkowników Gentoo ... Poczekamy zobaczymy.

Źródełka zbudowały się dość szybko i - bez problemów. Jednak po wylistowaniu wszystkich plików uruchamialnych wczytałem się ponownie w instrukcję na stronach google i zobaczyłem to. W czerwonej ramce było napisane, że poodpalać to sobie mogę - testy do przeglądarki, ale o surfowaniu nie ma mowy.

Sunday, August 31, 2008

Jak zrobić z Gmaila domyślnego klienta poczty w Firefoksie 3?

Buszując po internecie znalazłem wpis o tytułowej nazwie. Ciekawa rzecz :) polecam wszystkim gmailowcom :]

Saturday, August 30, 2008

Komentarz do MVC - czyli frameworki PHP

Dziś przeczytałem świetny wpis wyjaśniający o co chodzi w MVC. Osobiście chciałem dodać do niego mały komentarz, który mam nadzieję pojawi się również na blogu autora.

Ja dzisiaj - nie wyobrażam sobie tworzenia stron internetowych inaczej. Osobiście jednak - nie pisałem nigdy własnego Frameworka - raz tylko pomagałem koledze, gdyż uważam, że pisanie własnego MVC to wynajdywanie koła na nowo.

O Kohana nigdy nie słyszałem. Osobiście zaczynałem od CodeIgniter i jest to prosty framework. Jego zaletą, która jest ważna dla początkujących, jest fakt iż posiada dobrą dokumentację i można naprawdę szybko połapać się co gdzie jest.

Na kolejny ogień poszedł CakePHP. Tam dowiedziałem się co to jest scaffolding. Z cech, które przemawiają za CakePHP moim zdaniem jest na pewno obsługa drzew i ACL, których nie spotkałem w żadnym innym frameworku. Szczególnie widać to w wersji 1.2, w której pojawiło się wsparcie dla internacjonalizacji. Szalenie również podoba mi się mechanizm "elements", który moim zdaniem bardzo ułatwia tworzenie szablonów, z różnych powtarzalnych komponentów, pod, które możemy podkładać różne dane, co szalenie skraca pracę w tworzeniu szablonów. CakePHP posiada w najnowszej wersji mnóstwo innych bibliotek i wygląda mi na to, że obecnie jest to najlepszy framework.

Obecnie tworzę projekt z użycie Symfony. CakePHP w wersji 1.2 na pewno chciał doścignąć Symfony. Moim skromnym zdaniem - przypadkiem go prześcignął. Co do symfony. Posiada mnóstwo pluginów i dużą społeczność. Używa Propel, modele są więc generowane i dostępne ad-hoc - bez pisania jakiegokolwiek kodu. Dzięki użycia Propel modele generowane są w bardzo inteligentny sposób. Na koniec - bez pisania nawet połowy linijki kodu - dostajemy gotowe klasy w PHP, które obsługują między innymi CRUD oraz posiadają metody automatycznie pobierające dane z innych tabel używając złączeń. Dodatkowo są one szalenie elastyczne. Kolejna rzecz to scaffolding,który jest naprawdę piekielnie użyteczny i pozwala w 1 minutę(naprawdę właśnie w tyle) stworzyć funkcjonalny panel administratora do prostej aplikacji. W moim przypadku problemem okazało się korzystanie z dokumentacji, która z racji niekompletności,rozstrzelenia oraz braku opisania każdego modułu od A do Z (istnieje tylko kompletny opis API) jest nieużyteczna. Z tej przyczyn prawdopodobnie do czasu aż to się nie zmieni - będę korzystał z innych frameworków. Na obronę powiem tylko, że dokumentacji, która istnieje obecnie jest dużo, niemożna narzekać na jej brak czy na nie opisanie jakiś komponentów.Projekt jest jednak tak kolosalny, że stworzenie do niego dobrej dokumentacji to nie lada wyzwanie. Na razie, w moim mniemaniu jeszcze nie udało się temu wyzwaniu sprostać.

Innym ciekawym moim zdaniem framerowkiem jest Akelos, który jak możemy wyczytać na stronie internetowej, jest portem Ruby On Rails napisanym w PHP.Tyle z moich doświadczeń. Może okażą się dla kogoś pomocne w dalszej przygodzie z MVC. Chciałem przy okazji polecić swój artykuł, w którym również swojego czasu opisałem MVC na blogu Matriksa.

Friday, August 29, 2008

Nokia 6600 - Python on Board

Ostatnio zainstalowałem sobie na swojej Nokii (po 2 latach ?) język programowania. Programy napisane przeze mnie w Java nie działały :| ale na szczęście jest Python :) Na początku miałem problemy z dowiedzeniem się jaką wersję systemu posiadam. Po długim myszkowaniu w sieci znalazłem witrynę, z której wynika jasno, że posiadam system S60 Second Edition. Skoro tak ściągnąłem sobie odpowiednią wersję PyS60. Poza samym językiem zainstalowałem sobie również PythonScriptShell. Dobra - fajnie. Laptop -> Telefon połączenie działa, ale co dalej ? Szalenie spodobał mi się wpis pokazujący jak otrzymać konsolę Pytona z telefonu na komputerze. Co więcej. Lista aplikacji prezentowana na wiki PyS60 jest imponująca. Jak zobaczyłem co można uzyskać używając aplikacji controlblue wiedziałem, że nie ma bata. Musi zadziałać.

Zacząłem grzebać w sieci. Okazało się, że Ubuntu 8.04 ma niestety błędy w paczuszce bluez-utils. Rozwiązanie znalazłem na jednym z blogów. Chodziło o dodanie repozytorium:
http://ppa.launchpad.net/ubuntu-kennynet/ubuntu hardy main
i zaktualizowaniu paczki bluez-utils. Od teraz wszystko było już proste. W zakładce source dowiedziałem się jak ściągnąć źródła. Po starcie serwera okazało się, że trzeba zmienić troszkę kod. Wykomentowałem linijki:
#port = bluetooth.get_available_port( bluetooth.RFCOMM )
#s.bind(("",port))

i dodałem:
s.bind(("", bluetooth.PORT_ANY))
Po tym zabiegu serwer ruszył jak kobyła. Dobrze jest go odpalić w tle (& na końcu) i przekierować stdout i stderr do /dev/null. Po uploadowaniu klienta i uruchomieniu go, ruszył bez problemów dodałem kilka poleceń i zacząłem się bawić. Patrząć na kod serwera zauważyłem, że wykonywane są po prostu komendy systemowe. Po chwili moja konfiguracja wyglądała tak:
Play/Pause amarok-nightly -t 0
Next amarok-nightly -f 9
Prev amarok-nightly -r 7
Shutdown sudo halt 6

I leżąc wieczorem w łóżeczku zmieniałem sobie piosenki, a jak powieki zrobiły się ciężkie bez ruszania się z miejsca - wyłączyłem komputer :] Po prostu gucio.

Sunday, August 24, 2008

Łowcy smoków - o co chodzi ?

Ok - prawda. Przyznaję się bez bicia. Chciałem iść na film, z dobrą akcją. Właśnie wróciłem z kina. Wybrałem Łowców Smoków. Kobieta sprzedająca bilety i Pani wpuszczająca na sale - były w niezłym szoku widząc mnie wchodzącego na salę. Film był chyba rzeczywiście dla dzieci skoro ostatni seans zaczynał się około godziny 15:45.
Na początku zdziwił mnie "wytwórca". Coś mało mi znanego - biorąc pod uwagę, że znam może z 4, którzy robią pewnie 90% filmów to powiedziałem sobie - ok. Mają konkurencję, co z tego, że mało znani - może się właśnie postarają. Na początku, gdy tylko rozpoczął się film (bajka ?) .... byłem mocno zawiedziony grafiką i efektami specjalnymi. Miałem ochotę na film akcji, z dobrymi efektami, a ich brak dało się zauważyć już po 2 minutach. No ale, cóż - nawet kiepsko zrobione filmy niosą ze sobą często jakieś ważne przesłanie. Pocieszając się, że film być może zaskoczy mnie swoją treścią - oglądałem dalej. Bajka jak bajka. Treść wydała mi się szalenie infantylna... to znaczy ... Film miał 80 minut, przy czym z 5 minut to napisy początkowe (takie odniosłem wrażenie), i opowiedz tu historię tak, aby nie robić skrótów myślowych, uproszczeń i wszystko opowiedzieć. Jeżeli nawet jest to wykonalne - to tu się nie udało. Bajka więc wydała się pisana jakby "na kolanie". Co do przesłania z całego filmu wydłubałem tylko 3 rzeczy.
+ Uwierz w siebie i w to, że potrafisz - są ludzie, którzy w Ciebie wierzą, a ty nie jesteś przeciętny ale powołany do rzeczy nieprzeciętnych
- Posłuszeństwo jest relatywne
- Kiedy poczujesz się potraktowany niesprawiedliwe wolno Ci kraść - w relatywnie dobrej sprawie

Tak więc film wypada raczej in minus z punktu widzenia wartości wychowawczych. Chyba nie zrozumiem filozofii ludzi, którzy robili film. Czas wrócić do Kopciuszka i Zakochanego Kundla.

Saturday, August 23, 2008

Dotpay - zawód

Jakiś czas temu miałem "przyjemność" zaimplementować obsługę dotpay w jednym z portali. Portal na pierwszy rzut oka, szata, oprawa, wygląda solidnie. Kiedy pisze się do obsługi odpowiedzi są bardzo konkretne jednak - tutaj plusy się kończą. Po zajrzeniu do dokumentacji na pierwszy rzut oka można mieć wrażenie, że "wszystko jest" jednak już pierwsza próba zaimplementowania czegokolwiek okazuje się, że wymaga niemal wróżbiarskich zdolności.

Domyślenie się, że pewne parametry nie są przesyłane (ale trzeba je u siebie hardcodować), do czego służy dana opcja, czy w końcu co dokłądnie wykonuje "testowanie". Kompletny brak profesjonalizmu i żenada. Jako programista spędziłem sporo czasu próbując dojść do tego - dlaczego hashe md5 nie są ze sobą zgodne - oczywiście, brak w dokumentacji. Takie rzeczy tak porządnej firmie. Na szczęście wpadłem na to co nie grało. Czy jest to jednak słuszne postępowanie w przypadku tak porządnej firmy. Dokumetnacja 2 na szynach.

Wednesday, August 13, 2008

Pylons - raport z pola walki

Od kilku dni (tygodnia) piszę pewną aplikację w Pylons. Myślę, że to dobry moment (choć pewnie - to nie wszystkie przygody jakie mnie czekają), żeby opisać co i jak.

Po pierwsze szalenie podoba mi się python. Kod pisze się szybko, zgrabnie. Jak się na to wszystko patrzy - to nawet mniej jakoś tego kodu się wydaje - i dobrze :] Tak powinno być.

Jak pisałem wcześniej Pylons używa zewnętrznych, istniejących w oderwaniu od projektu rozwiązań, do najróżniejszych zadań. Bardzo mi się to osobiście podoba :) i wpływa pozytywnie, moim zdaniem, na cały projekt.

FormEncode - świetne rozwiązanie do walidacji formularzy. Lepiej bym sobie tego sam nie zaplanował. Bardzo rozbudowane. Szkoda, tylko, że w pythonsbook są błędy - które wyłapałem dopiero po zajrzeniu w kod źródłowy wyżej wspomnianej biblioteki. Do tej pory na przykład nie wiem zmienić treść domyślnych komunikatów - dla wszystkich pól jednym pociągnięciem nie wprowadzając jej w każdym z osobna bez robienia własnego validatora (a o ile rozumiem z pylonsbook jest to możliwe).

W ogóle muszę przyznać, że jestem mile zaskoczony tym iż w ogóle istnieje coś takiego jak pylons book.

Kolejna rzecz - jeżeli chodzi o opis ustawiania kodowania w SQLAlchemy - to dokumentacja Pylons ... nawet nie - nie powiadamia nas o tym, ale bezczelnie wyprowadza nas w pole. Przydałaby się tutaj, z racji czystej żetelności, aktualizacja i uświadomienie użytkowników.

No i jak przy kodowaniu jesteśmy to niestety - python ze swoim unicode w wersji 2 sprawia same problemy. Używanie znaczków polskich w templatach, czy w kodzie - powoduje nie lada problemy w bibliotekach ... i nie zawsze udaje się je ominąć, czy załatwić sprawę w kontrolerze. Tak np. jeżeli użyjemy w FormEncode polskich znaczków w którejś wartości "GetOne" - to po wybraniu jej w formularzu zostaniemy poczęstowni błędem o niemożności odkowania symbolu.

Mam nadzieję, że zmiany na poziomie języka w Python 3000 jakoś to załatają ... bo obecnie moim zdaniem - stan jest opłakany.

Co do wcześniej wspomnianych komunikatów - o ile nie znajdę w źródłach FormEncode metody to da się to bodajże załatwić (mam nadzieję, że tak) poprzez i18n ... i tak zamierzam to zrealizować - jest to jakieś rozwiązanie :)

Hmm - co więcej. W Pylons brakuje mi czegoś co pozwalałoby zmienić nazwę kontrolera, ale to tylko taka moja fanaberia (często zmieniam zdanie co do tego jak coś powinno się nazywać ... i po prostu by mi się przydało)

O co do SQLAlchemy i fillhtml. Metody używania SQLAlchemy opisane w Docs Pylons zwracają obiekty danego typu - zaś do fillhtml przydają się słowniki na przykład.... Tutaj fajnie było wpaść do pomysł zaimplementowania udawania przez klasę danego modelu słownika - i przekonwertowanie jej na słownik. Zadziałało i powiem szczerze, że jestem z tego szalenie dumny :)

Jednak zaniepokoiła mnie pewna sprawa. Otóż mój klucz główny w tabeli wcale nie nazyw się "id" i na jakiś czas "magicznie" metoda "get()" przestała mi zwracać wartości z tabeli - ciekaw jestem czy to ma jakiś wpływ... mam nadzieję, że to był jakiś mój błąd a nie przypadek. Głupio by było gdybya aplikacja przestawała losowo działać.

Dziś myszkując po internecie na blogu Zabiello znalazłem informację, że Jego zdaniem Merb-a jest jakby prościej się nauczyć od Pylons bo jest prostrzy. Z mojego punktu widzenia - łatwiej się nauczyć tego co posiada lepszą dokumentację ... Pylons opanowuję sobie spokojnie... w swoim tempie, natomiast w Merbie to jest dla mnie mega - zgaduj zgadula (przynajmniej bez dokumentacji - bo chyba takiej "dla ludzi" brak).

Martwi być może tylko, że czasami projekty, z których korzysta Pylons nie są często od dawna wydawane. Ciekawe czy są porzucone, czy "ukończone" i co się stanie kiedy znajdzie się w nich błąd. Wierzmy, że wszystko będzie dobrze :)

Dziś pozytywnie zaskoczył mnie nawet python, w którym z pomocą kolegi napisałem niskopoziomowy wrapper procesów z pipem komunikującym się na 3 i 4 deskryptorze - coś czego w rubym nie udało mi się napisać jeszcze jakiś czas temu (dzięki Łukasz !).

Podsumowując - wszystko na plus ! Uaktualnijcie tylko dokumentację tak aby nie robić ludzi w konia, poprawcie błędy w pylonsbook, zróbcie coś z tym unicode i cacy :)

Monday, August 11, 2008

IVONA i Skype

Jakiś czas temu używałem IVONY, potem zdobyła chyba jakieś wyróżnienie, więc było o niej głośno, następnie dowiedziałem się, że to projekt ludzi z Politechniki Gdańskiej (o ile dobrze pamiętam) - stała mi się więc bardzo bliska jako oprogramowanie.
Któregoś razu zobaczyłem jak korzysta się z niej na komputerze. Dla mnie do tej pory stanowiła wyłącznie zabawkę jednak ciekawa rzecz - osobom mającym problemy z czytaniem czy niedowidzącym IVONA w komputerze ratuje życie. Jest po prostu świetna :]
Po obejrzeniu tego filmiku byłem po prostu urzeczony. Moim zdaniem pomysł jest świetny ! Pierwszy raz zacząłem żałować, że nie mam IVONY - fajna rzecz :] czuję w końcu ten powiew XXI wieku :)

Memento - Turk Telecom

Jakiś czas temu zmagaliśmy się w Matriksie z Turk Telecom :) I proszę bardzo :] w jakim charakterze dowiadujemy się o nim ponownie: http://di.com.pl/news/22884,1,0,Rosja_i_Gruzja_walcza_takze_w_internecie.html

Niby usunięte pliki po KDE4

Po usunięciu części paczek, które zainstalowały się w moim systemie podczas próby przesiadki na KDE4 zauważyłem, że z jakiś przyczyn nadal siedzi u mnie pliczek /etc/init.d/kdm-kde4. No cóż. Paczuszka kdm-kde4 została usunięta (tak twierdził synpatic) - więc skąd to się wzięło. Aby sprawdzić do jakiego pakietu należy ten dziwoląg wpisałem sobie na prędce:
dpkg -S /etc/init.d/kdm-kde4
Okazało się, że to jednak (usunięty) pakiet kdm-kde4. Po zaznaczeniu go do całkowitego usunięcia udało się go w końcu pozbyć. Ciekawa sprawa :)

Gdy coś się psuje w Ubuntu

Ostatnio zainstalowałem sobie próbnie KDE4. Niestety nie odpaliło się już po raz drugi a co gorsza ! wywaliło mi GDMa - musiałem wpisać startx z konsoli, żeby się dostać do Xów. Ratunkiem okazało się:
sudo dpkg-reconfigure gdm
I chyba jest to metoda działająca najlepiej na wszystkie bolączki :]

Friday, August 8, 2008

Pismo Święte - wyrazy, które mnie zaskoczyły

Ostatnio podczas czytania Pisma Świętego natrafiłem na wyrazy, które szalenie mnie zaskoczyły. Naprawdę nie spodziewałem się ich tam spotkać. Oto one: piecyk, piekarnik, kameleon, puszczyk, kormoran, łabędź, pelikan, ścierwik (ale chyba chodziło o ścierwnika), bocian, czapla, dudek.
Kto by pomyślał ?

Sunday, July 27, 2008

Kung Fu - Panda

Dziś wybrałem się do Kina - z kolegami ze szkolnej ławki. Nie widziałem ich szmat czasu. Przy okazji - dowiedziałem się od nich, i zjadłem pyszne naleśniki, gdzie jest naleśnikarnia we Włocławku. Kung Fu - Panda (padł orzeł, szkoda, bo na reszce był WALL-E) ... hmm - odstresowałem się. Tak ujmę film. Byliśmy my w trójkę w rzędzie H i jakieś dwie ekipy w ostatnim rzędzie - może jakieś 8-12 osób... Siedziało się fajnie, chłopaki się rozwalili na siedzeniach :| klimat był jednak fajny. Odprężyłem się. Nie wiedziałem czego się spodziewać, więc film mi się po prostu podobał jednak osobiście wychodzę z założenia - że dzisiaj nie da się trafić w kinie na totalną chałę.

Monday, June 30, 2008

Vim .netrc i nie musisz pamiętać haseł

Dodałem sobie pliczek ~/.netrc do katalogu domowego. Wrzuciłem tam:
machine serwer.pl login dziubdziub password haslodziubdziuba
machine linux.pl login dziubdziub password nextpasswordofdziubdziub
Zrobiłem jeszcze chmod 0600 ~/.netrc i nie muszę się już użerać z pamiętaniem haseł w vim :] po prostu mnie loguje !

Vim i FTP

Dziś musiałem zabrać się za projekt - zdalnie. Wchodzę do vima. Wklepuję :e ftp://.... i błąd - nie działa... Co jest ? Zacząłem szukać po necie - nic. Zajrzałem w końcu w źródła wtyczki netrw i zobaczyłem, że błąd, który był zwracany this system doesn't support remote directory listing via ftp występuje gdy nie ma w systemie polecenia ftp. No to rozpoczęły się poszukiwania... Po jakimś czasie doszedłem do tego, że odpowiedzialny jest za to pakiet netkit-ftp. Przy okazji zainstalowałem jeszcze net-tools... kurcze - Arch jest dla mnie troszkę zbyt szczegółowy - żeby polecenia ftp nie było :]

Sunday, June 29, 2008

Arch Linux - krzaczki w Midnight Commander

No tak :) Ja tutaj się męczę a wystarczy zamiast mc zainstalować mc-utf8 i nie ma krzaczków :]

Smplayer na archlinux

Przed momentem zainstalowałem sobie mplayera i smplayer. Miałem problem z dźwiękiem. Po ustawieniu w "Opcje/Ustawienia" Główne / Główne:

Wideo: xv
Audio: alsa

Wszystko zaczęło ładnie działać. Pomogło również skasowanie katalog ~/.smplayer i odpalenie programu.

Saturday, June 28, 2008

Arch Linux on Board

W końcu pozwoliłem dotrzeć do mojej świadomości faktowi, że choć Ubuntu jest wygodne - to jako Linuksowca ten system mnie nie rozwija. Wszystko "jest" i "działa".

Postanowiłem więc przesiąść się wczoraj na Arch Linuksa. Zachęcił mnie fakt, że wydawany był już w Czerwcu. Wydrukowałem sobie nawet instrukcję instalacji.

Kiedy spojrzałem, że podczas instalacji systemu będę musiał edytować pliki konfiguracyjne "by hand" to powiedziałem sobie "Nie wracamy na Ubuntu". Pomimo tego podjąłem wyzwanie.

Dokumentacja jest po prostu świetna. To co skomplikowane okazało się proste - trzeba było tylko spróbować i - zadziałało :] Pliki konfiguracyjne są dobrze opisane i po chwili czytania już wiadomo co w nich zmienić i jaka sekcja jest za co odpowiedzialna. Pacman - działa dokładnie tak jak go zaprojektowano. Jest szybki i działa :) naprawdę nie ma z nim problemów. Co do aktualności paczek - jestem w szoku. Biją na głowę te z Ubuntu.

System był potrzebny do pracy z projektem na LAMP. Zamiast A wybrałem L(ighttpd). Tutaj były już problemy.

1) W php.ini musiałem zmienić konfigurację ponieważ w lighttpd pojawiał się błąd "No input file specified". Rozwiązanie znalazłem w FAQ : [ http://trac.lighttpd.net/trac/wiki/FrequentlyAskedQuestions#IgettheerrorNoinputfilespecifiedwhentryingtousePHP ] (u mnie chodziło o ustawienie cgi.fix_pathinfo i dodanie odpowiedniego katalogu do open_basedir)

2) PHP w ogóle nie mogło połączyć się z bazą danych. Okazało się, że jest to wina tego iż MySQL nie nasłuchuje na porcie TCP ale używa socketów unixowych. Po zakomnetowaniu:
# skip-networking
i zrestartowaniu demona : [ /etc/rc.d/mysqld restart ] MySQL nasłuchiwał już na localhoście i można się było połączyć.

3) Zrobienie aliasu do phpmyadmin :
alias.url = ("/phpmyadmin" => "/srv/www/phpMyAdmin/")
oczywiście odkomentowując moduł aliasów w lighttpd. Niestety działa tylko link http://localhost/phpmyadmin/ czyli z ukośnikiem na końcu.

Z systemu korzysta się systematycznie. Porządna dokumentacja w języku angielskim - to jest to co lubię. Naprawdę o systemie można czytać i czytać. Wszystko konfiguruje się w plikach konfiguracyjnych i działa ! to chyba najważniejsze. Czuję się troszkę jakby to było gentoo, ale takie szybsze :) i mniej "dziwne". Osobiście n systemie zrobiłem sobie tutorial z całego "OpenBox" i jestem szalenie zadowolny ze środowiska, które teraz mam. Jest lekkie, nowoczesne, szybkie, ciekawe :) i proste. Dodatkowo w systemie nie mam "pierdół", które nie są mi potrzebne - ale dokładnie to z czego korzystam. Po prostu miodzio. Oczywiście - cena tego wszystkiego istnieje. Na konfigurację systemu poświęciłem wczorajszy dzień. To nie to co Ubuntu - ale ... coś za coś :)

Wednesday, June 25, 2008

Gdy zapomnisz hasła root-a

Do tej pory gdy zapominałem hasła root-a próbowałem się chrootować z jakiegoś live-cd na system i zrobić jako root passwd. Problemy pojawiały się gdy trzeba było zadbać o zgodność wersji jądra - aby się chrootować. Jednak ostatnio doceniłem potęge single user mode. Po prostu wchodzi się do GRUBa, edytuje się linijkę zaczynającą się od "kernel" we wpisie w GRUBie (guziczek e) , dopisuje na jej końcu słówko single a następnie bootuje się z niej (guziczek b). Dostajemy bez hasła konsolę z root-a, któremu możemy zmienić hasło :] A potem po wyjściu z powłoki: [CTRL]+[D] na przykład następuje pozostała "część" bootowania i wgrywa się normalnie system - bomba nie ?

Inny pomysł to dodać z jakiegoś live czy innego systemu linijkę do /etc/sudoers, która pozwoli po wykonaniu sudo su z jakiegoś konta dostać konsolę z rootem bez hasła.

Monday, June 23, 2008

Geany - ciekawy edytor

Kolega pokazał mi swojego czasu edytor Geany. Pisze, albo pisał swojego czasu, w nim programy do Pythona. Edytor przypomina troszkę zwykły edytor spod Gnome. Szalenie użyteczną opcją jest moim zdaniem, opcjonalnie włączane, okienko plików w prawym panelu oraz "konsola" w jednej z dolnych zakładek, z której możemy podręcznie korzystać lub zarzyczyć sobie aby w niej były wykonywane skrypty. Program posiada system wtyczek i chyba tyle. Jest prosty, przejrzysty a praca z nim to naprawdę przyjemność. Polecam każdemu kto szuka lekkiego, prostego, schludnego środowiska.

Sunday, June 22, 2008

Ruby i Python w jednym żyli domu ...

Kolega, z którym przez ostatni rok miszkałem, zaczął pisać swoje projekty w Pythonie. Mnie natomiast, choć i ja w pythonie coś pisałem, wzięło na Rubego. Miałem więc w różny sposób styczność z obydwoma języka programowania. Chciałem napisać dwa zdania o moich przemyśleniach.

Chciałbym zacząć od tego, że kiedy zabierałem się za którykolwiek z tych języków czułem się dziwnie. Wcześniej programowałem w Java, PHP, C, C++ ... i w każdym z nich mogłem szukać jakiś analogii do poprzedniego. Korzystać ze zdobytej wcześniej wiedzy czy też patrzeć na nowe rozwiązania (przykładowo foreach w PHP) jak na załatanie "dziur" niewygody z poprzednich języków (C, C++). Jednak do Pythona i Rubego - po prostu masakra ! Nic nie mogłem z siebie wykrzesać. Nic !  Dla mnie osobiście był to tak "inny świat", że zabierając się za te języki, wciąż miałem jakby umysł na uwięzi. Spętany nawykami sprzed lat obowiązującymi we wszystkich innych języka programowania, które poznałem starałem się przebrnąć, zrozumieć - nie mogłem. Ratunek był tylko jeden: książką lub dobry kurs do języka idący kroczek po kroczku. Musiałem zacząć się uczyć tych języków tak, jakbym nigdy wcześniej nie programował. Potrzebowałem dobrego kursu lub książki oraz społeczności, która pomogłaby w stawianiu pierwszych kroków.

Przygodę z Pythonem zaczęliśmy z kolegą od rozmówek. Pomysł okazał się jednak nie trafiony. Oczywiście rozmów, kiedy już programuje się jakiś czas w pythonie, są świetne - jeżeli zaś chodzi o dobre poznanie języka - okazały się zbyt zwięzłe i ogólnikowe. Potem trafiłem na kurs Jakuba Swacha, który okazał się strzałem w dziesiątkę. Po prostu - z niego nauczyłem się podstaw pythona. Z różnymi zagadnieniami czy problemami pojawiającymi się w trakcie rozwiązywania zadań do kursu zwracałem się do forum polish python coder group, gdzie zawsze mogłem otrzymać wsparcie i pomoc. Później kolega zakupił już sam "Python Podstawy". Książka okazała się rzeczywiście robieniem wszystkiego "krok po kroku". Jednak nawet jako początkujący znaleźliśmy w niej kilka błędów. Omawiająca szeroki zakres zagdanień, od podstaw, do problemów związanych z dystrybucją komercyjnych programów pisanych w pythonie.

Python jest prosty. Nie łatwy (choć może też), ale prosty. Jeżeli w Pythonie coś robi się "tak" to tak się to robi i nie powinno stosować się żadnego innego sposobu aby to wykonać. Programy wyglądają przejrzyście, są logiczne i zrozumiałem. Osobiście przeszkadza mi tylko fakt iż ogólnikowo nie wszystko jest obiektowe. Pojawiające się tu i ówdzie funkcje czasem utrudniają - bo wydają się "nie pasować". Często, wiele funkcji, które sprawdzają czegoś długość, ilość elementów itd ... mogłyby być po prostu metodami obiektu - jednak tak nie jest i często zapędzając się w "obiktówkę"... zastanawiamy się "czemu nie działa ?" a dlatego, że takiej metody nie ma - trzeba użyć funkcji.

Jeżeli o Rubego chodzi na start kupiłem Ruby On Rails. Próba przebranięcia przez tą książkę bez znajomości języka to była porażka. Na urodziny od rodziców dostałem "Ruby. Tao programowania w 400 przykładach". Jestem osobą, kra czyta wstępy do książek. Przeczytałem i tutaj. Na starcie dowiedziałem się, że "książka ta nie nadaje się dla osób, które chciałyby nauczyć się języka Ruby" - bomba ... a po to ją kupiłem. Spróbuję ! Przecież jestem zdolny ... Po siedmiu rozdziałach się poddałem: "Co to za syf ? Ile tu składni ?! Za dużo ! Po co tyle możliwości. O co chodzi !?" ... Zbawieniem okazała się dla mnie książeczka "Ruby. Wprowadzenie". Tutaj autor bardzo powoli zaczął omawiać język - książka okazała się dla mnie idealna... Naprawdę solidnie pozwoliła mi pojąć nie tylko sam język ale również jego "filozofię" i dostrzec w tym całym "bałaganie" pewien sens. Dodatkowo moje wątpliwości szybko rozwiewała społeczność na forum RubyOnRails.pl.

Ruby nie jest językiem prostym. Jest jak system operacyjny. Możesz administrować systemem od 10 lat, spotkać kolegę po fachu i dowiedzieć się, że wykonuje te same czynności w zupełnie inny sposób. Z Rubym jest jeszcze ciekawiej. Posiada on nazwałbym to bardzo rozbudowaną składnię. Twórcy języka jakby dopieścili każdy jego najdrobniejszy element. Nie wystarczyło im że stworzyli już coś co działa, ale z pietyzmem starali się zrobić tego tyle wariantów... na tyle sposobów - ilu programistów na świecie tak, aby każdy znalazł sposób na wykonania swojego zadania tak jak lubi. Nie nazwałbym Rubego językiem programowania - bo języki programowania to język stworzony po to aby maszyna nas rozumiała. Ruby został stworzony nie dla maszyny, ale dla człowieka, aby mógł ekspresywnie, twórczo, kreatywnie oraz precyzyjnie wyrażać swoje myśli i intencje pisząc kod programu. Czytając kod Rubego możesz spojrzeć na niego i zobaczyć coś więcej poza samymi instrukacji - możesz zobaczyć styl, osobę, która pisała ten kod oraz Jej finzję w wyrażaniu myśli.

Wiele osób uważa, że duża ilość możliwości jaką daje Ruby powoduje problemy ze zrozumieniem kodu. Teoretycznie możemy czytać właśnie kod, który czyta plik kompletnie go nie rozumiejąc, bo przez całe życie robiliśmy to inaczej - i nie znamy "tej metody". Jednak moim zdaniem Ruby jest tak skonstruowany, że dzięki samym nazwom metod oraz operatorów - nawet takich, które widzimy pierwszy raz na oczy - będziemy w stanie zrozumieć co wykonuje dany program.

Oczywiście wiele zależy również do programisty. Jakiego zapisu użyje w tej sytuacji, jak ponazywa zmienne, czy to co zrobi będzie miało sens. Święte wojny o to czy klasy w Ruby powinny byc otwarte - czy nie przypominają mi dyskusje związane z bezsensownym przeładowywaniem opratorów różnych obiektów w C++. Moje zdanie jest takie: Dobry programista będzie umiał wykorzystać nawet potencjalnie "niebezpieczne" mechnizmy na rzecz czytelności i zrozumiałości kodu - nie mądry, nawet ograniczony składnią języka może natłóc kod z którego nic nie wynika. Tak więc nie winiłbym języka za to iż przy otwrtych klasach w Ruby można "nieźle nagmatwać", ale raczej składałby odpowiedzialność na barki programistów. Dynamit też był wynaleziony by służyć dobru - tylko od ludzi zależy czemu tak naprawdę będzie służył, sam w sobie - nie jest zły.