LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (69) - Projekt - online přenos

Perl Dnes dokončíme projekt, jehož obsahem bylo vytvořit uživatelsky přívětivou čtečku sportovních výsledků pro příkazový řádek.

6.6.2008 07:00 | Jiří Václavík | Články autora | přečteno 10084×

Dnes máme za úkol dokončit práce na projektu. Chybí nám napsat poslední věc a tou je online přenos.

Online přenos

Načrtněme si opět předběžný postup.

  • Abychom mohli spustit online přenos, musíme nejprve vybrat právě jeden zápas. Až pokud se to úspěšně podaří, můžeme pokračovat dále.
  • Vybraný zapas vytiskneme pomocí funkce tiskni_vyhovujici.
  • Na základě ligy a čísla zápasu určíme zápas.
  • Nyní budeme periodicky volat metodu prenos a na jejím základě aktualizovat zobrazená data.
  • Na závěr zobrazíme konečný výsledek

Pojďme se do toho pustit. Bude třeba napsat tuto podmínku, kterou jsme nechali minule neimplementovanou.

if($online){
    #implementace online přenosu
}

Předně musíme ze všech zápasů vybrat pouze jediný. K tomu si napíšeme zvlášť podprogram.

    @vyhovujici = vyber_zapas(@vyhovujici);

To je v podstatě opakované volání metody najdi_zapas_podle_kriterii, která na základě kritérií postupně zužuje výběr. Jakmile klesne na jediný zápas, můžeme výběr ukončit a postupovat dále.

sub vyber_zapas {
    my @vyhovujici = @_;
    while(scalar @vyhovujici > 1){
        print "Byly nalezeny zapasy (".scalar @vyhovujici."):\n";
        tiskni_vyhovujici(@vyhovujici);
        print "Musite zadat zpresnujici kriterium: ";
        my $kriteria;
        chomp($kriteria = <STDIN>);
        my @kriteria = split(" ", $kriteria);
        @vsechna_kriteria = (@vsechna_kriteria, @kriteria);
        @vyhovujici = $live->najdi_zapas_podle_kriterii(\@vyhovujici, \@kriteria);
    }
    return @vyhovujici;
}

Je ovšem možné, že doplňující kritérium vyloučí všechny zápasy. V takovém případě musíme program ukončit, protože nemáme jak pokračovat. Jinou možností by bylo nebrat poslední kritérium v úvahu.

   die "Zadny vyhovujici zapas\n" if scalar @vyhovujici == 0;

Nyní zjistíme ligu a číslo zápasu, které je třeba předat metodě prenos. Ale je třeba si dát pozor na tuto věc: Číslo zápasu a liga (parametry odkaz_idzapasu a odkaz_liga v hashi s informacemi o zápase) nemusí být vůbec dostupné - resp. nejsou dostupné, pokud zatím v zápase nedošlo ke sledované události. Nastává zde tedy problém. Jak můžeme získat data, když nevíme odkud? Tuto otázku nemá smysl řešit - tato data nezískáme, protože neexistují.

Vyřešíme to trochu jinak a to tak, že si počkáme, až budou dostupná. To znamená průběžně kontrolovat, zda nenastala událost a neobjevil se nám odkaz na seznam událostí. Jakmile událost nastane, získáme odkaz a budeme ji moci zobrazit. Bude to sice o něco náročnější na programování, ale v zásadě tím nic neztrácíme.

Periodicky tak budeme stahovat informace o zápasech. Vždy v nich najdeme ten náš zápas, který sledujeme. Ten nyní může být ve čtyřech stavech.

  • hraje se a nejsou dostupné detailní informace (nedošlo k události)
  • hraje se a už jsou dostupné detailní informace (došlo k události)
  • zápas byl ukončen
  • zápas je před výkopem

Je-li zápas před výkopem, budeme v intervalech zjišťovat, zda to stále platí, dokud se nezačne hrát. Když se začne hrát, nejsou zpravidla dostupné žádné události. Proto budeme v intervalech tisknout pouze probíhající minutu. Jakmile ale dojde k události, vyskočíme z cyklu, protože v tomto okamžiku budeme schopni stáhnout podrobnosti k zápasu - již známe odkaz (prvky odkaz_idzapasu a odkaz_liga). Pokud zápas skončil, ukončíme cyklus také. Pokud tyto požadavky zahrneme do další části programu, získáme toto.

