Galéria véletlen sorrendben

Adott egy mappában lévő sok-sok képfájl, többféle formátumban, kiterjesztéssel. A feladat az, hogy időzítve jelenítsük meg ezeket a képeket véletlen sorrendben saját fejlesztésű Java program segítségével. A tervezés során áttekintünk többféle lehetőséget. Bemutatjuk a megoldáshoz szükséges lépéseket és a program működését.

A program tervezése

A szükséges bemeneti adatok

  • Egy mappa, abszolút vagy relatív útvonal, ahol a képfájlok megtalálhatók. A mappa átvehető a program paramétereként (ha parancssorban meghívva átadjuk) vagy lehet az aktuális mappa (ahonnan a programot jar fájlként elindítjuk). A program a mappában közvetlenül megtalálható képeket olvassa be. Az ott található almappákba nem megy bele.
  • A képfájlok különböző kiterjesztéseit tárolni kell. Többféle is lehet, így ehhez szükséges alkalmas adatszerkezet. A listában nem szereplő kiterjesztéssel rendelkező fájlok nem kerülnek feldolgozásra.
  • Érdemes a képfájlokat egy lépésben betölteni a memóriába. Így a program takarékos erőforrásként bánik a tárhellyel (merevlemez, pen-drive, SSD, hálózati meghajtó). Csak egyszer dolgozza fel (olvassa végig) a mappát. Feltételezzük, hogy a képfájlok beférnek a memóriába.
  • A program teljes képernyős, amiből elérhető a rendelkezésre álló terület mérete, ahol megjeleníthetők a képek. A program a betöltött képfájlok méreteihez is hozzáfér. Ez a méret kétféle lehet: bájtban kifejezhető a képfájl elfoglalt tárhelye, illetve pixelben kifejezhető a képfájl dimenziója (másképpen a megjelentéséhez szükséges terület mérete a képernyőn).

Hogyan működik a program?

  • Egyszerre egy kép jelenik meg. Időzítő befolyásolja a képfájlok közötti váltást. Meghatározza, hogy a képfájlok meddig látszanak (másképpen: eltelt idő, késleltetés, várakoztatás). A swing GUI-hoz tartozó időzítőt kell hozzá használni.
  • A program alkalmazkodik a képernyő, kijelző felbontásához, képarányához. A program végtelenítve működik, Alt + F4 billentyűkombinációval lehet kilépni belőle.
  • A képfájlok megjelenítésük során optimálisan, dinamikusan kitöltik a rendelkezésre álló téglalap alakú területet. A túl kicsi képeket nagyítani kell. A túl nagy képeket kicsinyíteni kell. Mindezt úgy, hogy a képarányt (aspect ratio) meg kell tartani, hogy a képek ne torzuljanak el. Az alábbi három példa balról-jobbra mutatja az optimális kitöltést, illetve azt a két esetet, ami akkor történik, amikor a kép méretéhez képest a megjelenítésre használható terület túl magas vagy túl széles:
  • A galériába tartozó képek közötti véletlen sorrendet meg kell oldani. A program a memóriába betöltött képek sorszámai alapján valósítja meg a véletlenszerű kiválasztást. A sorszámok összekeverednek. Egymás után nem jöhet ugyanaz a kép többször. Ha a képek „elfogynak”, akkor a program végtelenített működése szerint a képek sorszámai újra összekeverednek és „lejátszásra kerülnek”.

A program megvalósítása

A mappát a java.io csomag File osztályából létrehozott folder objektum tárolja (a "./"  szövegliterál jelöli az aktuális mappát). A feldolgozandó képfájlok kiterjesztéseinek listáját egy dinamikus tömbből létrehozott generikus lista oldja meg: ArrayList<String> imageFileExtensionList=new ArrayList<>(Arrays.asList("JPG", "JPEG", "PNG", "GIF")). Egy képfájl memóriabeli tárolását a  java.awt.image.BufferedImage típus valósítja meg, amelyekből szintén generikus lista épül: ArrayList<BufferedImage> imageList. A grafikus felhasználói felülethez tartozó javax.swing csomagbeli Timer osztály szükséges, például 2 mp-es várakoztatás és eseménykezelés: timer=new Timer(2000, (ActionEvent) -> { showRandomImage(); }). A GUI JFrame leszármazott keretobjektum. A grafikus felhasználói felület a teljes képernyőt elfoglalja: setExtendedState(MAXIMIZED_BOTH) és setUndecorated(true). A keretre egyetlen JLabel típusú, fekete hátterű lbImage objektum kerül, az alapértelmezett határmenti elrendezésmenedzser közepére (vízszintesen és függőlegesen egyaránt). A képfájlok sorszámai (a későbbi véletlen kiválasztáshoz) az imageIndexList generikus listába/kollekcióba kerülnek. Az index változó jelöli az aktuális, memóriába betöltött képfájl sorszámát, ami kezdetben nulláról indul.

A képfájlok betöltése az alábbiak szerinti:

A fájlok kiterjesztésének szűrése a FileFilter interfész accept() metódusának megvalósításával történik. A fenti forráskódban mindez tömör, lambda kifejezéssel (művelettel) valósul meg. A fájlszűrőn az képfájl megy át, aminek a nagybetűssé alakított kiterjesztését tartalmazza az  imageFileExtensionList kollekció. Az i-edik képfájl memóriába való betöltését az ImageIO osztály statikus read() függvénye oldja meg. A képfájlok sorszámainak véletlen összekeverése kezdetben megtörténik: Collections.shuffle(imageIndexList). A fájlkezelés miatt kötelező kivételkezelést most – itt a szakmai blogban – nem részletezzük.

Az időzítő eseménykezelése, a 2 másodpercenkénti képváltás így valósul meg:

A program alábbi metódusa felel a képarányhoz kötődő műveletekért:

A program tesztelése

  • Érdemes lehet tesztelni nem ajánlott (rossz) megoldásként azt, hogy a program az időzítőnek megfelelően, dinamikusan olvasná be a képfájlokat, amivel lényegesen kevesebb memóriát igényelne.
  • Van-e reális korlát arra, hogy mennyi, mekkora képek „férnek el” a memóriában?
  • Hogyan befolyásolja a képfájlok száma és az általuk elfoglalt tárhely a program indulását?
  • Mi történik, ha nincs megfelelő kiterjesztésű képfájl a mappában? És ha több 1000 kép van benne?
  • Hogyan jelennek meg (megjelennek-e) az animációt tartalmazó képfájlok? Például a GIF képformátum nem csak statikus egyetlen képet tartalmazhat, hanem lehet animált is.
  • Teljesen megvalósul-e a reszponzivitás? Ha igen, mi indokolja? Ha nem, miért nem és hogyan lehetne megoldani?

Ha átmenetileg kikapcsoljuk a teljes képernyős megjelenítést, akkor könnyen tesztelhetővé válik a megvalósuló reszponzivitás. Másképpen a program dinamikusan alkalmazkodik a rendelkezésre álló (rajzolható) terület méreteihez (szélesség és magasság):

A program továbbfejlesztési lehetőségei

  • A program rekurzívan bejárhatná a folder által megjegyzett útvonalból kiindulva a teljes (al)mappaszerkezetet.
  • A program paraméterezhető lehetne a képfájlok kiterjesztéseivel. Akár konfigurációs fájlból is beolvashatná az imageFileExtensionList adatszerkezetet, például XML, JSON formátumban is.
  • A program ellenőrizhetné, hogy a mappában lévő összes kép befér-e a memóriába. A program kezelhetne ehhez kötődően többféle limitet: például az első 100 db képet töltené be, és/vagy csak annyi képet tölt be, ami belefér például 64 MB-ba.
  • A program mutathatná folyamatindikátorral induláskor a képfájlok betöltését. Vagy betölthetné például az első 5 db-ot és háttérszálon a többit, amíg az első 5-öt „lejátssza”.
  • Ha például a program 10 képet tölt be mappában lévő képfájlokból, akkor ezek 0-tól 9-ig sorszámozódnak. A sorszámok összekeverve következnek. Ha az első menetben az utolsó kép sorszáma például a 7 volt, akkor a következő ismétlődő menet nem kezdődhetne 7-tel.
  • A programból ki lehetne lépni az Esc billentyűvel is. KeyListener interfésszel megoldható.
  • A program kezelhetne egyéb képfájlformátumokat is: például animált GIF, statikus WebP, animált WebP.
  • A program könnyen kiegészíthető prezentációk diáinak időzített/felülbírált megjelenítésére.
  • A program által beolvasott képfájlokból generálható PDF fájl is (rácsos sablonnal, például 6 db kép laponként). A feldolgoztt mappában lévő képfájlok könnyen feltölthetők FTP szerver adott mappájába, átméretezhetőek csoportosan, elküldhetők nyomtatási sorba is.
  • Érdemes megismerni a JDK-n kívüli egyéb, képfájlokat kezelő osztályok, csomagok funkcióit, például: OpenIMAJ, TwelveMonkeys ImageIO.
  • A swing-es felület kiegészíthető mappatallózással, egyéni fájl(típus)szűrőkkel, paraméterezhető lehet a véletlenszerű kiválasztás algoritmusa, változtatható az időzítés késleltetése.
  • Mivel a program teljes képernyős, így elrejthető az egérmutató.
  • A képek „lejátszásából” lehetne generálni animált GIF-et.

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 animációs, szimulációs programot tervezni, kódolni, tesztelni.

Alkalmazottak életpálya modellje – munkakör, fizetés, jutalék

Az Oracle HR sémában 11 részleg található 107 alkalmazottal, akik 19 különböző munkakörben végzik munkájukat. Nyilvánvalóan mindenkinek a fizetése pozitív ( SALARY>0), havi, USD pénznemben. Két munkakörre jellemző, hogy tartozik hozzá jutalék ( COMMISSION_PCT), amely pozitív valós szám. A 17 többi munkakörben foglalkoztatott alkalmazott esetében az adatbázis EMPLOYEES táblájának jutalék mezőjében NULL található. Az Oracle HS séma:

Oracle HR séma

Életpálya-modellnek tekinthető a munkakörhöz ( JOB_ID és JOB_TITLE) tartozó adható legkisebb és legnagyobb fizetés ( MIN_SALARY, MAX_SALARY) nyújtotta mozgástér. Minden alkalmazottra teljesül, hogy a fizetése a megadott határok között található (zárt intervallumként kezelve). Ennek ellenőrzésére használható az alábbi SQL parancs:

Eredménytábla:

A MIN(SALARY) oszlopban található a valós/kapott fizetések minimuma. A mellette lévő oszlopok hasonlóan a maximumot és az átlagot mutatják. A részlegben található alkalmazottak számát az utolsó, COUNT_EMPLOYEE oszlop tartalmazza.

35 fő dolgozik a Sales részlegben. Az 5 fő Sales Manager (értékesítési vezető) jutaléka a fizetés 20%-ától 40%-áig terjedhet 10%-os lépésközzel (3-féle lehet). A 30 fő Sales Representative (üzletkötő) jutaléka a fizetés 10%-ától 35%-áig terjedhet 5%-os lépésközzel (6-féle lehet). Ennek igazolására használható az alábbi SQL parancs:

Eredménytábla:

A bejegyzéshez tartozó teljes Java forráskódot (ami beépítve tartalmazza a fenti SQL lekérdező parancsokat) ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

A feladatok megoldása során nem foglalkoztam külön azzal az egy alkalmazottal, akinek nincs részlege. A feladatok a Java adatbázis-kezelő tanfolyam 13-16. óra: Konzolos kliensalkalmazás fejlesztése JDBC alapon, 1. rész alkalmához és a 33-36. óra: Grafikus kliensalkalmazás fejlesztése JDBC alapon, 1. rész alkalmához kötődnek.

Az SQL forráskód formázásához a Free Online SQL Formatter-t használtam.

Murphy törvénykönyve – görbe tükör IT szemmel

Arthur Bloch népszerű könyvéből gyűjtögettem néhány szösszenetet. Biztosan sokaknak ismerős. A címe: Murphy törvénykönyve, avagy miért romlik el minden? A gondolatokat itt-ott kiegészítettem a programozásra, szoftverfejlesztésre jellemző szemléletmóddal. Ezt a blog bejegyzést április 1-jén tesszük közzé. Nem véletlenül. 🙂 Az alap Murphy-törvényből induljunk ki: „Ami el tud romlani, az el is romlik.” Következzen 13+1 bölcsesség.

„Semmi sem olyan egyszerű, mint amilyennek látszik.” Pláne, ha az ügyfél úgy gondolja, hogy ezt az apróságot bizony 4 perc alatt megoldja egy ügyes fejlesztő.

„Minden több időt vesz igénybe, mint gondolnád.” Ha csak egy paraméter típusát változtatod meg egy metódusban, akkor az biztos, hogy lavinát indít és a forráskódban sok helyen kell módosítanod.

„Ha többféle dolog is elromolhat, biztos, hogy az romlik el közülük, amelyik a legnagyobb kárt okozza.” Elegendő belegondolni abba, hogy egy WordPress-ben lehet bármennyi bővítményed, amik általában gond nélkül frissülnek, de egy apró PHP frissítéstől összedől az egész weboldal.

„Ha rájöttél, hogy egy művelet négyféle módon mondhat csődöt, s mindegyiket kivéded, menten fellép az ötödik.” Hiába készülsz fel minden input adatra, billentyűzet- és egéreseményből adódó problémára. Egy webes űrlap esetén, egy macska mindig átfuthat a billentyűzeten. Teljesen váratlanul.

„Semmit sem lehet a kétbalkezesek ellen bebiztosítani, mert a kétbalkezesek rendkívül találékonyak.” Egy tesztelő mindig tud olyan tesztesetet produkálni, amire senki sem gondolt korábban a tervezésnél, megvalósításnál, dokumentálásnál. Bár egy kicsit sántít ez a gondolat, mert egy tesztelő messze nem kétbalkezes, hanem tudatosan csinálja, amit csinál. Legalábbis remélem.

„Ha javulni látod a dolgokat, akkor valami fölött elsiklottál.” Amikor azt érzed, hogy ez a sprint végre most elkészül határidőre, akkor az utolsó napon, órában, percben tutira borul valami.

„Ha egyszer összekutyulódott valami, a kijavítására tett minden kísérlet csak rontani fog rajta.” Pláne, hogy mindenhol, még a jól megtervezett osztálykönyvtárakban is van legalább egy leggyengébb láncszem.

„Amit ember összerakott, előbb-utóbb szétesik.” Amikor azt gondoljuk, hogy egy jó dátumkezelő funkciót kiválóan megterveztünk, rommá teszteltünk, akkor bezzeg nem 3,9 év múlva jön egy szökőév…

„Egy esemény előfordulásának valószínűsége fordítottan arányos bekövetkezésének kívánatosságával.” Azt kár feltételezni, hogy a jogszabályok, végrehajtási rendeletek ritkán változnak. Pedig gyakran építünk sok-sok funkciót ezekre építve szinte bármilyen szoftverben, webáruházban.

„Nyomás alatt a dolgok tovább rosszabbodnak.” Pedig kipróbáltuk az legkritikusabb adatbázis táblát 1000 db tesztadattal, de arra nem számítottunk, hogy élesben napi 500 rekord kerül bele és ugye előbb-utóbb eljön a havi zárás annyi adattal, amire nem készültünk fel. Ugyanilyen, ha nem skálázható webtárhelyen futó WordPress-re irányítunk intenzív marketingkampánnyal sok-sok látogatót és akkor egyszer csak összeomlik a weboldal a váratlan nagy terhelés alatt.

„Ha n számú alkatrészre van szükség, éppen n-1 van raktáron.” Ez – főleg – akkor (is) igaz, ha egy SCRUM csapatban az alkatrészt kollégának tekintjük. Még szűkebb keresztmetszet, hogy legyen releváns tapasztalata is az aktuális problémához és éppen érjen is rá. És persze ne holnap menjen el a konkurenciához/külföldre dolgozni f+1 fizetésért és ne holnapután üsse el a villamos.

„Legjobban azzal ébreszthetsz magadban új gondolatokat, ha leragasztasz egy levelet.” Korszerűsítve és adaptálva a gondolatot: miután lenyomtad a Deploy gombot egy webalkalmazás aktuális változatának publikálásához, akkor biztosan eszedbe jut, hogy mit kellett volna még beletervezni, fejleszteni a szoftver aktuális verziójába. Nem baj, hamarosan kiadjuk majd a következő frissítést is.

Eddig volt 13 bölcsesség. Azzal akartam zárni, hogy a +1-edik bölcsesség elromlott, hiszen biztosan erre is érvényes a Murphy-törvény, de inkább írok még egyet. Még jó, hogy „Murphy optimista volt”. 🙂 Ez a szerencsénk. Mi lenne velünk, ha pesszimista lett volna? 🙂

Programozd a jövőd! – IT a jövőd

A GINOP-3.1.1-VEKOP-15-2016-00001 „Programozd a jövőd!” projekt célja volt, hogy a nemzetgazdasági szempontból egyre jelentősebb informatikai ágazatban minél több diplomás fiatal kezdje meg pályafutását.

Kiemelt feladata volt a munkaerő-kínálat fejlesztése, a felsőoktatási informatikai kompetenciafejlesztés és a képzés támogatása, valamint, hogy a képzési rendszer a gazdasági szereplők igényeinek megfelelő piacképest tudást nyújtson.

Arra került a fókusz, hogy az egyetemi hallgatók megismerhessék az információs-kommunikációs technológiai (IKT) vállalkozások által alkalmazott technológiákat.

A Programozd a jövőd! projekt pillérei

  • I. pillér – Az informatikai oktatás megújítását támogató tudásbázis kialakítása
    Olyan kutatás, felmérés és adatgyűjtés valósult meg, amely lehetővé tette az informatikai munkaerő-piaci igények feltérképezését és a beavatkozások tervezését nemzetközi és hazai jó gyakorlatok feltárásán keresztül.
  • II. pillér – A képző intézmények és a környezetükben működő IKT vállalkozások közötti együttműködések fejlesztése
    Vállalati együttműködések valósultak meg felsőoktatási intézmények bevonásával, amelyek növelték a képzések munkaerő-piaci relevanciáját.
  • III. pillér – Az informatikai szakmák társadalmi-gazdasági elismertségének és népszerűségének növelése
    A középiskolásokat célzó motivációs akciók valósultak meg, amelyek az informatikai szakmák bemutatásán keresztül elősegítették a pályaorientációt a pályaválasztást.
  • IV. pillér – Kommunikációs tevékenységek megvalósítása
    Megvalósultak a projekt tevékenységeit támogató kommunikációs kampányok, amelyek fő célja volt a társadalmi szemléletformálás, a digitalizáció népszerűsítése.
  • V. pillér – IT pályára terelést segítő digitális élményközpontok létrehozása
    Olyan digitális élmény központok kerültek kialakításra, amelyek a diákok, családok számára az IT szakma élményszerű bemutatását szolgálta.

A projekt megvalósulása

A projekt a foglalkoztatás és a gazdaság bővítését kívánta elősegíteni a munkaerő-piaci szempontból releváns informatikai végzettséggel rendelkezők számának növelésével és szaktudásuk minőségének fejlesztésével. Közvetlen célja volt a gazdasági szereplők által meghatározott munkaerő-piaci illeszkedési problémák okait feltáró és kezelő javaslatok kidolgozása és pilot programok lebonyolítása együttműködésben a gazdasági és munkaerő-piaci szereplőkkel, a vállalkozások és a képző intézmények közötti együttműködések fejlesztése, valamint az informatikai szakmák vonzerejének, társadalmi-gazdasági elismertségének növelése.

A KIFÜ, az ITM és az IVSZ voltak a projekt megvalósítói. Célcsoportjaiba az IKT vállalkozások, a felsőoktatási és közoktatási intézmények, az oktatásban érintett szervezetek, illetve az oktatási intézmények tanulói és szüleik tartoztak. 2016 szeptemberben indult és 2023 februárban zárult le a projekt, amely során 21 egyetemmel alakult ki együttműködés, valamint számos kisebb vállalkozással és nagyobb vállalattal is.

Adódott lehetőség Microsoft, Oracle, ULX, SAP tananyagokhoz való hozzáférésre és vizsga voucherekre többféle, elismert MTA és MCP szinten, valamint releváns szakmai gyakorlat megszerzésére is. Az IKT vállalkozások, vagy IKT vállalkozásban dolgozó szakemberek jelezhették részvételi szándékukat vendégoktatásokat szervező cégek felé.

A felsőoktatási intézményeknek lehetőségük volt kiválasztani a vendégoktatás tartására jelentkező személyek/cégek közül a számukra érdekes témában előadó leendő vendégoktatókat.

Az it-tanfolyam.hu részvétele

Az it-tanfolyam.hu oktatói bekapcsolódtak a Programozd a jövőd! projektbe. Ennek keretében:

  • 2 felsőoktatási intézményben vettünk részt a projekt pilot fázisában (2016-2017),
  • 12 vendégelőadást tartottunk 5 felsőoktatási intézményben Java programozás, Ipar 4.0 digitalizáció és mesterséges intelligencia, Funkcionális programozás, Tervezési minták címmel és témakörökben (2017-2022),
  • 47 pályaorientációs előadást tartottunk 34 középiskolában az IT a jövőd! – A Tiéd a pálya! előadás sorozathoz kötődően országszerte (2018-2023),
  • tanfolyamaink hallgatói számára évente offline vagy online rendezvényt szerveztünk, amelyeken sok-sok ismeretterjesztő előadást és laborgyakorlatot tartottunk (2018-2022),
  • tanfolyamaink hallgatóival és gyermekeikkel 6 alkalommal látogattunk meg digitális élményközpontokat (2018-2020),
  • karrierváltó hallgatóink gyermekei 4 alkalommal részt vettek az élményközpontok nyári táborain, ahol mi is tartottunk előadásokat (2019, 2021-2022),
  • mindent precízen dokumentáltunk a projekt követelményeinek megfelelően, valamint
  • oktatóink 14 szakmai vizsgát szereztek (2017, 2019-2021).

Köszönöm oktató kollégáimnak a folyamatos lelkesedést, az állandó tenni akarást és a rendezvényeinken való aktív közreműködést! A koordinációban nyújtott segítséget szerteágazó szakmai kapcsolatainknak köszönhetjük és köszönjük.

Tankocka – Csoportba rendezés: adatbázis-kezelés, fájlkezelés, hálózatkezelés

Tankockák blog bejegyzés sorozat

Folytatjuk Tankockák blog bejegyzés sorozatunkat. A csoportba rendezés feladatban 24 db rövidítést, fogalmat kell a megfelelő csoportba húzni. A 3 csoportot az adatbázis-kezelés, a fájlkezelés és a hálózatkezelés adja.

A fájlkezelés témakör és az adatbázis-kezelés témakör JDBC része a Java SE szoftverfejlesztő tanfolyamunkhoz, az adatbázis-kezelés témakör ORM (objektumrelációs modellezés) része a Java adatbázis-kezelő tanfolyamunkhoz, a hálózatkezelés a Java EE szoftverfejlesztő tanfolyamunkhoz kötődik. Érdemes ismerni ezeket a rövidítéseket, mozaikszavakat, betűszavakat, mert hatékonyan segítik a csoportmunka során szükséges kommunikációt. Többször előfordulhat a feladat megoldása során, hogy nem tűnik egyértelműnek egy-egy kulcsszó, osztály, fogalom, rövidítés. Kizárásos alapon gondolkodva mégis mindig egyértelmű(vé válik) a csoportosítás.