Hóesés szimuláció

Hóesés szimulációt tervezünk és valósítunk meg Java nyelven. A téma igazi örökzöld. Elvileg minden télen aktuális. 😉 A grafikus felülethez és az eseménykezeléshez a swing gyűjteményt használjuk. Adott egy téglalap alakú terület amelyen – méretéhez igazodva – több száz hópehely mocorog. A területet önállóan programoztuk le – azaz ez alkotja a teljes GUI-t –, de lehetne egy nagyobb kép része is. Többféleképpen is beépítünk véletlenszerűséget a szimulációba. Tervezünk is, hiszen az sosem árt. 😉

Többnyire beépített komponenseket, elemeket használunk, de van saját, örökítéssel testre szabott komponensünk is:

  • A szimuláció a Window osztályból példányosított felületen működik, amely JFrame utód. Nem átméretezhető és látható.
  • A területet JPanel típusú pnTransparentWindow alkotja. Mérete 300*200 pixel. Színe a szürke egyik árnyalata. Ezen mozognak a hópelyhek.
  • A hópehely Snowflake típusú JPanel utód. Mérete 2*2 pixel. Színe fehér. Saját swing-es Timer biztosítja az eseménykezelését. A szimulációban 600 hópehely szerepel.

Az elkészült szimuláció

A teljes forráskódból íme a hópehely megvalósítása

A hópehelynek „tudnia kell” hol van, azaz mekkora területen mozoghat, ez a rectangle. A hópehelynek van size mérete. A hópehely saját magát mozgatja a területen a timer segítségével. Az időzítés várakoztatására/késleltetésére vonatkozó delay értéke véletlenszerűen 50, 100, , 250 milliszekundum lehet. Másképpen: a szél által össze-vissza fújt hópelyhek között lehetnek lassabban és gyorsabban mozgók is. Az eseményobjektumhoz lambda kifejezés rendeli hozzá a reakciót jelentő, mozgást megvalósító move() metódus meghívását, amely így adott időközönként bekövetkezik.

A hópelyhet a konstruktora hozza létre. Átveszi azt a pnTransparentWindow területet, amelyre később rákerül a Window példányosítása során. A gyengébb setSize() metódus helyett az erősebb setPreferredSize() metódus állítja be a méretet. Véletlenszerű x és y pozícióba kerül ki/fel a területre. A setBounds() örökölt metódus beállítja a pozícióját és méretét. Erre épít a fogadó oldalon az abszolút helyzet, külön elrendezésmenedzser nélkül. Végül a hópehely átlátszó, fehér és elindítja saját időzítőjét a timer.start() metódushívással.

Az időzítés/várakoztatás véletlenszerűsége után íme a második véletlenszerűség a szimulációban. A hópehely mozgása során a szél által össze-vissza fújva eltérő eséllyel/valószínűséggel mozog 8 lehetséges irányba az alábbiak szerint:

  • 5-5% eséllyel felfelé, azon belül jobbra vagy balra (átlósan),
  • 10-10% eséllyel jobbra vagy balra,
  • 20-20% eséllyel lefelé, azon belül jobbra vagy balra (átlósan),
  • 30% eséllyel lefelé, függőlegesen,
  • felfelé, függőlegesen nem mozog.

Az esélyek összege 100%. Másképpen kulcsszavakban: 1 = biztos esemény (teljes eseménytér, nincs más lehetőség), egymást kizáró események, geometriai valószínűség. A képen középen lévő hópehely a 8 szomszédja közül a 7 szóba jöhető közül valamelyikre adott eséllyel mozog. A geometriai valószínűséget az ábra alapján az óramutató járásával megegyezően leképeztük az 1..100 intervallumra:

A move() metódus megvalósítja a fenti tervnek megfelelően a hópehely mozgatását. Első lépésben tudni kell a jelenlegi/kiinduló location helyét (a bal felső csúcs, elkérjük). Ezután véletlenszerű esély/ tip generálódik. Az első elágazásban a hópehely translate() metódusával eltoljuk az előbb elkért pontot. Az eltolás relatív. Az utolsó elágazásban kompenzálunk, ha a hópehely alul kilépne a területről. Ekkor felül újra belép a területre. Végül beállítjuk a hópelyhet megvalósító komponenst a manipulált location helyre.