Nejprve tedy zkusíme, zda již jsou detaily dostupné.

    my $vyhovujici_liga = $vyhovujici[0]{"odkaz_liga"};
    my $vyhovujici_idzapasu = $vyhovujici[0]{"odkaz_idzapasu"};
    my $probihajici_minuta;

Pokud ne, budeme si na ně muset počkat. Periodicky budeme kontrolovat, zda již jsou dostupné.

    while(!$vyhovujici_idzapasu){
        @vyhovujici = $live->ziskej_zapasy_dane_ligy();
        @vyhovujici = $live->najdi_zapas_podle_kriterii(\@vyhovujici, \@vsechna_kriteria);

        $probihajici_minuta = $vyhovujici[0]{"minuta"}, "\n";
        last if($vyhovujici[0]{"hraje_se"} == Livescore::UKONCEN);
        if($vyhovujici[0]{"odkaz_idzapasu"}){
            $vyhovujici_idzapasu = $vyhovujici[0]{"odkaz_idzapasu"};
            $vyhovujici_liga = $vyhovujici[0]{"liga"};
        }

        if($vyhovujici[0]{"hraje_se"} == Livescore::PROBIHA){
            print "Probiha $probihajici_minuta'          \r";
        }elsif($vyhovujici[0]{"hraje_se"} == Livescore::PRED_VYKOPEM){
            print "Zapas zatim nezacal\r";
        }
        sleep $refresh;
    }

K tomu, aby se nám neuchovávala data ve výstupním bufferu zatímco je v činnosti funkce sleep je třeba připsat na začátek skriptu tyto dva řádky. Vyprazdňování bufferu musí být automatické.

use IO::Handle;
STDOUT->autoflush(1);

Pokud skončil předchozí cyklus, znamená to, že buď zápas skončil nebo probíhá a jsou dostupné události. V obou případech vytiskneme dostupné události. Jestliže zápas probíhá, budeme navíc tisknout přibyvší události dokud zápas také neskončí.

    do {
        my @udalosti = $live->prenos($vyhovujici_liga, $vyhovujici_idzapasu);
        $probihajici_minuta = shift @udalosti;
        $hraje_se = shift @udalosti;

        #vytiskneme nové události

        print "Probiha $probihajici_minuta'\r";
        sleep $refresh if $hraje_se == Livescore::PROBIHA;
    }while($hraje_se == Livescore::PROBIHA);

Nyní projdeme všechny události a ty, které jsou nové zobrazíme. ID starých událostí budeme kopírovat do pole @zobrazene_udalosti, abychom měli přehled o tom, co již bylo zobrazeno.

        for (@{$udalosti[0]}){
            next if in_array($_->{"id_udalosti"}, \@zobrazene_udalosti);

            #zobrazíme událost a zapíšeme do @zobrazene_udalosti

        }

Nyní zbývají poslední dva kroky. Zvolíme vhodnou formu zobrazení a opět pomocí funkce colored vytiskneme. Máme 3 druhy události - gól, žlutá karta a červená karta. Na základě prvku udalost můžeme u všech událostí rozhodnout, o který případ jde. Poté aktualizujeme pole @zobrazene_udalosti.

            if ($_->{"udalost"} eq "yellow"){
                print colored(sprintf("%2s'     %-20s (%s)\a\n", $_->{"minuta"},
                    $_->{"hrac"}, $_->{"tym"}), "bold yellow");
            }elsif ($_->{"udalost"} eq "red" or $5 eq "yellow-red"){
                print colored(sprintf("%2s'     %-20s (%s)\a\n", $_->{"minuta"},
                    $_->{"hrac"}, $_->{"tym"}), "bold red");
            }elsif ($_->{"udalost"} eq "goal"){
                print colored(sprintf("%2s' ", $_->{"minuta"}), "bold white");
                print colored(sprintf("%d:%d ", $_->{"skore1"}, $_->{"skore2"}),
                    "bold yellow");
                print colored(sprintf("%-20s (%s)\a\n", $_->{"hrac"}, $_->{"tym"}),
                    "bold white");
            }
            push @zobrazene_udalosti, $_->{"id_udalosti"};
        }

