#!/usr/bin/perl -w
# Histogram z dowolnej kolumny danych wejsciowych
# [c]piotao, 20011115, @emalia, perl 5+
# zmieniony i przetlumaczony na polski 20070123 dla studentow
# wykladu monograficznego Perl-programowanie
# Sposob uzycia:
# histogram.pl input.txt > results.txt
# Opcje: -r10 -c1 -f10%f10%f\\n
# -r - okresla wielosc zakresow na osi x
# -c - okresla ktora kolumna z pliku ma byc wczytana (0-pierwsza, domyslnie)
# -f - format danych wynikowych wypisywanych na standardowe wyjscie (zawsze 2 kolumny)
#
# Wartosci standardowe: ZAKRES=1000 COLUMN=0 FORMAT=%10.4f%10.4f\n
### KONFIGURACJA ############################################
my $ZAKRES = 1000; # zrob histogram z czynnikiem skalujacym = 1000
my $COLUMN = 0; # wczytaj dane z pierwszej kolumny (ma ona numer 0)
# teraz okreslamy format danych wyjsciowych, sa to dwie kolumny wysylane na standardowe
# wyjscie; pierwsza z nich to wartosc zakresu danych, druga to wartosc
# histogramu dla tego zakresu
my $FORMAT = "%10.4f%10.4f\n"; # format jednego wiersza w stylu C - printf
#############################################################################
use strict; # tryb scislego sprawdzania nazw
use warnings; # tryb ostrzezen
use Getopt::Std; # uzywamy obslugi wiersza polecen: proste argumenty typu -x
my $var2,%hist; # zmienne pomocnicze, w tym %hist do pamietania histogramu
# analiza argumentow wiersza polecen i przedefiniowanie $ZAKRES, $COLUMN lub $FORMAT
&AnalizujOpcje;
# obliczanie wartosci histogramu dla kazdego zakresu danych
# polega to na tym, ze dzielimy wybrana kolumne przez zakres
# w jakim histogram ma byc policzony i wynik zapamietujemy w haszu
# jako wartosc calkowita, ktora bedzie na osi X, zliczajac wszystkie
# takie same wystapienia tych wartosci (dlatego hasz)
# zapamietaj: wynik histogramu jest kluczem, ilosc tych wynikow - wartoscia
while(<>){
$hist{ int( (split)[$COLUMN] / $ZAKRES ) }++;
}
# wypisywanie wynikow to proste wypisanie hasza z sortowaniem kluczy
foreach my $value (sort { $a <=> $b } keys %hist){
printf $FORMAT,$value*$ZAKRES,$hist{$value};
}
exit;
# analiza argumentow z wiersza polecen programu
sub AnalizujOpcje {
# na poczatek ustawiamy format, o ile go podano, w tym celu:
for(my $i = 0; $i <= $#ARGV; $i++){ # zasuwamy po wszystkich argumentach
if($ARGV[$i] =~ /^-f(.+)/){ # jezeli opcja to -f...
$FORMAT = $1; splice @ARGV,$i,1; last; # to wyciagamy to '...' jako format
}
}
getopt('rcf'); # wyciagamy opcje -r, -c i -f (one znikaja)
if(defined $opt_r){ $ZAKRES = $opt_r } # ale trafiaja do zmiennych $opt_X skad je
if(defined $opt_c){ $COLUMN = $opt_c } # przepisujemy do wlasciwych zmiennych
$FORMAT =~ s/\\n/\n/g; # ostatnia poprawka w FORMAT
}