Sunday, December 30, 2007

utf8_general_ci vs utf8_bin

Od jakiegoś roku głowiłem się nad problemem - dlaczego w dokumentacji MySQL LIKE jest case sensitive a u mnie nie. Problem polegał na tym, że wszystkie pola miałem utf8_bin. Oznacza to mniej więcej tyle, że wyszukiwanie odbywa się wtedy binarnie.

Wyszukiwanie binarne, czy sortowanie binarne nie jest czułe na wielkość znaków. Pole utf8_bin wymusza takie właśnie traktowanie i wszystkie zapytania automatycznie działają na danych jako binarne. Dlatego, jeżeli chcesz mieć wybór używaj pól utf8_general_ci a efekty binarne zawieraj w zapytaniu np. BINARY ORDER BY ... itp.

Friday, December 7, 2007

Listowanie na strony

Zawsze miałem problem, z tym jak obliczyć ile stron będzie zajmowało wyświetlenie wyników pewnego zapytania powiedzmy po 30. Jak robiło się LIMIT to COUNT automatycznie zawracało wartość w limicie. Ostatnio kolega podesłał mi takie zapytanie:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

The second SELECT returns a number indicating how many rows the first SELECT would have returned had it been written without the LIMIT clause.
Więcej znajdziecie tutaj:
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html

Monday, December 3, 2007

Pierwsze wrażenia z programowania w Rails

Powiem od razu nie są najlepsze. Może wpływa na to fakt, że kiedyś na spotkaniu TLUGu jakiś gość zbeształ PHP (porównując go do Rails) więc na dzień dobry podchodziłem do tego zupełnie sceptycznie.

Po pierwsze do tej pory nie udało mi się odpalić procesu i komunikować się z nim na poziomie strumieni 3,4 wykraczających poza standard in/out/err i nikt ze społeczności jak na razie nie jest w stanie mi pomóc.

Kolejna sprawa to dokumentacja. W porównaniu do PHP jest do niczego. Nawet www.noobkit.com czy getapi.com wypada bardzo słabo. Ok - nawet nie porównujemy tego, bo w sumie PHP ma najlepszą dokumentację jaką w życiu widziałem. Ale nawet dokumentacja frameworków PHPowych jest lepsza niż Rails.

Dodatkowo ogromna ilość artykułów niespecjalnie pomaga zorientować się w sytuacji... i odnaleźć drogę do celu :/ co stanowi pewien problem.

To taka pierwsza refleksja - może czas przyniesie zmiany. Zobaczymy.

Tuesday, November 20, 2007

Program z OJP

Zamieszczam swój program z OJP. Może komuś się przyda - jest tutaj bardzo dużo dobrego kodu (chociaż i słabego nie brakuje)... Mam nadzieję, że ktorą na tym skorzysta.

Powodzenia :)

http://jan.koprowski.zhr.pl/studia/OJP.tar.bz2

Monday, November 19, 2007

Ignorowanie w SVN

Swojego czasu znalazłem ciekawe linki na temat ignorowania w svn.

http://svn.haxx.se/users/archive-2006-01/0494.shtml
http://dotnot.org/blog/archives/2005/12/30/ignore-a-file-in-subversion-svn-ignore/
http://wolfram.kriesing.de/blog/index.php/2005/svnignore-and-svnkeywords

dla wszystkich, którym potrzebna jest ta umiejętność polecam zapoznanie się z nimi.

Troszkę plików z przeszłości

Postanowiłem pokazać co nieco plików z mojej przeszłości... Zamieszczona paczuszka zawiera:

1) Kilka programików ze współbiegów
2) Programy z OJP (C++)
3) Ciut programów z metod numerycznych
4) Program ZOO (katalog OJP), w którym można zobaczyć jak używać MySQL-a pod C++

Mam nadzieję, że komuś się przyda.

http://www.jan.koprowski.zhr.pl/studia/olimp.tar.bz2

Monday, November 12, 2007

OJP część E

W całym programie stosujemy ten sam styl wcięć. Jeżeli szef nakazuje używać K2R to używamy K2R choćbyśmy całe życie używali czegoś innego.




K2R:


for (int i=0; i <= 100; i++) {
-> ...

-> ...

-> ...

}


// wada nie można jednym komentarzem sprawić by pętla wykonała się tylko raz.

// Styl Almana eliminuje ten problem:

// pętla leci tylko raz nie da się tego zrobić w K2R for (int i=0; i <= 100; i++)
{
-> ...
-> ...
-> ...
}


//Tabulacje zamieniamy na spacje. Bo nie ma wtedy problemu przy przeniesieniu z Linux-a na MAC-a programu, w którym zgadzają się wcięcia. Najlepiej jest mieć edytor, który automatycznie umie robić to za nas.

Taki komentrz jest problematyczny

/*

/* */

*/


Nie zadziała wyłączenie sekcji kodu.


Inna metoda wyłączania kodu


#ifndef 0

//

/*

*/

#endif

i tutaj zadziała :)

Dodatkowo, możemy opisywać każdy plik podając na przykład:

autora
data utworzenia
data ostatniej modyfikacji.

Opisujemy też każdą klasę mówiąc (nie programistycznie, ale tak z punktu widzenia modelowanej rzeczywistości) co przedstawia i co robi.

Komentujemy każdą metodę, mówiąc co robi (z punktu widzenia modelowanej rzeczywistości)

Komentujemy trudniejsze kawałki kodu, mówiąc co robią (ogólnie co robi dany kawałek kodu) jeżeli nie widać explicite co robi.

Parametry w stylu "zmienna = "wartosc"" podajemy w plikach nagłówkowych *.h, nie w plikach *.cpp - dodatkowo, jeżeli sparametryzujemy wszystkie parametry np. konstruktora to jest to automatycznie konstruktor domyślny: konstruktor();
Wirtualizacja:
Robimy wirtualizację. Czyli robimy metody czysto wirtualne + destruktor musi być wirtualny.
Zasada substytucji Liskova mówi o tym, że jeżeli wszystkie klasy bazowe zastąpimy pochodnymi to działa nadal poprawnie.

Tuesday, November 6, 2007

Django, Rails, Pylons - zdobywanie informacji

Nie licząć blogów programistów to najlepiej informacje zdobywać:

O Pylon i Django na stronach poświęconym Rails.
O Rails na stronach poświęconych Pylon i Django.

To właśnie tam zawarte informacje nie dopełniają informacji pisanych przez fanów konkretnych rozwiązań. Wciąż brakuje mi obiektywnej tabelki rodem z chip-a, gdzie byłoby po prostu porównanie wszystkich frameworków i możliwość "spojrzenia" co mi odpowiada a co nie. A szkoda - bo czy to, że ma się wybór pomiędzy prostotą a meandrami kreatywności jest złe ?

Monday, November 5, 2007

Obiektowe języki programowania - część D

Mowa o wyjątkach...

Zwykła obsługa błędów w C

int sprawdz_saldo() {
...
return saldo;
}

1) Musimy poświęcić jakieś wartości na kod błędu (jaką ? -1, 0.1, -0.9999)
2) Trzeba sprawdzać w kodzie czy funkcja zakończyła się powodzeniem czy nie i reagować na niepowodzenia
3) Nie możemy wymusić na programiście reagowania na kody błędów
4) Program zaczyna wyglądać:

// spaghetti - code

if (funkcja(x) == -1) {
// Reakcja na blad
} else {
// Poprawny kod
}
if (function(y) == -1) {
// Reakcja na blad
} else {
// Poprawny
}

Czyta się potwornie nie wygodnie. Wady te niwelują wyjątki.

Zgłaszanie wyjątku:

// Definicja klasy, ktora zwracamy jako wyjatek

class blad_zakresu() {};
class blad_db() {};

void ustaw_rok_prod (int x) {
// blad_zakresu x;
// throw x; // Nazwany obiekt - x.
if (x <>> dane;
s >> dane;
if (!s) // oops
// Zanim zareagujemy na daną sprawdźmy czy strumień jest ok bo dane nie zostaną wczytane
// Może być tak, że EOF będzie powodował błąd więc ostatni odczyt powinien robić coś takiego:
if (!s && s.eof) // koniec pliku
if (!s && !s.eof) // błąd nie koniec pliku

// Strumieni same zgłaszają wyjątki

Polecane książki:
http://www.josuttis.com/
http://wysylkowa.pl/ks239250.html
Język C++

jezyk c++
Stroustrup Bjarne

Thursday, November 1, 2007

latex pod PHP

Kiedy zacząłem używać polecenia latex poprzez php - system() ... zaczął wyskakiwać komunikat:
This is pdfeTeX, Version 3.141592-1.21a-2.2 (Web2C 7.5.4) I can't find the format file `latex.fmt' PHP
Plik latex.fmt znalazłem o dziwo w /home/dziubdziub/.texmf-var/web2c/latex.fmt.

Ponieważ linijka PHP wyglądała mniejwięcej tak:

system('/usr/share/texmf/bin/latex -output-directory='.TMP.'songbooks '.TMP.'songbooks/'.$name.'.tex');
Przekopiowałem ten plik do katalogu wskazanego przez -output-directory i zaczęło działać :)

Wednesday, October 31, 2007

Dwa pudełka

Trzymam w dłoniach dwa pudełka,
dostałem je od Pana Boga.
On powiedział:
"Wszystkie swoje smutki włóż do czarnego,
zaś wszystkie radości do złotego".

Posłuchałem Jego słów i napełniłem oba pudełka
moimi smutkami i radościami.

Chociaż złote pudełko co dzień stawało
się coraz cięższe, czarne ważyło ciągle tyle samo.

Chciałem dowiedzieć się, dlaczego tak jest,
z ciekawości więc otworzyłem to czarne
i zobaczyłem w dnie pudełka dziurę -
moje smutki wypadły przez nią.

Pokazałem dziurę Panu Bogu i głośno
się zastanawiałem:
"Ciekawe, gdzie się podziały
wszystkie me smutki".

Pan uśmiechnął się do mnie czule.
"Moje dziecko, wszystkie twe smutki
są tutaj, ze Mną".

Boże, dlaczego dałeś mi te pudełka:
Spytałem: "Panie jedno złote,
a drugie czarne i dziurawe?"

"Moje dziecko, złote jest po to,
by policzyć dane ci łaski,
czarne jest po to, byś pozbył się smutków".

Monday, October 29, 2007

Serializacja w C++

Serializowanie to metoda na zapisanie pełnego stanu naszej klasy.

class samochod {
void zapisz (ofstream & s); // Metoda przyjmuje wyjściowy strumień plikowy jako parametr
void odtworz(ifstream & const s); // stały: bo nie zmianiamy jego zawartości
}

void Samochod::zapisz (ofstream & s) {
s << marka << endl;
s << rejestracja << endl;
}

Klasa typu POD:
-> Nie ma konstruktora
-> Nie jest wirtualna
-> Nie ma elementów składowych innych niż stanadrowe (nie może być string, vector itd...)

Jeżeli klasa nie jest typu POD wtedy nie da się zapisać jej za pomocą "adres -> sizeof(class)" ponieważ posiada elementy dynamiczne.

#include

void Samochod::odtworz (ifstream & s) {
getline(s, marka);
getline(s, rejestracja);
}

main() {
ifstream s("plik.txt");
s.open("plik.txt");

s.close
// Tutaj samo się zamknie (robi to destruktor)
}

Sunday, October 14, 2007

ZHR : Za mało czasu na śmierć

W związku ze śmiercią ks. prałata hm. Zdzisława Peszkowskiego naszła mnie pewna refleksja. Nie pojechałem na Turbacz ponieważ przyjechał do mnie na weekend chrzestny, którego nie widziałem naprawdę dawno. W oczekiwaniu na przyjazd mojego chrzestnego do rodzinnego miasta zdążyłem spędzić trochę czasu z qmplami z Kręgu, pozałatwiać kilka spraw związanych ze studiami, wpaść w odwiedziny do Ciechocinka w celu wyjaśnienia co i jak ze śpiewnikiem, nacieszyć się nowo dostanym laptopem i kilka innych mniej lub bardziej czasochłonnych spraw. Pewna refleksja:

Starając się działać aktywnie w HOPRe, pełniąc służbę w Kręgu, użerając się z całą kretyńską biurokracją ZHRu, pisząc projekty dla ZHR, pomagając innym w sprawach informatycznych gdzie powinno się w ramach pełnionej służby ... gdzie kalendarz imprez harcerskich pęka w szwach... gdzie trzeba znaleźć jeszcze czas na bycie mężem, synem, wnukiem, studentem, chrześniakiem, przyjacielem... czy jest jeszcze czas aby zatrzymać się. Czy harcerza na czas ba czyjąś śmierć ? Czy strażnik ma czas na śmierć innego harcerza ? Czy harcerz w ogóle ma czas na coś poza harcerstwem ? Czy idee nadal służą nam czy to my zaczynamy służyć ideom ? Czy nie zatracamy się ... w naszym harcerstwie.... nie mając już czasu na normalne życie ?

................................

Tuesday, October 9, 2007

Podstawy subversion (SVN)

No tak, pewnie (podobnie jak ja) słyszałeś 2,500 razy aby tego używać w swoich projektach ale może wciąż zastanawiasz się po co, i jak. Sp19róbujemy coś z tym zrobić.

Co robi SVN ?
W dużym skrócie SVN przetrzymuje pliki, które każesz mu przetrzymywać jednak w taki sposób, że jest w stanie otworzyć dowolny z tych plików w dowolnej z jego kiedykolwiek istniejących wersji. Jeżeli edytowałeś plik 100 razy i wprowadziłeś w nim 100 zmian. To SVN pozwoli Ci wrócić do dowolnej ze zmian (przywrócić plik w postaci z przed zmiany 39 jak i z postaci jaką przybrał po zmianie 76).

Po co SVN ?
Podam kilka tylko przypadków w których SVN okazuje się użyteczny:
  1. Masz system operacyjny, w którym jest kilku administratorów. Trzymanie w SVN plików konfiguracyjnych systemu pozwala na natychmiastowe wrócenie do stanu poprzedniego (działania) w momencie w którym po jakiejś zmianie coś przestaje działać - bez zastanawiania się i szukania pomyłki.
  2. Kilku programistów pracuje nad tym samym projektem i istnieje groźba, że będą pracowali nad tym samym fragmentem kodu w jednym czasie.
  3. Szlak trafił nam projekt, ktoś narozrabiał i wywalił pliki, które właśnie są Ci potrzebne. Przywracasz je jednym poleceniem.
  4. Nawet jeżeli coś było tylko epizodem w twoim życiu i dawno usunąłeś te dwa skrypty rubego ze swojego dysku, a używałeś w trakcie svn-a to możesz (nawet po 2 latach) do nich wrócić....
Skrócony opis obsługi SVN:
Oprę się na świetnym tutorialu dostępnym pod adresem: http://artis.imag.fr/~Xavier.Decoret/resources/svn/index.html
Przedstawię tylko i wyłącznie podstawy jednak w pewnym konkretnym ujęciu, które może okazać się dobrym uzupełnieniem powyższego artykułu:
  1. Tworzymy miejsce, w którym będziemy przetrzymywać nasz projekt:
    mkdir /mnt/saveplace/dziubdziub/svn
    svnadmin create --fs-type fsfs /mnt/saveplace/dziubdziub/svn
    Tak przygotowany katalog będzie bazą dla polecenie svn, którym zaczniemy się posługiwać.
  2. Importujemy nasz projekt do svn (robimy to tylko raz ! na początku projektu):
    svn import /home/dziubdziub/poszukiwania file:///
    mnt/saveplace/dziubdziub/svn/poszukiwania -m "Initial import"
    Co właśnie zrobiliśmy ? Otóż kazaliśmy svn-owi (w jemu tylko znany sposób) zaimportować cały projekt z plikami i opisać tą zmianę "Initial import"
  3. Po imporcie musimy wykonać checkout (tylko raz tylko na początku zaraz po zaimportowaniu), który pobierze nasze pliki z svn-a. Możemy wykonać go do innego katalogu. Możemy wykasować istniejący projekt i w jego miejsce pobrać spowrotem te same pliki z svn-a:
    cd
    /home/dziubdziub
    rm -fr poszukiwania
    svn checkout file:///mnt/saveplace/dziubdziub/svn/poszukiwania
  4. Kiedy wykonaliśmy checkout możemy zacząć używać svn-a. Od tej pory w katalogach z projektem istnieją katalogi .svn, które przetrzymują informacje pozwalające nam nie podawać ścieżki file://... ale działać bez niej (dzięki tym katalog svn sam wie gdzie są trzymane repozytoria) Powiedzmy, że nad projektem na tym repozytorium pracuje kilku programistów. Aby mieć najświeższą wersję ZAWSZE przed rozpoczęciem pracy wykonujemy:
    cd /home/dziubdziub/poszukiwania
    svn update
    Dzięki czemu pobierzemy najnowszą wersje plików.
  5. Po wprowadzonej przez siebie zmianach schodzimy do najniższego katalogu i patrzymy co się zmieniło:
    svn status
    ?
    - plik został dodany lub usunięty i nie wiadomo co z nim zrobić
    ! - plik został usunięty
    M - plik został zmodyfikowany
  6. Podejmujemy jedną z kilku akcji względem plików oznaczonych ?:
    svn add sciezka/do/pliku - dodajemy (?)
    svn rm sciezka/do/pliku - usuwamy (!)
  7. Po podjęciu akcji (nie ma żadnych plików oznaczonych ?, ! ale same oznaczone A(dd), D(elete), M(odify) każemy wprowadzić zmiany do repozytorium SVN:
    svn commit -m "Description of changes"
  8. Za każdym razem po wprowadzeniu zmian musimy ponownie (jakby od początku) wykonać svn update ponieważ nasze zmiany zostały nałożone na zmiany innego programisty w svn i trzba pobrać skompilowaną wersję tych wszystkich wspólnych zmian (które łączy svn):
    svn update
Luźne rady:
  1. Komituj każdą najdrobniejszą zmianę. Im więcej i częściej będziesz komitować tym szczegółowiej będziesz mógł określić, która ze zmian Cię intereuje w kodzie (i chcesz ją zatrzymać) a która nie.
  2. Nie warto dodawać do repozytorium plików czy katalogów tymczasowych czy np... plików pochodzących z mechanizmu cachowanie czy logów. Dlatego warto oznaczyć niektóre katalogi aby były ignorowane (zmiany w nich zachodzące dokładnie) przez svn. Powiedzmy, że mamy katalog tmp w którym jest katalog cache i logs, których zawartości nie chcemy brać pod uwagę podczas naszego commitowania. Każdy z katalogów ma swoją listę ignorowanych plików. Robimy to mniej więcej tak:
    cd /home/dziubdziub/poszukiwania/tmp
    svn propedit svn:ignore logs
    Wpisujemy:
    *
    Od teraz w katalogu logs ustawiony jest parametr svn:ignore na * (wszystkie pliki). Analogicznie postępujemy z cache:
    cd /home/dziubdziub/poszukiwania/tmp
    svn propedit svn:ignore cache
    Wpisujemy:
    *
  3. Aby przywrócić jakiś plik wpisz:
    svn revert sciezka/do/pliku
  4. Program svn pozwala nam działać na wirtualnym systemie plików znajdującym się w: /mnt/saveplace/dziubdziub/svn na zasadzie zwykłych poleceń systemowych poprzedzonych svn:
    svn ls file:///mnt/saveplace/dziubdziub/svn/poszukiwania
    svn rm file://...
    svn mkdir file://...
    svn tree file://...
    Pomimo tego, że polecenia:
    ls file:///mnt/saveplace/dziubdziub/svn/poszukiwania
    rm file://...
    mkdir file://...
    t
    ree file://...
    A w katalogu /mnt/saveplace/dziubdziub/svn wcale nie znajdzmyjawnie pokazanych naszych folderów, ale tylko i wyłącznie wewnętrzną strukturę organizacji danych stworzoną przez svnadmin.

Monday, October 1, 2007

OJP 1 zajęcia :)

Dziś na zajęciach z OJP usłyszałem pierwszy raz jak wygląda obiektowe programowanie w ujęciu "ewolucji". Powiedzmy, że robimy bazę danych samochodów:



int : rocznik

int : przebieg

string : rejestracja

string : kolor



Operujemy na 4 tablicach - funkcja, która miałaby operować na samochodzie musiałby przyjmować 4 parametry (porażka)... lub działać na zmiennych (tablicach) globalnych. Sortowanie takich samochodów np. według rocznika czy przebiegu sprawia, że drobny błąd w algorytmie (operującym na 4 tablicach) rozsynchronizuje bazę.



Kolejnym pomysłem jest zamknąć te dane w strukturze samochód:



struct samochod {

int : rocznik
int : przebieg
string : rejestracja
string : kolor

}



Dzięki temu funkcja (np. funkcja info() wyświetlająca informację o samochodzie) może przyjmować już tylko jeden parametr (samochód)... Jednak teraz programista może celowo (lub przypadkowo) zmniejszyć przebieg lub zmienić rocznik - czego byśmy nie chcieli. Nasz obiekt nie jest bezpieczny, nie jest niezmienniczy. Nie możemy zagwarantować, że przebieg się nie zmieniszy, że rocznik się nie zmieni.



Idąc dalej możemy zamknąć wszystko w klasie a dane umieścić w sekcji private.



class samochod {



// Interfejs: co sie składa na samochód

private:
int : rocznik

int : przebieg

string : rejestracja

string : kolor

string : numer_silnika

string : marka



public:

// Implementacja: jak się zachowuje samochód

zmien_przebieg() {

++przebieg;

}
}



Dzięki temu programista nie może zmniejszyć przebiegu:



samochod * mazda_jasia = new samochod();

mazda_jasia->przebieg = 200 km;



Dzięki temu jesteśmy pewnie, że przebieg nigdy się nie zwiększy. Minusem tego jest jednak, że nie możemy odczytać przebiegu:



cout <<>przebieg;



No i mamy problem. Musimy więc dopisać nową metodę.



int function Samochod::pobierz_przebieg() {

return this.przebieg;

}



Dzięki temu mamy pełna kontrolę nad przebiegiem. Jesteśmy pewni, że nie zmniejszy się jednak możemy sprawdzić jego wartość i monotonicznie go zwiększać. Jednak jaki rocznik będzie miał samochód, który jest nowo utworzony ? No właśnie. Często zero, jednak nie można na tym polegać... Musimy więc zainicjować wartości na nowo - robimy to w konstruktorze.



Samochod::Samochod() {

this.rocznik = 1970;

this.przebieg = 0;

}



Jednak taki samochód nie ma ani marki ani koloru. Możemy więc zrobić inny konstruktor.



Samochod::Samochod(string _rejestracja, string _silnik, unsigned int _rocznik ...) {

rejestracja = _rejestracja;

silnik = _silnik;

rocznik = _rocznik;

}



Jednak kiepskim pomysłem jest wypisywanie w liście wszystkich parametrów. W powyższym przypadku tworzą się kopie obiektów, które są przekazywane przez do metody. Możemy jednak nie przekazywać parametrów i nie przypisywać ich do skałdowych klasy w ciele konstruktora. Do tego słuzy lista inicjalizacyjna:



Samochod::Samochod(string _rejestracja, string _silnik ...):rejestracja(_rejestracja), silnik(_silnik), kolor("czerwony") {

[...] // tutaj ciało metody

}



Mamy teraz przeciążony konstruktor (istnieją i moga istnieć różne funkcje o tych samych nazwach a o różnych parametrach). Możemy np. zrobić dodatkową metodę zwiększ przebieg:



Samochod::zwieksz_przebieg(int ile) {

if (ile > 0) {

przebieg += ile;

}

}



W C++ mamy możliwość dawać parametrow wartości domyslne, co pozwala uiżytkownikom daje mozliwośc na opuszczanie parametrów. Na z 2 metod zwieksz przebieg możemy zrobić 1:



class {

[...]



zwieksz_przebieg(int ile = 1);

-







-

Samochod::zwieksz_przebieg(int ile) {

}



mazda_jasia->zwieksz_przebieg(); // += 1

mazda_jasia->zwieksz_przebieg(12); // += 12



Wartości domyślne (zmienne z wartościami domyślnymi) dajemy na końcu.



Dalej mówiac o konstruktorze. Jeżeli tworzymy knstruktor dla klasy to musimy zadbać, żeby wszystko było w nim zainicjowane.



Dziedziczenie:

------------------------------------------------



Stosujemy kiedy chcemy stworzyć specjalizację klasy, lub dodać jakieś cechy lub zachowania, których nie miała klasa oryginalna.



-------------

samochod < [ samochod_sportowy ] (bool spoiler, unsigned int data_tuningu)

-------------

^

i a kind of

^

--------------

ciezarowka

--------------



Kiedy zaczniemy dodawac do klas pochodnych coraz wiecej metod czy skladowych pokaze, ze nie warto tworzyc jednej wielkiej klasy samochod z ogromna ilosccia skladowych, poniewaz niektore skladowe (spoilery) dotycza tylko i wylacznie samochodwo sportowych, a w samochodach musialby by zaincjalizowane na jakies dizwne bezsensowen wartosci. Jak wyglada dziedziczenie:



class Ciezarowka public Samochod {



private:

// ciezarowka stala sie samochodem. Dodajemy tylko to co chcemy dodać:

int ladownosc; // Tym się różni od samochodu.

}



Jakie można popełnić błędy ? 1) Otóż mazda nie DZIEDZICZY po samochodzie. Jest samochodem ! a nie klasą... Powinna być obiektem klasy samochód ! a nie samochodem !



2) Kompozycja (is a part of) -> jest częścią. Na przykład silnik jest częścią samochodu, ale nie dziedziczy po samochodzie ! Jest natomiast częścią samochodu ! (diamencik).



