2014. szeptember 17., szerda

Lottószimulátor - Futtató program

Most hogy készen van a Szelveny osztály, teszteljük azt. Ehhez kell egy úgynevezett tesztelő vagy futtató program. Nézzük meg hogy miért is van ez.

A Java tisztán objektum-orientált nyelv. Ez azt jelenti hogy minden objektum a programban. Az objektumok valamilyen osztály egy-egy példánya, mely a példányosítás során jön létre. Az egyes objektumpéldányok létrehozása kostruktorral történik. Ha nem definiálunk konstruktort akkor is létezik az osztály nevével azonos nevű metódus. Ennek fő feladata a memóriafoglalás és az objektum kezdeti állapotának beállítása. A Szelvény osztálynak két konstruktort definiáltunk. Egy paraméterezettet és egy paraméter nélkülit. A példányosítás után az objektumnak a publikus metódusain keresztül üzeneteket tudunk küldeni, illetve a publikus adattagok közvetlenül elérhetők (ezt én kerülendőnek tartom még akkor is ha triviális lenne a megoldás).

Minden osztályt külön forrásfájlban (.java kiterjesztésű fájl) kell definiálni. A forrásfájl nevének meg kell egyezni az osztály nevével. Így lett a Szelveny osztályunk a Szelveny.java fájlba definiálva.

Amikor egy osztályt a virtuális gépbe betöltünk akkor a JVM megpróbálja elindítani az osztály main() metódusát. Ha ilyet talál akkor elindul a metódus. Így indíthatók a programok.

Hozzunk létre most egy LottoTest osztályt, amibe létrehozzuk a main() metódust. Ennek is szabályai vannak, az alábbi kötött formában kell definiálni a main()-t.

  1. public class LottoTest {
  2.    public static void main(String[] args){
  3.      //létrehozunk két szelvényt
  4.      //sz1 automatikusan generált 5 számot fog tartalmazni
  5.      Szelveny sz1 = new Szelveny();
  6.      
  7.      //sz2 a paramétrelistájában megadott öt számot tartalmazza
  8.      Szelveny sz2 = new Szelveny(19,71,8,16,7);
  9.  
  10.    }
  11. }

Ezzel létrehoztunk két objektumot, melyek tartalmaznak tippeket. Ezeket a tippeket írassuk most ki!
Rá kell jönnünk hogy a szelvény osztályban nem készítettünk metódust a kiíratásra, az adattag ami a tippeket tartalmazza az pedig private (nagyon helyesen), amihez ugyebár az objektumon kívülről nem lehet hozzáférni. Készítenünk kell hát valamilyen metódust ami kiíratja, vagy visszaadja a tippeket.
A Java-ban szokás definiálni egy toString() metódust. Ez kvázi szabvány. A metódus visszaad egy String típusú értéket mely tartalmazza azt a szöveget, amit az objektum adatairól  tartalmaz információt. Most ezt fogjuk megadni. Egyébként a számok tárolására használt TreeSet konténernek is van "gyári" toString() metódusa, amit fel is használunk.
Természetesen a Szelveny.java fájlt kell kiegészíteni a következő sorokkal:

  1. public String toString(){
  2.    // a TreeSet objektum toString() metódusát úgy írták meg hogy
  3.    // [] jelek között, vesszővel elválasztva felsorolja
  4.    // növekvő sorrendben az elemeit. Ez nekünk teljesen megfelel!
  5.  
  6.    return "Szelvény száma: "+szelvenyId+" Tippek: " + tippek.toString();
  7. }

Ezek után már a tesztelő osztályunkban a példányosítások után használhatjuk is a szelvények toString()-jét a kiíratásra.
A kiíratáskor a kiertekel() metódust felhasználva, értékeltessük is ki a szelvényeket.
Ez lesz a tesztelő osztályunk tartalma:

  1. public class LottoTest {
  2.    public static void main(String[] args){
  3.      //létrehozunk két szelvényt
  4.      //sz1 automatikusan generált 5 számot fog tartalmazni
  5.      Szelveny sz1 = new Szelveny();
  6.      
  7.      //sz2 a paramétrelistájában megadott öt számot tartalmazza
  8.      Szelveny sz2 = new Szelveny(19,71,8,16,7);
  9.  
  10.      // ha nem adjuk meg cska az objektum nevét, akkor megpróbálja megfelelő típusúra konvertálni.
  11.      //String típushoz a toString() metódust hívja automatikusan.
  12.      System.out.println(sz1 + " Találatok száma: " + sz1.kiertekel(2,7,18,71,87));
  13.      System.out.println(sz2 + " Találatok száma: " + sz1.kiertekel(2,7,18,71,87));    
  14.  
  15.    }
  16. }


Futtatás hatására a kimenet hasonló lesz  (valószínű más számok jelennek meg az sz1 kiírásakor)

Szelvény száma: -1 Tippek: [8, 51, 66, 71, 75] Találatok száma: 1
Szelvény száma: -1 Tippek: [7, 8, 16, 19, 71] Találatok száma: 2


2014. szeptember 14., vasárnap

Lottó szimulátor - osztályok első nekifutásra

A lottó szimulátorral kapcsolatban először gondoljuk át hogy milyen osztályok szükségesek az alkalmazáshoz.

A Java egy tisztán objektumorientált programozási nyelv és mint minden ilyen nyelvben osztályokkal és az osztályok alkotta osztályhierarchivál dolgozunk. Az osztályok a való világ egyes elemeinek, objektumainak absztrakció útján történő leképezései.
Most próbáljuk meg a feladattal kapcsolatban az első absztrakciót elvégezni. Képzeljük el hogy milyen osztályok és azok milyen kapcsolatai fogják alkotni a Lottószimulátort! Most nem törekszünk teljes részletességre, csupán nagy vonalakba gondoljunk a feladatra.

A lottófogadásokat szelvényeken tudjuk megtenni. Az összes fogadást és azok kezelését is meg kell valósítani egy közös helyen. Első menetben erre a két osztályra lesz szükségünk.

Nézzük ezeket részletesebben.

Szükség lesz (vagy nem?) egy olyan osztályra, ami a tippek tárolására alkalmas. Ezt úgy kell elképzelni mint a fogadó fejében lévő lottószámok, amiket meg szeretne tenni. Tehát semmi más nem jellemzi, csak maguk az ember elméjében létező számokat tartalmazza, amiket vagy megtesz a lottón vagy nem. Tehát ez még nem maga a fogadás ez csak egy tipp. Ahhoz hogy fogadás legyen belőle, ahhoz ki kell tölteni egy lottószelvényt. A kérdés az hogy maga a számsor, ami egyéb más jellemzővel nem rendelkezik azt szükséges-e külön osztályban megvalósítani vagy sem. Elsőnek induljunk el úgy hogy mégse csináljunk ebből külön osztályt.
Tehát a tippet már eleve egy szelvényen kezeljük, mert amíg nem teszik meg a fogadást addig tökmindegy hogy benne van-e valaki fejében öt szám vagy sem.
A lottószelvény osztálynak tárolni kell tudni az öt számot, illetve van egy 7 jegyű egyedi sorszáma amivel majd a joker játékra lehet fogadni. A sorszámot a szelvény létrehozásakor generáljuk. A lottószelvény a sorsolás után lehet nyertes szelvény akkor, ha legalább két találat van rajta. A szelvényobjektumnak a létrehozásakor vagy megadjuk az öt számot amire fogadást kötnek, vagy ha nem akkor generálunk öt számot. Ez tehát kétféle konstruktort jelent (többalakúság). Az hogy egy szelvény nyertes-e, azt egy metódussal fogjuk kiértékelni. Paraméterül adjuk át a kihúzott öt számot és eredményül adja vissza hogy hányas találat van a szelvényen.

Az implementációban az öt lottószám tárolására használjunk egy konténert. Ehhez használjuk a TreeSet tárolóosztályt, aminek az a jellemzője, hogy egy elemet csak egyszer tartalmazhat és az elemeket rendezve tárolja. Természetesen Integer elemekkel dolgozunk. A generálást a Math osztály Random() metódusával generáljuk. Ez a 0 és 1 között generál egy lebegőpontos véletlen számot. Ezt először 1 és 90 közöttivé kell alakítani, majd típuskényszerítéssel (cast) egésszé kell alakítani.

Íme a lottószelvényeket tároló osztály Java forrása:

public class Szelveny {
  private int szelvenyId = -1; //jelöljük így a szelvényt amíg nincs sorszáma
  private TreeSet tippek = new TreeSet();
  private boolean joker = false;

  public Szelveny(){
     //generálni kell 5 különböző számot 1-90 között.
     //Ha egy számot már kisorsoltunk, akkor helyette új kell
     for(int i=1;i<=5;i++){
         int j;
         do 
            j=(int)(Math.random()*89+1);             
         while(tippek.contains(j));
         tippek.add(j);
     }
  }

  public Szelveny(int n1, int n2, int n3, int n4, int n5){
     //paraméterekben megkapjuk a tippeket. 
     //Az hogy a tippek helyesek-e azzal ne foglalkozzunk. 
     //Nem tudjuk hogy mi volt a célja a szelvény kitöltőjének, 
     //had töltse ki ahogy akarja. Majd a szelvény beadásakor 
     //kell eldönteni hogy elfogadjuk-e a tippet, vagy sem.

     tippek.add(n1);
     tippek.add(n2);
     tippek.add(n3);
     tippek.add(n4);
     tippek.add(n5);

  }

  public int kiertekel(int n1, int n2, int n3, int n4, int n5){
     //le kell ellenőrizni az öt számot egyenként.
     //a -1 azt jelenti hogy érvénytelen a szelvény
     int talalat = -1; 

     // érvényes a szelvény ha 5 tippet tartalmaz
     if (tippek.size()==5) talalat++;
     if (tippek.contains(n1)) talalat++;
     if (tippek.contains(n2)) talalat++;
     if (tippek.contains(n3)) talalat++;
     if (tippek.contains(n4)) talalat++;
     if (tippek.contains(n5)) talalat++;

     return talalat;
  }
}

2014. szeptember 11., csütörtök

LOTTÓ feladat Javában

Nemrég nézegettem az emelt szintű informatika érettségi feladatokat és ott láttam egy lottózós feladatot. Erről jutott eszembe, hogy csináljak gyakorlásként egy ilyen lottózós példát.
Java-ban fogom megcsinálni, lehet hogy nem egy lépcsőben hanem szépen lépésről lépésre.
Itt fogom blogolni, hátha hasznos lesz valakinek.


Előszöris a feladatot kéne megfoglamazni első lépésben, aztán lehet hogy még pontosítjuk.

Szóval a cél egy lottó szimulátor készítése a következő funkciókkal:

  • 5-ös lottó (90-5) feladatról van szó
  • Lehessen megadni fogadásokat (akármennyit)
  • A fogadásokról készítsen statisztikát (később pontosítjuk hogy mit statisztikázzon)
  • Sorsolja ki a nyerő számokat
  • Statisztikázza és listázza ki a nyertes szelvényeket.
  • Lehessen a lottószelvény sorszámával joker-re is fogadni.
  • Sorsolja ki a jokert
Hát egyelőre ennyi feladat lenne. Rengeteg ötlet jut hirtelen eszembe amit még meg lehetne valósítani. (pl. fordított lottó. Először sorsoljon, aztán kezdjen el generálni fogadásokat addig amíg lesz egy 5-ös szelvény, vagy 4-es stb...)

A fent felsorolt pontokból indulok ki és ahogy haladok, blogolni fogom a részfeladatokat... (remélem)

2014. augusztus 23., szombat

Egy kis retro érzés: Mi és a computer

A minap néztem az M3-at és éppen a számítógépről illetve annak programozásáról beszélgettek. Egy 1983-as ismeretterjesztő sorozat egyik epizódjába botlottam, a címe: Mi és a computer.
Tovább nézve az epizódot mindjárt tudtam hogy valahogy meg kell néznem minden epizódját, hiszen amiről bezséltek, amilyen gépeket és programokat használtak azok pontosan azok voltak amiket én magam is használtam akkor amikor összetalálkoztam az informatikával. A riportokban az akkori kissrácok ugyan azokról a dolgokról érzésekről bezsélnek amit én éreztem és átéltem.
Szerencsére a youtube-on elérhető a sorozat minden része.
A programozni tanulóknak is ajánlom, mert vannak benne feladványok, magyarázatok a programozással kapcsolatosan, gyakran nem is olyan egyszerűek ezek. Meg lehet próbálni megoldani ezeket a feladatokat.
Az egyik ilyen feladat pl az volt hogy egy maximum 10 soros verset elemezzünk és adjuk meg a rímképletét. Izgalmas és nem feltétlenül egyszerű feladat, Oldjuk meg! :)

2014. július 21., hétfő

Programozás oktatás (www.learneroo.com)

A napokban találtam egy weboldalt ahol különféle programozással kapcsolatos oktatóanyagok vannak. Az oldal néhány programozási nyelv mellett főként az alábbi témákat oktatja:


Programozási nyelvek közül az aktuális trendnek megfelelően a Java, JavaScript, Python és Ruby nyelveket oktatja rengeteg rövid, gyakorlati feladatok használatával.
Ami leginkább megtetszett az az, hogy a példák megoldását nem a saját fejlesztői környezetünkkel kell megoldani, hanem az oldalba beépített emulátor segítségével. Kapunk egy "teljes" fejlesztői környezetet, editorral, debugerrel együtt, és ott kell megírni a kért feladatokat, amit a mellékelt tesztadatokon le is futtat.



Nekem nagyon tetszik ez a megoldás.

Az említett programozási nyelvek alapjai mellett algoritmusokat, matematikai problémákat illetve különféle praktikus programozási fogásokat is oktató modulokat is találunk a weboldalon. Ezek alap esetben Java nyelven oldhatók meg, de lehet választani más (PHP, C++, Python stb) nyelvek közül is.

Az oldal nyelve angol. Azt gondolom hogy aki programozásra adja a fejét és komolyan is gondolja azt, annak elkerülhetetlen az angol nyelv értő olvasása. Az oldal nyelvezete egyszerű, minimális nyelvtudással könnyen érthető. Ennyire tudni kell minden programozónak angolul.

Ajánlom az oldalt a kezdőknek és haladóknak egyaránt. A kezdők megtanulhatják az alapokat és még egy picit többet is, a haladók pedig tesztelhetik, frissen tarthatják tudásukat.

Még egy megjegyzés! Az oldal üzemeltetője a kickstarter.com-on indított egy gyűjtést az oldal fejlesztésére. Bárki felajánlhat bármekkora összeget. 4000 dollárt célzott meg ami szükséges lenne az oldal fejlesztésére, jelenleg 406$ van felajánlva. Aki teheti támogassa az oldal fejlesztését.

2014. január 18., szombat

Helló világ!

Van egy program, amit minden C nyelvet tanulni kezdő ember megír. Ez a Hello world!
A program elhíresült és alap példává vált. Szerintem ez az a  program amit a legtöbben megírnak.
Brian Kernighan és Dennis Ritchie által írt The C Programming Language című könyv a C nyelv bibliájaként ismert. Ezt maguk a nyelv kitalálói írták és a mai napig a leghíresebb C könyv, ami minden programozónak a polcán ott kell hogy legyen, már csak tiszteletből is. Ez olyan mint a gitározásban a Hey Joe Jimmy Hendrixtől. Mindenkinek, aki komolyan gondolja...  :)

Szóval nézzük a példát:

#include
void main() {
       printf("hello world\n");
}

A programot beírjuk egy hello.c fájlba, majd lefordítjuk és futtatjuk akkor a program kiírja  a képernyőre hello world üzenetet.

Tesztnek nem rossz... :)


A C nyelvről

Én a programozást BASIC nyelvvel kezdtem. Ez egy nagyon egyszerű, magas szintű programozási nyelv volt, amivel kényelmesen lehetett megfogalmazni a programokat. A következő az assembly nyelv volt, még Z80 mikroprocesszoros gépeken.
A két nyelv között a különbség abban rejlett, hogy a BASIC nagyon egyszerű és könnyen elsajátítható volt. Rendelkezésre álltak a különféle ciklusműveletek, feltételes vezérlésátadás, szubrutinok írása és hívása. Viszont a nyelv nagyon lassú volt mivel interpretált futtatást (azaz minden programsorra külön értelmezés, fordítás, futtatás) tett lehetővé. Az assembly nyelv nagyon gyors gépi kódú programokat készítését tette lehetővé, ezzel szemben a ciklusszervezést, az utasítások sorozatát mind alacsony szinten kellett megvalósítani, ami sokkal nagyobb hibázási lehetőséget teremtett.
Később a Pascal nyelven folytattam programozói tevékenységemet, amire komoly típusosság volt jellemző és erős szigorral ellenőrzött minden egyes programsoromat.
Van egy számomra misztikus nyelv, a C nyelv, ami gyors is és magas szintűnek is nevezhető, ugyanakkor nagyon "hanyag" lazaság is jellemzi a típusszigorát.. A típusossága nagyban hasonlít az assemblyhez, a mutatók használata - ami a komolyabb programozás alapja - kényelmes. Fordítója kifejlett és gyakorlatilag assembly programot állít elő (a mai fordítók persze ezt a lépést kihagyják, de kikényszeríthető ez a kimenet is). A lényeg hogy ez a fura nyelv, a maga fura gondolkodásával igazi forradalom volt a maga idejében a '70-es évek elején. Akkoriban egy operációs rendszert készítettek a segítségével, mégpedig a Unixot, ami napjainkban is hihetetlen népszerű, hatékony és biztonságos operációs rendszer. Erre azért felkapja egy programozó a fejét. Operációs rendszert írni magas szintű nyelven? Hmmm.
Ez aztán a csemege. Így találkoztam a C nyelvvel. Akkoriban én a Pascal mellett döntöttem, mint általános célú programozási nyelv mellett. A C-be csak az egyetemi tanulmányok kapcsán merültem bele.
Szóval most elkezdenék egy újabb témát itt a Programozz! blogon. Ez pedig a C nyelv használata lesz.
Nem akarom bemutatni a különféle agyafúrt C-s pointerezést, meg az előfordító adta csodás lehetőségeket (írtak C-ben PC emulátort is, aminek forráskód hossza belefért 2000 karakterbe). Egyszerűen alapszintű megoldásokat, alap programozási feladatokat szeretnék bemutatni a segítségével.
A cikkeket a C címkével jelölöm.