Za cyklus do-while se program dostane pouze v jediném případě - pokud skončil zápas. Tuto informaci tedy vytiskneme a na závěr zopakujeme aktualizovaný výsledek.

    print "Zapas skoncil\n";
    $live->ziskej_zapasy_dane_ligy;
    tiskni_vyhovujici($live->najdi_zapas_podle_kriterii(\@vyhovujici, \@vsechna_kriteria));
    exit;

Závěr

Nyní jsme hotovi. Všechny požadavky ze zadání projektu jsme úspěšně dokončili. Kompletní program si můžete stáhnout (Livescore.pm, live) a vyzkoušet.

live -o -l italy torino live -o li + interaktivní zadání live -o feyenoord

Výsledek zápasu *** Výsledek interaktivně vybraného zápasu *** Aktualizovaný probíhající online přenos

Samozřejmě by nyní tento program mohl být rozšířen o nové funkce. Například souběžné online přenosy více zápasů najednou, lepší členění pomocí přepínače -l a s tím související vylepšení cachování nebo přepis do Curses, Qt či jiného pokročilejšího uživatelského rozhraní.

Nicméně náš původní cíl je nyní splněn a proto tato šestidílná série, jejíž cílem bylo předvést některé techniky probrané v seriálu i z trochu jiného pohledu, dneškem končí.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

8.5.2016 17:19 /Redakce Linuxsoft.cz
PR: Dne 26.5.2016 proběhne v Praze konference Cloud computing v praxi. Tématy bude např. nejnovější trendy v oblasti cloudu a cloudových řešení, cloudové služby, infrastruktura cloudu, efektivní využití cloudu, možné nástrahy cloudů a jak se jim vyhnout
Přidat komentář

21.4.2016 8:01 /František Kučera
Spolek OpenAlt zve na 127. distribuovaný sraz příznivců svobodného softwaru a otevřených technologií (hardware, 3D tisk, SDR, DIY, makers…), který se bude konat ve čtvrtek 28. dubna od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

2.3.2016 22:41 /Ondřej Čečák
Letošní ročník konference InstallFest již tento víkend!
Přidat komentář

14.2.2016 16:39 /Redakce Linuxsoft.cz
O víkendu 5. a 6. března 2016 proběhne na pražském Strahově 8. ročník tradiční konference InstallFest. Celkem za dva dny uvidíte ​30 přednášek​ a ​6 workshopů.
Přidat komentář

5.2.2016 17:38 /Petr Ježek
Utilitka z XFce "xfce4-power-manager" nejen umožňuje nastavení lhůty pro uspání či hybernaci, ale i zapínání a vypínání prezentačního módu pro nerušené sledování videí. Stačí ji nastavit v každém vybavenějším panelu a v jakémkoli nontiled WM/DE.
Přidat komentář

10.1.2016 11:32 /Pavel `Goldenfish' Kysilka
LinuxMarket změnil provozovatele. Nově jej provozuje Marek Pszczolka. Více info a detaily #1 a #2.
Přidat komentář

29.12.2015 11:38 /Ondřej Čečák
Ještě posledních pár dní můžete přidávat příspěvky nebo nápady na Install Fest 2016, který se bude konat 5. a 6. března 2016.
Přidat komentář

8.12.2015 11:36 /Petr Ježek
Logické se stává realitou. LibreOffice a Thunderbird se mají dle článku na Redditu stát protiváhou MS řešení (MS Office a Outlook).
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

10.6.2016 21:10 / pavel riha
FreeBSD 10.3 a virtualizace

8.6.2016 21:56 / Milan Gallas
Nevalidní prefix m

7.5.2016 14:58 / Teodor Komárek
Soubory

20.4.2016 0:07 / Jakub Cleing
Sázkový panel PHP FUSION

9.4.2016 9:43 / jiwopene@gmail.com
Re: problém s dpkg a nemožností instalovat

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2016) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze