od CiTrus » 20. 1. 2015 12:03
Další náhled na to samé.
- Bylo potřeba číst binární soubor. (hodně lidí nevědělo, že existuje něco jako ios::binary)
- V souboru mohlo být libovolné množství bloků HDU, takže bylo zapotřebí zpracovávat data jednotlivě po HDU až do konce streamu.
- HDU neměly pevnou velikost. Určovala se z jejich obsahu – headeru a dat.
- Header se skládal z libovolného rámců. Každý měl pevnou velikost 80B.
- Byte 0-7 byl povinný keyword.
- Byte 8-9 byl vždy rovnítko a mezera.
- Zbytek byl value a comment (tyto hodnoty byly obě nepovinné).
Na konci headeru byl vždy speciální rámec s keywordem 'END'. Za tímto rámcem mohly ještě následovat prázdné rámce (obsahující jenom mezery) tak, aby byla celková velikost headeru zarovnána na násobek 2880B. Bohužel se nedalo spolehnout na to, že tento násobek bude nejmenší možný. Muselo se tedy kontrolovat, kdy přestanou chodit prázdné rámce.
- Data byla uložena rovnou za headerem a pro účely testu nás nezajímala. Mohli jsme je tedy přeskočit. Bylo ale zapotřebí spočítat správně jejich velikost pro čtení (opravdová velikost uložených informací, která se vypisovala) a velikost pro skok (mohla být větší kvůli zarovnání na násobky 2880B, byla nutná, aby čtení HDU skončilo přesně na začátku další HDU nebo na konci streamu).
Velikost dat se spočítala z headeru. Položka NAXIS určovala dimenzi datové matice (počet os). Velikosti jednotlivých os byly určeny položkami NAXIS1, NAXIS2, atd. Položka BITPIX udávala počet bitů na jednu položku datové matice. Výsledná velikost dat tedy byla určena násobkem BITPIX*NAXIS1*NAXIS2*...*NAXIS? (kde ? je hodnota NAXIS). Tato hodnota ale byla v bitech, a tak jí bylo nutno vždy vydělit 8. Ve skutečném vzorci navíc ještě figurovaly další dva koeficienty GCOUNT a PCOUNT, které však ve všech testovacích příkladech byly nastaveny na 1, a tak se jejich vynecháním nic nerozbilo.
Data byla podobně jako header zarovnána na nejbližší horní násobek 2880B, a tak bylo nutné správně spočítat počet bytů k přeskočení.
Program měl přečíst soubor FITS z argumentu a vypsat na stdout pro každou HDU typ, rámce z headeru a skutečnou velikost dat.
- Typ se zjistil z keywordů v headeru. První HDU byla vždy "Primary". Ostatní HDU obsahovaly v headeru položku XTENSION, která nabývala dvou hodnot "IMAGE" nebo "BINTABLE" - tyto hodnoty se vypisovaly jako typ.
- Rámce z headeru nešlo jen tak překopírovat do výstupu, musely se parsovat. Keyword i value obsahovaly počáteční a koncové mezery, které bylo potřeba odstřihnout. Navíc se po nás chtělo, abychom odebrali comment, který byly oddělen prvním lomítkem po skončení hodnoty v poli value. Komentáře ale byly nepovinné a museli jsme počítat s tím, že se ve value nevyskytnou.
- Value jsme měli ještě parsovat na typ, který se vypisoval do výstupu.
- string - byl ohraničen dvěma apostrofy ('). Pokud však obsahoval dva apostrofy za sebou, byla to escape sequence pro normální apostrof. Navíc, musel se dávat pozor na lomítka uprostřed stringu (byla to součást hodnoty, nikoli oddělovač komentáře). Ve výpisu musely být okolní apostrofy odstraněny a vnitřní dvojapostrofy správně nahrazeny.
- logical - prakticky bool. Mohl obsahovat hodnotu T nebo F (bez apostrofů). Vypisoval se ale jako TRUE nebo FALSE.
- int32 - celé číslo v desítkové soustavě. Mohlo být i záporné (pozor na minus). Vypisovalo se standardním c++ způsobem.
- double - reálné číslo. Mohlo být i záporné. Navíc jsme museli počítat kromě klasického zápsiu i se zápisem ve vědecké notaci (např. 1e09). Vypisovalo se standardním c++ způsobem.
- complex int, complex double - komplexní varianta předchozích dvou. Obsahovala uspořádanou dvojici dvou int32 nebo double. Bylo nám však řečeno, že tyto dva typy nemusíme implementovat, protože se v testovacích datech nevyskytují.
- undefined - cokoliv jiného (vč. prázdné hodnoty)
- Bylo nám řečeno, ať naše programy nevypisují rámce s keywordem HISTORY nebo keywordem začínajícím na COMMENT.
- Výpis několika rámců headeru na stdout tedy například mohl vypadat takto:
Kód: Vybrat vše
SIMPLE[logical]=TRUE
NAXIS[int32]=2
XTENSION[string]=IMAGE
Co jsem slyšel od spolužáků, řešili to různě. Někdo to napsal celé prakticky v Céčku, ostatní do toho rvali regex nebo v několika procedurách prakticky implementovali stavový automat (který se jim z regexu stejně vygeneruje). Moje řešení bylo hodně objektové (dědil jsem různé druhy value) a používalo hlavně streamy a streamové operátory.
Odevzdání probíhalo zamáváním na Yaghoba, který přišel, omrknul výpis na stdoutu, případně požádal, ať mu tam dám jiný FITS soubor, a napsal OK k mému jménu na seznam. Nechtěl vidět kód ani způsob řešení.
Času na úlohu bylo celkem dost. Začínalo se před 14 a končilo se v 18. První odevzdali kolem půl páté. Mezi 17:30-18 to ale odevzdali skoro všichni.
Další náhled na to samé.
[list]
[*] Bylo potřeba číst binární soubor. (hodně lidí nevědělo, že existuje něco jako [i]ios::binary[/i])
[*] V souboru mohlo být libovolné množství bloků HDU, takže bylo zapotřebí zpracovávat data jednotlivě po HDU až do konce streamu.
[*] HDU neměly pevnou velikost. Určovala se z jejich obsahu – headeru a dat.
[*] [b]Header[/b] se skládal z libovolného rámců. Každý měl pevnou velikost 80B.
[list][*]Byte 0-7 byl povinný [b]keyword[/b].[*]Byte 8-9 byl vždy rovnítko a mezera.[*]Zbytek byl [b]value[/b] a [b]comment[/b] (tyto hodnoty byly obě nepovinné).[/list]
Na konci headeru byl vždy speciální rámec s keywordem 'END'. Za tímto rámcem mohly ještě následovat prázdné rámce (obsahující jenom mezery) tak, aby byla celková velikost headeru zarovnána na násobek 2880B. Bohužel se nedalo spolehnout na to, že tento násobek bude nejmenší možný. Muselo se tedy kontrolovat, kdy přestanou chodit prázdné rámce.
[*] [b]Data[/b] byla uložena rovnou za headerem a pro účely testu nás nezajímala. Mohli jsme je tedy přeskočit. Bylo ale zapotřebí spočítat správně jejich velikost pro čtení (opravdová velikost uložených informací, která se vypisovala) a velikost pro skok (mohla být větší kvůli zarovnání na násobky 2880B, byla nutná, aby čtení HDU skončilo přesně na začátku další HDU nebo na konci streamu).
Velikost dat se spočítala z headeru. Položka [i]NAXIS[/i] určovala dimenzi datové matice (počet os). Velikosti jednotlivých os byly určeny položkami [i]NAXIS1, NAXIS2, atd.[/i] Položka [i]BITPIX[/i] udávala počet bitů na jednu položku datové matice. Výsledná velikost dat tedy byla určena násobkem [i]BITPIX*NAXIS1*NAXIS2*...*NAXIS?[/i] (kde [i]?[/i] je hodnota [i]NAXIS[/i]). Tato hodnota ale byla v bitech, a tak jí bylo nutno vždy vydělit 8. Ve skutečném vzorci navíc ještě figurovaly další dva koeficienty [i]GCOUNT[/i] a [i]PCOUNT[/i], které však ve všech testovacích příkladech byly nastaveny na 1, a tak se jejich vynecháním nic nerozbilo.
Data byla podobně jako header zarovnána na nejbližší horní násobek 2880B, a tak bylo nutné správně spočítat počet bytů k přeskočení.[/list]
Program měl přečíst soubor FITS z argumentu a vypsat na stdout pro každou HDU typ, rámce z headeru a skutečnou velikost dat.
[list]
[*] Typ se zjistil z keywordů v headeru. První HDU byla vždy "Primary". Ostatní HDU obsahovaly v headeru položku [i]XTENSION[/i], která nabývala dvou hodnot "IMAGE" nebo "BINTABLE" - tyto hodnoty se vypisovaly jako typ.
[*] Rámce z headeru nešlo jen tak překopírovat do výstupu, musely se parsovat. Keyword i value obsahovaly počáteční a koncové mezery, které bylo potřeba odstřihnout. Navíc se po nás chtělo, abychom odebrali comment, který byly oddělen prvním lomítkem po skončení hodnoty v poli value. Komentáře ale byly nepovinné a museli jsme počítat s tím, že se ve value nevyskytnou.
[*] Value jsme měli ještě parsovat na typ, který se vypisoval do výstupu.
[list][*][b]string[/b] - byl ohraničen dvěma apostrofy ('). Pokud však obsahoval dva apostrofy za sebou, byla to escape sequence pro normální apostrof. Navíc, musel se dávat pozor na lomítka uprostřed stringu (byla to součást hodnoty, nikoli oddělovač komentáře). Ve výpisu musely být okolní apostrofy odstraněny a vnitřní dvojapostrofy správně nahrazeny.
[*][b]logical[/b] - prakticky bool. Mohl obsahovat hodnotu T nebo F (bez apostrofů). Vypisoval se ale jako TRUE nebo FALSE.
[*][b]int32[/b] - celé číslo v desítkové soustavě. Mohlo být i záporné (pozor na minus). Vypisovalo se standardním c++ způsobem.
[*][b]double[/b] - reálné číslo. Mohlo být i záporné. Navíc jsme museli počítat kromě klasického zápsiu i se zápisem ve vědecké notaci (např. 1e09). Vypisovalo se standardním c++ způsobem.
[*][b]complex int, complex double[/b] - komplexní varianta předchozích dvou. Obsahovala uspořádanou dvojici dvou int32 nebo double. Bylo nám však řečeno, že tyto dva typy nemusíme implementovat, protože se v testovacích datech nevyskytují.
[*][b]undefined[/b] - cokoliv jiného (vč. prázdné hodnoty)[/list]
[*] Bylo nám řečeno, ať naše programy nevypisují rámce s keywordem [i]HISTORY[/i] nebo keywordem začínajícím na [i]COMMENT[/i].
[*] Výpis několika rámců headeru na stdout tedy například mohl vypadat takto:
[code]SIMPLE[logical]=TRUE
NAXIS[int32]=2
XTENSION[string]=IMAGE[/code][/list]
Co jsem slyšel od spolužáků, řešili to různě. Někdo to napsal celé prakticky v Céčku, ostatní do toho rvali regex nebo v několika procedurách prakticky implementovali stavový automat (který se jim z regexu stejně vygeneruje). Moje řešení bylo hodně objektové (dědil jsem různé druhy value) a používalo hlavně streamy a streamové operátory.
Odevzdání probíhalo zamáváním na Yaghoba, který přišel, omrknul výpis na stdoutu, případně požádal, ať mu tam dám jiný FITS soubor, a napsal OK k mému jménu na seznam. Nechtěl vidět kód ani způsob řešení.
Času na úlohu bylo celkem dost. Začínalo se před 14 a končilo se v 18. První odevzdali kolem půl páté. Mezi 17:30-18 to ale odevzdali skoro všichni.