Takarékosak vagyunk: ezzel a megoldással „újrahasznosítjuk” a hópelyheket. Csak annyi van belőlük, amennyi szükséges. Nem kell őket folyamatosan megszüntetni és újra létrehozni. Nem mozognak feleslegesen. Nem mozognak olyan területen, ahol nem láthatóak.

Ötletek továbbfejlesztésre

  • A hópelyhek színe lehetne véletlenszerű a fehér és a középszürke között. Ezzel a nézőtől való távolságot, esetleg a kép élességét lehetne modellezni.
  • A szél nem feltétlenül szimmetrikus, vagy a hópelyhek mozgatását meg lehetne oldani jobbra és balra eltérő eséllyel is.
  • A terület lehetne más alakú, például trapéz, íves, kör, ellipszis.
  • Másképpen is vezérelhetnénk a szimulációt. Ahelyett, hogy most minden hópehelynek van saját időzítője, lehetne csak 5 db (lassabbak és gyorsabbak), amelyek közül véletlenszerűen kiválaszthatnánk, hogy melyik hatására mozgatjuk az adott hópelyhet. Fordítva is mehetne: az 5 db időzítőhöz előre hozzárendelhetnénk a hópelyheket. Ez így más-más felelősség, kommunikáció, üzenetküldés, vezérlés lenne az objektumok között. Hasznos tapasztalat lehet megvalósítani bármelyiket.
  • A terület lehetne egy nagyobb kép része. Például meghatározhatnánk egy tetszőleges átlátszóságot (színt vagy arányt) és többrétegű felületet megvalósítani képes JLayeredPane komponens elé vagy mögé is elhelyezhető lehetne a terület a grafikus felületen.
  • Aki kihívást keres: illessze a területet az alábbi hangulatos képre úgy, hogy a középső ablakok téglalap alakúak, a két szélső trapéz alakú vagy perspektivikus nézetű és a kör/ellipszis alakú tükörben pedig tükröződik valahonnan a hóesés látványa.
  • Még bátrabbaknak: a kandallóban lévő tüzet is lehet hasonlóan szimulálni. Itt már többféle fizikai paraméter is figyelembe vehető, például fényerősség, tükröződés. Egy 3D modellezett térben a sugárkövetés (Ray Tracing) algoritmus is megvalósítható. A hópelyheknél lehetne az egyszerű mozgástól eltérő más fizikát is programozni: rugalmas ütközéssel összetapadhatnának vagy rugalmatlan ütközéssel lepattanhatnának egymásról és mindez hathatna a sebességükre 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 szimulációs programot tervezni, kódolni, tesztelni.

Programozási Hét 2019 – CodeWeek.eu

Programozási hét CodeWeek.eu

Programozási hét CodeWeek.euAz Európai Programozási Hét idén 2019. október 5-20-ig került megrendezésre. Ez egy önkéntesek által működtetett, alulról szerveződő kezdeményezés. Az önkéntesek saját országukban a Programozási Hét nagyköveteként népszerűsítik a programozást. Ehhez nyílt és ingyenes eseményeket hirdetnek meg a CodeWeek.eu weboldalon.

A Programozási Hét célja

  • a programozással való alkotás megünneplése,
  • az emberek felvértezése képességekkel,
  • az emberek összekapcsolása,
  • még több ember érdeklődésének felkeltése a tudomány, a technológia, a mérnöki ismeretek és a matematika iránt.

Miért jó ez az érdeklődőknek/résztvevőknek?

  • A programozás szórakoztató!
  • Programozni kreatív tevékenység! Az emberiség a kezdetektől fogva alkot: agyagból, kőből, téglából, papírból vagy fából. Manapság programozással is alkotunk.
  • A programozás felvértez! Sokkal többre is képesek vagyunk annál, hogy csak fogyasszuk a digitális tartalmat; programozással sokféle dolgot alkothatunk, és azokat milliók számára elérhetővé tehetjük. Létrehozhatunk weboldalakat, játékokat, irányíthatunk egy számítógépet vagy egy robotot.
  • Értsük meg a világot! Manapság egyre több minden össze van kapcsolva. Ha némi rálátásunk van arra, hogy mi történik a színfalak mögött, akkor a világot is jobban megérthetjük.
  • A programozás megtanítja nekünk a számítógépes gondolkodást, fejleszti a problémamegoldást, kreativitást, kritikus érvelést, analitikus gondolkodást, valamint csapatmunkára késztet.
  • Manapság a munkahelyek 90%-a digitális készségeket, köztük programozási ismereteket követel a munkavállalóktól.

2015-től veszünk részt az esemény szervezésében, programozást népszerűsítő előadások, laborgyakorlatok meghirdetésével és megtartásával. 2017-ben 50+ országban 1,2 millió érdeklődő résztvevő csatlakozott.

Meghirdetett eseményeink

2019-ban három it-tanfolyam.hu-s eseményt hirdettünk meg Programozási Hét 2019 rendezvényen.
Helyszín: 1056 Budapest, Váci utca 47., 3. emelet 309-es terem, megközelítés
Dátum és időpont: 2019. október 8. 10:00-13:00-ig
Az események ingyenesek voltak, de a részvétel előzetes regisztrációhoz kötött.

Rendezvényünk plakátja

it-tanfolyam.hu - Programozási Hét 2019 CodeWeek.eu plakát

A rendezvény jó hangulatban telt, 47-en látogattak el hozzánk. Idén is volt közöttük emelt szintű informatika érettségire készülő középiskolás csoport informatikatanárával együtt, tanfolyamaink iránt érdeklődő és jelentkezést fontolgató, Java SE szoftverfejlesztő tanfolyamunkat korábban sikeresen teljesítő hallgatók és olyan is, aki tavaly járt nálunk először a Kutatók éjszakája 2018 rendezvényünkön. Az egyszerűbb lottószelvényes előadásnál most is elhangzott számos kérdés és ötlet, az absztraktabb témákhoz már lényegesen kevesebb hozzászólás/kérdés érkezett, de azért előfordult néhány. Igazán tartalmasan telt el idén is ez a három óra. Köszönjük mindenkinek, aki részt vett a Programozási hét 2019 – CodeWeek.eu rendezvényünkön. Az előadások prezentációit tanfolyamaink hallgatói számára – a témához kapcsolódó témakörökhöz, ILIAS-ra feltöltve – tesszük elérhetővé.

10:00-11:00 – Kaczur Sándor: Generáljunk lottószelvényeket és hasonlítsuk össze megoldásainkat!
Véletlenszám-generátorral lottószelvényeket állítunk elő. Többféle ötletet, módszert, algoritmust, adatszerkezetet, tesztelési módszert összehasonlítva vizsgáljuk, hogy melyik a hatékonyabb lépésszámot, memóriaigényt, bonyolultságot tekintve. Java nyelven implementálunk és az érdeklődők javaslatait is azonnal beépíthetjük a forráskódba. A program a Java SE szoftverfejlesztő tanfolyamunk tematikájához kapcsolódik. Előismeretként feltételezünk némi jártasságot programozási alapismeretek, programozási tételek, ciklusok, metódusok, tömbök témakörökből.

11:00-12:00 – Kaczur Sándor: Írjunk hatékony adatbázis-lekérdezéseket!
Az Oracle HR sémában, először tipikus, hétköznapi szavakkal megfogalmazunk néhány lekérdezést, majd SQL nyelven megvalósítjuk és elemezzük, hogy helyesek-e, hatékonyak-e, mit adnak vissza. Szükség esetén optimalizáljuk, testre szabjuk ezeket. Kategóriák: egyszerű, összetett, aggregáló, soktáblás, hierarchikus/rekurzív lekérdezések. Ha lehet, grafikusan is megjelenítjük a lekérdezések eredményeit Java swing felületen, beépített JTable és  JTree komponensekkel, illetve  JFreeChart grafikonnal is. A Java adatbázis-kezelő tanfolyamunk tematikájához kötődik a program. Előismeretként feltételezünk némi jártasságot adatbázis-kezelés, SQL, Java swing felhasználói felület témakörökből.

12:00-13:00 – Kaczur Sándor: Építsünk látványos weboldalt XML fájlból megszerzett adatokból!
XML adatforrásban kapjuk egy cég alkalmazottainak adatait, amelyeket Java programmal feldolgozva, látványosan, animálhatóan megjelenítjük böngészőben az eredményt. Például: ki melyik részlegben dolgozik, kik dolgoznak az egyes részlegekben. Az érdeklődők igénye szerint a feladatot megoldhatjuk a következő technológiák közül választva: JavaScript, Bootstrap, jQuery. A Java EE szoftverfejlesztő tanfolyamunk tematikájához kötődik a program. Előismeretként feltételezünk némi jártasságot Java fájlkezelés, kivételkezelés, adatfeldolgozás, HTML, JavaScript témakörökből.

 

Digitális Témahét 2019

A Digitális Témahét 2016-ban indult országos rendezvénysorozat. Fő célja a digitális pedagógia módszertanának népszerűsítése és elterjesztése. A program fontos törekvése, hogy a digitáliskompetencia-fejlesztés az informatikán túl kiterjedjen más tantárgyakra is. A résztvevő pedagógusok és diákok változatos és kreatív iskolai projektek keretében fejleszthetik képességeiket technológiával támogatott tanulás során. A Digitális Témahét rendezvény minden meghirdetett programja ingyenes.

A 2018/2019-es tanévben a rendezvény április 8-12. között valósul meg. Kiemelt témakörök/szempontok:

  • a multidiszciplináris megközelítés: a matematika, a természet- és mérnöki tudományok, valamint a művészet- és társadalomtudományok együttes megjelenítése;
  • a digitális technológia alkotó használata és az algoritmikus gondolkodás fejlesztése;
  • a kiemelt figyelmet igénylő tanulók fejlesztése és bevonása;
  • a nevelési-oktatási intézmények közötti együttműködés élénkítése;
  • a határon túli magyar pedagógusok és oktatási intézmények bevonása;
  • ebben a tanévben is a digitális gyermekvédelem, a médiatudatosság, a közgyűjtemények digitális tartalmainak nevelésben, oktatásban történő megjelenése.

Az it-tanfolyam.hu 2019-ben is csatlakozott a rendezvénysorozathoz. Meghirdettünk hat programot a https://digitalistemahet.hu weblapon. A programjainkra 2019. április 6-án 9:00-12:00 óráig kerül sor.

Rendezvényünk plakátja

Ízelítő a meghirdetett programból

Bemutatjuk, hogy lottószelvények előállítása során nem mindig mehetünk biztosra. A problémák szintje különböző:

  • elemi probléma: egyetlen 1 és 90 közötti egész véletlenszám előállítása,
  • lokális léptékű probléma: egyetlen ötöslottó-szelvény előállítása, azaz 5 db különböző 1 és 90 közötti egész véletlenszám előállítása,
  • globális léptékű probléma: sok különböző ötöslottó-szelvény előállítása.

Sok olyan algoritmust és implementált Java programot ismerünk, oktatunk, amelyek biztosra mennek. Másképpen: képesek érvényes szelvényt generálni. Kísérletet végzünk, mi történik, ha nem megyünk mindig biztosra. Például, mi történik, ha a lokális léptéknél nem figyelünk a véletlenszámok különbözőségére. Generálunk 1000 számsorozatot, és kiválogatjuk a pozitív teszteseteket, azaz ezek közül azokat a számsorozatokat, amelyek érvényes lottószelvények. Megkapjuk, hogy 89% körül ingadozik a helyes és 11% körül pedig a hibás tesztesetek aránya.

Átgondoljuk, miket tehetünk, ha egy ilyen nem tökéletes, nem biztosra menő implementált algoritmus köré kell építeni olyan környezetet, hogy szükség esetén vissza tudjunk kapni előre megadott számú érvényes lottószelvényt. Vajon hogyan alakul a 89-11 arány a hatoslottó, heteslottó esetén? Ki fog derülni. Például, mi történne, ha sok gépi szelvénnyel játszunk és van közöttük két azonos nyertes szelvény? Gondot jelent ez? Meg kell oldani, hogy ez ne forduljon elő? Ha igen, hogyan? Ha nem, miért nem? Ez is ki fog derülni.

Köszönöm oktató kollégáimnak, hogy örömmel csatlakoztak szakmai előadással, interaktív kódoló-tesztelő foglalkozással, gamifikációs elemekkel. Biztosan jól fogjuk érezni magunkat. Bízom abban, hogy jó hangulatú, valódi szakmai párbeszéd alakul majd ki a jelenlévők és köztünk a rendezvényünkön. Várjuk a jelentkezőket, hogy Java programozáshoz kötődően együtt töltsünk egy izgalmas szombat délelőttöt. A részvétel ingyenes, de előzetes regisztrációhoz kötött.

Stream API lambda kifejezésekkel

lambda kifejezés logo

lambda kifejezés logoKorábban blogoltunk már a Stream API-ról és a lambda kifejezésekről: Ismerkedjünk lambda kifejezésekkel! Most másképpen közelítve újra foglalkozunk a témával.

Tanfolyamainkon szinte minden adatszerkezethez, tömbhöz, kollekcióhoz, fájlkezeléshez kötődő témakörben használjuk mindkettőt. Áttekintjük az ezekhez szükséges minimális verziószámot, a szintaktika fejlődését, az együttes használat elvi és gyakorlati lehetőségeit. A szükséges alapfogalmakat definiáljuk: hozzárendelési szabály, funkcionális interfész, metódus referencia, alapértelmezett metódusok, típus kikövetkeztetés képessége, generikus és funkcionális programozás. párhuzamos adatfeldolgozás lehetőségei.

Összehasonlításokat is végzünk: a lambda előtti verziók lehetőségei, korlátai, tipikus lambda hibák, mikor mit érdemes és mit nem érdemes használni, paraméterek típusait megadjuk vagy elhagyjuk, hagyományos kollekciós műveletek (azért a generikusság előtti időkre már nem térünk ki) és folyam feldolgozás (adatforrás meghatározása, közbenső és végső műveletek).

Most azokat a Stream API-hoz és lambda kifejezésekhez kötődő bevezető mintapéldákat ismertetjük, amiket részletesen elemzünk tanfolyamaink szakmai moduljának kontakt óráin. Ezek közül közösen meg is írunk néhányat, kombinálunk is néhányat egy-egy összetett adatfeldolgozó művelet megvalósítása során. Programozási tételenként specifikáljuk a feladatokat és megmutatunk néhány megoldást.

1. Adatforrás

100 db olyan véletlen kétjegyű számot állítunk elő generikus listában, amelyek között biztosan előfordul legalább egyszer a 80.

2. Elemi programozási tételek

2.1. Sorozatszámítás

Kiírjuk, hogy mennyi a listában lévő számok összege:

2.2. Eldöntés

Két kérdésre adunk választ. Van-e a listában lévő számok között 35 (konkrét elem), illetve páros (adott tulajdonságú elem)?

2.3. Kiválasztás

Kiírjuk, hogy a biztosan előforduló (legalább 1 db közül balról az első) 80, hányadik helyen (index) található meg:

2.4. Keresés

Keressük a 35-öt az eldöntés és a kiválasztás összeépítésével:

2.5. Megszámolás

Kiírjuk, hogy hány db öttel osztható szám (adott tulajdonságú elem) található a listában:

2.6. Szélsőérték-kiválasztás

Kiírjuk a listában lévő legkisebb számot (értéket, nem indexet):

3. Összetett programozási tételek

3.1. Másolás

Készítünk egy másolatot a lista elemeiről (közben esetleg mindegyiket meg is változtathatjuk):

3.2. Kiválogatás

A listában lévő számok közül kiválogatjuk az öttel osztható számokat:

3.3. Szétválogatás

Külön-külön szétválogatjuk a listában lévő páros és páratlan számokat:

3.4. Unió

A korábban szétválogatott páros és páratlan számokat tartalmazó halmazok unióját állítjuk elő:

3.5. Metszet

A korábban szétválogatott páros és páratlan számokat tartalmazó halmazok metszetét állítjuk elő:

3.6. Összefésülés

A korábban szétválogatott páros és páratlan számokat összefésüljük:

4. A program eredménye a konzolon

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, a Java EE szoftverfejlesztő tanfolyam és a Java adatbázis-kezelő tanfolyam szakmai moduljának több alkalmához és az orientáló moduljának 1-4. óra: Programozási tételek alkalmához is kötődik. A Stream API-val és a lambda kifejezésekkel sokszor foglalkozunk.

Korábban is blogoltunk már a Stream API-ról és a lambda kifejezésekről: Ismerkedjünk lambda kifejezésekkel!

Barátságos számok

Barátságos számok

Barátságos számokAzokat a számpárokat, amelyekre igaz, hogy az egyik szám önmagánál kisebb osztóinak összege megegyezik a másik számmal és fordítva, külön-külön barátságos számoknak, együtt barátságos számpárnak hívjuk.

Másképpen: legyen d(n) az n természetes szám önmagánál kisebb osztóinak összege. Ha d(a)=b és d(b)=a, ahol ab, akkor a és b barátságos számpár.

Például: (220; 284), hiszen a 220 önmagánál kisebb osztói: 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 és ezek összege 284, illetve 284 önmagánál kisebb osztói: 1, 2, 4, 71, 142 és ezek összege 220.

Írjunk Java programot, amely kiírja az 1-10000 zárt intervallumban található barátságos számpárokat!

1. megoldás

A baratsagosSzamparok1() eljárás ciklusai a brute force módszer szerint behelyesítik az összes lehetséges számot. Minimális lépésszám csökkentésre adódik lehetőség, hiszen a belső ciklus j változója i+1-ről indítható (így a megtalált számpárok nem íródnak ki fordítva is, mert teljesül, hogy i<j).

Az osztokOsszege1(n) függvény is minden lehetséges osztót figyelembe vesz 1-től n-1-ig.

2. megoldás

Kisebb módosításokkal a lépésszám csökkenthető. A baratsagosSzamparok2() eljárás külső ciklusánál figyelembe vettem, hogy a legkisebb barátságos számpár kisebb tagja nagyobb 200-nál. Mivel a barátságos számpárok tagjainak paritása mindig megegyezik (azaz mindkettő páros vagy mindkettő páratlan), így a belső ciklus j változója indítható i+2-ről és léptethető kettesével ( j+=2), és továbbra is teljesül, hogy i<j.

Az osztokOsszege2(n) függvényt is módosítottam. Mivel az 1 minden számnak osztója, illetve a 2 minden páros számnak osztója, így s lehet 3 vagy 1 és a ciklus indítható 3-ról. A páros számok esetén a számnál kisebb legnagyobb osztó maximum n/2 lehet, illetve ugyanez páratlan számok esetén n/3 lehet. Ezekre figyelve a max változó adja a ciklus léptetésének felső határát. Az i változó léptetésénél figyelembe vettem, hogy páratlan számnak csak páratlan osztói lehetnek ( i=3-mal szinkronban).

3. megoldás

Az eddigi két egymásba ágyazott ciklus helyett átszervezhető a baratsagosSzamparok3() eljárás. A j>i && osztokOsszege2(j)==i feltétel kiértékelése így sokkal hatékonyabb.

Vajon milyen nagyságrendű különbségek adódnak, ha összehasonlítjuk a három megoldás futási idejét?

Az 1. megoldás futási ideje 1104156 ms, a 2. megoldásé 257055 ms, a 3. megoldásé 121 ms. A konkrét értékek helyett a nagyságrendet megfigyelve a különbség nagyon látványos.

Mindhárom megoldás helyes és megkapjuk az intervallumban található öt barátságos számpárt: (220; 284), (1184; 1210), (2620; 2924), (5020; 5564), (6232; 6368).

A bejegyzéshez tartozó teljes – időméréssel kiegészített – forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.

Források:

A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 9-12. óra: Metódusok, rekurzió alkalomhoz kötődik.