Koronaprojekti: Osterivinokkaiden kasvatus

Tämä korona-aika on tuonut uusia tapoja hoitaa etätyöt. Minulla satunnaiset etätyöt ovat aina sujuneet, mutta nyt, kun olen koko ajan kotona, huomaan kaipaavani monipuolista työpaikkalounasta ja meinaa vähän harmittaa, kun kodin arkiruokailu on helposti vähän yksipuolista.

Tämä aika mahdollistaa tietynlaisen back-to-basics-ajattelun, joka tukee kokonaishyvinvointia: mitä, jos opettelisi tekemään laadukkaita ruokia ja saisi sitä kautta vähän hohtoa tähän arkeen? Googlesta löytyy hyvin simppelit ruokaohjeet lähes kaikkeen, mitä tulee mieleen. Monet ruuat tulevat pienellä vaivalla ja joitakin niistä voi tehdä kerralla monen päivän tarpeiksi.

Innokkaimmat voivat kok(k)eilla vähän jännienkin asioiden kanssa. Kaveri vinkkasi minulle osterivinokkaiden kasvattamisen. Tänään teimme niistä pienellä vaivalla herkullisen sienirisoton perheen lounaaksi. Ensimmäisen sienierän kasvattamiseen meni pari kuukautta, mutta olipa mukavasti merkitystä tuottava pikku projekti. Uusin innostus on hapanjuuren teko…ensi viikolla teen ehkä ensimmäiset hapanjuurileivät.

Työkin sujuu, kun tämä korona-aika ei tunnu pelkältä kärsimykseltä.

Niin, ne osterivinokkaat. Hankin aloituspaketin helsieni.fi kautta, ja kasvatin ne heidän ohjeillaan. Lisäksi sain vinkkejä http://sieniapaja.fi/ – sivuston ylläpitäjältä. Tässä on vähän kuvia kasvatusprojektista, joka kesti pari kuukautta:

Aloitusrihmasto lähti kasvamaan kahvisakassa. Lisää sakkaa vain päälle ja odotetaan sen valkenevan tällä lailla…
…kunnas ämpäri on täynnä rihmastoa. Sen jälkeen odotellaan ensimmäisten sienten pompsahtamista.
Tältä näyttää, kun ensimmäinen ”lähetys” tulee esiin. Mustat pisteet ovat kahvisakkaa, ei vaarallista 🙂
Tässä 3 päivää vanha sieni.
Korjasin 300 gramman sadon viidentenä päivänä. Sato korjattiin mahdollisesti päivän parasta-ennen-päivän jälkeen, kun odotin lakkien aukeavan, mutta nämä eivät auenneet, vaikka odotin. Erinomaista ruokasientä siitä tuli silti. Ensi kerralla olen tarkempi satopäivän kanssa.

Nörttiprojekti: Nettisivujen rankkausta iän mukaan

Töissä tuli kerran tarve järjestää lista nettisivuja sivuston teknologian vanhuuden mukaiseen järjestykseen. Koska emme löytäneet valmista palvelua/ohjelmaa, joka tämän tekisi, otin tästä itselleni pienen pähkinän purtavaksi. Tuli nimittäin tunne, ettei tuollaiseen kovin monta tuntia mene, sillä tiesin, ettei järjestelmän tarvitse olla täydellinen. Noin viiden tunnin päästä pystyin tuottamaan nettisivulistan yllättävänkin uskottavasti ikäjärjestyksessä.

Voisin näyttää, miten sen tein, jos joku innostuisi kehittämään tätä ideaa pidemmälle. Otan mielelläni vastaan kehitysehdotuksia! 🙂

Näin aloitin

Sain ajatuksen, että sivustoja voisi rankata niiden html-koodissa löytyvien tekstipätkien ja html-tägien mukaan. Web-teknologia on 1990-luvun alkuvuosien jälkeen kehittynyt kovasti, ja olen itse työskennellyt sen parissa alusta asti. Siksi ajattelin, että minulla voisi olla jonkinlainen mutu-pohjainen käsitys siitä, millä vuosikymmenellä löytyi mitäkin html-tägejä jne.

Jatkoajatuksena tuli, että tägejä voisi pisteyttää plus- ja miinuspisteillä tägien ”moderniuden” mukaan: miinuspisteitä tulee vanhoista tägeistä ja pluspisteitä uudemmista. Tein hakuammunnalla tällaisen listan tägeistä ja koitin muutaman testisivun perusteella arvioida niiden pisteytyksiä:

Rankdata.xlsx

Nyt tarvitaan vielä ohjelma, joka lukee listan nettiosoitteista ja tuon Rankdata.xlsx:n. Nettiosoitelista (tässä Yritykset.xlsx) sisältää kolme saraketta:

Y-tunnusYritys WWW-osoite
1234567-8Yritys Oyhttp://www.yritys.fi

Koska työympäristöni oli tuota tehdessä Windows ja halusin päästä nopeasti liikkelle, päätin käyttää koodauskielenä minulle hyvin tuttua Perliä. (En vielä tuolloin ollut opetellut Pythonia, joka olisi nykyisin valintani tällaiseen). Latasin läppärilleni ActivePerlin ja aloin koodata. Muistin, että 2000-luvun alussa Professional Tester-lehteen kirjoittamassani artikkelissa, on valmiita pätkiä copy-pastettavaksi, joten hyödynsin tietenkin sitä. (Kai tiesit, että kaikki koodaajat copy-pastettavat ratkaisuja, tyypillisesti googlettamalla? 🙂 )

Jouduin asentelemaan Perliin lisämoduleja, jotta sain sen kutsumaan nettisivuja. En enää muista, oliko ActivePerlissä oma lisäosien lataamisohjelma, vai hainko niitä CPANista.

Ohjelmastani ei tullut mitenkään kovin kaunis, mutta sain sen kyllä toimimaan. Tässä on koko koodi:

use LWP::UserAgent;
use Spreadsheet::ParseXLSX;
use Spreadsheet::WriteExcel;

my $parser = Spreadsheet::ParseXLSX->new;

#
# Read the input data  from rankdata.xlsx into the @data hash
#
my @data;
my $excel = $parser->parse("rankdata.xlsx");
foreach my $sheet (@{$excel -> {Worksheet}}) {
 	$sheet -> {MaxRow} ||= $sheet -> {MinRow};     
	foreach my $row (1 .. $sheet -> {MaxRow}) {
         
		$sheet -> {MaxCol} ||= $sheet -> {MinCol};         
		$data[$row]{"tag"} = lc($sheet -> {Cells}[$row][0]->{Val});
		$data[$row]{"points"} = $sheet -> {Cells}[$row][1]->{Val};
	}
}

#
# Read the company info to the @companies hash
#
my @companies;
$excel = $parser->parse("Yritykset.xlsx");
foreach my $sheet (@{$excel -> {Worksheet}}) {
 
 	$sheet -> {MaxRow} ||= $sheet -> {MinRow};
        
	foreach my $row (1 .. $sheet -> {MaxRow}) {
         
	        $sheet -> {MaxCol} ||= $sheet -> {MinCol};
        
                $companies[$row]{"businessid"} = $sheet -> {Cells}[$row][0]->{Val};
                $companies[$row]{"company"} = $sheet -> {Cells}[$row][1]->{Val}; 
		$companies[$row]{"url"} = $sheet -> {Cells}[$row][2]->{Val};
		$companies[$row]{"points"} = 0;
		
	} 
}

# Open excel file for writing and write headers
my $workbook = Spreadsheet::WriteExcel->new('Output.xls');
$worksheet = $workbook->add_worksheet();
$format = $workbook->add_format();
$format->set_bold();

$worksheet->write(0,0, "Business ID",$format);
$worksheet->write(0,1, "Company",$format);
$worksheet->write(0,2, "URL",$format);
$worksheet->write(0,3, "Points",$format);
$worksheet->write(0,4, "Size",$format);
$worksheet->write(0,5, "Other",$format);
$worksheet->write(0,6, "Tags",$format);
#
# Loop all companies, call URLs, determine points, write result to Output.xls
#
my $ua = LWP::UserAgent->new;
for my $c (1 .. $#companies) {  
 	print "Analyzing ".$companies[$c]{"url"}."...";
	my $req = HTTP::Request->new(GET => $companies[$c]{"url"});

	my $resp = $ua->request($req);
	if (!$resp->is_success) {
    	$companies[$c]{"error"} = "Error ".$resp->code.". ";
    	if (!$resp->code == 500) {
    		$companies[$c]{"points"} = -100;
    	}
	}
	else {
		$companies[$c]{"error"} = "";
	}

	# Loop the http response
	$companies[$c]{"tags"} = "";
	$page_content = lc($resp->as_string);
	$companies[$c]{"size"} = length($page_content);
	my @lines = split /\n/, $page_content;
	foreach my $line (@lines) {	
		# Check with tag data	
		for my $i (1 .. $#data) {   
			if ( index($line, $data[$i]{"tag"}) > 0 && !$data[$i]{"found"}) {
	    		$companies[$c]{"points"} += $data[$i]{"points"};
	    		$companies[$c]{"tags"} = $companies[$c]{"tags"}.", ".$data[$i]{"tag"};
	    		
	    		print $companies[$c]{"tags"}.";";
	    		$data[$i]{"found"} = 1;
			}
		}
		
	
	}
	print $companies[$c]{"error"};
	
	# Penalize small pages
	if ($companies[$c]{"size"} < 5000) {
		$companies[$c]{"points"} -= 30;
	}
	elsif ($companies[$c]{"size"} < 10000) {
		$companies[$c]{"points"} -= 15;
	}
	
	$worksheet->write($c,0, $companies[$c]{"businessid"});
	$worksheet->write($c,1, $companies[$c]{"company"});
	$worksheet->write($c,2, $companies[$c]{"url"});
	$worksheet->write($c,3, $companies[$c]{"points"});
	$worksheet->write($c,4, $companies[$c]{"size"});
	$worksheet->write($c,5, $companies[$c]{"error"});
	$worksheet->write($c,6, $companies[$c]{"tags"});
	print $companies[$c]{"points"}." points. ";
	print "Done.\n $c.";
	
	# Reset "tag found" status for the next page in loop
	for my $i (1 .. $#data) {
		$data[$i]{"found"} = 0;
	}
}
print "Analyze completed.";

