Ruby po kapkách (24.) – webový teploměr
Naprostá většina informací na internetu je dostupná pomocí protokolu HTTP. Ukážeme si, jak jednoduché je načíst v Ruby obsah webové stránky a aby toho nebylo málo zkusíme si první aplikaci s grafickým uživatelským rozhraním (GUI).
Minule jsme používali část standardní knihovny skrývající se pod cestou net/ftp. Tentokrát potřebujeme net/http. Knihovna obsahuje poměrně dost tříd, které podporují rozmanité vlastnosti protokolu HTTP. Pro naše účely však zcela postačí třída Net::HTTP
. Ta definuje metodu get
, která provede požadavek GET podle HTTP protokolu a výsledek vrátí jako řetězec. Pro začátek nebudeme načítat a zpracovávat žádný složitý obsah. Pro naše experimenty využijeme Strahovský teploměr, který již dlouhá léta na adrese http://teplomer.sh.cvut.cz/servlet/teplota poskytuje aktuální údaj z teploměru ve formě prostého textového řetězce. Ale dost povídání, podívejme se, jak to vypadá v kódu.
irb(main):001:0> require ‚net/http‘
=> true
irb(main):002:0> res = Net::HTTP.get(‚teplomer.sh.cvut.cz‘, ‚/servlet/teplota‘)
=> „20.3“
irb(main):003:0> res.to_f
=> 20.3
irb(main):004:0> Net::HTTP.get(‚www.interval.cz‘, ‚/‘).size
=> 84
Jak je vidět, obdržený řetězec snadno převedeme na reálné číslo pro případné další zpracování. Metodou get
lze samozřejmě načítat i obsah v HTML. Celý formát volání je get(uri_or_host, path = nil, port = nil)
. Cesta je nepovinná, stejně tak poslední parametr port, který je defaultně obvyklých 80. První parametr je buď název cílového počítače nebo objekt třídy URI
. Pokud bychom dostávali na vstupu URL, více by se nám hodilo volání v následující podobě.
irb(main):007:0> Net::HTTP.get(URI.parse(‚http://teplomer.sh.cvut.cz/servlet/teplota‘))
=> „20.1“
Jako u každé metody pracující se vstupem a výstupem může i v případě get
vznikat spousta různých výjimek, které je v reálném životě třeba ošetřovat. Zkusme vytvořit kostru programu s jednoduchou metodou, která zajistí bezpečné načtení teploty. V případě vzniku chyby vrátí zvláštní hodnotu, která bude chybu indikovat. Protože teplotu budeme chtít zobrazovat, zajistíme si rovnou rozumné formátování výstupu.
require ‚net/http‘
def read_temperature
Net::HTTP.get(‚teplomer.sh.cvut.cz‘, ‚/servlet/teplota‘).rjust(5)
rescue
‚ xx.x‘
end
puts read_temperature
Na výpisu vidíme definici metody a zatím neznámé použití klauzule rescue
. V rámci definice metody nám Ruby umožňuje vynechat začátek bloku pro ošetření výjimek v podobě klíčového slova begin
. Respektive místo něho je začátkem bloku začátek metody. To nám v kombinaci s faktem, že návratovou hodnotou metody je hodnota posledního vyhodnoceného výrazu, umožňuje elegantně popsat zpracování v případě s chybou i bez chyby jen na několika řádcích. Řetězcová metoda rjust
zarovná vrácený výsledek, který je ve tvaru -nn.n, kde n jsou číslice a na začátku může a nemusí být záporné znaménko. Zarovnání proběhne doplněním mezery, aby výsledek měl dohromady pět znaků i když zrovna nemrzne.
c:>ruby strahov.rb
19.9
Jak jsem slíbil, dáme teď teploměru GUI kabátek. Pro Ruby existuje vícero knihoven zajišťujících propojení s prakticky všemi rozšířenějšími grafickými toolkity. Pro naše potřeby bude nyní nejvhodnější jedna ze starších knihoven, která využívá toolkitu s prozaickým názvem ‚tk‘. Vhodný je zejména proto, že bývá dostupný na všech platformách, kde je k dipozici Ruby a obvykle není potřeba ničeho jiného než použití příslušbného ‚require‘. Práce s toolkitem není složitá. Pro začátek jsem opět mírně zadaptoval příklad z knihy Hala Fultona Ruby – kompendium znalostí pro začátečníky i profesionály. Informace o ní najdete na tomto serveru.
require ‚tk‘
root = TkRoot.new() do
title „Datum“
end
str = Time.now.strftime(„Dnes jen%d.%m.%Y“)
lab = TkLabel.new(root) do
text str
pack(„padx“ => 15, „pady“ => 10, „side“ => „top“)
end
Tk.mainloop
Takto jednoduchá GUI aplikace vzniká postupně v několika krocích. Vždy vytvoříme některý prvek grafického rozhraní a předáme mu blok, ve kterém lze volat metody nastavující různé vlastnosti právě vytvářeného prvku. Na konci spustíme metodu mainloop
, která zajišťuje cyklus, ve kterém aplikace běží a čeká na události – například kliknutí na některý z prvků. Zde jsme nejdříve vytvořili hlavní okno aplikace a nastavili mu popisek. Referenci na okno máme uloženu pod názvem root. Dále si zformátujeme řetězec s dnešním datem a vytvoříme textový popisek, kterému nastavíme jako obsah tento text. Pomocí metody pack
říkáme knihovně, jakým způsobem má prvek zobrazit. Pojmenované parametry metody zadané ve formě hashe říkají, že prvek má být odsazen horizontálně o 15 pixelů a vertikálně o 10 a text má být zarovnán na střed.
Spuštěnou aplikaci lze ukončit pouze standardním ovládacím prvkem operačního systému – v případě Windows křížkem v pravém horním rohu. To však nyní nebudeme řešit a pokusíme se raději příklad zkřížit s předchozím kódem pro stahování teploty. Následuje ukázka jednoho možného řešení.
require ‚tk‘
require ‚net/http‘
TXT = „Teplota jen%s“
def read_temperature
Net::HTTP.get(‚teplomer.sh.cvut.cz‘, ‚/servlet/teplota‘).rjust(5)
rescue
‚ xx.x‘
end
def refresh_temperature(lab)
lab.text = sprintf(TXT, read_temperature)
end
root = TkRoot.new() do
title „Teplota“
end
lab = TkLabel.new(root) do
pack(„padx“ => 15, „pady“ => 10, „side“ => „top“)
end
TkButton.new(root) do
text „Obnov“
command(proc { refresh_temperature(lab) })
pack(„padx“ => 15, „pady“ => 10, „side“ => „top“)
end
refresh_temperature(lab)
Tk.mainloop
Hlavní část programu vypadá velmi podobně jako předchozí ukázka. Navíc je přidáno tlačítko, které při stisknutí spouští metodu refresh_temperature
. Ta má za úkol nastavit text textového popisku. Šablona textu je uložena v konstantě TXT a využíváme metody sprintf
, abychom do šablony dosadili řetězec načtený z webu. Metoda sprintf
má jako první parametr formátovací řetězec – šablonu, která může obsahovat zástupky, které jsou pak nahrazeny dalšími parametry metodami. Zástupka %s je pro řetězcový parametr. Stisknutím tlačítka se tedy popisek nastaví na šablonu s doplněnou aktuální teplotou.
Vytvořená aplikace je velmi primitivní. Může ale posloužit jako základ a po dalším zdokonalování se stát užitečnou pomůckou. Možná se k ní vrátíme v některém z příštích dílů.
Mohlo by vás také zajímat
-
Vstupte do éry umělé inteligence: ASOME Max Studio s AMD Ryzen™ 9 7940HS
14. listopadu 2023 -
Monitory OLED: klíčové pojmy a funkce
13. května 2024 -
Landing page: Jak vytvořit landing page s vysokým CTR
7. května 2024
Nejnovější
-
Výkonný a kompaktní: ASOME Max Studio s výjimečným poměrem cena/výkon
11. listopadu 2024 -
Šokující data od Microsoftu: Kyberútoky rostou o stovky procent!
8. listopadu 2024 -
Chcete jedinečnou doménu? Objevte koncovky FOOD, MEME a MUSIC!
7. listopadu 2024 -
OpenAI představilo novou funkci ChatGPT Search
6. listopadu 2024
Karel
Zář 17, 2009 v 12:39Mám dotaz trochu mimo téma, sice v poslední době třeba nemám příliš čas sledovat každý nový článek seriálu, tak když už někdy chvilku vyšetřím, tak je čtu tzv. po vícero, tedy chtěl bych vznést takovou malou žádost, zda by nemol být na konci každého článku odkaz na předchozí a následující článek. Přehled „Souvisejcích článků“ je sice fajn věc, ale je to o něco chaotičtější než fce „tam a zpět“.
Miroslav Kucera
Říj 22, 2009 v 8:13Zdravim, momentalne me nenapada, jak bychom to udelali :-(, nicmene, vsechny clanky, pekne jeden po druhem, naleznete v sekci RUBY na adrese http://interval.cz/programovani/ruby/
mikrom
Led 24, 2010 v 20:41Serial uz skoncil?