Gyakorlati alapok
Virtuális traffipax
Napjaink legújabb és eleddig legrafináltabb traffipax-technológiája már nem az
út szélén vagy a bokorban rejtőzve leselkedik a gyorshajtókra...
...hanem adott útszakaszok között átlagsebességet számol és ha az nagyobb a megengedettnél, akkor szinte automatikusan megy is a bírság. Ehhez a járműnek jól beazonosítható módon először egy virtuális belépési pont előtt...
...majd egy kilépési pont előtt is el kell haladnia...
...amely pontokat autópályán alapjában véve nem nehéz kialakítani, bár a
rendszámfelismerés nyilvánvalóan problematikus tényező. Ha a jármű gyorsabban
megy a megengedett sebességnél, akkor hamarabb fog odaérni a kilépési ponthoz,
amely egyértelmű bizonyítéka a gyorshajtásnak.
A rendszer sokféle módon játszható ki:
-
hackerek megtámadják a rendszert és eltüntetik az adatokat vagy Gizikét, a szabálysértési osztály adminisztrátorát,
-
a jármű valamilyen módon elkerüli a belépési vagy kilépési pontot, esetleg mindkettőt,
-
valamilyen módon meghiúsul a jármű beazonosíthatósága (rendszám letakarása közlekedési bűncselekmény),
-
a jármű gyorsan megy, de a kilépési pont előtt addig várakozik, amíg az átlagidő vissza nem tér a megengedett alá,
-
illetve elképzelhető a fentiek színes variációja.
Magyar autópályán a sebességkorlátozás 130 km / h. Ez azt jelenti, hogy ha 1
óra alatt 130 km-nél messzebb jutottunk járművünkkel, akkor gyorshajtók
voltunk. Mivel 1 óra 60 percből áll, nem nehéz ezt percre lebontani:
130 / 60 = 2.1666 km
Tehát 1 perc alatt maximálisan 2.1666 km tehetünk meg, másként gyorshajtók vagyunk.
A feladat legyen most az, hogy meg kell írnunk egy olyan algoritmust, amelynek a specifikációja a következő:
-
a Rendőrség szabadon mozgatható belépési és kilépési pontokkal rendelkezik: ezeket bárhová teheti. Ez lényegében azt jelenti, hogy míg a belépési pont garantáltan mindig 0 km, addig a kilépési pontot magának a felhasználónak (a Rendőrségnek) kell megadnia. Csak remélhetjük, hogy a rendőr bácsi nem teszi a kilépési pontot a belépési pont elé, ezt úgy tudjuk modellezni (bár kivédeni nem), hogy a kilépési pont bemeneti értéke nem lehet kisebb 0-nál. Egyúttal legyen a kilépési pont bemeneti értékének mértékegysége kilométer (km), típusa pedig double, így nem egész számokat is képes lesz fogadni, például 10,65 km = 10650 m.
-
Mivel a legtöbb laptop furcsamód nem rendelkezik rendszámleolvasó hardveregységgel, ezért valahogy modelleznünk kell a jármű mozgását: mivel a kérdés a sebesség, ezért bemeneti adatként csakis az eltelt időt kérhetjük be. A program ebből fogja kiszámítani, illetve kiértékelni a sebességet. Legyen ennek mértékegysége másodperc (s) még akkor is, ha nagy időintervallumokról van szó, például 2 óra (ami tehát 7200 s), típusa szintén double. Automatizált számítógépes rendszereknél ez nem szokott gond lenni.
-
Amint az a magyar közlekedésrendészetnél is gyakorlat, határozzunk meg adott tűréshatárt. Ne minősüljön még gyorshajtónak, aki a sebességet csak néhány kilométer / órával lépi túl.
Nézzük meg a futtatható Java-kódot:
import java.util.*;
public class Main {
public static void main(String[] args) {
final double sebessegHatar = 2.1666;
final double turesHatar = 0.1;
Scanner scanner = new Scanner(System.in);
System.out.println ("Kérem, hogy adja meg a kilométert!");
String elem = scanner.nextLine();
double km = Double.parseDouble(elem);
while(km <= 0) {
System.out.println("Kérem, hogy csak
pozitív számot adjon meg!");
elem = scanner.nextLine();
km = Double.parseDouble(elem);
}
System.out.println("Kérem, hogy adja meg az eltelt időt!");
elem = scanner.nextLine();
double s = Integer.parseInt(elem);
while(s <= 0) {
System.out.println("Kérem, hogy csak
pozitív számot adjon meg!");
elem = scanner.nextLine();
s = Double.parseDouble(elem);
}
double m = s / 60;
double eredmeny = km / m;
System.out.println(s + " másodperc = " + m + " perc");
System.out.println("1 kilométer alatt megtett út: " +
eredmeny);
System.out.println("Az Ön sebessége " + (eredmeny * 60) + "
km/h volt.");
if(eredmeny > sebessegHatar + turesHatar){
System.out.println("Ön gyorshajtó
volt.");
}
else
System.out.println("Ön szabályosan
közlekedett.");
}
}
130 kilométer 1 óra alatt:
Végeredmény:
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
3600
3600.0 másodperc = 60.0 perc
1 kilométer alatt megtett út: 2.1666666666666665
Az Ön sebessége 130.0 km/h volt.
Ön szabályosan közlekedett.
130 kilométer 1/2 óra alatt:
Végeredmény:
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
1800
1800.0 másodperc = 30.0 perc
1 kilométer alatt megtett út: 4.333333333333333
Az Ön sebessége 260.0 km/h volt.
Ön gyorshajtó volt.
130 kilométer 2 óra alatt:
Végeredmény:
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
7200
7200.0 másodperc = 120.0 perc
1 kilométer alatt megtett út: 1.0833333333333333
Az Ön sebessége 65.0 km/h volt.
Ön szabályosan közlekedett.
Ugyanakkor a megállapított 0.1 tűréshatár (final
double turesHatar = 0.1;) nagyjából +5 kilométer / órás
sebességtúllépést eredményezett:
Végeredmény:
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
3480
3480.0 másodperc = 58.0 perc
1 kilométer alatt megtett út: 2.2413793103448274
Az Ön sebessége 134.48275862068965 km/h volt.
Ön szabályosan közlekedett.
Végeredmény:
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
3420
3420.0 másodperc = 57.0 perc
1 kilométer alatt megtett út: 2.280701754385965
Az Ön sebessége 136.8421052631579 km/h volt.
Ön gyorshajtó volt.
A kódban 2 helyen is használtam a final módosítószót, erről részletesen olvashatunk az Ami a változót (és a többieket) változatlanná teszi: a final című fejezetben.
A program működőképes, bár sok további lehetséges hibalehetőséget nem kezeltünk le benne, igaz, a jelen tanulási fázisban ez még nem is feladat. Azonban 1 hibalehetőséget kis logikus gondolkodással még gond nélkül lekezelhetünk.
Tételezzük fel, hogy rossz lesz valamelyik bemeneti adat, vagy km, vagy s megadása, hiszen nagyon könnyű +1 digittel többet vagy kevesebbet írni. 0 vagy kisebb szám esetén már lekezeltük őket, most viszont kissé bonyolultabb a helyzet.
Észrevehetjük, hogy a hibaszűrést inkább a 2 érték arányából kéne elkezdenünk, illetve kiindulópontként van itt még 1 fontos, szintén közlekedésrendészeti szabály:
Magyar autópályákon az alsó sebességkorlátozás 80 km / h. Ez azt jelenti, hogy
extrém eseteket kivéve (például torlódás) alapjában véve tilos ennél kisebb
sebességgel közlekednünk. Mivel 1 óra 60 percből áll, nem nehéz ezt percre lebontani:
80 / 60 = 1.3333 km
Foglaljuk össze:
-
alsó sebességhatár 1 percre: 1.3333 km,
-
felső sebességhatár 1 percre: 2.1666 km.
Nézzünk meg 1 extrém sebességtúllépést is; BMW-k például gyárilag 250 km / óra sebességre vannak korlátozva. Természetesen más márkájú járművel lehetséges nagyobb sebességtúllépés, de a modellezéshez tökéletesen elég ez az adat:
250 / 60 = 4.1666 km
Tehát:
-
alsó sebességhatár 1 percre: 1.3333 km,
-
felső sebességhatár 1 percre: 2.1666 km
-
extrém sebességtúllépés 1 percre: 4.1666 km.
Kezd kirajzolódni egy olyan arányszám, amely alapja lehet a 3. ellenőrzésnek: nevezetesen, jól írtuk-e be a 2 db bemeneti adatot. Az ellenőrzéshez:
-
egy hátultesztelő ciklust (Dönteni kell! (do - while) című fejezet),
-
annak speciális feltételmegadását (if(eredmeny < 1.3333 || eredmeny > 4.1666)),
-
és némi hibaüzenet-szöveget fogunk felhasználni.
További járulékként egy kissé át is kell szerkeszteni a kódot, főként, hogy a változók értékei globálisan elérhetők legyenek. Nézzük meg a futtatható Java-kódot:
import java.util.*
public class Main {
public static void main(String[] args) {
final double sebessegHatar = 2.1666;
final double turesHatar = 0.1;
double s, m, eredmeny;
do{
s = 0;
m = 0;
eredmeny = 0;
Scanner scanner = new
Scanner(System.in);
System.out.println ("Kérem, hogy adja
meg a kilométert!");
String elem = scanner.nextLine();
double km = Double.parseDouble(elem);
while(km <= 0) {
System.out.println("Kérem, hogy csak pozitív számot adjon meg!");
elem =
scanner.nextLine();
km =
Double.parseDouble(elem);
}
System.out.println("Kérem, hogy adja
meg az eltelt időt!");
elem = scanner.nextLine();
s = Integer.parseInt(elem);
while(s <= 0) {
System.out.println("Kérem, hogy csak pozitív számot adjon meg!");
elem =
scanner.nextLine();
s =
Double.parseDouble(elem);
}
m = s / 60;
eredmeny = km / m;
if(eredmeny < 1.3333 || eredmeny >
4.1666){
System.out.println("Rossz bemeneti adatok, ismételje meg!");
}
}while(eredmeny < 1.3333 || eredmeny > 4.1666);
System.out.println(s + " másodperc = " + m + " perc");
System.out.println("1 kilométer alatt megtett út: " +
eredmeny);
System.out.println("Az Ön sebessége " + (eredmeny * 60) + "
km/h volt.");
if(eredmeny > sebessegHatar + turesHatar){
System.out.println("Ön gyorshajtó
volt.");
}
else
System.out.println("Ön szabályosan közlekedett.");
}
}
Végeredmény:
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
7000
Rossz bemeneti adatok, ismételje meg!
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
2
Rossz bemeneti adatok, ismételje meg!
Kérem, hogy adja meg a kilométert!
130
Kérem, hogy adja meg az eltelt időt!
3600
3600.0 másodperc = 60.0 perc
1 kilométer alatt megtett út: 2.1666666666666665
Az Ön sebessége 130.0 km/h volt.
Ön szabályosan közlekedett.