Organogram készítése

Organogram logó

HR-organogram-logoAz Oracle HR sémából építünk organogramot, amivel megjeleníthető a szervezeti hierarchia. Személyenként készítünk csomópontokat. (Másképpen is lehetne: például részlegenként.) A megvalósítás során kétszer konvertálunk A-ból B-be. Először az adatbázisból/adatforrásból SQL lekérdezéssel jutunk hozzá a szükséges adatokhoz, amelyeket generikus listába képezzük le. Ezután a listát feldolgozva generálunk HTML fájlt, amely tartalmaz egy Organization Chart diagramot.

Hasonló feladat: Ki kinek a vezetője?, rekurzív lekérdezéssel. Érdemes összehasonlítani a kétféle szemléletmódot.

Tervezés

Most pedig azt használjuk fel, hogy az Oracle HR sémában az EMPLOYEES táblában reflexió van, amelyet az EMPLOYEE_ID és a MANAGER_ID mezők biztosítanak.

Az Organization Chartnál három adatsor adható meg. Ezek most testre szabva (mindegyik szöveges): 'Employee lastname', 'Job ID', valamint jelmagyarázatként további három mező összefűzve: 'Employee name, Department name, Job title'. Az organogramon megjelenő adatok például: "Raphaely", "PU_MAN", valamint a csomópontra fókuszálva megjelenő tooltip: "Employee: Den Raphaely, Department: Purchasing, Job: Purchasing Manager". A DEPARTMENTS táblából – az EMPLOYEES-zel a DEPARTMENT_ID-vel összekötve – megkapjuk a DEPARTMENT_NAME-t. A JOBS táblából pedig – az EMPLOYEES-zel a JOB_ID-vel összekötve – megkapjuk a JOB_TITLE-t.

A lekérdező parancs

SQL-organogram

Az EMPLOYEE_ID elsődleges kulcs, vagyis kötelező. A MANAGER_ID nem kötelező, a hierarchia tetején álló vezetőnél ez a mező null értékű. Mivel a MANAGER_ID nem kötelező, így külön lekérdező parancsban kell előállítani a 15 középvezetőt együtt a 2 felső vezetővel, valamint az egyetlen felső vezetőt, akinek a MANAGER_ID-ja null. Ezt a két részeredményt össze kell fűzni ( UNION).

Az eredménytábla

SQL-eredménytábla

Az adatfeldolgozás lépései

Java programozási nyelven kötelező a kivételkezelés a JDBC kapcsolatfelvétel, SQL parancs futtatása, valamint a fájlkezelés során. A JDBCConnection interfészben definiált szöveges konstansok: DRIVER, URL, USER, PASSWORD (az adatbázis-szerverrel való kommunikációhoz), SQL (a lefuttatandó lekérdező parancs). Az OrganizationChart interfészbe került a HTML_FILE_PATH (a generálandó HTML fájl Path útvonala) és a HTML (konstans váz az organogram testre szabott HTML+JavaScript forráskódja). Az SQL parancs ResultSet eredménytáblájának feldolgozása során áll elő az orgChartDataList generikus lista. A HTML konstans szövegben lévő #OrgChartData# elemet ki kell cserélni a generikus listából Stream API-val dinamikusan összefűzött adatokra. A fenti példa ide kapcsolódó része: "[{'v':'Raphaely', 'f':'Raphaely<div style="color:red; font-style:bold">PU_MAN</div>'}, 'King', 'Employee: Den Raphaely, Department: Purchasing, Job: Purchasing Manager']". Ezt követően a java.nio csomag Files osztályának write() metódusával fájlba menthető az előállított fájltartalom. A konkrét Java forráskódot most nem részletezem.

Az elkészült organogram

HR-organogram

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 adatbázis-kezelő tanfolyam 9-12. óra: Oracle HR séma elemzése, 13-16. óra: Konzolos kliensalkalmazás fejlesztése JDBC alapon, 1. rész, 33-36. óra: Grafikus kliensalkalmazás fejlesztése JDBC alapon, 2. rész alkalomhoz kapcsolódik.

Fibonacci-spirál

Fibonacci nap

Fibonacci nap 2018A Fibonacci-spirál a népszerű Fibonacci-sorozat elemei által meghatározott oldalhosszúságú négyzetekbe rajzolt maximális sugarú negyedkörök megfelelően összeillesztett darabjaiból/sorozatából áll. Sokszor hasonlítják az arany spirálhoz (jól közelíti), amely az aranymetszéshez kötődik.

A Fibonacci-spirál

Vegyük a Fibonacci-sorozat első 10 elemét! Rajzoljuk egymás mellé az alábbi elrendezésben belülről kifelé haladva az 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 oldalhosszúságú négyzeteket (az alábbi ábrán vékony sárgával jelölve). Piros színnel rajzoljuk bele a négyzetekbe a négyzet oldalhosszával megegyező sugarú negyedköröket. A negyedkörök megfelelő elrendezésben folytonos görbét alkotnak, és ezt nevezzük Fibonacci-spirálnak (az alábbi ábrán vastag pirossal jelölve).

Fibonacci-spirál 1

A rajzolás bármeddig folytatható, mert a sorozat végtelen, a négyzetek illeszkednek és az ábra rekurzív, önhasonló. Az alábbi animáció mutatja, hogyan alakul a spirál a nézőpont közelítésével. A viselkedés távolítás során is azonos lenne.

Fibonacci-spirál 2

Korábban blogoltunk már a Fibonacci napról, amelyet minden évben november 23-án ünneplünk. A sorozat első néhány eleméből összeáll a 11.23. és értelmezhető dátumként. Most nem a sorozat elemeinek előállítására fókuszálunk, hanem arra, hogy ezekből felépítsük a Fibonacci-spirált.

Készítsünk Java programot!

Grafikus felületű Java programot készítünk, amely 21 animációs fázisban mutatja be a Fibonacci-sorozat első 10 eleméből álló Fibonacci-spirál felépítését. A rajzolás fázisai:

  • Az 1. fázis a kiindulópontként tekinthető fehér, üres rajzlap. A rajzlap fekvő, mérete 890*550 pixel, amelyre éppen elfér a 10 negyedkörből álló spirál.
  • A 2-11. fázisban megfelelő pozícióba/koordinátákra kerülnek fel az ábra vázát alkotó négyzetek, belülről kifelé haladva. A négyzetek oldalainak hosszúsága a sorozat elemeinek megfelelő. A szomszédos négyzetek különböző színekkel kitöltöttek és mindegyikben megjelenik a sorozat megfelelő eleme.
  • A 12-21. fázisban – szintén belülről kifelé haladva – a négyzetek törlődnek és helyükre a spirált alkotó negyedkörök kerülnek fekete színnel. A 21. fázist tekintjük végeredménynek.

A fázisok kézzel, nyilakkal jelölt (Első, Előző, Következő, Utolsó) vezérlő nyomógombokkal megjeleníthetők, illetve egyben, időzítve animációként is lejátszható a rajzolási folyamat. Az elkészült program működése megfigyelhető az ábrán:

Fibonacci-spirál Java program

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 Java SE szoftverfejlesztő tanfolyamunkon, a szakmai modul Objektumorientált programozás témakörét követő 29-36. óra Grafikus felhasználói felület alkalmain már tudunk egyszerűbb szimulációs programot tervezni, kódolni, tesztelni.

Címkefelhő generálása

szófelhő logó

szófelhő logóA címkefelhők/szófelhők népszerűek, sok weboldalon megtalálhatóak. A CMS rendszerekben beépített szolgáltatás is lehet, vagy külön bővítmény/plugin is megvalósíthatja. Egy szövegben előforduló szavakból a gyakrabban előfordulókat nagyobb betűmérettel emeli ki. Eredménye lehet listás, táblázatos, esetleg képpé generált is. Kétféleképpen is megközelíthető, erre utal a Word Cloud és a Tag Cloud elnevezés. Utóbbi inkább egy blog taxonomiájához kapcsolódik és kategóriákra/címkékre érvényesül. A szakmai blogunkhoz is tartozik egy táblázatos címkefelhő. A szófelhő a szöveg betűméretén túl megjelenítheti a szavak előfordulását, például Java forráskód (31).

Példánkban tetszőleges szöveget dolgozunk fel. Ebből felépítünk egy előfordulást is mutató listás szófelhőt, amely rendezett, és a szavak betűmérete 32-16-ig változik. Azok a szavak kerülnek a szófelhőbe, amelyek legalább 5-ször előfordulnak. Kezelünk kivételeket is, például olyan szavakat, amiket nem érdemes szófelhőbe tenni. Lépésenként haladva ismertetjük a megvalósító forráskódot, és külön megjeleníthetők az egyes lépések részeredményei.

A Java programozási nyelv csomagjait, osztályait, interfészeit, metódusait, műveleteit használjuk. Különböző adatszerkezetek kerülnek elő: tömb, generikus lista, generikus map, generikus folyam. Építünk a Stream API szolgáltatásaira és a lambda kifejezésekre. A megvalósítás könnyen testre szabható, kezeli a tipikusan előforduló igényeket.

1. Szövegforrás előkészítése

Generálunk egy 10 bekezdésből álló szöveget a Lorem Ipsum – All the facts – Lipsum generator weboldalon és a későbbi feldolgozáshoz mentjük a Java projekt files mappájába  lorem.txt néven. A fájl mérete: 5781 bájt. Szövegfájl:

2. Szöveges tartalom előkészítése

A megadott útvonalról a java.nio csomag metódusaival betöltjük a szövegfájl tartalmát byte[]-be, majd az s szövegbe. A replace() metódus hívásaival eltávolítjuk a szövegből a sor és bekezdés végét jelző soremelés ( LF="\n") és kocsi vissza ( CR="\r") vezérlőkaraktereket, a vessző és a pont írásjeleket (mindet külön-külön cseréljük a semmire), végül kisbetűssé alakítjuk ( toLowerCase()) a szöveget. A szöveg 5563 db karakterből áll. Előkészített szöveg:

3. Szólista elkészítése

A szóközök mentén darabolva ( split()) a szöveget elkészül belőle egy névtelen szövegtömb ( String[]), amit rögtön átalakítunk ( Arrays.asList()) szöveg típusú generikus listává ( List<String>). A lista 826 db elemből áll. Generikus lista:

4. Csoportosítás és megszámolás

A szólistát csoportosítjuk és megszámoljuk, hogy az egyes szavak hányszor fordulnak elő (másképpen: egy-egy csoport hány elemű). Elkészül a wordCountMap generikus map, amely kulcs-érték párok halmaza (leképezés). A kulcs a szó ( String), az érték a darabszáma ( Long). Alkalmazkodunk ahhoz, hogy a csoportosítás során használt counting() megszámoló művelet Long típusú értéket ad vissza. 188 db kulcs-érték párt kapunk. Generikus map:

5. Szűrés és rendezés

A generikus map-et kétszer szűrjük ( filter() művelet) úgy, hogy a kivételeket tartalmazó exceptList-ben ne szerepeljen a szó, valamint csak a legalább 5-ször előforduló szavakat hagyjuk meg. 71 db elemből álló folyam marad. Ebből a maradékból készítünk rendezett generikus folyamot ( sortedWordCountStream). A sorted() művelet két kulcs-érték párt hasonlít össze. A rendezés érték/darabszám szerint ( getValue()) csökkenő, azon belül kulcs/szavak szerint ( getKey()) növekvő sorrendet biztosít. Másképpen: ha az értékek megegyeznek, akkor a növekvő sorrendet a szavak ábécé sorrendje határozza meg, egyébként a darabszámok csökkenő sorrendje dönti el. Most már könnyen látható, hogy a leggyakrabban előforduló kevés szóból 15 van, 14 előfordulás nincs… Rendezett generikus folyam:

6. Saját típusú listává konvertálás

Definiálunk egy WordCount POJO-t, String típusú word nevű, Long típusú count nevű, int típusú fontSize nevű tulajdonságokkal, getter/setter metódusokkal, és toString() függvénnyel.

A map() intermediate művelettel a rendezett generikus folyamot bejárva, előállítjuk a POJO/ WordCount  típusú kimeneti objektumok rendezett generikus listáját. Továbbra is 71 elemmel dolgozunk. Rendezett generikus lista:

7. Darabszámok összegyűjtése

A POJO típusú rendezett generikus listában lévő objektumoktól elkért darabszámok ( getCount() POJO függvény) közül a különbözőeket ( distinct() művelet) összegyűjtjük egy Long típusú generikus listába ( distinctCountList). Az egyediesítő művelet nincs hatással az adatok sorrendjére. Tízféle előfordulást kapunk. Generikus lista:

8. Betűméret lépésköze

A szófelhőben a szavak gyakorisága alapján határozzuk meg a betűméretet. A betűméret 32-ről indul és fokozatosan csökken 16-ig. A betűméret léptetéséhez a tízféle gyakoriság/előfordulás meghatározza a stepFontSize  lépésközt. Lépésköz:

9. Betűméret kiszámítása

Csoportváltást alkalmazunk és a csoportot gi-vel indexeljük. Egy csoportba azok a POJO objektumok tartoznak, amelyeknél a szavak előfordulása megegyezik. Az algoritmus 2. lépésében az aktuális csoportra érvényesen kiszámítjuk a betűméretet ( fontSize), ami az algoritmus 3. lépésében a csoportba tartozó minden POJO objektumnál beállításra kerül a setFontSize() POJO eljárással. Az algoritmus 4. lépésében léptetjük a csoport gi indexét. A POJO-k esetén először csak a word és count tulajdonságok kerültek beállításra, de most már a fontSize tulajdonság is értéket kapott. Generikus lista:

10. HTML tartalom előállítása

A generikus lista POJO objektumain végighaladva, a forEach() záró művelettel összeállítható a weboldal szófelhőt tartalmazó része ( sbHTML). A 71 db szóból álló szófelhő HTML forráskódjának mérete 3409 bájt. HTML forráskód:

Eredmény

Szöveges formában:

lorem ipsum szófelhő

Képként (a 3. lépés részeredményéből a WordClouds.com weboldalon generálva):

lorem ipsum szófelhő eredmény

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 szakmai moduljának több alkalmához is kötődik. A Stream API-val és a lambda kifejezésekkel sokszor foglalkozunk.

Dr. Sheldon Cooper szólánc játéka

Sheldon, Agymenők

Sheldon szólánc kiemelt képDr. Sheldon Cooper karakterét nem kell bemutatni. Az Agymenők (The Big Bang Theory) című sorozat 2. évad 5. epizódjának címe A vitatkozás nagymestere (The Euclid Alternative). Nagyon találó az epizód címe magyarul. Miközben Penny reggel Sheldont munkába viszi, Sheldon az autóban kémiai elemek nevéből álló szólánc játékával különösen Penny agyára megy (pedig a játékot Penny nyeri 😀):

A játék során Sheldon az alábbi kémiai elemeket mondja:

  • magyar nyelven: Hélium ↦ Mangán ↦ Neptúnium ↦ Magnézium ↦ Molibdén ↦ Nitrogén ↦ Nobélium ↦ Mendelévium
  • angol nyelven: Helium ↦ Mercury ↦ Ytterbium ↦ Molybdenum ↦ Magnesium ↦ Manganese ↦ Europium ↦ Mendelevium

Támogassuk meg ezt a játékot! Készítsünk olyan programot Java nyelven, ami segít(ene) felkészülni Sheldon szólánc játékára!

A szükséges lépések áttekintése

  • Gyűjtsük össze a kémiai elemek nevét magyar nyelven a Wikipédia – Kémiai elemek listája szócikkéből és rendezzük ábécé sorrendbe!
  • Építsük be az elemlistát a program adatmodelljébe!
  • Indítsuk el a lépésszámláló nulláról! Ha a lépésszámláló páros, akkor az ’A’ játékos, egyébként a ’B’ játékos lép.
  • Készítsük elő a játékmenet tárolására alkalmas adatszerkezetet, szöveget, listát!
  • Kezdetben kínáljuk fel a teljes elemlistát úgy, hogy mindig egy és csak egy legyen belőle kiválasztható!
  • A kiválasztást követően tároljuk el a játékmenetben az elemet, töröljük ezt az elemlistából, majd kínáljuk fel azoknak az elemeknek a listáját, amelyek kezdőbetűje megegyezik az előzőleg kiválasztott elem utolsó betűjével és növeljük meg a lépésszámlálót!
  • Amíg a felkínálható elemek listája nem üres, addig az előző lépést ismételjük meg!
  • A játék végén az nyert, aki a játékmenet utolsó elemét választotta ki. Írjuk ki a nevét és a lépésszámot!

A grafikus felületű megvalósítás képernyőképe rövid játékmenettel

Szólánc képernyőkép

Ötletek a megvalósításra és a továbbfejlesztésre

  • A program Java nyelven konzolos menükezeléssel, asztali alkalmazásként swing-esen többféle GUI komponens használatával és eseménykezeléssel, böngészőben futó JSP webalkalmazásként többféle űrlapmezővel, illetve HTML+CSS+JavaScript alapon is implementálható.
  • A kémiai elemek listája lecserélhető az angol nevekre. Ekkor figyeljünk arra, hogy a kis- és nagybetűket ne különböztessük meg az utolsó-első betű párosítása során.
  • Lehet a játék bármikor megszakítható, illetve a vége után újrakezdhető.
  • A program mérhetné a játék során az eltelt időt.
  • A program lehetne peer-to-peer vagy szerver-kliens elosztott és megvalósíthatna hálózatos kommunikációt.
  • A program mobil alkalmazásként is implementálható.

A bejegyzéshez tartozó teljes forráskódot – többféle változatban is – ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

Többféleképpen is hozzájuthatunk az adatokhoz attól függően, hogy milyen előismeretekkel rendelkezünk a különböző tanfolyamainkon:

  • A Java SE szoftverfejlesztő tanfolyamon dolgozhatunk szövegtömbbel, generikus kollekcióval (listával/halmazzal), konzolos és swing-es változatot is készíthetünk. Ehhez a feladathoz objektumorientált alapok mindenképpen szükségesek. Kézzel előállított szövegfájlból olvasva (mentve a Wikipédia oldaláról a táblázatot) hozzájuthatunk a kémiai elemek nevéhez, amihez kivételkezelés is szükséges.
  • A Java EE szoftverfejlesztő tanfolyamon megvalósítható, hogy a program kivételkezeléssel hálózati kapcsolatot épít, majd közvetlenül olvassa és/vagy menti a Wikipédia HTML tartalmából a kémiai elemek nevét szövegfájlba vagy generikus kollekcióba, amivel a feladat visszavezethető az SE szemléletű megközelítésre. Böngészőben futó JSP és/vagy Servlet technológiára építő webalkalmazásként is megvalósítható a feladat.

KSH táblázatból dolgozunk

KSH-logo

KSH-logoA 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

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):

KSH-result

További programozható feladatok

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).