Ar veikia slankieji vidurkiai? Bandymas pasiknaisioti su programavimo kalba R

Įspėjimas: tai labai techniškas ir programiškas dienoraščio įrašas, toks, kokio jau nebuvo gerus septynetą metų. Bet net ir programuotojams jo vertė ribota, nes dar tik mokausi susigyventi su programavimo kalba R, bet jau jaučiu, kad mano programavimo įgūdžiai ganėtinai atšipę ir užrūdiję. Jeigu ir toliau esate pasiryžę imti ir gaišti laiką skaitant ką prirašiau, nesiskųskite, jog nebuvote įspėti.

Skaitykite toliau

CNN: Lietuviai turi daugiausiai laisvų dienų pasaulyje

Nežinau, kaip čia tiksliai CNN paskaičiavo, bet jie teigia, jog lietuviai ir brazilai turi daugiausiai laisvų dienų pasaulyje. Jei brazilai man iš tiesų asocijuojasi su saule, samba ir gyvenimu per daug sau nesukant galvos, tai lietuviai šioje kompanijoje gana sunkiai pritampa. Matyt čia tų laisvadienių Lietuvoje tiek daug dėl jau nebegaliojančio įstatymo, kuriuo būdavo perkėlinėjamos savaitgalį išpuolančios šventės į kitas darbo dienas. Visgi, mano nuomone, šis faktas apie lietuvių „darbštumą“ iškalbingas: kai tiek daug atostogaujama, vertė nekuriama – lietuvių darbo produktyvumas yra vienas mažiausių Europos Sąjungoje.

Įdomu, kaip darbo produktyvumo statistika pasikeis po šios krizės: ar ko nors išmoksime? Euforiško ekonomikos augimo metu buvome pratę kasmet iš darbdavio reikalauti vis daugiau, nors abejotina, ar mūsų sukuriama pridėtinė vertė augo proporcingai mūsų reikalavimams. Darbdaviui nebuvo kur dėtis: naujos darbo jėgos neprisišauksi, nes jos trūko. Dabar lazda apsisuko kitu galu, bet, kaip prieš beveik metus rašė buvęs kolega Algimantas Variakojis, vis dar atrodo, lyg krizės nėra. O gal pokyčiai jau matomi?

PHP programuotojų susitikimas

Vakar dalyvavau PHP prijaučiančių susibėgime. Sakau, jog prijaučiančių, nes tarp programuotojų šmėstelėjo keletas merginų, o ir šiaip nemažai senųjų PHP programuotojų užsiima jau visai kitais reikalais, nelabai susijusiais su PHP ir netgi programavimu. Kalbų buvo nemažai – geru žodžiu neminėjom smartweb, taipogi pakeiksnojom PHP vystymą (dėl to, kad ištaisytos klaidos PHP5 nebackportinamos į PHP4, o kartu ir dėl to, jog vystymą kontroliuoja Zend‘as). Buvo sugalvota idėja duoti visiems pasukti smegenis ir pabandyti optimizuoti vieną SQL užklausą, ties kuria ABLomas jau ilgokai užstrigęs.

Vėliau, jau likus tik kokiai dešimčiai žmonių, buvo kalbama apie tai, jog reikėtų bendros svetainės, kurioje butų galima dėti visus programuotojų nusiskundimus savo darbdaviais – šiek tiek specializuotas skundai.lt variantas, labiau orientuotas į freelancer‘ius programuotojus ir dizainerius. Ši idėja kilo, nes kolegos programuotojai buvo pasibaisėję Gauminos darbo sąlygomis. Be to, diskutavome ir apie tai, kokia yra Lietuvoje teisinė situacija su turinio cenzūra: t.y. ką daryti, jeigu kas nors yra nepatenkintas svetainės turiniu ir reikalauja jį pakeisti grasindamas teisinėmis priemonėmis. Nesu tikras, bet mano nuomonė visgi ta, jog tokie reikalavimai dažniausiai būna tušti, nebent yra pažeidžiamos autorinės teisės ar panašiai. Nuomonės skleidimas juk neturėtų būti cenzūruojamas.

Vėliau persikėlėme į Mano klubą, kur žaidėme Jenga, ragavau sambuko, ir galų gale išsiskirstėm namo. Vienas keisčiausių nutikimų — visos sąskaitos buvo sumokėtos, pinigų joms nepritrūko, kaip tik atvirkščiai, jų buvo per daug.

Nuotraukas įdėsiu šiek tiek vėliau. Apie susitikimą dar rašo ir scooox.

Kokia jūsų didžiausia programavimo klaida?

Andy Lester, vienas iš pasaulinio lygio Perl programuotojų užduoda klausimą „kokia buvo tavo didžiausia su programavimu ar sistemų administravimu susijusi klaida?“ ir svarbiausia, ko ji tavęs išmokė? Nors jau pats nebeužsiimu programavimais ir administravimais, bet vis dar pamenu vieną pamoką, kurią išmokau kažką ne taip pakeitęs serverio konfigūracijoje: po to teko praleisti vos ne pusę nakties atstatinėjant duomenis ir taisant klaidą. Dabar prieš lendant prie serverio ar tvarkant kokį nors seniai matytą kodą visada užduodu sau klausimą, kas bus, jeigu mano pertvarkymai ką nors sugadins – ar turiu atsargines duomenų kopijas, ar sugebėsiu jas greitai ir efektyviai atstatyti ir ar iš viso esu įsitikinęs, jog žinau ką darau. Kartais šias pamokas galima pritaikyti ir ne vien programavime, bet ir kitose gyvenimo srityse :)

Čekai vs. slovakai

Vakar buvo užvažiavę mūsų partneriai ir kolegos iš Čekijos, su kuriais po pokalbių darbe apie Čekijos akcijas ir makroekonominę situaciją praleidome ir vakarą vienoje Vilniaus užeigoje. Pokalbis dažnai sukosi apie įmones, apie verslą, apie visa tai, kas iš esmės mus ir sieja. Bekalbant su jais prisiminiau, jog esu susidaręs tokią nuomonę, jog Slovakija yra itin agrarinė, neišsivysčiusi, o žmonės ten labiau išlaikę tradicijas, labiau „kaimietiški“ ir „nuo dūšios“ nei Čekijoje. Nežinau, ar tai tik Kunderos knygų sudarytas įspūdis, tačiau kiek teko bendrauti su slovakais, šis mano požiūris lyg ir pasitvirtina (štai Bratislavos birža likvidumu tikrai nepasižymi). Kolegos čekai irgi patvirtino šį slovakų stereotipą: jų nuomone čekai yra vakarietiškesni, labiau kapitalistinio mąstymo, galvojantys apie pinigus. Tuo tarpu slovakai yra ramesni, kaimiškesni, bet žymiai šiltesni ir nuoširdesni. Čekų nuomone, slovakai labai paprasti ir nesididžiuojantys. Taigi, mano slovakų stereotipas tapo dar stipresnis.

Perliška vartotojų sistema

Skaičiausi čia neseniai apie Perlo modulį Class::DBI ir šiandieną sumaniau jį šiek tiek išbandyti. Šis modulis yra duomenų bazės objektinė abstrakcija, ir viską daro tokiame aukštame lygyje (t.y. taip toli nuo pačios duomenų bazės), kad norint ja naudotis net nereikia mokėti SQL (OK, OK, SQL visada pravartu mokėti, bet labai paprastiems dalykams gali to ir neprireikti). Taigi išbandymui sugalvojau pasirašyti vartotojų prisijungimo sistemą.

Class::DBI priverčia viską apgalvoti ir išdėlioti objektiškai, į atskirus modulius, tad atsiranda krūvos mažų failiukų, kuriuos reikia dėti kažkur į atskirą lib direktoriją. Bet pirma pradėkim nuo SQL lentelės:

CREATE TABLE `vartotojai` (
  `vartotojoid` int(11) NOT NULL auto_increment,
  `login` varchar(40) NOT NULL default '',
  `pass` varchar(32) NOT NULL default '',
  `status` int(11) NOT NULL default '0',
  `vartotojaskada` timestamp(14) NOT NULL,
   PRIMARY KEY  (`vartotojoid`),
   UNIQUE KEY `login` (`login`)
) TYPE=MyISAM PACK_KEYS=0 AUTO_INCREMENT=1;

Tiesa, login yra unikalus, tad realiai užtektų tik jį padaryt pirminiu raktu, bet man kažkodėl patinka turėti ir skaitinį vartotojo ID. Nevisai dar sugalvojau kodėl.

Pradedam apsirašinėti duomenų bazę. Byloje lib/Bilekas/DBI.pm saugom duomenų bazės prisijungimo duomenis:

package Bilekas::DBI;
use base 'Class::DBI';
Bilekas::DBI->set_db('Main', 'dbi:mysql:bilekas', "root", "");
1;

Apsirašome klasę Bilekas::Vartotojas ir išsaugom byloje lib/Bilekas/Vartotojas.pm:

package Bilekas::Vartotojas;
use base 'Bilekas::DBI';
Bilekas::Vartotojas->table('vartotojai');
Bilekas::Vartotojas->columns(All => qw/vartotojoid login pass status vartotojaskada/);
1;

Bilekas::Vartotojas modulyje užtenka tik nurodyti kurią SQL lentelę naudoti, bei kokie yra tos lentelės stulpeliai (jeigu būtų ir daugiau lentelių tai reikėtų nurodyti ir ryšius tarp jų)

Galvojant apie ateitį, reikėtų pasirašyti ir vieną pagrindinį modulį Bilekas.pm, kuris būtų atsakingas už bendrą visai svetainei kodą (reikiamų modulių užkrovimą, CGI objekto sukūrimą, sesijas ir pan). Štai ir Bilekas.pm:

package Bilekas;
use strict;
use CGI;
use CGI::Session;

BEGIN {
        use Exporter ();
	our (@ISA, @EXPORT);
        @ISA = qw/Exporter/;
        @EXPORT = qw/$q $s/;
}

our $q = new CGI;
our $s = new CGI::Session("driver:File", $q, {Directory => '/tmp'});

END {
	$s->close;
}
1;

Šiame pakete yra šiek tiek magijos, kurią vertėtų paaiškinti. Pačioje pradžioje yra užkraunami moduliai CGI ir CGI::Session. Toliau eina BEGIN blokas, kuriuo iš paketo Bilekas vardų srities (namespace) eksportuojami kintamieji $q ir $s – tai leidžia vėliau bet kurioje byloje parašius use Bilekas; iš karto naudotis jau sukurtais ir užpildytais kintamaisiais $q ir $s (viename iš jų yra CGI objektas, o kitame – sesijos objektas).

Kitomis dvi eilutėmis yra sukuriami minėtieji eksportuojami kintamieji, o po to seka END blokas, kuri yra vykdomas paskutiniu programos gyvavimo metu. Jo pareiga yra teisingai įrašyti visus sesijos duomenis į bylą, kad jie neliktų laikinojoje atmintinėje (tą daro $s->close;)

Kadangi turime šitus modulius, galima pradėti jais naudotis. Pirma parašome index.pl, kuris nesant užsiregistravusio vartotojo rodys formą, kurios pagalba galima prisijungti prie sistemos:

#!/usr/bin/perl -w
use strict;
use lib './lib';

# Mūsų parašytieji moduliai
use Bilekas;
use Bilekas::Vartotojas;

# Siunčiame HTTP antraštes (su sausainiuku su sesijos informacija)
print $s->header;

# Jeigu yra nustatytas sesijos kintamasis, pranešantis apie klaidą, tai ją išspausdiname
if($s->param("bilekas_error")) {
        print "<h1>!!! " . $s->param("bilekas_error") . " !!!</h1>";
	# Išspausdinę klaidos pranešimą ištriname šį sesijos kintamąjį, kad
	# nespausdintume klaidos keletą kartų
        $s->clear(['bilekas_error']);
}

