A Központi Statisztikai Hivatal honlapján elérhető STADAT táblákból könnyen kinyerhetjük a nekünk szükséges adatokat. A témastruktúrába sorolt online és XLS exportként is böngészhető táblázatokban megtalálhatjuk logikusan csoportosítva összesítve az adatokat régiónként (megyénként), évenként, százalékosan. Az XLS fájlformátum Java nyelven a JExcel API-val hatékonyan feldolgozható. Lássunk erre egy példát!
Feladat
A KSH 2.1.2.35. táblázatából gyűjtsük ki a 19 magyar megyére + Budapestre vonatkozóan a gazdaságilag aktívak létszámát és az első évet alapnak tekintve adjuk meg évenként a változást százalékosan!
Tervezés
A KSH témastruktúrában a táblázat elérési útja:
- 2. Társadalom,
- 2.1. Munkaerőpiac,
- 2.1.2. A munkaerőpiac alakulása Magyarországon (1998–2018) -> Területi adatok,
- 2.1.2.35. A 15–64 éves népesség gazdasági aktivitása megyénként és régiónként (1998–2018)
Online böngészhető táblázat:
https://www.ksh.hu/docs/hun/xstadat/xstadat_hosszu/mpal2_01_02_35.html.
Letölthető táblázat (XLS formátumban): https://www.ksh.hu/docs/hun/xstadat/xstadat_hosszu/xls/h2_1_2_35.xls.
A táblázat A oszlopában szerepelnek a régiók, megyék, időszakok (vegyesen, szövegként) és a D oszlopában a gazdaságilag aktívak (ezer fő, valós számként). A fejlécet nem szabad feldolgozni. 1998-tól 2018-ig 546 sorból áll az adatsor. A csoportosítás 26 régiót és megyét tartalmaz, amiből a 6 régiót (például: Közép-Dunántúl) ki kell hagyni.
A megyékre vonatkozóan 440 sort kell feldolgozni. Ebből az első sor a megye (vagy Budapest) neve, a többi (2019-ben 21 db) sorban találhatók az adatok (időszak). Olyan algoritmusban érdemes gondolkodni, ami a jövőben is működik. Ha csoportváltást alkalmazunk, akkor nem számít, hogy megyénként minden évben egy sornyival több adat lesz majd. A KSH táblázatok szerkezete nagyon ritkán változik, így bátran írható rájuk testre szabott forráskód (ezeket nem kell évente frissíteni).
Az évenkénti változást százalékosan nem tartalmazza a táblázat, ezt nekünk kell kiszámítani. A valós számok formázását érdemes egységesíteni, például a gazdaságilag aktívak létszámát 3 tizedesre, a változást 2 tizedesre kerekítve.
A belső adatábrázolást érdemes átgondolni. Hasznos, ha az időszakhoz tartozó három összetartozó adatot egyetlen Data POJO-ba fogjuk össze ( String period, double active és double change). Ezeket generikus listába szervezve ( ArrayList<Data> list) könnyen hozzájuk rendelhető a megye ( String county) és ezek együtt alkotják a Region POJO-t. A Region és Data kapcsolati fokszáma: 1:N. 2019-ben N=21 .
Részlet a megoldásból
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
private List<Region> readXLS() throws IOException, BiffException { WorkbookSettings workbookSettings=new WorkbookSettings(); workbookSettings.setEncoding("Cp1252"); Workbook workbook=Workbook.getWorkbook( new File("./files/h2_1_2_35.xls"), workbookSettings); //munkafüzet Sheet sheet=workbook.getSheet("2.1.2.35."); //munkalap List<String> skipRegionList=Arrays.asList(new String[] { "Közép-Dunántúl", "Nyugat-Dunántúl", "Dél-Dunántúl", "Észak-Magyarország", "Észak-Alföld", "Dél-Alföld"}); List<Region> list=new ArrayList<>(); int i=3; //kihagyjuk a fejlécet while(i<sheet.getRows()) { Cell cellA=sheet.getCell(0, i); //megyék if(cellA.getType()==CellType.LABEL) { String county=((LabelCell)cellA).getString().trim(); Region region=new Region(county); i++; Cell cellD=sheet.getCell(3, i); //gazdaságilag aktívak while(i<sheet.getRows() && cellD.getType()!=CellType.EMPTY) { cellA=sheet.getCell(0, i); //időszakok String period=""; if(cellA.getType()==CellType.LABEL) period=((LabelCell)cellA).getString().trim(); double active=0; if(cellD.getType()==CellType.NUMBER) active=((NumberCell)cellD).getValue(); region.addList(period, active); i++; if(i<sheet.getRows()) cellD=sheet.getCell(3, i); } if(!skipRegionList.contains(county)) list.add(region); } } workbook.close(); return list; } |
A JExcel API használatához a Java projekthez hozzá kell adni a jxl.jar fájlt. A XLS fájl olvasható közvetlenül a webről is, de egyszerűbb helyi fájlrendszerbe mentett változatból dolgozni ( ./files/h2_1_2_35.xls). A megyék nevében található ékezetes karakterek miatt ügyelni kell a megfelelő karakterkódolásra ( Cp1252). A munkafüzet azonosítását követően hivatkozni kell a feldolgozandó munkalapra ( 2.1.2.35.). Az adatfeldolgozás során kihagyott régiókat (kivételeket) érdemes listába gyűjteni ( skipRegionList). A csoportváltást a két egymásba ágyazott ciklus valósítja meg. Ügyelni kell az adatok formátumának ellenőrzésére.
Eredmények
Például Somogy megyére az alábbi adatokat kapjuk eredményként (XLS formátumban, Excel-be betöltve, tipikus háttérszín kiemeléssel: szélsőértékek a C oszlopban, negatív értékek a D oszlopban):
További programozható feladatok
- Hogyan alakult a magyar autóbuszgyártás 1960-tól évtizedenként csoportosítva (átlag, min, max, szórás)? – 4.2. Ipar (1960–)
- Milyen a lakossági építkezés aránya az ezredforduló után a teljes építőipari termelés értékéhez viszonyítva évenkénti bontásban? – 4.3.1. Az országos építőipari termelés értéke kivitelezők szerint (1990–)
- Milyen kapcsolat figyelhető meg a szállodák száma és a kiadható férőhelyek száma között a 2008-ban kirobbant gazdasági világválság előtt és után? – 4.5.11. A kereskedelmi szálláshelyek kapacitása, július 31. (2001–)
- Melyik években volt a legmagasabb (TOP 3) a saját mobilhálózatba irányuló beszélgetések hossza az összes mobilhálózatba irányuló beszélgetések hosszához viszonyítva? – 4.7.5. A mobilhálózatokból kiinduló beszélgetések (2001–)
- Hogyan alakultak az üzemanyagok éves fogyasztói átlagárai (átlag, min, max, szórás)? – 3.6.3. Egyes termékek és szolgáltatások éves fogyasztói átlagára (1996–)
- Ábrázoljuk tematikus térképen: hogyan alakult régiónként a munkanélküliségi ráta a mindenkori utolsóként megadott negyedévben az előző év azonos negyedévéhez viszonyítva! – 6.2.1.11. Munkanélküliségi ráta
A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.
A feladat a Java SE szoftverfejlesztő tanfolyam tematikájához kötődik (ha az XLS fájlt a helyi fájlrendszerből érjük el), és a Java EE szoftverfejlesztő tanfolyam tematikájához kapcsolódik (ha az XLS fájl tartalmát közvetlenül a webről olvassuk).
Megküzdöttem az autóbuszgyártás alakulása feladattal. Az volt benne a csavar, hogy 1960-2018-ig, néhány évből hiányzik az adat. Hiszen tényleg nem volt buszgyártás. Ezek az évek a táblázatban nem nullaként, hanem …-ként (egyetlen ASCII karakterként) vannak benne. Erre fel kell készülni a ciklusban, beolvasás közben. Szám kellene, egész, de szöveg, karakter jön. Kivételkezeléssel oldottam meg.
Örülök, hogy sikerült Máté. Megmutatnád a csoportnak a jövő keddi órán? Zalán is írt, ő a szálláshelyeket kérdezte le. Hasonlítsuk össze a megoldásaitokat.
„Azon tűnődtünk, miért ellenzik az emberek annyira a sima objektumok használatát a rendszereikben, és arra jutottunk, hogy azért, mert az egyszerű objektumoknak nem volt fantázianevük. Így hát adtunk nekik egyet, és az szépen elterjedt.” – Martin Fowler
Köszönöm Csenge. Igen, a POJO-ról van szó.
További gyűjteményünk itt található: Híres IT idézetek
Más megközelítésben is hozzáférhetők a KSH adatai.
Aki elég kitartó és elszánt a hosszú-hosszú dokumentáción átrágni magát, a KSH ELEKTRA rendszerét is használhatja. Ehhez XML formátumban kell a lekérdezések feltételeit kérdőívként megfogalmazni/elküldeni:
https://www.ksh.hu/docs/adatgyujtesek/elektra/elektra_kerdoiv_generalas.pdf
A adat XML formátum sablonja/szerkezete:
http://www.ksh.hu/docs/adatgyujtesek/elektra/elektra_adat_xml_strukturaja.pdf
Eddig mindig az Excel API-t használtam hasonló feladatokhoz. Most használtam ennek egy alternatíváját, az Apache POI-t is. Amire kellett egy kis projektfeladathoz, szinte mindegy volt, hogy melyikkel szerzem meg a szükséges adatokat a táblázatokból. Érdemes lehet ezt is megismerni:
– jar fájlok (XLS-hez és XLSX-hez külön): https://poi.apache.org/components/index.html
– Quick Guide: https://poi.apache.org/components/spreadsheet/quick-guide.html
– JavaDoc: https://poi.apache.org/apidocs/4.1/
Tervezek egy API-t írni Pythonban, ami egyrészt összeszedi és strukturálja a KSH oldalán található összes kimutatást.
Itt van különben az összes csv és xlsx fájl, ami a KSH oldalán letölthető.
Gratulálok Gergő és köszönjük!