Perl - cvičení 9

  1. Máte soubor data.txt, který má následující strukturu. Na každém řádku jsou tři hodnoty oddělené dvojtečkou. První hodnota je příjmení osoby, druhá hodnota udává typ třetí hodnoty. Přípustné jsou pouze typy 'JMENO', 'BYDLISTE' a 'PLAT'. Každá osoba může mít v souboru pouze jedno jméno a bydliště, ale plat tam může být zadán vícekrát (např. za každý měsíc).

    Úkoly:

    Novak:JMENO:Josef
    Novak:PLAT:100
    Novak:PLAT:20
    Novak:BYDLISTE:Brno
    Novak:PLAT:130
    Dvorak:PLAT:100
    Novak:PLAT:125
    Dvorak:BYDLISTE:Praha
    Dvorak:PLAT:30
    Novak:PLAT:150
    Dvorak:PLAT:80
    

    Příklad komunikace s programem:

    [darena@civinek perl]$ perl data.pl
    Zadejte akci: aaa
    Zadali jste neplatny retezec
    Zadejte akci:jmeno
    Nemate vybranou osobu. Zadejte akci: zvol novak
    Zadejte akci (zvoleno NOVAK):plat
    100, 20, 130, 125, 150
    Zadejte akci (zvoleno NOVAK):jmeno
    Josef
    Zadejte akci (zvoleno NOVAK):qwe
    Zadali jste neplatny retezec
    Zadejte akci (zvoleno NOVAK):zvol dvorak
    Zadejte akci (zvoleno DVORAK):pla
    Zadali jste neplatny retezec
    Zadejte akci (zvoleno DVORAK):plat
    100, 30, 80
    Zadejte akci (zvoleno DVORAK):zvol
    Nezadano prijmeni
    Zadejte akci (zvoleno DVORAK):konec
    [darena@civinek perl]$
    

    Příklad řešení (navíc pro příkaz JMENA vypíše všechna přípustná jména:

    open F, "data.txt";
    
    while (<F>) {
            chomp;
            ($prijmeni, $typ, $hodnota) = split ':';
    
            if (uc $typ eq 'PLAT') {
                    push @{$osoby{uc $prijmeni}->{PLAT}}, $hodnota;
            } else {
                     $osoby{uc $prijmeni}->{uc $typ} = $hodnota;
            }
    }
    
    # kontrolni vypis struktury
    use Data::Dumper;
    print Dumper \%osoby;
    
    # zatim nevime, s kterou osobou pracujeme
    $prijmeni = '';
    
    print "Zadejte akci: ";
    while (1) {
            $_ = <>;
            chomp;
    
            # prevedeme si zadany retezec na velka pismena
            $_ = uc;
    
            # zadano konec, ukoncime cyklus
            last if $_ eq 'KONEC';
    
            # ted muze byt zadano bud JMENO, BYDLISTE, PLAT nebo ZVOL
            unless ($_ eq 'JMENA' or $_ eq 'JMENO' or $_ eq 'BYDLISTE' or $_ eq 'PLAT' or /^ZVOL\s+/) {
                    print "Zadali jste neplatny retezec\n";
            } else {
                    # kdyz chceme vybrat novou osobu
                    if (/ZVOL\s+(.*)/) {
                            if ($1) {
                                    unless (exists $osoby{$1}) {
                                            print "takove prijmeni neexistuje\n";
                                    } else {
                                            $prijmeni = $1;
                                    }
                            } else {
                                    print "Nezadano prijmeni\n";
                            }
                    } elsif ($_ ne 'JMENA') {
                            # provadime nejakou akci, musime mit vybranou osobu
                            unless ($prijmeni) {
                                    print "Nemate vybranou osobu. Zadejte akci:";
                                    next;
                            }
    
                            if ($_ eq 'PLAT') {
                                    # zobrazime platy
                                    print join (', ', @{$osoby{$prijmeni}->{PLAT}}), "\n";
                            } else {
                                    print $osoby{$prijmeni}->{$_}, "\n";
                            }
                    } else {
                            print "Pripustna jmena: ", join(', ', keys %osoby), "\n";
                    }
            }
            print "Zadejte akci", ($prijmeni?" (zvoleno $prijmeni):":":");
    }