3)



elipsa <- punkt : połżenie_środka, float : szerokość, float : wysokość, narysuj()...



Koło nie może dziedziczyć po elpisie ! Koło => (szerokość = wysokość). Wszystko jest ok do momentu, kiedy my nie skomplikujemy elipsy.... np po dodaniu Elipsa::Rozciagnij() { szerokosc *= 2) okazuje się, że koło nie jest dobryn przykładem na dziedziczenie z elipsy... bo koła nie wolno dodawać.



Zasada substytucji Miskowa.



-----------------

Zasłanianie !

-----------------



Samochód: function f(int par), f(string par), f(float par);



class SamochodSportowy public Samochod {



funtion f(string par) {

// Ta metoda zaslania WSZYSTKIE funkcje f z Samochod

}



}



Przeciązanie: w jednej klasie te same nazwy różne parametry

Zasłanianie: w klasie pochodnej metoda o tej samej nazwie.



Dwa sposoby na wybrnięcie z problemu:



1) using Samochod::f; <- pierwszy sposób

2) Wywołać Samochod::f() <- w metodzie klasy.



Projekty ! (wymyślić obiekt do hierarchi dziedziczenia)

Saturday, July 21, 2007

Psi i Pidgin - solucje

Wszystko zaczęło się gdy zażyczyłem sobie SSLa do Google Talk na Psi... Znalazłem jakieś QCA w systemie ale SSLa nie było. Dopiero w README doczytałem, że do QCA potrzebne jest QCA-TLS aby Psi łapał szyfrowanie. Jednak w systemie miałem OpenSSLa 0.9.8e ... co zrobiłem ?

[Psi]

Wywaliłem OpenSSL 0.9.8e - który miałem zainstalowany.
Skompilowałem czyste QCA [http://delta.affinix.com/download/qca/qca-1.0.tar.bz2]
Skompilowałem OpenSSL 0.9.6m [http://www.openssl.org/source/openssl-0.9.6m.tar.gz], który domyślnie zagnieździł się w /usr/local/ssl
Skompilowałem plugin QCA niezbędny do działania SSLa w Psi [http://delta.affinix.com/download/qca/qca-tls-1.0.tar.bz2]:
./configure --with-openssl-inc=/usr/local/ssl/include --with-openssl-lib=/usr/local/ssl/lib
Uruchomiłem wcześniej zainstalowane Psi. Psi obsługuje już SSLa.

[Pidgin]
Bardzo spodobał mi się Pidgin [http://pidgin.im/pidgin/home/]. Jednak na wstępie miałem z nim już problemy. Otóż po zaimportowaniu listy kontaktów z serwera Gadu-Gadu podczas wyszukiwania przez wpisywanie gdb wyrzucał jakieś błąd sprawdzającej chyba długość stringu, a po kolejnym uruchomieniu wyskakiwał błąd, że nie można czytać blist.xml, że został skopiowany do blist.xml~ i, że jest źle.

Zajrzałem więc do ~/.purple/blist.xml~ - okazało się, że jest tam moja stara lista kontaktów, tylko są w niej jakieś dziwne krzaki. Doszedłem do wniosku, że to coś z kodowanie nie tak :/ Wszedłem więc do mojego kadu i wyeksportowałem listę do pliku kontakty.txt. Jednak po zaimportowaniu Jej do pidgina nadal było źle. Metodą prób i błędów znalazłem solucję. Otworzyłem plik z eksportem kotantków z kadu (kontakty.txt) w leafpad i zapisałem go ponownie ustawiając w Zapisz jako ... kodowanie na CP1250 CR+LF jako cp1250_kontakty.txt. Po zaimportowaniu kontaktów z tak przygotowanego pliku do Pidgina krzaczki zniknęły. Jednak to nie koniec :/ Otóż pidgin błędnie koduje znaczki (u mnie w nazawach grup). Otwieramy plik (kodowany jako utf-8) ~/.purple/blist.xml, ręcznie szukamy nieprawidłowo wpisanych znaków i je poprawiamy. U mnie osobiście występowały w nazwach grup w znaczniku name="". Po wprowadzeniu poprawek zapisujemy plik na razie pod jakąś inną nazwą (u mnie n_blist.xml) kodowany jako utf-8 (wszystko można wykonać na przykład w leafpad) Zamykamy pidgina. Pidgin błędnie zapisał nazwy do pliku blist.xml jednak nasz plik n_blist.xml jest poprawiony :) podmieniamy więc plik blist.xml na nasz własny, odpalamy pidgina i cieszymy się :)

Wednesday, July 11, 2007

Ładny terminal

Najlepiej działającym u mnie terminalem jest urxvt. Udało mi siew końcu ustawić dla niego przezroczystość. Oto mój plik .Xdefaults:
URxvt.background: black
URxvt.foreground: white
URxvt.font: -misc-fixed-medium-r-normal--18-120-100-100-c-90-iso8859-2
URxvt.scrollBar: false
URxvt.tintColor: white
URxvt.shading: 20
URxvt.inheritPixmap: true
URxvt.saveLines: 777
URxvt.geometry: 110x40
#URxvt.loginShell: true

Thursday, July 5, 2007

System kontroli wersji podstawy

Zostałem ostatnio zmuszony do używania systemu kontroli wersji. No i dobrze. Na reszcie się czegoś nowego nauczę. Bardzo dobry tutorial, poleconym mi przez Łukasza, opisuje wszystko co trzeba wiedzieć aby z niego korzystać.

Do czego używać SVNa i dlaczego używać SVNa.
1) Każda zmiana jest logowana wraz z nazwą użytkownika. Wiesz więc kto co i kiedy zmienił w kodzie.
2) Gdy okazuje się, że program nie działa możesz jednym poleceniem wrócić do poprzedniego stanu - stanu w którym działał.
3) W razie utraty plików odzyskasz je z SVNa.

To tylko kilka cech, które zauważyłem. Na pewno bardziej zaawansowani użytkownicy podali by znacznie więcej argumentów. Jednak te wystarczają aby spróbować nauczyć się choć podstaw tego narzędzia. SVN trzyma informacje o projektach w swojej bazie. Musimy wybrać sobie katalog, gdzie svn będzie trzymał swoje informacje. Powiedzmy, że dla użytkownika dziubdziub będzie to katalog svn w jego katalogu domowy. Jako użytkownik dziubdziub wydajemy polecenie:
svnadmin create --fs-type fsfs /home/dziubdziub/svn

Polecenie to stworzy "bazę danych" dla SVN a. Teraz możemy zacząć z niego korzystać. Powiedzmy, że w katalogu public_html tworzymy stronę internetowa dziubdziub. Mamy więc katalog /home/dzibdziub/public_html/dziubdziub w którym są pliki naszej strony internetowej. Jeżeli chcemy je włączyć do naszego systemu kontroli wydajemy polecenie:
svn import /home/dziubdziub/public_html/dziubdziub file:///home/dziubdziub/svn/dziubdziub -m 'Pierwszy import. (działa)'

Co właśnie zrobiliśmy. Już omawiam:

svn - uruchomiliśmy program svn
import - z opcją importowania istniejącego projektu do Jego bazy danych (drugie polecenie to zawsze import)
/home/dziubdziub/public_html/dziubdziub - projektu znajdującego się w tym katalogu
file:///home/dziubdziub/svn/dziubdziub - i zaimportować go do katalogu SVN file:///home/dziubdziub/svn/ jako dziubdziub - SVN założy sobie swój własny katalog dziubdziub i będzie w nim trzymał pliki naszego projektu.
-m "Pierwszy import. (działa)" - Każdy "import" musimy jakoś opisać. W opis wpisujemy zmiany, których dokonaliśmy, oraz możemy zaznaczyć czy coś działa, co zaczęło działać, a może coś było do dokończenia...

Kilka słów komentarza. SVN tworzy swój własny "system plików"... Po zajrzeniu do /home/dziubdziub/svn zobaczymy tylko kilka nic nie mówiących nam plików i katalogów. Aby oglądać ten system plików wydajcie polecenie:
svn ls file:///home/dziubdziub/svn/
svn ls file:///home/dziubdziub/svn/dziubdziub

Zobaczymy nasze pliki :) Istnieją też komendy svn rm, svn mkdir i kilka innych analogicznych do poleceń dostępnych w powłoce Linuksa. Jeżeli wywołamy:
svn log file:///home/dziubdziub/svn/
svn info file:///home/dziubdziub/svn/dziubdziub

Dowiemy się jakie zmiany zaszły w naszych plikach. Powinniśmy teraz wykonać checkout-a. W tym celu przejdźmy do katalogu /home/dziubdziub/public_html (katalog niżej niż projekt), zmieńmy nazwę projektowi (lub usuńmy go, ja jednak wolę zmienić nazwę i nie usuwac plików na wypadek, gdyby SVN nawalił) mv dziubdziub dziubdziub_bak. Teraz katalog dziubdziub nie istnieje. Możemy teraz wykonać checkout svn checkout file:///home/dziubdziub/svn/dziubdziub. Co się stało ? SVN przeniósł zapisane przez siebie pliki do katalogu. Została sprawdzona poprawność naszego importu i coś jeszcze :)... Otóż po wykonaniu w katalogu projektu (w każdym z katalogów) okazuje się, że znajduje się katalog .svn. Dzięki niemu nie będziemy musili podawać ścieżki przy wykonywaniu poleceń svn log, svn info. Po wykonaniu checkout a możemy edytować swoje pliki i zmieniać je, tak jak wcześniej. Kiedy dokonamy zmian i chcemy odnotować je w naszym SVN możemy najpierw sprawdzić co nasz SVN odnotował. Sprawdzamy to wchodząc do katalogu z projektem i wpisujemy komendę svn status. Odpowiednie zmiany, usunięcia, dodania będą oznaczone odpowiednimi literkami. Powiedzmy, że utworzyliśmy plik opis.txt. Wtedy svn status wyrzuci nam:
? opis.txt

Musi więc dodać go do naszego SVN svn add opis.txt:
A opis.txt

I odnotować zmiany w naszym repozytorium. svn commit -m "Plik z opisem do programu." okraszając go odpowiednim komentarzem. Ale halo halo ! Ci, którzy zamiast czytać dalej spróbują wywołać svn log stwierdzą... Nić się nie zmieniło... A no właśnie. Musimy ponownie wejść katalog niżej cd .. skasować katalog rm -fr dziubdziub i wykonać checkout. svn checkout file:///home/dziubdziub/svn/dziubdziub Pliki zostaną przywrócone a svn log pokaże kolejną zmianę. Zwrócę jeszcze tylko uwagę na pewien drobiazg. Checkout (i commit) podają na dole numerek... checkout zawsze przywróci nam ostatnio opisaną wersję programu. A co jeżeli chcielibyśmy na przykład pierwsza ? Nic prostrzego. Powiedzmy, że chcielibyśmy wersję numer 1 (musi taka istnieć, jeżeli taka nie istenieje program zwróci błąd). Ponownie kasujemy katalog dziubdziub i wykonujemy polecenie svn checkout -r 1 file:///home/dziubdziub/svn/dziubdziub i analogicznie w zależności, do jakiego stanu chcecie przywrócić swój projekt.

Checkouta robimy tylko za pierwszym razem kolejne zmiany po wykonaniu commit (wcześniej add, del itd...) wykonaujemy komendą svn up

SVNa można używać także do utrzymywania porządków w plikach systemowych - szczególnie jeżeli jest wielu adminów, którzy wprowadzają wiele zmian.

Wednesday, June 20, 2007

Gdzie jest ...

Ciemno...
Czy jesteś przy mnie ?

Cisza...

Czy jesteś przy mnie ?

Kapanie...

Czy jesteś przy mnie ?

Ptak zatrzepotał skrzydłami...

Czy jesteś przy mnie ?

"Nie ma mnie ..."

Odpowiedział delikatnie słodki, kryształowy głos...

Thursday, June 14, 2007

Klucz

Zamknąłem swoje serce na złotą kłódkę z żelaza
I obciąłem sobie obie dłonie.

Wyzierając z zardzewiałego otworu
Złoty klucz sterczy i lśni w słońcu
Niczym strzała w piersi wojownika
Groźnie łypiąca swym krwawym pióropuszem
Na pole bitwy gdzie polegli ... zwycięzcy.

Klucz czeka ...

Aż weźmiesz go w swoje dłonie
Ożywisz dotykiem śnieżnobiałego cedru i płatków róż
Nie ważne kim będziesz, choć ma swoje marzenia.
Czeka tylko na czułości uśmiechu, kroplę miłości i ...
... zaufanie

I znajdziesz tam przestraszone szczenię
skulone w kącie,
z oklapłymi uszami,
walącym ze strachu sercem i
parą wielkich zaszklonych oczu, patrzących błagalnie wprost w Twoje serce

Przytul je - ono tylko tyle potrzebuje.

Monday, May 28, 2007

Dlaczego NIE Linuks

Wciąż trwająca wojna Windows(owcy) vs Linuks(owycy) to tylko fala na morzu... a co siedzi w głębi ?

Chęci... No właśnie... na czym Ci zależy. Wielu użytkowników Windows stwierdzają "działa" i to im wystarcza. W gruncie rzeczy o to tylko chodzi i żadne argumenty w stylu "Linuks ma to to to i tamto, lepiej zarządza pamięcią, siecią, jest bezpieczniejszy ..." (i ta cała lista plusów) nic nie zmienią jeżeli gość w życiu nie miał problemu z komputerem, albo nie był on dotkliwy to po co mu Linuks, który ... nie działa ? No tak ! Bo ile razy wejdzie się na forum linuksowe, widać tylko wątki "nie działa mi", "jak zrobić żeby", "dlaczego ...", "wyskakuje mi błąd", "error", "zawiesz mi się przy..." i pierwsza myśl, która się nasuwa to "To nie działa !"... Po co komu system, w którym może robić "cuda", które wcale mu nie są potrzebne...
Użytkownicy Linuksa to pewni perfekcjoniści, puryści, ideliści, którzy lubią mieć wszystko cacy, bomba i po swojemu... Ale Polacy to społeczeństwo raczej ... leniwe :P więc po co się "męczyć" skoro DZIAŁA w Windows... Dla grafika komputerowego, dla którego Corel i Photoshop to chleb powszedni tłumaczenie się GIMPem czy WINEem to porażka... Bo przecież to działanie jest takie "wymuszone" i nie stabilne, a tutaj po prostu wygoda działania i przyzwyczajenia. W gruncie rzeczy wychowaliśmy się w większości na Windows, na programach, które w nim są i często poszukiwanie tak wygodnych aplikacji jak PSPad, eSkiMoS, Foobar czy innych oznacza przesiadkę na mniej wygodną aplikację, korzystanie z kilku z nich, albo pogodzenie się z okrojoną funkcjonalnością... no i nie pomoże, że boli.

Myślę, że na Linuksa trzeba chcieć się przesiąść. W gruncie rzeczy nie ma wielu logicznych argumentów, dla których nie należałoby używać Windows kiedy jest się szarym użytkownikiem. Windows ma wiele wygodnych mechanizmów, na których człowiek się wychował, przyzwyczajenie staje się jego drugą naturą i zmiana powoduje obniżenie wydajności jego pracy. To na czym mu zależy działa, antywirus jak coś nie gra zgłosi co trzeba, firewall popyta o aplikacje i czuje się bezpiecznie... więc po co mu coś więcej ?

Linuks nie jest dla wszystkich i dla wielu użytkowników Windows to znaczenie leprze rozwiązanie, czasem z przyzwyczajenia, czasem z wygody, innym razem z powodu dostępnego oprogramowania... I denerwujące "aktulizacje" Windows... są denerwujące tylko dlatego, że zmusić do nich to jedyna metoda Microsoftu aby zadbać o bezpieczeństwo systemu LENIWYCH użytkowników, gdzie każdy świadomy użytkownik Linuks zadba o to sam... :) Więc nie narzekajmy tylko głowa do góry i czyńmy nasze aplikacje dla Linuksa jeszcze bardziej użytecznymi :) aby był to system, na który na prawdę warto się przesiąść.

Monday, May 21, 2007

Kilka słów o instalowaniu ze źródeł

Czasami naprawdę trzeba zainstalować coś ze źródeł. Po prostu nie ma naszego kochanego programu w żadnym repozytorium i nie pozostaje nam nic innego. Jest kilka rzeczy, które mogą nam pomóc, jeżeli wcześniej zwrócimy na nie uwagę.

Źródła rozpakowuje się zazwyczaj:
tar -xf nasz-program-10.tar.gz
a czasami jeżeli spakowane są bz2
bunzip2 nasz-program.tar.gz.bz2
tar -xf nasz-program-10.tar.gz
Po wypakowaniu źródeł zazwyczaj powstaje katalog nasz-program. Po wejściu do niego koniecznie przeczytaj pliki INSTALL i README. To bardzo dużo ułatwia. Często programy używają innych bibliotek, które ktoś już opracował i na ich podstawie budują swoją funkcjonalność. Zamiast denerwować się, że coś się nie kompiluje sprawdź najpierw te dwa pliki (jak są inne wyglądające podejrzanie, których nazwy napisane są wielkimi literami też je sprawdź). Użyteczna przydaje się komenda:
vim INSTALL README -p
która otwiera nam nasze pliki w zakładkach, po których możemy poruszać się [gt] (jak go tab). Przeczesz stronę internetową, FAQ, manual, dokumentację (część z instalacją), aby zanim wykonasz pierwszy krok być pewnym, że w systemie jest już wszystko co jest niezbędne do działania tej aplikacji. Warto jest jeszcze zweryfikować czego możemy od programu oczekiwać, z jakimi opcjami kompiluje się domyślnie, jakich brakuje. Po lekturze ./configure --help | less lektura tego help-a jest niezbędna aby dopasować funkcjonalnośc programu (co ma obsługiwać co nie, jakich bibliotek się spodziewać jakich nie, czy ma korzystać z ALSA czy z JACKa itd...) Oczywiście możesz próbować robić podchody w stylu:
updateos -i brakująca-biblioteka
a jak nie znajdzie:
updateos -f brakująca-biblioteka
Czasami jednak trzeba wpisać nazwę biblioteki w googlach, z dodatkiem home page,albo bez i ściągnąć ją i kompilować ze źródeł. Po katalogu ze źródłami warto się jeszcze rozejrzeć po plikach konfiguracyjnych aplikacji, themah i innych gadżetach (pliki konfiguracyjne, themy i skróty klawiszowe znalazłem na przykład w źródłach MOCa). Później zaczynamy ./configure (będąc w katalogu ze źródłami). Programik sprawdza sobie biblioteki dostępne w systemie i patrzy czy są te przez niego wymagane. Jeżeli instalowałeś jakieś biblioteki do systemu (potrzebne do aplikacji) to aby system je "zobaczył", czy łyknął warto dla pewności po ich instalacji, a przed kompilacją źródeł programu wydać polecenie ldconfig. Configure może czegoś nie znaleść. niektóre biblioteki jeżeli nie zostaną znalezione nie spowodują błędu. Program je po prostu pominie, kosztem mniejszej funkcjonalności programu. Aby dowiedzieć się co dokładnie w trawie piszczy możemy wydać polecenie ./configure --help | less i z bliska przyjrzeć się co możemy sobie w programie "włączyć" lub wyłączyć. Często bywa tak że configure albo make generuje jakieś błędy przy jakiejś nazwie. Po przejrzeniu
./configure --help | less widzimy gdzieś tą nazwę a obok nie coś w stylu --disable-to_cos_co_nas_nie_lubi albo --to_cos_co_nas_nie_lubi=no albo --to_cos_...=disable. Wydanie polecenia ./configure --disable-cos. Spowoduje, że do programu nie zostanie włączona obsługa tego czegoś, nie zostanie to wogóle wzięte pod uwagę, program skompiluje się z mniejszą funkcjonalnością, ale w 90% przypadków w ogóle tego nie odczujemy :) bo programy pisane są tak, że jedną rzecz robią na 10 różnych sposobów i jak nie jednym to drugim. Często aby program skompilować pod nasze potrzeby albo pod nasz system piszemy spory tasiemiec: ./configure --disbale-options --enable-gtk --disable-qt [...] --prefix=/usr. No właśnie opcja prefix powoduje, że przed każdym katalogiem do którego będzie kopiowany plik (przed jego nazwą) dopisywane jest /usr. Co to znaczy ? Domyślnie prefix ustawiony jest na /usr/local (chyba, że w programie albo INSTALL albo README albo gdzie indziej jest napisane inaczej). I jak będziesz miał binarki tego progamu to znajdą się one w /usr/local/bin, zasoby w /usr/local/share. Mi to nawet pasuje i wszystko co nie pochodzi z systemu ładuję właśnie tam, wiem przynajmniej gdzie szukać plików w /usr/local. Jednak możesz chcieć władować to do /usr (bin, share itd...). Wtedy dajesz --prefix=/usr i wsio. Po ./configure kiedy system wie co jest i czego nie ma a dzięki temu wie jak skompilowac program tak aby się skompilował robimy polecenie make. To jest kompilacja źródeł. Czasami dopiero tutaj okazuje się, że biblioteki są w złej wersji albo coś nie działa. Możemy znowu instalować biblioteki, aktualizować je albo brutalnie wycinać przez przełączniki przy ./configure. Kiedy make już przejdzie mamy dwie opcje. Albo pokopiować pliki, które właśnie się utworzyły do systemu na łyso przez make install, albo zrobić paczkę. Make install wymaga uprawnień dostępu do katalogów systemowych a więc tu, należy wydać polecenie su i dopiero make install. Pokopiuje on pliki do katalogów i wsio. Wszystkie poprzednie czynności należy wykonywać z uprawnieniami zwykłego użytkownika ponieważ gdyby w kodzie źródłowym był jakiś wirus zadziała on z bardzo ograniczonymi uprawnieniami a nie uprawnieniami superużytkownika. make install ma pewną wadę - otóż, nie działa On jak paczka. Dzisiaj Linuxy mają swój system paczek. Make install nic nikomu nie mówi, gdzie i czy coś skopiowało. Tylko ono wie, że coś się działo. Jedynym sposobem aby potem odinstalować taki program jest zachować sobie katalog, w którym wszystko kompilujemy i w momencie chęci odinstalowania wejść do niego i wydać polecenie Jednak jeżeli katalog ten skasujemy czeka nas ponowna kompilacja z poprzednio ustawionymi flagami i po kolejnym zainstlowaniu do czasu kiedy jeszcze istnieją źródła wydanie natychmiast po tym komendy make uninstall. Jednak istnieje narzędzie checkinstall które pozwala robić paczki. W Kasi paczuszkę slackową (czyli nawet dość pasującą do naszych potrzeb) możemy zrobić wykonując zamiast make install checkinstall -S. Jeżeli nie chcemy być pytani o drobiazgi, i robimy paczkę tylko na chwilkę, aby ją zainstalować możemy kazać programowi stworzyć podstawową dokumentację i odpowiedzieć na pytania twierdząco poprzez checkinstall -S --nodoc -y. Po tym zabiegu powstanie ładna paczuszka tgz, która po pkg -i nasz-program.tgz zarejestruje się w systemie i pozwoli ładnie usunąć przez pkg -r nasz-program, a my źródła kompilacji będziemy mogli wyrzucić do kosza. Ma to jeszcze jeden plus. Możemy za w czasu podejrzeć paczuszkę i sprawdzić gdzie po kopiują się nam pliki i w razie czego prze konfigurować i skompilować ponownie program z innym, bardziej odpowiadającym nam prefiksem. Jeżeli dużo mieszamy ze źródłami, przerwaliśmy make-a bo zapomnieliśmy o dodanie do configure jakiś drobiazgów i przy tym zaczynają się dziać jakieś niespodziewane rzeczy, błędy możemy wyczyścić wszystko co do tej pory pozostawiło po kompilacji swoje pozostałości przez wydanie polecenie make clean co spowoduje, że zaczniemy kompilację od zera.

Jeżeli chcesz wyjść do sklepu i mieć po powrocie działający programik w systemie możesz łączyć polecenia w sprytne łańcuszki. na przykład:
./configure && make && checkinstall -S --nodoc -y && pkg -i nasza-paczka.tgz


Wracasz do domu, terminal zaśmiecony :) ale programik działa :P (o ile po drodze nie wyskoczył żaden błąd).

Powodzenia i miłego kompilowania programów !

Gdzie pójdzie po make install ?

Często chcielibyśmy mieć pewność gdzie umieści pliki make install. Ostatnio nieciekawy numer wywinęło mi qingy :| Jeżeli jesteś na etapie kompilowania źródeł to w miejscu make install możesz wydać polecenie checkinstall -S --nodoc -y:
-S - paczka slackware (czyli coś jak Kasia)
--nodoc - bez dokumentacji (tworzy domyślną dokumentację, w tym przypadku w ogóle nie potrzebne)
-y - Nie męczy Cię zbędnymi pytaniami i na wszystkie odpowiada yes
Powstanie paczuszka tgz, której zawartość możemy obejrzeć sobie dość dokładnie w mc lub innym programem pozwalającym na podejrzenie tgz-ów. Jeżeli chcemy sprawdzić gdzie ulokował się już zainstalowany program możemy podejrzeć: /var/log/packages/ --- program ---

Sunday, May 20, 2007

Gmail notifier

Trafiłem właśnie na bardzo sympatycznego gmail notifier-a:

http://gmail-notify.sourceforge.net/


Ściągnąłem źródełka. Wypakowałem wszystkie pliki do /usr/local/gmail. Dodałem do mojego ~/.zshrc:
export PATH=$PATH:/usr/local/gmail
Wykonałem . ~/.zshrc później notifier.py i ... okazało się , że brakuje pygtk. No to szybciutko:
su
updateos -i pygtk
[CTRL]+[D]
[ALT]+[F2]
/usr/local/gmail/notifier.py

Wypełnieł username, password, Save user name and password (check) i mogłem się już cieszyć pięknym gmail notifierem w mojej nowej Kasi :)

XFCE może zapamiętywać podczas zamykania systemu sesję, czyli co jest odpalone co nie i uruchamiać to ponownie lub wchodząc w ustawienia autormatyczne uruchamianie aplikcji możesz dodać Gmail notifier-a podając: /usr/local/gmail/notifier.py

Saturday, May 19, 2007

Kary za reklamy

Kiedyś znajomy opowiedział mi o zamiarze kupna breloczka, który umie wyłączyć kilkaset tysięcy modeli telewizorów. Wchodzicie do MediaMarkt, stajecie przy ścianie zapełnionej gadającymi telewizorami, wyciągacie breloczek, naciskacie guziczek i ... cisza.

W perspektywie ciszy reklamowej w Media Markt spojrzałem na dzisiejsze reklamy, które "witają mnie" na strona portali internetowych. Reklama, często zajmująca 50-100% mojego ekranu i nie działający guziczek, który ją wyłącza. Ktoś powinien za to zapłacić ! Za co ? Za czas, który poświęcam, aby dotrzeć do treści, które są dla mnie w danym momencie ważniejsze aniżeli, reklama, której TEORETYCZNIE mam PRAWO nie oglądać. Ktoś narusza nie tylko moją wolność i zabiera mi mój bezcenny czas, ale dodatkowo PŁACĘ ZA TO, że ktoś mi COŚ reklamuję. Jak to płacę ? A no tak ! Kilka kilo-bajtów tekstu i kilkaset kilo-bajtów reklamy na pół strony ! Ciekaw jestem ile transferu HTTP to reklamy. Jestem prawie pewien że ponad 50%, a kto za ten transfer płaci ? Ja ! Czyj czas zżera ? Mój ! Ktoś powinien zrobić z tym porządek.

Wednesday, May 16, 2007

Zatruwanie switcha

Dziś razem z jednych z doktorów z uczelni na której studiuję postanowiliśmy zatruć switcha. Był to jakiś 3com, podobno miał 8MB pamięcie... Postawiliśmy dwa laptopy, na jednym na Windowsie postawiliśmy WireShark-a, na drugim zapuściliśmy Knoppix STD.

Troszkę się namęczyłem z napisaniem skryptu, który by pozwolił tego switcha zapchać. Początkowo pomysł był taki, że ponieważ do switcha podłączone były tylko dwa komputery, słać jednym ramki na jakiś lewy MAC, drugim zaś czekać, aż zacznie wyłapywać te ramki, przy czym MAC źródłowy był preparowany.

Wstępnie napisałem w bash-u prosty skrypt generujący MACi - nic trudnego... Problemy zaczęły się gdy trzeba było preparować MACi źrółowe. Chłopacy z Matrixa zapodali wersję z ifconfigiem jednak kilka dni później trafiłem na Knoppix STD z arpingiem :)

Już na samym początku okazało się jednak, że jak się wyśle na lewy MAC to on go nie ma w pamięci i wysyła wszędzie... no to 3 komputer :| by był potrzebny, ale nie. Podszyliśmy się pod jakiś dobrze znany nam MAC, puściliśmy z niego arpinga i router to łyknął ;) Mogliśmy więc słać na MAC, którego w sieci nie ma, a switch go zna i wie co z nim robić.

Okazało się, że wersja bash-a na Knoppix STD jest tak stara, że skrypt trzeba było przepisać :| (szkoda, że nie rozwijają już Knoppix STD - świetna dystrybucja ! A byłaby jeszcze lepsza, gdyby ktoś ją odświerzył) Po przepisaniu skryptu - udało się, zapodaliśmy skrypt ... i czekamy, komunikaty się pojawiają, a my czekamy.

Doszliśmy do wniosku, że tak średnio to idzie 1 na sekundę więc przy 8MB switcha przyjdzie nam czekać 1200 godzin (szacunkowo i to z dużym błędem)... Zwiększenie ilości wątków do 400 pozwoliłoby nam liczyć na 4 godziny. Dopisaliśmy pętlę while odpalającą skrypt 400 razy i aby przyśpieszyć pracę wysłaliśmy wszystko do /dev/null. A co ! Niech sobie działa ! System trochę przysiadł i zaczął działać "w zwolnionym tempie" długo zastanawiając się nad każdym ruchem myszki jednak efekt był widoczny już po 15 minutach rozmowy - WireShark został zasypany mnóstwem pakietów :)

To było piękne :)

Sunday, May 6, 2007

Rozmyślania o MVC

Od jakiegoś już czasu ludzie męczą mnie o to abym zaczął programować używając MVC. Podobno łatwiej. Ale ja w tym, żadnego sensu nie wiedziałem ... No bo co to za sens ? pisać tylko:

<title> <?=$tytul?> </title>

czy

<title>${tytul}</title>

Jakiś piekielnie skomplikowany mechanizm, który dba o przekazywanie zmiennych do odpowiednich plików, dodatkowo o to, aby to wszystko pozamieniać, generując tylko narzuty czasowe ... więc o co chodzi ?

Ale może najpierw co to jest MVC. Za wikipedią:
MVC (ang. Model-View-Controller - Model-Widok-Sterownik) to wzorzec projektowy w informatyce, którego głównym założeniem jest wyodrębnienie trzech podstawowych komponentów aplikacji:
  • modelu danych,
  • interfejsu użytkownika,
  • logiki sterowania
Czyli tak dla ludzi. Chodzi o to, aby jak najbardziej oddzielić logikę prezentacji PHP od logiki kontrolera HTML (tak w dużym uproszczeniu). No tak miało być dla ludzi. Otóż chodzi o to aby oddzielić to co skrypt robi od tego jak skrypt to pokazuje. Ja sam sobie mówiłem: "Ale co to za problem ... przecież <php? include ('licznik.php'); ?> czy <php? $licznik->show(); ?> nikomu jeszcze nie zaszkodziło !".

Jednak nie o takie podejście w całym tym przedsięwzięciu chodzi. Aby mówić o MVC trzeba po prostu dojrzeć do niego - inaczej to będzie wciskanie ci "dobrego" rozwiązania, do którego w cale nie jesteś przekonany i jest Ci wciskane na siłę ! :)

Moim ideałem programowania jest pewien ideał nabyty z C++. Jeżeli piszę klasę, to chcę ją napisać tak, aby ktoś sobie wziął pliczek z moją klasą skopiował do swojego katalogu, includował i już mógł jej używać - jak swojej. Tak też starałem się robić w PHP - i tu pojawia się problem - oprócz PHP jest przecież ... HTML :|. No właśnie :| W C++ sprawa jest prosta, możemy nie martwić się o "prezentację danych" (pod konsolą) robimy cout. A jeszcze lepiej zwracamy po prostu wynik nic nie wyświetlając. Jednak w PHP Dochodzi HTML. Opowiem wam historyjkę z życia wziętą.

Musiałem kiedyś przerobić portal oparty o XOOPSa. Chodziło o zmianę layoutu. Kiedy zagłębiłem się w kod okazało się, że jego fragmentu porozrzucane są po najróżniejszych zakamarkach tabel baz danych ... Uwierzcie ! grzebanie i dochodzenie w jakim rekordzie znajduje się ten konkretny fragment MENU doprowadzało mnie do szału ! A wyobraźcie sobie, że poza tym kod HTML mógłby być porozrzucany po najróżniejszych metodach używanych tam klas... po prostu masakra ! W takiej sytuacji prosty plik HTML z jasno powstawianymi elementami pochodzącymi z PHP byłby idealny zamiast grzebanie się po metodach klas i bazie danych - udręka !

O wiele łatwiej jest stworzyć własny formularz do bazy danych mając:

<form action="${action}" method="${method}">
<fieldset>
<legend>${tytul}</legend>
<label>${login}: <input name="${login}" type="text"></label>
</fieldset>
</form>

niż jakąś czarną skrzynkę pod tytyłem:

$login->pokaz_formularz();



Niby też ładnie, ale dla osoby, która chciałaby nasz formularz zupełnie przerobić (bo nie pasuje Jej do jego layout) kompletnie nie pasuje. Wtedy znacznie łatwiej jest powstawiać sobie kilka pól (nasze zmienne ${nazwa}) w nowe miejsca, do przez siebie przygotowanego pliku niż szukać po klasach i bazie danych - gdzie on mógł to wcisnąć ?

A więc klasa musi się już tylko zająć przetworzeniem danych i wrzuceniem ich w odpowiedni szablon. Może to wyglądać na przykład tak:

$zmienne = array {
'tytul' => 'Moje MVC',
'nazwa' => 'firma',
}

$controller->parse('formularz.html', $zmienne);


No i tu pojawia się kolejny element. Kontroler - czyli element, który zajmie się włożeniem odpowiednio przez nas wcześniej napisanych zmiennych w odpowiedni szablon HTML.

Z praktycznego punktu widzenia wygląda to tak:
  • HTML - zajmuje się formą w jakiej prezentowane są dane.
  • PHP - naprawdę zajmuje się tylko obróbką danych.
  • Jakiś parser - czyli klasa (albo funkcja, czy co tam sobie chcecie) zajmuje się tym, żeby włożyć suche zmienne PHP w odpowiednie miejsca w pliku HTML.
Możemy spróbować sami napisać parser, albo spróbować używać frameworku.

No właśnie i tu pojawia się kolejna kwestia. Framework. O co chodzi ? Myślę, że wiele osób pisząc o MVC zaczyna pisać o jakimś konkretnym frameworku i przez to wprowadza tylko bałagan, gdyż framework to pojęcie o wiele szerszym znaczeniu.

Framework to tak po ludzki napisany w jakimś języku mechanizm, zbiór biblitotek, którego używa się jak języka programowania... czyli buduje się w opraciu o nie swój kod. To znaczy tak jakbyś napisał swój własny język programowania w PHP i go opublikował. Na początku wydawało mi się to głupotą do kwadratu ! Po co mi język napisany w PHP do obsługi PHP. Żadnych więcej możliwości nie daje, a tylko powoduje, że wszystko działa wolniej ... głupie. A jednak nie zawsze, tylko trzeba wiedzieć kiedy z niego korzystać, a kiedy nie. A powodów może być kilka.

Frameworki pisane są do różnych języków programowania np. do JavaScript i jedną z korzyści z nich wynikających opiszę właśnie na tym przykładzie. Dwa dobrze znane mi frameworki w JavaScript to jquery i prototype. Ładuje się do przeglądarki pliczek w poprzez na przykład i ... pisząc w JavaScript od tej pory ma się dwie możliwości. Albo używamy JavaScript, albo używamy framework-a...

Przykładowy kod, który powoduje zniknięcie elementu na stronie (będzie to element
) w jquery wygląda następująco.

$('div.cos').hide('slow');

i tyle ! Proste nie ? Teraz zastanów się. Gdybyś nie używał jquery jak chciałbyś to zrobił ? Ja nie wiem... Jednak wiem jedno - znając burzliwe dzieje przeglądarek internetowych pisząc w JavaScript wcześniej czy później natknąłbym się na moment, w którym coś pod konkretną przeglądarką przestałoby działać ... :( Byłbym wtedy zmuszony do próby zaprogramowania tego samego na dwa, a może nawet trzy czy cztery (a może nawet więcej) sposobów, tylko po to aby obsłużyły to wszystkie przeglądarki... Powiedzmy, że się udało - napisałem skrypt... przychodzi rok 2008 i na rynku pojawia się kIEpska 8 nie zgodna z niczym ... i mój skrypt nie działa :( i co znowu siadam do kodu i rzeźbię ....

I tu pojawia się nasz framework. Działa jak język programowania, czyli pozwala nam pisać program... pod spodem jednak siedzą rzeczywiste funkcje JavaScript, które wszystko robią za nas :) Jaki jest z tego plus - nie my, ale twórcy frameworka zadręczają się problemem "nie działa na nowej przeglądarce :(" My piszemy nasz kod RAZ, wrzucamy na stronę, a o zgodność i całą resztę martwi sie framework :) i działa. Takie rozwiązanie (w przypadku JavaScript) ma wiele więcej plusów. Wymienię kilka:
  • Nie obchodzi nas jak obsługiwana jest wersja JS w przeglądarce.
  • Nie martwimy się gdy wychodzi nowy standard JS - o to martwią się twórcy frameworka.
  • Nie martwimy się gdy wychodzi nowa przeglądarka. Czekamy aż wyjdzie nowa wersja frameworka, podmieniamy jeden pliczek z nim zawarty i wszystko działa :)
We frameworkach chętnie pisane są też najróżniejsze dodatki i pluginy, do odsłuchiwania muzki mp3, tworzenia zakładek, generowania grafiki i wiele innych.

Dlatego wybierając framework należy zwrócić uwagę na kilka drobiazgów:
  • Jak często aktualizowany jest framework i czy w ogóle jest jeszcze rozwijany.
  • Jak wygląda jego dokumentacja i czy jest często wykorzystywany.
Framework z kiepską, albo żadną dokumentacją może sprawić nam więcej problemu aniżeli pomóc. Natomiast jeżeli framework kiepsko się rozwija to w przypadku znalezienia w nim błędu lub nowej przeglądarki jesteśmy zmuszeni na samodzielne grzebanie w kodzie, albo długie czekanie ... ew. męczenie twórców mailami.

Dodatkowo w JS frameworki mogą oferować obsługę fajnych efektów, animacji, składnię dużo przejrzystrzą i prostą aniżeli samo JS (dużo łatwiej czytać kod), kod może być w nich krótszy i bardziej zwięzły. Często framework posiada dodatkowe możliwości i dostępne w sobie użyteczne algorymty, których na próżno szukać w suchym JavaScript. Nie musimy wtedy pisać własnych funkcji. Przykładowo w jquery obsługa AJAXa jest bajecznie prosta a kod obsługujący go jest bajecznie prosty, przejrzysty i pisze się całkiem przyjemnie :) Nie martwię się o to, że AJAX w IE obsługiwany jest totalnie inaczej niż w FireFox czy w Operze, nie muszę też zagłębiać się też wszczegóły techniczne i sposób działania. Piszę sobie:

$('div.tresc').load('rozdzial.php?rozdzial=1');

a w uzyskanym dzięki frameworkowi czasie piję sobie kakao ;)

Istnieją też frameworki do PHP. Starają się one eliminować niedogodności języka oraz platform, na których jest uruchamiany. Dostarczają także użytecznych mechanizmów, które często są wykorzystywane w programowaniu, a które nie jeden z nas musiałby opracowywać na własną rękę:
  • Często nie wiemy na jakim PHP będziemy pracować, albo przychodzi nam zmienić serwer. Wszystko było napisane w PHP 5, funkcje czystego DOMu działały świetnie a tu klops :( usługodawca zapodaje na serwer PHP4 a my ... kwiczymy. Może przyjść nam tutaj z pomocą framework ! Jeżeli jest tak zaprogramowany piszemy mu wtedy "php5" i kod napisany we frameworku działa używając funkcji z php5. Zmienia się sytuacja musi działać na php4 podajemy frameworkowi "php4" i działa na php4. Zmieniamy tylko jedną literkę ! zamiast kilkuset linijek aplikacji.
  • Frameworki, także te w PHP mogą wspomagać programowanie od strony baz danych czy AJAX-a (np. symfony wspiera AJAX). Przykładowo baza danych - zmieniamy silnik z MySQL na Postgresa ... Framework może oferować nam swoją własną klasę dostępu do bazy danych, która działa tak samo bez względu na to z jakiego mechanizmu bazodanowego korzystamy.
  • Jeżeli pojawi się PHP 6 ... to my nadal pracujemy w naszym frameworku a o poprawność męczą się ludzie tworzący go.
  • Często framework wspomaga programowanie w MVC udostępniając nam klasy, które w sprytny i zgrabny sposób potrafią przetransportować informacje z klasy do odpowiedniego szablonu w PHP i powstawiać wszystko na swoje miejsce.
Ma to też swoje minusy. Największy to ten, że aby programować czasami musimy uczyć się praktycznie "nowego języka programowania", czyli frameworka, który nie oferuje specjalnie nic ponad to co PHP generując tylko narzuty czasowe (czyli wszystko to wykonuje się wolniej niż napisane w suchym PHP). Często więc przydaje się napisanie własnej klasy wkładające dane z PHP do szablonu HTML czy obsługującej w sposób transparentny bazę danych tak, aby nie ważne było czy to Postrges czy MySQL.

Wszystko zależy od stopnia skomplikowania naszego projektu. Jeżeli tworzymy prostą stronę internetową prawdopodobnie framework będzie tylko zawracaniem głowy i może nam tylko utrudnić to co jest proste. Jeżeli jednak decydujemy się na bardziej skomplikowany projekt, używanie MVC pozowli wywalić z kodu klas zbędnych HTML (który często zawala miejsce) co sprawi, że kod w metodach stanie się bardziej jasny, przejrzysty i czysty. Poskutkuje to łatwiejszym zrozumieniem tego co robi dana metoda oraz zwiększy czytelność kodu a przez to ułatwi modyfikowanie go ... co tylko się opłaci ! Czytając kod klas skupimy się na tym co klasa robi i co zwraca, a uwolnimy się od zastanawiania się nad tym jak to wyświetla co zdecydowanie pozwoli nam skoncentrować naszą uwagę na rozwiązaniu problemu.

Jeżeli już decydujemy się na skorzystanie z MVC następuje pytanie, czy piszemy własne klasy do obsługi tego co potrzebujemy ponieważ na przykład używamy tylko MVC czy może przydadzą nam się dodatkowe mechanizmy pozwalające na niezależność od rodzaju bazy danych (nie wiemy na czym będziemy pracować), dodatkowe opracowane już przez kogoś mechanizmy czy w końcu niezależność od wersji PHP :)

Saturday, May 5, 2007

Moje programy - Linux

Komunikatory:
Ekg2 - świetnie mi się go używa. Jest prosty i po prostu działa. Obsługuje mi pocztę (gmail), jabbera, IRCa, Tlena i GaduGadu. Jest po prostu idealny.

Pidgin - świetny komunikator, który potrafi obsłużyć bardzo wiele sieci. Estetycznie wykonany pod GTK na Kasi wygląda naprawdę bomba !

Kadu - Nie trzeba przedstawiać. Przeszkadza mi tylko to, że napisany jest pod QT, ale to dla mnie w sumie jego jedyna wada, wada związana z estetyką - a dokładniej Jej brakiem.

Psi (daisy) - Świetnie nadaje się do Jabbera. Sam używam na chromie.

Skype - Znajomi i rodzice używają, więc czemu nie ja :) w sumie miło się gada :)
Przeglądarki:
Opera, Firefox -nie trzeba przedstawiać.

IEs4linux - używam do testowania stronek internetowych pod Linuksem - bardzo wygodne.
Odtwarzacz muzyki:
MOC - po prostu urzekł mnie swoją prostotą i genialnym rozwiązaniem - klient serwer. Jak doinstalować zgodnie ze wskazówki na stronie dodatkowe kodeki to można posłuchać muzyki w najbardziej pstrokatych formatach.

AmaroK - Lubię to w jaki sposób kataloguje muzykę, jak na mnie zbyt ociężały. Na dzień dzisiejszy używam go tylko do słuchania radia internetowego do momentu, w którym nie poprawią MOCa aby też to potrafił.
Inne multimedia:
mplayer - razem z wtyczką do FireFox-a po prostu super ! Odtwarzam prawie wszystko.

VLC - wiem, że mogę na nim polegać. Czasem nie działają mi pliki WMP ... wtedy używam VLC i idzie jak burza. Poza tym ma świetne opcje do streamingu :) mi oczywiście nie potrzebne, ale może komuś się przydadzą :)
Edytory programistyczne:
vim - podoba mi się jego funkcjonalność i kolorowanie składni, umie sprawnie sprawdzać pisownię ASPELLem - w sumie wszystko czego człowiekowi do szczęścia potrzeba.

Eclipse (dokładnie PDT - dedykowane dla PHP) - jak na mój komputer do bólu ociężały, ale wybajerzony. Podoba mi się wsparcie dla wpisywanych funkcji, dostęp do manuala oraz menadżer klas - bardzo pomaga przy pisaniu kodu.

Bluefish - świtny edytor, jednak jego głównym mankamentem jest brak uzupełniania składni poleceń oraz strasznie brakuje mi wbudowanego klienta FTP.

Kate - Lekki, napisany w QT edytor. Najwygodniejsze jest to, że jak każda aplikacja w QT umie obsłużyć prawie każdy protokół, który się Jej zaserwuje - to jest bardzo wygodne. Wkurza mnie tylko jego tempota na zapisywanie stanu środowiska pracy i uparte proszenie o hasło do kont zdalnych przy uruchamianiu.

Quanta Plus - rozbudowana wersja Kate dziedzicząca po niej swoje wady i zalety ! Dużo bardziej rozbudowana pod kątem tworzenia stron www.
Klienci FTP:
gftp - po prostu lekki i przyjemny w użyciu, typowy, dwu panelowy klient FTP.

konqueror - dzięki obsłudze protokołów zaimplementowanej w QT niesamowicie wygodnie używa się go ponieważ zdalny system plików jest transparentny i używa się go jak lokalnego.
Menadżer logowania:
qingy - świetne możliwości graficzne, fajne motywy i możliwość stworzenia naprawdę WŁASNEGO niepowtarzalnego ekranu logowania, także do konsoli :) jest naprawdę świetny !
Pulpit zdalny:
rdesktop - świetny sposób na dobranie się do swojego Windowsowego przyjaciela :)
Grafika:
JAlbum - świetny program do generowania miniaturek - nic dodać, nic ująć :)

GIMP - Darmowy program do obróbki grafiki - bardzo użyteczny :)

GTKSee - świetny program do pokazu slajdów.

GQView - genialnie nadający się do wybierania zdjęć programie z kapitalną opcją kopiowania aktualnie oglądanego zdjęcia do wcześniej ustalonego katalogu.
Menadżer plików:
Thunar - świetne podglądy plików i nie do pobicia system masowej zmiany nazw plików :) oraz świetna możliwość dodawania swoich miejsc w panelu po lewej stronie.

Konqueror - nie do przebicia, wszystko co QT oferuje znajduje się tutaj - trochę przeciążony, ale obsługuje kapitalne podglądy, metody sortowania i dostępu do zdalnych zasobów.

Sunday, April 22, 2007

Konfiguracja mojego vim-a

Nie chcę was zanudzać szczegółami. W sieci dostępnych jest mnóstwo wspaniałych opisów do konfiguracji vim-a. Podaję tutaj tylko swój plik konfiguracyjnych i kilka ciekawych linków:
set nu " Włączamy numerowanie linii
set softtabstop=3 " Wcięcie [TAB] ustawione na 3 spacje
set shiftwidth=3 " Wcięcie używając [>]
set tabstop=3 " Wcięcie [TAB] na sztywno w plikach już wcześniej edytowanych

if &t_Co > 2 || has("gui_running") " Jeżeli tylko dostępone są kolory
syntax on " Włącz podświetlanie składni
set hlsearch " Włącz podświetalnie wyszukiwania
endif

set nobackup " Nie chcemy plików backupowych

set autoindent " Kontrola wcięć: Takie samo wcięcie dla kolejnej linii

" Rozpoznawanie typów plików przez vim-a i właściwe podświetalnie składni
" Możliwość używania wtyczek typów plików pomagających
" Wykorzystywaie reguł automatycznego robienia wcięć
filetype plugin indent on

set linebreak " Łamenie wierszy kiedy nie mieszczą się na ekranie
set nowrap " Tekst po dojściu do niewidocznej części tekstu zostaje przesunięty

" Rozpoznawania znaków tabulacji i odstępu
" set list
" set listchars=tab:>-,trail:=

" Ładne wcięcia dla programowania w języku C
" set cindent shiftwidth=3

" Kolorowanie składni XHTML i SQL wewnątrz stringów w plikach PHP
let php_sql_query = 1 " Koloruj SQL w stringach
let php_htmlInStrings = 1 " Koloruj HTML w stringach
let use_xhtml = 1 " Używaj XHTML-a

" Pokazywanie tego co się wpisuje przy wyszukiwaniu /
set incsearch

let spell_executable = "aspell"
let spell_language_list = "polish,english"
let spell_markup_ft = "html,php,xhtml,dhtml,tex,mail,help,text"
let spell_auto_type = "tex,mail,text,html,sgml,otl,cvs,none"

command! Gcc !gcc % -o %.out
command! Run !./%.out
command Php :!php %

" Kodowanie
set encoding=iso-8859-2 " Kodowanie
set fileencoding=iso-8859-2 " Kodowanie pliu
set termencoding=iso-8859-2 " Kodowanie termianala

" Koloruj komentarze na jasno zielono
" highlight Comment ctermfg=lightgreen

"set showmatch

Linki:
Wikibooks:
http://pl.wikibooks.org/wiki/Vim

Seria artykułów vim dla PHP [eng]:
http://schlitt.info/applications/blog/index.php?/archives/278-Comfortable-PHP-editing-with-VIM.html
http://schlitt.info/applications/blog/index.php?/archives/283-Comfortable-PHP-editing-with-VIM-2.html
http://schlitt.info/applications/blog/index.php?/archives/331-Comfortable-PHP-editing-with-VIM-3.html
http://schlitt.info/applications/blog/index.php?/archives/372-Comfortable-PHP-editing-with-VIM-4.html
http://schlitt.info/applications/blog/index.php?/archives/372-Comfortable-PHP-editing-with-VIM-4.html
http://schlitt.info/applications/blog/index.php?/archives/488-Comfortable-PHP-editing-with-VIM-5.html

Dodatkowe skrypt dla programistów PHP:
http://www.vim.org/scripts/script.php?script_id=1120
http://www.vim.org/scripts/script.php?script_id=967

Strona oficjalna:
http://www.vim.org/

Pisanie kodu PHP pod vim-em:
http://leon.w-wa.pl/texts/vim-php.php

Najlepszy artykuł o vim-e jaki czytałem - dla programistów C:
http://users.uj.edu.pl/~ufkapano/linux/cz3konsola/lp-vim.html


Vim dla PHP po polsku:

Tuesday, March 27, 2007

Pobieranie stringów w MySQL++

Po wczytaniu się w dokumentację znalazłem sposób na wyciąganie ładnych stringów:
row = res.at(i);
pom.erase();
pom = row["gatunek"].get_string();
gdzie pom to zwykły string pom;

Narzędzia programisty.

Już dawno miałem dokończyć ten wpis - dziś może w końcu się uda. Podczas jednych z konsultacji z C++ usłyszałem o kilku ciekawych narzędziach, które mogą pomóc w znajdowaniu wycieków pamięci. Pierwszym z nich jest valgrind, program, który pozwala tworzyć narzędzia do badania działania programu w trakcie jego wykonywania. W najprostszej wersji może on posłużyć przykładowo do sprawdzania miejsc, w których nie zwolniliśmy pamięci w programie (malloc / free). Podobną funkcjonalność oferuje nam narzędzie electric fence (całkiem sympatyczny opis na wikipedii). GDB to chyba wszystkim znany debugger :) Możemy sobie o nim poczytać międzyinnymi:

http://www.google.pl/search?hl=pl&client=firefox-a&rls=com.ubuntu%3Apl-PL%3Aofficial&hs=i0d&q=GDB&btnG=Szukaj&lr=lang_pl
http://student.agh.edu.pl/~gkozlow/GDB/
http://pl.wikipedia.org/wiki/GNU_Debugger

Wednesday, March 14, 2007

SELECT w MySQL++

Rozwiązania z dokumentacji co do zapytania SELECT mi nie działały. Zamieszczam własne:
mysqlpp::Row row;
unsigned long int ile = res.num_rows();
unsigned long int i;

for (i = 0; i < ile; i++) {
   row = res.at(i);
   cout << row["nazwa_kolumny"];
}

Sunday, March 11, 2007

Gdzie jest dziubdziub ?

http://www.gdziejestdziubdziub.prv.pl/

Problem z NVIDIĄ rozwiązany

Dziś doszedłem dlaczego nie działały mi sterowniki NVIDII ;P Wstyd się przyznać. Nie czytałem komunikatów instalatora ;P No i dopiero dziś dopatrzyłem się, że moja karta jest obsługiwana przez sterowniki w wersji 1.0-7184 a nie 1.0-9755 :P

Super odtwarzacz muzyki MOC

Trafiłem dziś na kapitalny odtwarzacz muzyki przeglądając http://www.linuxsoft.cz/pl/. MOC [http://moc.daper.net/.] Co prawda wersja alpha u mnie nie zadziałała, ale stable ;) poszło pięknie. Po zwykłym:
./configure
make
su
make install
Musiałem jeszcze z katalogu źródeł przekopiować do katalogu ~/.moc
  • katalog thems/ z themami
  • plik keymap.example jako ~/.moc/keymap
  • plik config.example jako ~/.moc/config
W pliku config odkomentowałem sobie jeszcze:
Theme = example_theme
XTermTheme = transparent-background

Po prawej stronie dodaje się pliki poprzez guziczek [a], [TAB]-em przechodzi się na prawą i klika [ENTER] aby zacząć odtwarzać.

Plik manuala (ubogi, dokumentacja na stronie też biedna) można otworzyć np. man /usr/local/share/man/man1/mocp.1

"Wychodzi się" guziczkiem [q] ;)

Saturday, March 10, 2007

qingy - Nowy menadżer logowania

Postanowiłem sprawić sobie jakiś graficzny menadżer logowania. Kolega polecał qingy więc pomyślałem, że spróbuję. updateos -f qingy nic nie zwróciło więc poszukałem źródeł w internecie. Samo wpisanie qingy w pasku adresu Firefox-a zwróciło mi (o dziwo) właściwą stronę [http://qingy.sourceforge.net/] . Po ściągnięciu źródełek zacząłem jak zwykle kompilacje.
bunzip2 qingy-0.9.5.tar.bz2
tar -xf qingy-0.9.5.tar
cd qingy-0.9.5
vim INSTALL README -p
./configure (nie poszło - nie ma directfb :/)

updateos -f directfb coś znalazło, ale chyba nie o to chodziło. Na stronie jest oczywiście wyraźna informacja o potrzebie doinstalowania directfb [http://www.directfb.org/] więc zaczynamy ;)
tar -zxf DirectFB-1.0.0.tar.gz
cd DirectFB-1.0.0
vim INSTALL README -p
./configure (poszło ;))
mak
su
make install
Wracam do katalogu z qingy:
ldconfig
./configure (poszło ;) )
make
su
make install

Czasami pada pytanie czy da się tak zainstalowany program odinstalować. Jeżeli ma się katalog, w którym kompilowało się źródła, zostawiło się go na dysku - to wystarczy wejść do tego katalogu i wykonać polecenie make uninstall.

whereis qingy podało mi informacje gdzie mogę szukać mojego qinqy - ale trudno. Zgodnie ze wskazówkami z pliku INSTALL dopisałem do /etc/inittab co i jak trzeba. W moim przypadku vim INSTALL /etc/inittab -p. Po moich modyfikacjach fragment tego pliku wygląda mniej więcej tak:
# These are the standard console login getties in multiuser mode:
c1:12345:respawn:/usr/local/sbin/qingy tty1
c2:12345:respawn:
/usr/local/sbin/qingy tty2
c3:12345:respawn:
/usr/local/sbin/qingy tty3
c4:12345:respawn:
/usr/local/sbin/qingy tty4
c5:12345:respawn:
/usr/local/sbin/qingy tty5
c6:12345:respawn:/sbin/agetty 38400 tty6 linux

#c1:1235:respawn:/sbin/agetty 38400 tty1 linux
#c2:1235:respawn:/sbin/agetty 38400 tty2 linux
#c3:1235:respawn:/sbin/agetty 38400 tty3 linux
#c4:1235:respawn:/sbin/agetty 38400 tty4 linux
#c5:1235:respawn:/sbin/agetty 38400 tty5 linux
#c6:12345:respawn:/sbin/agetty 38400 tty6 linux

Nadeszła godzina zero. qingy działa nawet dl
id:4:initdefault. Zanim uruchomimy go po raz pierwszy warto zmodyfikować plik /usr/local/etc/qingy/settings i ustawić temp_files_dir = "/tmp/qingy" (u mnie temp_files_dir = "/tmp/qingy"). Program jednak sam sobie katalogu nie zrobi. Trzeba go więc utworzyć samemu. Ja dodatkowo na wszelki wypadek dałem na niego chmod 0777 /tmp/qingy.

Przed restartem komputera jako root utwórz jeszcze katalog /usr/local/etc/qingy/sessions. I tutaj pojawia się pewien zgrzyt :| otóż, aby odpalić w qingy X-y należy w pliku domowym utowrzyć sobie plik: .xsession. U mnie w Kasi jest on pusty. Po kilku minutach przyglądania się systemowi doszedłem do wniosku, że odpowiednie środowisko graficzne odpala /etc/X11/xinit/xinirc.[nazwa środowiska] Kiedy istnieje pliczek .xsession podczas logowania można wybrać sobie czy chcemy wejść do konsoli czy zalogować się do X-ów. Ponieważ nic mądrzejszego od twórców Kasi nie wymyślę posłużyłem się zbawiennym już dowiązaniem symbolicznym (u mnie xfce):
su
rm /home/johny/.xsession
ln -s /etc/X11/xinit/xinitrc.xfce /home/johny/.xsession
chown johny:users /home/johny/.xsession
I od tej pory mogłem cieszyć się logowanie qingy :) do X-ów.

Jeżeli wiemy z góry, że boimy się mrówek warto przed restartem komputera zajrzeć na [http://qingy.sourceforge.net/themes.php]. Może się wydawać, że wiele themów "nie działa". Można je zawsze znaleźć na http://themes.freshmeat.net/. Czasami jednak podanie w wyszukiwarce qingy to za mało i trzeba posiłkować się nazwą themu. Dodatkowo warto wspomnieć, że katalog, w którym umieszcza się themy (rozpakować theme to tego katalogu. np. powstaje wtedy katalog einstein) można znaleśc w pliku /usr/local/etc/qingy/settings:
themes_dir - katalog, w którym umieszczamy katalogi z themami (wystarczy zazwyczaj rozpakować tam theme)
theme - nazwa katalogu z themem w środku
W razie jakichkolwiek problemów czy wątpliwości zajrzyjcie na http://qingy.sourceforge.net/manual.php

Powodzenia i miłej zabawy !

Kompilacja z MySQL++

Namęczyłem się, żeby jakoś skompilować program z MySQL++. Więc podaje jeszcze nie rozbdudowany Makefile:
CC = g++
CFLAGS = -lmysqlpp -lmysqlclient
LFLAGS = -I/usr/include/mysql -I/usr/include/mysql++

ZOO: main.o klatka.o klatki.o
$(CC) main.o klatka.o klatki.o -o ZOO $(CFLAGS)

main.o: main.cpp
$(CC) -c main.cpp -o main.o $(LFLAGS)

klatka.o: klatka.cpp
$(CC) -c klatka.cpp -o klatka.o $(LFLAGS)

klatki.o: klatki.cpp
$(CC) -c klatki.cpp -o klatki.o $(LFLAGS)

clean:
rm -f *.o
Mam nadzieję, że to dużo wyjaśni - bo ja się z tym męczyłem dobrą dobę.

Friday, March 9, 2007

Błogosławieństwo dowiązań symbolicznych

Często jak kompiluje się jakieś biblioteki, grę wrzuca się je do /usr/local - potem chcemy odpalić nasz wymarzony program a tu wiadomośc, że brakuje biblioteki libgladeui-1.so.4.

Należy pamiętać, że po każdym zainstalowaniu programu warto wydać komendę ldconfig, która zrobi update bibliotek współdzielonych w systemie, to znaczy odświerzy informacje o nich. Generalnie podobne sytuacje zdarzają się w innych przypakach, mi na przykład program na sztywno szukał jakiś sterowników (do Neo) w jakims konkretnym wyimaginowanym katalogu (na szczęście mówił w jakim), ale go nie było. I to jest właśnie błogosławieństwo dowiązań symbolicznych. W moim przypadku gdy brakuje biblioteki to dowiązuje sobie ją do /usr/lib:

ln -s /usr/local/lib/libgladeui-1.so.4 /usr/lib/libgladeui-1.so.4
I mam z głowy tak samo zrobiłem z plikiem od Neo - nie raz taka sztuczka uratowała mi "niedziałający" program - może i Tobie się przyda.

Jak Vista.

Po przeczytaniu artykułu [KŚ Ekspert 3/07] o upodobnianiu Windows-a XP do Visty postanowiłem przestać teoretyzować, spróbować i wyrobić swoje własne zdanie. Kilka spostrzeżeń po instalacji Vista Transformation Pack 6.0:

1) Komputer z bajerkami zaczął ciut wolniej działać - ale czego można wymagać od Durona 1.0 i 600 MB RAMu - pewnie na innym kompie byłoby lepiej, jednak mam wrażenie, że wszystkie bajerki graficzne obciążają procesor a nie kartę graficzną, a szkoda.

2) W TaskSwitchXP niebieskie literki na ciemnym tle podczas przełączania okien są prawie niewidoczne. Domyślam się, że dodatek Power Toys o tej samej funkcjonalność, lepiej komponowałby się ze stylem Visty, na szczęście w zakładce Wygląd TSXP można zmienić styl wyglądu okna przełączania aplikacji i wszystko wygląda ładniej.

3) Nie wiem czy to wina łatek Windows, czy tego programiku, a może samego błędu w IE7 czy Windows Defender-a (bo instalowałem wszystko jednocześnie), ale straciłem dostęp do Opcji Internetowych - pomimo tego, że jestem administratorem nie mam do nich dostępu.

4) Musiałem poprzesuwać "guziczek" emulujący fragment START-u. Wygodnie robi się to najpierw przesuwając go gdzieś myszką potem operując strzałkami.

5) LClock czy coś takiego wyłączyłem, wole prostą cztelną informacji o godzinie, a kalendarz mam na SideBarze.

6) Sidebar wydaje mi się słabo konfigurowalny - lepiej moim zdaniem prezentuje się Desktop Sidebar, fajna jest opcja guziczków odtwarzacza, jest wsparcie dla wielu odtwrzaczy w tym Winamp-a niestety :/ foobar-a zabrakło :(. Posiada bardzo czytelny i fajny kalendarz, kontrolkę obciążenia kart sieciowej czy zegary procesor-a ;)

7) Brzydko kontrastuje biała plama najczęściej uruchamianych programów w STARCIE.

8) Zjadło mi pokazywanie popularnych zadań w folderach.

9) Po wpisanie adresy strony www w IE7 odpala mi się FireFox :/

10) Nie dział podwójne klikanie [CTRL]+[ALT]+[DEL] przy ekranie logowania.

To tyle w dużym skrócie.

Rzecz o moim Windowsie

Na komputerze obok mojej Kasi rezyduje na którejś partycji Windows XP z MSDNAA. Czasami profesorom, którzy programują pod Windowsem, coś nie działa, rzucają pomysł, żeby znaleźć błędy w ich kodzie i wypadałoby mieć kompilator, którego używają. Może pokrótce opisze programy, które mam zainstalowane pod Windowsem.

Odtwarzacz muzyki [Foobar 2000]: Moim zdaniem najlepszy odtwarzacz muzyki pod Windowsem. Nie jest bajerancki, ale prosty jak cep. Mam wrażenie, że zajmuje mniej miejsca w RAM-ie i na pewno na wolniejszych komputerach działa szybciej niż Winamp. Doinstalowałem sobie do niego dodatek Columns UI, który pozwolił mi w dużo wygodniejszy dla mnie sposób zarządzać playlistami. Myślę, że nawet jakość dźwięku jest lepsza więc polecam go wszystkim amatorom dobrej muzyki.

Komunikator do Gadu-Gadu [Gadu-Gadu]: Używam go przede wszystkim ze względu na opcję Gadu-Radia. Generalnie używam ekg2 na uczelnianym shell-u. Specjalnie dla słuchania Gadu-Radia zainstalowałem też Winamp-a w wersji Lite. Pod Kasią używam tylko ekg2.

Wysyłanie SMS-ów [eSkiMoS]: Super programik do wysyłania nie tylko SMS-ów. Ponieważ jestem harcerzem często przydałaby mi się opcja wysyłania SMS-ów masowo np do wszystkich członków jednego zastępu. Eskimos pozwala na to i jeszcze więcej. Możemy w nim tworzyć grupy, przypisywać kontakty do grup i wysyłać wiadomość wszystkich z grupy w kilku kliknięciach. Aplikacja jest napisana naprawdę dobrze i z głową ! Kapitalnie się z niej korzysta. Obsługuje chyba wszystkie dostępne bramki SMS-owe (przy okazji polecam bramkę http://sms.ikp.pl - wysyła na Erę i na Orange u osoby z wyłączonym odbieraniem SMS-ów z internetu), pozawala na wysyłanie wiadomości do użytkowników Gadu-Gadu i Tlen-a ma bardzo wiele ciekawych opcji, obsługuje bramki kilku innych krajów - no po prostu dla mnie miodzio !

Przeglądanie partycji ReiserFS [YAReG]: Oczywiście tylko do odczytu, ale moim zdaniem to i tak wiele. Jak mam jakieś dane na Linuchu i siędzę pod Windowsem to krytycznie skraca czas dostępu do tych informacji, bo nie muszę rebootować dwa razy komputera.

Obsługa zdalnego terminala SSH [PUTTY]: Nie wiem czy jest coś konkurencyjnego. Jak muszę zalogować się spod Windowsa na shell-a uczelnianego to używam po prostu putty.

VOIP [Skype]: Bo moi znajomi używają.

Przeglądarka [Firefox/Opera/IE 7]: Obecnie używam masowo Firefox-a, jednak tylko ze względu na funkcjonalność serwisów Google. Gdyby wszystko działało poprawnie w Operze, używałbym Opery - trudno takie życie. Mam też IE7. Niesamowicie podoba mi się w nim opcja miniaturek okien [CTRL]+[Q].

Czytnik PDF [Foxit reader]: Bo jest lekki i nie zasysa jak Adobe.

Odtwarzacze multimediów, kodeki itd... [Video LAN VLC]: Za każdym razem starałem się instalować moim znajomym kodeki (u mnie w domu siostra siedziała w Mandze i Anime, więc Ona w tym siedziała i wszystko instalowała) optymalnie - tak żeby wszystko działało. Zawsze próbowałem zasięgnąć rady w internecie żeby poznać najlepszą opcję ! No i każdy miał swoje zdanie ! KLite Codec Pack (MEGA KŚ Expert poleca - ja im wierzę), AllinOne (to zawsze instalowałem i mi działało), Nimo - nie wiem co tam jeszcze, a moja siostra na przykład instalowała wszystko po kolei osobno, (divx3, 5, 6 ... etc) podobno była jakaś magiczna kolejność instalowania setek tych pakietów, która sprawiała, że wszystko działało. No i czasami trzeba było doinstalować jeszcze Real Media Player, Quick Time... No po prostu masakra ! Do odtwarzania filmów w domu zawsze pod Windowsem był BestPlayer (jest lekki no i ma Best w nazwie), AllPlayer - bo jest moim zdaniem naprawdę dobry i mam go też na swoim windowsie, posiada opcję jakiś inteligentnych napisów, integrację z syntezatorem mowy, ale co najlepsze ma opcję autmatycznego ściągania brakujących kodeków, dlatego sprytna osoba dzięki tej opcji szybko rozwiąże problem niedziałającego filmu. Do QuickTime i RealMedia używałem Real Alternative i Quick Time Alternative - nie męczyły reklamami, jakimiś wyskakującymi okienkami i innym spywerowatymi opcjami, które były dla mnie stresogenne.
I chociaż na AllInOne się nigdy nie zawiodłem (bo nie znalazłem filmu, którego nie dało się na nim odtworzyć), to moi znajomi zawsze mówili, że jakiś ich znajomy polecał im jakiś codepack i jednak jakiś film im nie działa i żeby do nich wpaść. Ponieważ sam nie ufałem codekpackom, które sam instalowałem, wściekłem się i zacząłem instalować programy programy bez kodekowe. Pierwszym, którego używałem był Kliper, dziś mam doinstalowanego VideoLAN VLC i nie narzekam. Pierwszego polecam ze względu na oparcie się o stare sprawdzone rozwiązanie jakim jest mplayer. Myślę, że dobra opcja, jeżeli nie koduje się filmów, tylko je ogląda, szczególnie dla osoby-laik-a. Ja do codek-packów zaufania nie mam :/ No może Do jakiegoś Mega Codeck-Pack, który zajmuje tyle, że zawiera chyba wszystkie możliwe kodeki - ale czy warto zaśmiecać sobie system. Poza tym do nieinstalowania kodeków przyczyniła się jeszcze jedna historia. W którejś wersji Gadu-Gadu po zainstalowaniu FDDShow GG przestawało się odpalać generując jakiś błąd.
Do rozpoznawaniu kodeku używam GSpot-a.

[ALT]+[TAB] Task Switch XP: Programik podmieniający okienko spod [ALT]+[TAB] - całkiem przyjemny i użyteczny.

Powiadomienie o poczcie [Gmail Notifier]: Ten Googlowski.

Edytory, środowiska programistyczne:
EditPlus - bo się tak przyzwyczaiłem - poza tym jest lekki, posiada 100% funkcjonalności, jakiej potrzebuję, konfigurowalny, opcja otwierania zdalnie przez FTP, i bardzo mi się podoba jego kolorowanie składni (tylko vim przebija).

Dev C++: Bo piszą w tym profesorowie na PG.

Free Pascal: Właściwie sam się zastanawiam po co, ale się pałęta na dysku.

Code Block: Bo słyszałem, że dobre. W sumie nic poważnego w niej nie pisałem. Chyba aplikacja jak każda inna i wszystko zależy od gustu. Dla mnie po prostu szczytem jest vim (dla C/C++) i takie coś innego mi nie odpowiada. Nie mam jednak nic do zarzucenia tej aplikacji. Porządnie wykonana, możliwość tworzenia projektu QT, OpenGL, WxWidgets - moim zdaniem bardzo fajna bo otwarta na OpenSource i na pewno równie dobrze napisana. Jak ktoś szuka dobrego edytora do C/C++ to na pewno warto sprawdzić i ten.

Eclipse: Raczej używam PHPIDE, bo pisanie kodu w vim-ie w obecnym projekcie jest ciut męczące - generalnie przydaje się uzupełnianie, widok klas, wbudowana pomoc do funkcji - bardzo przyśpiesza i ułatwia mi pracę.

Pliki DJ-VU [DjVu Browser]: Działa jako dodatek do FF, ale czy jest coś innego - nie wiem.

Odśmiecanie Windows [Odkurzacz]: Moim zdaniem porządnie wykonana aplikacja. Bardzo mi się podoba opcja DOBRZE DZIAŁAJĄCEGO monitor-a instalacji, do którego mam zaufanie i wierzę, że naprawdę wyłapie wszystkie pliki jakie zagnieździły się w moim systemie, podczas instalacji oprogramowania.

Robienie galerii HTML [JAlbum]: Nie znalazłem nic lepszego-darmowego.

Antywirus [AVAST]: Bo jest darmowy i nie zawiodłem sie jeszcze na nim. Mam też gdzieś Windows Defender jako antyspamer.

Przeglądanie grafiki [IrfanView/Picasa]: IV bo zawsze było, Picasa fajnie kataloguje zdjęcia, lubię w niej robić kolaże dla znajomych i szybko pozwala mi wysłać zdjęcia gmail-em co jest dla mnie bardzo wygodną funkcją. Generalnie na codzień wystarcza mi funkcjonalność Windows XP.

Nagrywanie dźwięku [AudaCity]: Na moje potrzeby lepszego programu nie widziałem.

Kompresja 7-zip: Obsługuje sporo formatów jest darmowy i wygodny jako menadżer plików, przynajmniej w funkcjonalności jaka jest mi potrzebna.