Ylläoleva ohjelma tuotti noin 20 minuutissa (kävi siisläpi 1700 nettiosoitetta) Excel-tiedoston, jossa nettisivut olivat saaneet rankkauksia sen mukaan, mitä sivulta löytyi (yritystiedot poistettu ennen kuvakaappauksen ottamista…ymmärrätte varmaan).

Ei mitenkään kaunista, mutta siivoilin listan käsin ja järjestelin sen Points-sarakkeen mukaana ja muutama pistokoe todisti, että olin onnistunut hankkeessani melko hyvin.

Mitä opin?

  • Perl on vanha ohjelmointikieli ja teknologia, opin sen 1990-luvulla. Oli esim. vaikea saada SSL-modulia toimimaan; sitä tarvittiin https-suojattujen sivujen tutkimiseen. Myöhemmin tajusin, että esim. modernilla Pythonilla tuo ohjelma olisi ollut kaikin puolin kätevämpi tehdä, sillä se kommunikoi sujuvammin nykyrajapintojen kanssa.
  • Kaikki sivustot eivät päästäneet skriptiä läpi, sillä ne tunnistivat sen todennäköisesti ”robotiksi” User Agent-tiedon perusteella. Myöhemmin testasin User Agentin feikkaamista (sai nettisivut luulemaan systeemiäni Chrome-selaimeksi) ihan hyvällä menestyksellä. Tässä Perl-koodinpätkä siihen:
    $ua->agent(”Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36”);

Vielä yksi asia!

Varomaton nettisivujen tutkiminen tällaisella ”robotilla” voidaan hyvällä syyllä pitää vähän kyseenalaisena puuhana. Kannattaa olla tarkkana, ettei vahingossa kehitä vaikkapa silmukkaa, joka pommittaa jotain tiettyä nettisivua kutsuilla. Sellaista voisi kutsua jonkinlaiseksi alkeelliseksi palvelunestohyökkäykseksi. Nykyiset nettisivut eivät tällaisesta yleensä kyykähdä, mutta onhan vastuuton robottien käyttö kiusantekoa ja sotkee ainakin ”pommituskohteiden” nettisivu-kävijätilastoja.

Automaatinen antenninvaihtaja

Minulla on muutama radioamatööriantenni, yksi talon katolla ja loput metsässä. Antennit on tarkoitettu eri taajuusalueille. Aiemmin olen vaihtanut antenneja käsin, mutta monen paksun antenninjohdon tuominen sisään on muutoin ollut vähän hankala ratkaisu, sisustuskin siinä kärsii, kun joudun tuomaan monta paksua johtoa pitkän matkaa sisätiloissa.

Kasvoi ajatus järjestää niin,  ettei kaikkia johtoja tarvitsi tuoda sisään. Sellainen vaatisi antenninvaihtajan ulos. Automaattinen antennin vaihtaminen alkoi kiinnostaa myös siksi, että se olisi kätevää ja huoletonta, etenkin radiokilpailuissa.

Tänä syksynä aloin tuumasta toimeen: tilasin kamat järjestelmään, jonka sain tähän vaiheeseen tänään:

Tuli vähän juotoshommia ja Arduino-ohjelman säätämistä. Hommaan meni kokonaisuudessaan muutama tunti ja nyt alkaa olla aika valmista. remoteqth.comista löytyi ohjeet ja he selvittivät epäselvyyksiä ystävällisesti sähköpostitsekin.

Tuo harmaa laatikko on tarkoitus siirtää ulkotiloihin, ja metsästä tulevat antennijohdot kytketään siihen. Laatikosta tulee vain kaksi johtoa radioasemalle: ohjauspiuha ja antennijohto. Ohjauspiuha (n.20m) on tehty verkkojohdosta. Todennäköisesti en ollut ensimmäinen, joka keksin sen?

EDIT: Tältä vaihtaja näyttää asennettuna: