A Pi grafikus ábrázolása

A nemzetközi Pi nap alkalmából (március 14) Java programmal grafikusan ábrázoljuk a π számjegyeit. Kiindulunk egy négyzet alakú grafikus felület középpontjából. Ezt tekintjük origónak. Sorra vesszük a π első néhány számjegyét: 100, 1000, 10000 paraméterezhető módon. Minden számjegyet egy rövid szakasszal ábrázolunk. A szakaszok egymást követik. Az előző végpontja megegyezik a következő kezdőpontjával. A rajzolás elejét és végét kör jelzi.

Tervezés

Az alábbi szabály alapján döntjük el, hogy a π előforduló számjegyei esetén melyik irányba és milyen színnel rajzolunk szakaszt:

A π első 100000 db számjegyét tároljuk egy szövegfájlban. Ömlesztve, sortörés, tizedesvessző nélkül. Így a π első 30 számjegye: 314159265358979323846264338327. A szövegfájl helyét a String PI_FILE  konstans jegyzi meg. A paraméternek megfelelően ebből vesszük az első N db számjegyet. Ezt a Java program beolvassa egy String típusú pi szövegobjektumba. A számjegyek összetartozó adatait egy Digit osztály rendeli egymáshoz. Ennek három adattagja van: melyik számjegy: int digit, melyik irányba kell szakaszt rajzolni java.awt.Point direction, milyen színnel kell szakaszt rajzolni java.awt.Color color. A tízféle színt egy konstans tömb tárolja: Color[] COLORS.

Részletek a Java forráskódból

A π tízféle számjegyéből az alábbi forráskód-részlettel létrejön egy tömb adatszerkezet: Digit[] digits. A koordináták/vektorok kiszámítása követi az analóg óra számlapjának 36 fokonként való felosztását.

A rajzoláshoz szükséges még néhány konstans: milyen vastag vonalat kell rajzolni: double PEN_RADIUS, mekkora átmérőjű kör jelzi a rajzolás kezdő- és végpontját: double POINT_RADIUS, milyen hosszú vonalat kell rajzolni: int LINE_LENGTH, a rajzterületet mekkorára kell méretezni/skálázni: int SCALE.

Mindezek alapján az alábbi forráskód-részlet vizualizálja a π számjegyeit:

Eredmény

Eredményül ezek az ábrák készíthetők el:

A rajzoláshoz felhasználtuk az StdDraw osztályt, amely ennek a tankönyvnek a példatárából származik: Robert Sedgewick, Kevin Wayne: Computer Science: An Interdisciplinary Approach, 1st edition, Princeton University, Addison-Wesley Professional, 2016, ISBN 978-0134076423. Az osztály metódusaival könnyen beállítható a nézőpont, a vízszintes/függőleges skála, a rajzoláshoz használt toll mérete/színe és a grafikai primitívek közül csak a kör és szakasz ábrázolása szükséges.

Korábban is megemlékeztünk néhány közelítő algoritmus – Viète-féle sor, Leibniz-féle sor, Wallis-formula, Csebisev-sor – implementálásával erről az ünnepnapról: Nemzetközi Pi nap. Ajánljuk korábbi blog bejegyzéseinket rajzolás, animáció, grafika címkékkel, illetve ASCII művészet Java-ban.

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 5-8. óra: Vezérlési szerkezetek, 13-16. óra: Tömbök, 17-28. óra: Objektumorientált programozás, 29-36. óra: Grafikus felhasználói felület, 37-44. óra: Fájlkezelés alkalmaihoz kötődik.

Szívgörbe ábrázolása

Szívgörbét ábrázolunk Java programmal. A Valentin-nap inspirálta ezt a feladatot. Számos matematikai görbe ismert, amelyek szívformához (kardioid) hasonlítanak. Szükséges egy megfelelő paraméteres görbe. A függvény szív formájú ábrája/grafikonja és egyenletrendszere alapján is nagy a választék.

Ábrázoljuk ezt a paraméteres szívgörbét Java swing GUI felületen!

A szívgörbe ábrázolásához felhasználom az StdDraw osztályt, amely ennek a tankönyvnek a példatárából származik: Robert Sedgewick, Kevin Wayne: Computer Science: An Interdisciplinary Approach, 1st edition, Princeton University, Addison-Wesley Professional, 2016, ISBN 978-0134076423. Az osztály metódusaival könnyen beállítható a nézőpont, a vízszintes/függőleges skála, a rajzoláshoz használt toll mérete/színe és a grafikai primitívek közül csak a pont ábrázolása szükséges.

Négy megoldást mutatok. Mindegyik azonos szívgörbét rajzol a fenti egyenletrendszer alapján. Mindegyik metódus átveszi az N paramétert, amely az összetartozó x és y koordinátapárok számát jelenti. Az N db pont meghatározása/kiszámolása szükséges a szívgörbe ábrázolásához. A szívgörbe ábrázolása önálló ablakban – grafikus felhasználói felületen – jelenik meg. A feladat matematikai jellegéből adódik, hogy tipikus a t nevű ciklusváltozó használata. A metódusokat a vezérlés az 512 paraméterrel hívja meg.

1. megoldás

A heartCurveDraw1() metódus a kiszámolt x és y koordinátákat két párhuzamos, double típusú tömb adatszerkezetben tárolja. A két tömbbe összesen 2*N db double típusú szám kerül. Azonos index jelöli az összetartozó koordinátapárokat. Az egymást követő két ciklus közül az első előállítja az adatszerkezetet és a második megjeleníti a pontokat.

2. megoldás

A heartCurveDraw2() metódus a párhuzamos tömbök helyett adatszerkezetként egyetlen tömböt használ. A java.awt.geom csomag Point2D osztályú objektumai kerülnek a tömbbe. Mivel a Point2D absztrakt osztály, így a Double() osztálymetódusával (factory method) példányosítható úgy, hogy a szükséges koordinátapárokat megfelelően tudja tárolni. A tömbbe N db objektum kerül.

3. megoldás

A heartCurveDraw3() metódus nem használ tömb adatszerkezetet. Tehát nem emlékszik az összes pont koordinátájára. Ehelyett a ciklus röptében, egyesével létrehozza a pontobjektumokat és azonnal ki is rajzolja azokat (átmeneti az emlékezet).

4. megoldás

A heartCurveDraw4() metódus Stream API-t és lambda kifejezéseket használ. Az első N természetes számból készül egy sorozat, amihez röptében hozzákötődik a t-edik Point2D típusú objektum. Ezzel létrejön egy folyam adatszerkezet. Tehát van egy pillanat, amíg a program emlékszik az összes folyambeli pontobjektumra. Végül a folyam feldolgozása, bejárása során egyesével megszólítva a folyam objektumait, a pontok kirajzolódnak a vászonra.

A vezérlés

Az eredmény

A szívgörbe önálló – swing, grafikus felhasználói felület, GUI – ablakban így jelenik meg:

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 matematikai háttértől eltekintve – a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 21-24. óra: Objektumorientált programozás 2. rész, valamint a 29-36. Grafikus felhasználói felület alkalmaihoz kötődik.

A 2D szívforma egyenletrendszerét erről a weboldalról választottam: Heart Curve – from Wolfram MathWorld. Egy merész továbbfejlesztési ötlet: a haladóknak megtalálható a 3D szívforma ábrázolása is: Heart Surface – from Wolfram MathWorld.

Sándor is blogolt már a Valentin-nap témában: Rómeó és Júlia. Ebből kiderül, hogy vajon ki szereti jobban a másikat: Rómeó vagy Júlia.

Nemzeti pizza nap

Az USA-ban és még néhány országban február 9-én ünneplik a nemzeti pizza napot. Ehhez kötődően kreatív ötletekkel és persze finom pizzákkal vonzzák az éttermek a vendégeket.

Kreatív ötletekkel a mi oktatói csapatunk is rendelkezik. A nemzeti pizza nap inspirált bennünket az alábbi feladat megoldására.

Osszunk szét igazságosan 9 db egyforma pizzát 10 fő között!

Az igazságost úgy értelmezzük, hogy mindenkinek ugyanannyi (ugyanakkora szelet) pizza jut. Két megoldást mutatunk be grafikusan. Ötleteket adunk ahhoz, hogyan programozható le mindez Java nyelven: swing grafikus felületen, grafikai primitívekkel vagy ismert algoritmusokkal. Ábrákkal mutatjuk be a megoldásokat, színekkel kiemelve az azonos/különböző méretű pizzaszeleteket.

1. megoldás

Mind a 9 db pizzából vágjunk ki egytized méretű szeletet. Marad 9 db kilenctized méretű pizzaszelet és a 9 db egytizedből összeállítható a 10. főnek járó szintén kilenctized méretű pizzaszelet/adag.

2. megoldás

A 9 db pizzából 5 db pizzát vágjunk ketté. Keletkezik 10 db fél pizza. A maradék 4 db pizzát harmadoljunk fel. Keletkezik 12 db egyharmad pizza. A keletkező 2 db egyharmad pizzát osszuk fel 5-5 részre. Keletkezik 10 db egytizenötöd méretű pizzaszelet. Az egyharmad ötödrésze adja az egytizenötöd részt. A 10 főnek járó adaghoz rakjuk össze a 30 db részből a különbözőket: egy adag kilenctized, ami egy fél és egy harmad és egy tizenötöd részből áll össze. Másképpen: 9/10 = 27/30 = 15/30 + 10/30 + 2/30.

Ötletek a Java nyelvű megvalósításhoz

  • A JFrame osztályból származtatott ablak utódosztály tartalompaneljére ráhelyezhető egy öröklődés útján testre szabott JPanel utódosztályból létrehozott objektum. Ennek van grafikus vászna ( Graphics objektum), amely saját koordináta-rendszerrel és pixelszintű hozzáféréssel rendelkezik. Rendelkezésre áll számos grafikai primitív rajzolására használható metódus, például vonal/szakasz, téglalap, ellipszis. A grafikai primitíveknek rajzolható adott színű körvonala és lehetnek adott színnel kitöltöttek is. Például: drawArc(x, y, width, height, startAngle, arcAngle), vagy az azonos paraméterezésű fillArc(...) metódus. A két szög értelmezése: a startAngle az analóg órán a 3 óra irányába néz, valamint az arcAngle pozitív szög fokban megadva az óramutató járásával ellenkező irányba mutat.
  • A beépített grafikus primitívek helyett használhatunk klasszikus algoritmusokat is. Például a Bresenham vonalrajzoló algoritmus, vagy ennek általánosítása a Bresenham körrajzoló (felezőpont) algoritmus. Ezekhez hasznos némi koordináta-geometria és többféle koordináta-rendszer ismerete.

Ötletek továbbfejlesztéshez

  • Megpróbálhatjuk általánosítani a problémát: osszunk szét igazságosan n db egyforma pizzát n+1 fő között!
  • A statikus képek előállítását követően időzítéssel ellátott animációt is készíthetünk, amely megfelelően mozgatja, forgatja a pizzaszeleteket. Így fázisonként megmutathatók a feladat megoldásának lépései. Ehhez többrétegű vászontechnika szükséges, amelyen könnyen mozgatható a nézőhöz közelebbi réteg úgy, hogy a háttér nem változik meg.
  • A saját rajzolt elemek időzítővel – javax.swing.Timer – történő mozgatására példáink java.swing-ben: Hóesés szimuláció és Naprendszer szimuláció – megvalósítás Java nyelven.
  • A saját rajzolt elemek kézi – eseménykezelővel megvalósított – mozgatásához felhasználható példánk JavaFX-ben: Kígyókocka grafikus felületen.
  • A fázisokból lépésenként vezérelhetően felépülő ábrák elkészítéséhez példáink: Fibonacci-spirál és Koch-görbe rajzolása.

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 matematikai háttértől eltekintve – a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 21-24. óra: Objektumorientált programozás 2. rész, valamint a 29-36. Grafikus felhasználói felület alkalmaihoz kötődik.

Rácsrejtjelezés

Időnként készítünk oktatóprogramokat is tanfolyamainkon. Most az volt a cél, hogy kódolás/dekódolás szakterület egyik ismert betűkeveréses algoritmusának működését mutassa be lépésről-lépésre az oktatóprogram. A rácsrejtjelezést választottuk.

Az elkészült program Java swing-es felületű és Windows Classic look-and-feel bőrrel így néz ki működés közben:

A rácsrejtjelezés a képernyőképen látható 4×4-es Kódrács használatán alapul.

A titkosítandó szöveget karakterenként beleírjuk az aktuális kódrácsba soronként lefelé, azon belül balról jobbra haladva. Ha a négy pozíció betelt, akkor el kell fordítani a kódrácsot az óramutató járásával megegyező irányban 90 fokkal. Ha a szöveg hosszabb 16 karakternél, akkor elölről kell kezdeni. Ha készen vagyunk, akkor soronként haladva leírjuk egymás után a kódrácsban található karaktereket.

A megfejtéshez ismernünk kell a titkosított karaktersorozaton kívül a felhasznált kódrácsot is. A karaktersorozatot soronként lefelé haladva beírjuk a kódrácsba, az ismert kódrácsot ráhelyezve soronként lefelé, azon belül balról jobbra haladva kiolvashatjuk a megfejtést. Természetesen a kódrácsot most is forgatni kell minden negyedik karakter után.

Megfigyelhető, hogy bármely karaktert tudunk titkosítani és megfejteni. Ezért a rácsrejtjelezés ebből a szempontból univerzális módszer.

A kódrács ismerete nélkül a titkosított szöveg nem fejthető meg, tartalmára csak nehézkes következtetést adhatunk. Például, ha tudjuk, hogy milyen nyelvű a titkosított szöveg, akkor támpontot adhat a megfejtéséhez a nyelv ábécéjében előforduló betűk ismert gyakorisága.

A képernyőkép éppen a megfejtés egyik pillanatában készült. A feladó továbbította a titkosított szöveget és a kódrácsot a címzettnek, aki elkezdte annak megfejtését. A negyedik karakter a b volt, utoljára erre kattintott a (4;4) pozícióban. Ezt követte egy rácsforgatás, amelyhez tartozik egy ablak, amely megjeleníti a „Rácsforgatás következik.” szöveget. Ezután a kódrács elfordult, és a következő cella a második sor első cellája lesz. Ha hibás cellára, pozícióra kattintunk, akkor a következő hibaüzeneteket kaphatjuk: „Hibáztál! Folytathatod a titkosítást.” vagy „Hibáztál! Folytathatod a megfejtést.” Ha befejeztük a titkosítást, vagy a megfejtést, akkor a következő üzeneteket kaphatjuk: „A kódolás sikerült.” vagy „A megfejtés sikerült.”

A program tartalmaz egy gyakorlást támogatandó szövegkészletet. Ennek minden eleme 16 hosszúságú, az egyszerűség kedvéért – így nem kell véletlenszerű karakterekkel feltölteni a rács kimaradt celláit, illetve nem kell 16-os csoportokkal foglalkozni.

A Titkosítás és megfejtés fülön látható egy véletlenszerűen kiválasztott szöveg, amelyet karakterenként kódolni lehet a kódrács megfelelő cellájára kattintva. Ha kész, a Továbbítás gombbal a feladó elküldi a címzettnek a titkosított karaktersorozatot, aki hasonlóan megfejti. „Útközben” megfigyelhető, hogy éppen hányadik elforgatásnál tartunk és természetesen megjelenik az aktuális ráccsal titkosított szöveg is.

Az űrlapon lévő Kódrács csoportablak az aktuálisan, véletlenszerűen legenerált kódrácson kívül a kiválasztott cellák pozícióit is tartalmazza. Az (1;1) pozícióban a bal felső cella található. A kódrács a Másik nyomógombbal véletlenszerűen újragenerálható. Ennek megvalósításakor több probléma, ötlet is felmerülhet. Például használható visszalépéses keresés algoritmus.

Most nem specifikáljuk részletesebben, például objektumorientált tervezés, eseménykezelés, háttérbeli objektumok vagy GUI komponensek működésének/vezérlésének szintjén. Aki kedvet kapott és úgy érzi, hogy meg tudja ugrani ezt a kihívást, akkor bátran elkészítheti. Hajrá! Mivel oktatóprogram, szükséges hozzá Leírás és Teszt is.

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 oktatóprogramot tervezni, kódolni, tesztelni.

Doktoranduszok programoznak – újratöltve

it-tanfolyam.hu doktoranduszok programoznak

it-tanfolyam.hu doktoranduszok programoznakSaját doktorandusz csoporttársaimmal én is többször beszélgettem már arról – ahogyan Sándor is tette 2018-ban –, hogyan tudnák/tudják használni a programozás eszköztárát, módszereit, lehetőségeit saját kutatási munkájukban, beépítve a kutatási folyamat egyes lépéseibe, illetve disszertációjuk elkészítésébe.

A 7 fős csoportban mindenkinek más az alapvégzettsége, így szoftverfejlesztéshez, programozáshoz közös szókincs és terminológia haladó szinten természetesen nincs, viszont közös bennünk, hogy mindannyian alkotunk különféle modelleket és elemzünk adatokat. A csoport teljesen inhomogén, több szempontból is: ki melyik évfolyamot végzi, hol tart a kutatómunkájában, vannak-e ipari kapcsolatai, nappali vagy levelező képzésben végzi tanulmányait és persze ki mikor ér rá.

Különféle modelleket alkotunk

  • a mérnökök, fizikusok, geográfusok, biológusok többféle kísérletet végeznek el, szimulációkat terveznek és futtatnak, mérőeszközöket és műszereket használnak,
  • az informatikusok különböző matematikai eszközöket alkalmazva objektumorientált – vagy másféle – modellezést végeznek, szoftvereket terveznek, javítanak, újraírnak.

Adatokat is elemzünk, ki-ki előképzettségének megfelelően

  • kérdőívező szoftverekből exportálva valamit,
  • Excel munkalapokon, függvényekkel, adatbázis-kezelő funkciókkal, kimutatásokkal (Pivot táblák),
  • különböző fájlformátumokkal (CSV, XML, JSON, egyedi) dolgozunk és konvertálunk A-ból B-be,
  • távoli adatbázisokhoz, felhőbeli adattárházakhoz csatlakozunk, lekérdezünk és kapunk valamilyen – többnyire szabványos – adathalmazt,
  • matematikai, statisztikai szoftvereket használunk, például: MATLAB, Derive, Maple, SPSS.

Az öt évvel ezelőtti tematikát újragondoltuk. Kérdőívben felmértük a csoporttársak koncepcionális és konkrét igényeit. Más doktori iskolák hallgatói közül is toboroztunk. Ehhez kötődően köszönjük a DOSZ segítségét. Ezek alapján összeállítottunk egy olyan 3 részből álló tematikát, ami mindannyiunk számára hasznos. A 72 óra három 24 órás modulból áll: Java programozás, MATLAB programrendszer, mesterséges intelligencia.

Java programozás modul

  • 1-6. óra: Objektumorientált modellezés, MVC rétegek, algoritmus- és eseményvezérelt programozás
  • 7-12. óra: Fájlkezelés és szövegfeldolgozás (XLS, CSV, XML, JSON formátumú adatok írása, olvasása, feldolgozása), helyi és távoli adatforrásból
  • 13-18. óra: Adatbázis-kezelés JDBC alapon (SQL parancsok, CRUD műveletek, hierarchikus lekérdezések), helyi és távoli adatforrásból, natív módon és készen kapott API-kkal
  • 19-24. óra: Komplex adatfeldolgozási feladatok megoldása programozási tételek használatával, egyszerű statisztikai funkciók implementálásával

MATLAB programrendszer modul

  • 1-6. óra: Bevezetés az MATLAB nyelvbe (R2012 vs. R2022), utasításkészlet, vektorok, mátrixok, szkriptek, függvények, grafika
  • 7-12. óra: Szimulációk tervezése és készítése, numerikus módszerek áttekintése, algoritmizálása, tesztelés, analitikus megoldás, egyenletek megoldása
  • 13-18. óra: Adatok importálása helyi és távoli adatforrásból is, fájlkezelés: szövegfájlok, Excel-fájlok, import, feldolgozás, export, statisztikai alapok
  • 19-24. óra: Statisztikai próbák (illeszkedés- és függetlenség vizsgálata), hisztogramok készítése, differenciálegyenletek megoldása

Mesterséges intelligencia modul

  • 1-6. óra: Klasszikus és újabb megközelítések, alap AI funkcionalitás, megerősítéses és gépi tanulás lehetőségei és korlátai, OpenAI GPT nyelvi modell
  • 7-12. óra: Általános csevegés lehetőségei, korlátai, hasznos tanácsok; csevegés fájlok (szöveg, multimédia) tartalmáról; generatív AI funkciói; kép, ábra, grafikon, térkép, hang, animáció, videó generálása és ezek tömeges feldolgozása; programozási tételek alkalmazása multimédia analitikával együtt
  • 13-18. óra: Statisztikai adatok elemzése AI eszközökkel, automatikus tételbizonyítás AI eszközökkel, gráfelméleti kérdések kontra AI, hatékonysághoz kötődő kérdések AI eszközök esetén
  • 19-24. óra: Objektum- és aspektusorientált tervezés AI eszközökkel, kutatómunkát támogató AI eszközök

Mivel mindenki doktorandusz a csoportban, így a különböző MSc-s alapvégzettsége ellenére mindannyiunknak vannak strukturális programozáshoz kötődő alapismeretei, valamint adatok elemzéséhez szükséges elméleti matematikai/statisztikai alapjai.

A csoport órái szeptembertől decemberig, szombatonként zajlottak. Sándor tartotta a 24 órás Java programozás modult. Ez nagyban lefedi a Java SE szoftverfejlesztő tanfolyamunk tematikáját és kapcsolódik a Java EE szoftverfejlesztő tanfolyamunk és a Java adatbázis-kezelő tanfolyamunk tematikájához is. Én tartottam a 24 órás MATLAB programrendszer modult. Ketten közösen tartottuk a 24 órás Mesterséges intelligencia modult. Igazán tartalmas őszi időszakot jelentett számunkra ez a 12 szombat. Mindenki elvitte, amit beletett.

A koncepciót once-in-a-lifetime jelleggel dolgoztuk ki 🙂 (újratöltve) azzal a fő szándékkal, hogy hatékonyabban működjünk együtt a jövőben. A visszajelzések alapján bátran állíthatom, hogy ez gördülékenyen fog menni. Egyben köszönöm mindenkinek az aktív, konstruktív részvételt.