mar 29

Szczegóły tutaj.




mar 12

Domena firmy Symbolics została zarejestrowana dnia 1985-03-15. Zdawać by się mogło, że witryna nie zmieniła się za bardzo przez te 22 lata, ale wystarczy przenieść się do 1998 roku – piękny fraktal, teraz już takich nie robią.




mar 03

Jak dla amatora to baza jest duża, ponad 8 milionów rekordów, około 600MB. Wyszukiwanie w niej, nawet po częściowo zaindeksowanych kolumnach trwało przynajmniej 20 sekund. Zwykle znacznie więcej. Dotarło do mnie, że taka baza to koszmarek – pól tylko pięć – id, nazwisko_imie, miasto, ulica, numer – z czego zawartość trzech jest powtarzalna. I pierwszy raz w życiu dane mi było przeprowadzić procedurę atomizacji i normalizacji bazy danych. Oddzieliłem imię od nazwiska, usunąłem niepotrzebne znaki, rozbiłem dane na pięć tabel (nazwiska, imiona, ulice, miasta oraz tabela główna). Po zaindeksowaniu wszystkiego co się dało zaindeksować baza zwiększyła się o 100%, ale wyszukiwanie teraz trwa nie więcej niż 1-2 sekundy.
I tak właśnie utraciłem swą wiarę w wydajność mysql’a.




lut 14

Powiedzmy że mamy już te ponad 200 tysięcy plików na dysku. Przystępujemy do procesu parsowania, który wydaje mi się najtrudniejszy i najbardziej wrażliwy na choćby drobne zmiany formatu pliku źródłowego.
W Perlu można skorzystać z modułów ułatwiających wyciąganie czystego tekstu z plików .html, na przykład HTML::Parser, niestety nie jest to specjalnie elastyczna metoda (bez ekwilibrystyki). Postanowiłem zrobić wszystko ręcznie i krok po kroku. Na początek otwieramy sobie plik .html:

$plik_html="html/".$numer.".html";
open(HTML, '< ' , $plik_html);
@tablica = ;
close (HTML);

Po otwarciu zawartość pliku jest przepisywana wiersz po wierszu do tablicy. Dostęp do danych staje się łatwy. Teraz pętla usuwająca tagi html’a i konwertująca polskie znaki:

#interesujace dane znajduja sie od 72 do 20 od konca tabeli
for ($i=72; $i < = $#tablica-20; $i++)
{
@tablica[$i]=~ s/<(?:[^>'"]*|(['"]).*?\1)*>/ /gs; #wywalami tagi html'a
@tablica[$i]=~ s/& n b s p ;/ /g; #zamieniamy twarde spacje na spacje w ascii
@tablica[$i]=~ s/& q u o t ;//g; #kasujemy cudzyslow

@tablica[$i] =~ s/\/t/ /g; #zamieniamy tabulacje na spacje
@tablica[$i] =~ s/^\s+//; #kasujemy spacje z przodu wiersza
@tablica[$i] =~ s/\s+$//; #kasujemy spacje z tyłu wiersza
@tablica[$i] =~s/( )\1+/$1/g; #kasujemy powtarzajace sie spacje

#korekta polskich znaków z utf8 na iso-8859-2
@tablica[$i] = utf8(@tablica[$i]);
@tablica[$i] = $str_latin2->from_unicode(@tablica[$i]->utf16);
#jeszcze drobne korekty diakrytyczne
@tablica[$i]=~ s/& # 2 1 1 ;/Ó/g; #aby przeglądarka internetowa nie interpretowała...
@tablica[$i]=~ s/& # 2 4 3 ;/ó/g; #...kodowanych znaków (np. Ó) wstawiłem spacje!

Ady dokonywać konwersji polskich znaków w ten sposób trzeba sobie przygotować wcześniej metodę:

use Unicode::Map();
use Unicode::String qw(utf8 utf16);
$str_latin2 = new Unicode::Map("ISO-8859-2");

Teraz dla wygody warto przepisać sobie niepuste wiersze obrabianej tablicy do nowe tablicy:

if (length(@tablica[$i]) > 0)
{
push (@dane,@tablica[$i]);
}

Zbieranie danych z tak przygotowanej tablicy nie będzie stanowiło wielkiej trudności. Format jest stabilny, zmienia się tylko ilość wierszy kiedy wpis do KRS-u posiada długą nazwę, długi opis sposobu reprezentacji oraz przy datach wpisania i wykreślenia z rejestru. Koniec tablicy to zawsze dane osób reprezentujących. A więc sprawę załatwiają instrukcje tego typu (czasami warunkowo zapętlone):

$numer=substr(@dane[1],10,length(@dane[1]))."\n"; #numer KRS

Skrypt całego parsera jest nudny, zamieszczę go na końcu jako finalny program. Tymczasem przychodzi czas wprowadzenia danych do bazy.




lut 07

Nawiedziła mnie silna pedagogiczna potrzeba i postanowiłem zaprezentować tasiemca, kilkuodcinkowy cykl powstający równolegle do pisania mojego aktualnego projektu.
Przyjąłem sobie za cel przerobienie wyszukiwarki uproszczonych wpisów do KRS. Od 1.01.2007 Ministerstwo Sprawiedliwości na ustawowy obowiązek nieodpłatnego publikowania wybranych danych z Krajowego Rejestru sądowego. No i faktycznie chłopcy od Wielkiego Zbiga udostępnili bazę danych i wyszukiwarkę. W zasadzie do zawartości merytorycznej nie ma się jak przyczepić, ale bolesne są dwie sprawy. Strona jest dosyć popularna, a hosting lichy, więc każde zapytanie to kilka, a w południe nawet kilkanaście sekund oczekiwania. Druga sprawa to ograniczona możliwość wyszukiwania – serwis daje nam możliwość jedynie przeglądania bazy po numerze KRS-u lub nazwie podmiotu. Brakuje wyszukiwarki po adresie i nazwiskach członków zarządu. Tyle preambuły.

Przepis na przyspieszenie i zwiększenie funkcjonalności wyszukiwarki KRS:
1. Ściągamy całą bazę danych.
2. Pasujemy pliki .html i wyciągamy z nich istotne dane.
3. Pozyskanymi danymi wypełniamy lokalną bazę danych.
4. Piszemy wyszukiwarkę i przeglądarkę wpisów.
5. Ew. przygotowujemy skrypt dla cron’a, który będzie okresowo aktualizował bazę.

Wyszukiwarka podaje nam dane po takich linkach: http://pdi.cors.gov.pl/KRSSED/Podmiot.aspx?nrkrs=0000100679 – struktura linku jest przejrzysta jak Bajkał w zimie. Aż się prosi aby do pracy zatrudnić wget’a – wystarczy go zapętlić i dać mu kilka (?) godzin. Wpisów w bazie jest około 280 tysięcy i tak ustawiłem pętlę ściągającą dane, ale trudno powiedzieć ile czasu może zająć cała procedura downloadu. Wg moich szacunków może to potrwać nieco więcej niż dobę, jednak operację zamierzam przeprowadzać jedynie w nocy.
Cała procedura ściągania wygląda tak:


#!/usr/bin/perl

$numer=100; # pod numerami 0-100 nie ma danych

while ($numer < 280000)
{
$numer++;
$numer = sprintf '%.*s%s', 10 - length ($numer), '0' x 10, $numer;
$status = system ("wget http://195.164.168.100/KRSSED/Podmiot.aspx?nrkrs=$numer -O html/$numer.html -q");
print $numer." - kod wyjscia: ".$status." ";
}

Jak widać zrezygnowałem z raportów by wget, ale procedurka zawiera prostą informację o błędach (kod wyjścia równy jest 0 kiedy wget'owi wszystko się powiedzie). W zasadzie jedyną ciekawą linią jest:
$numer = sprintf '%.*s%s', 10 - length ($numer), '0' x 10, $numer;
czyli dopełnienie numeru wpisu zerami z przodu, aby łącznie numer miał 10 cyfr. Poza tym oczywistości.

W następnym odcinku wydobędę i sformatuję interesujące nas dane ze ściągniętych plików .html




sty 11

Wpadam tylko na chwilę, bo czasu niewiele gdy jest się permanentnie pomiędzy kończeniem jednego projekciku, a rozpoczynaniem drugiego. Do tego trzy kolejne klują się w głowie. Bardzo się cieszę, że podróżuję autobusami, bo nie ma lepszego miejsca na spokojne projektowanie skryptów.
Chciałem napisać, że od kilku dni PHP jest moim faworytem. Bardzo sprytna maszynka.




gru 09

UWAGA!
Wszystkim, którzy szukają tutaj artykułu dotyczącego routingu w Window XP, polecam zapoznanie się z aplikacją WinRoute Lite.

Po tygodniu niemalże codziennych, kilkugodzinnych prób skonfigurowania winxp aby udostępniał internet z sieci światowo-bezprzewodowej do lokalnie-skrętkowej mogę powiedzieć, że udało się. Wniosek mój opieram na tym, ze system podniósł się dwukrotnie i wszystko zdaje się działać. Ciekawe jak długo?
A ile mnie to nerwów kosztowało… jakieś konflikty usług, komunikaty błędów tak czytelne jak inkaskie kipu, a najgorsze to nazewnictwo. Przykładem niech będzie Menedżer przekazywania, usługa ta zarządza synchronicznymi i asynchronicznymi transferami plików między komputerami klienckimi a serwerami w sieci. A ja się pytam co z tego wynika? Przecież to nic nie znaczy. Konfiguracja zerowej sieci bezprzewodowej? Że niby MOJA sieć jest zerowa?
Nazw usług nie da się zapamiętać, brak w tym wszystkim czegoś co zwane jest logiką i spójnością. Zrobienie tej samej operacji w moim populistyczno-desktopowym GNU/Linux zajęło mniej niż 10 minut. Tryb był taki: google -> grupy dyskusyjne -> wklejenie odpowiedniego skryptu dla iptables -> już mam internet przed telewizorem w drugim pokoju.
Ja nie wiem, może do windowsa w wersji box dodają jakieś książki, w których można znaleźć rozwiązanie magicznych komunikatów typu:

Model DCOM odebrał błąd „%1084” podczas próby uruchomienia usługi EventSystem z argumentami „” w celu uruchomienia serwera:
{1BE1F766-5536-11D1-B726-00C04FB926AF}

Z grup dyskusyjnych windowsa można się dowiedzieć głównie, że: „przeinstaluj system, na 99% pomoże”, albo „zainstaluj servicepacka”. A ja naprawdę chciałem polubić ten system!




lis 10

Chcąc wykorzystać dane z plików Excel’a w skryptach Perl’a mamy (jak to zwykle w przypadku tego języka) kilka możliwości. Można oczywiście skonwertować pliki do formatu CSV i wczytywać je wiersz po wierszu wpisując dane do tablic, ale po co, skoro struktura danych plików .xls jest sama w sobie bardzo wygodna. Jej główną zaletą jest możliwość czytania danych zawartych w poszczególnych komórkach podając współrzędne tychże.
Wystarczy wykorzystać moduł Spreadsheet::ParseExcel. Sposób dosyć elegancki, banalny, szybki i multiplatformowy.
Jednak nie dla Polaków – moduł w absolutnie nieczytelny dla mnie sposób interpretuje polską diakrytykę, nie da się tego naprawić przez proste przestawienie znaków właściwych dla danej strony kodowej. Straciłem sporo czasu na szukanie w sieci, ale rozwiązania brak.
Trzecią możliwością jest wykorzystanie modułu Win32::OLE. Prostota i wygoda w implementacji jest znaczna, jednak rozwiązanie posiada zasadniczą wadę. Niezbędna jest obecność Microsoft Excell w systemie (oczywiście system = MS Windows). Czytanie z .xls w ten właśnie sposób jest wolne, a nawet bardzo wolne, ale jest. Do tego moduł musi dostać pełną, bezwzględną ścieżkę prowadzącą do pliku .xls. Zwykle moje parsery jednorazowo przetwarzają jedynie do kilkudziesięciu tysięcy komórek skoroszytów Excel’a, opóźnienia przy takich ilościach danych nie są specjalnie uciążliwe.

Temat w sposób obszerny omówiono tutaj.




lis 09

Jakiś rok, może dwa, temu widziałem film, na którym pewien uzdolniony magik przeszedł Fallout II w kilkanaście minut. Kunszt to wielki, ponieważ mi, z tego co pamiętam, jeszcze jako uczniowi szkoły średniej, tą sama grę udało się ukończyć w około tydzień. A raczej nie grałem wtedy sporadycznie… Dzisiaj szacuję, że mógłbym ją ukończyć w jeden dzień – nie stosując oczywiście technik zaobserwowanych na filmie.
Okazuje się że istnieje strona zbierająca podobne rekordy wraz z zapisem video. Można podziwiać następujące osiągnięcia:

Baldur's Gate 0:30:24
Diablo 0:17:38
Doom 0:21:25
Fallout 0:09:19
Half-Life 0:45:45
Quake 0:13:46

Nieźle, prawda? Szczegóły tutaj.




lis 03

Właśnie miałem reanimować bloga, bo pojawiło się sporo tematów, które warte są opisania. Dzisiaj przyszła mi ochota na podzielenie się refleksjami na temat eksportowania danych z .xls przy uzyciu Perl’a, ale jak zobaczyłem te popupy to mnie wzdrygnęło.
Niestety.