# Jeigu yra nustatytas sesijos kintamasis 'user', reiškia vartotojas prisijungęs
if($s->param('user')) {
        print "Esi isilogines kaip UID <em>", $s->param('user')->{vartotojoid}, "</em>";
} else {
	# Vartotojas neprisijungęs, rodome prisijungimo formą
        print <<EOHTML;
        <form action="login.pl" method="post">
        <input type="text" name="user"><br>
        <input type="password" name="pass"><br>
        <input type="submit">
        </form>
EOHTML
}

Beliko parašyti patį prisijungimo kodą login.pl:

#!/usr/bin/perl -w
use strict;
use lib './lib';

use Bilekas;
use Bilekas::Vartotojas;
use Digest::MD5 qw/md5_hex/;

my $location = $q->referer || 'index.pl';

if ($q->param('user') && $q->param('pass')) {
        my $user = Bilekas::Vartotojas->retrieve(login => $q->param('user'),
                                                 pass  => md5_hex($q->param('pass')));
	if ($user) {
		$s->param('user', $user);
		$s->expire(user => "+15m");
	} else {
		$s->param('bilekas_error', "Blogas login/pass");
        }
}

print $s->header(-location => $location);

Sitepoint apie PHP::Strings

Harry Fuecks, PHPPatterns kūrėjas ir sitepoint PHP weblogo savininkas, pastebėjo minėtame webloge mano dabar palaikomą Perlo modulį PHP::Strings. Harry klaidingai mano, jog perlininkai priešiškai nusiteikę prieš PHP dėl to, kad pavydi jam sėkmės. Kiek teko bendrauti su viso pasaulio perlininkais, tai požiūris į PHP visada būdavo neigiamas ne dėl pavydo, o dėl to, kad PHP nelaikoma rimta kalba (dėl tokio įsitikinimo teisingumo, aišku, galima ginčytis, bet enterprise lygyje PHP vis dar neturi tokių stiprių pozicijų kaip Perl, Java ir panašiai). Na, tikiuosi neužvirs šventasis karas dėl mano palaikomo modulio. Juolab, kad stengsiuosi jį padaryti naudingesniu PHP programuotojams.

Santrumpų automatizavimas

Atsibodo kiekvieną kartą darant įrašą visoms santrumpoms <abbr> žymas dėlioti rankomis. Tad pasirašiau
Perlinį skriptuką, kuris visą tai atlikea automatiškai. Visą skriptą rašiau troleibuse važiuodamas namo ant Psiono
– vat dėl Perlo jį galima mylėti ;-)

Šitam automatizavimui išrinkau visas santrumpas, kurios buvo naudotos mano dienoraštyje. Visos jos čia – gal kam
pravers.

API	Application Programmer's Interface
ASCII	American Standard Code for Information Interchange
CGI	Common Gateway Interface
CMS	Content Management System
CPAN	Comprehensive Perl Archive Network
CSS	Cascading Style Sheets
CVS	Concurrent Version System
DDOS	Distributed Denial of Service
DOS	Denial of Service
DRM	Digital Rights Management
DTD	Document Type Definition
FOAF	Friend Of A Friend
GPL	GNU Public Licence
GPS	Global Positioning System
HTML	HyperText Markup Language
IP	Internet Protocol
IRC	Internet Relay Chat
JAPH	Just Another Perl Hacker
LCD	Liquid Crystal Display
LWP	Lib-Www Perl
MIT	Massachusetts Institute of Technology
MMS	Multimedia Messaging Service
PEAR	PHP Extension and Application Repository
PECL	PHP Extension Community Library
PHP	PHP: Hypertext Preprocessor
PMC	Perl Magic Cookie
POP3	Post Office Protocol version 3
PPM	Perl Package Manager
RC	Release Candidate
RDF	Resource Description Framework
RSS	Really Simple Syndication
SMTP	Simple Mail Transfer Protocol
SQL	Sequential Query Language
TCO	Total Cost of Ownership
TVS	Turinio Valdymo Sistema
URL	Universal Resource Location
W3C	World Wide Web Consortium
WAP	Wireless Application Protocol
WML	Wireless Markup Language
XFN	XHTML Friends Network
XHTML	eXtensible HyperText Markup Language
XML	eXtensible Markup Language
XSS	Cross Site Scripting
ssh	Secure SHell
yacc	yet another compiler compiler