Kurzusok
/
jq
jq
/
Feladatok
/
Távirányítós autó
Távirányítós autó

Távirányítós autó

Tanulófeladat

Bevezetés

Függvények

Saját egyéni függvényeket definiálhatsz a jq-ban, hogy bármilyen logikát egységbe zárj vele. A függvények pontosan úgy viselkednek, mint a beépített függvények: kapnak egy bemenetet, és nullát, egyet vagy több kimenetet adnak.

Függvény definiálása

A jq-ban a következő szintaxissal definiálhatsz egy függvényt:

# no arguments
def funcname: expression;

# or with arguments
def funcname(args): expression;
  • a def kulcsszóval kezdődik,
  • a függvény törzse előtt kettőspont áll,
  • a törzs egyetlen kifejezésből áll,
  • pontosvesszővel zárul,
  • a jq szintaxisának többi részéhez hasonlóan tetszőleges whitespace-t használhatsz az olvashatóság kedvéért.

Hová kerüljenek a függvények

A függvényeket a használatuk előtt kell definiálni: ez hiba:

def A: B(10);
def B(n): n + 1;
A
# => error: B/1 is not defined

Ez azt jelenti, hogy a függvényeket a jq-kódod elejére kell tenned, a „fő” kifejezés elé.

Egymásba ágyazott függvények

A függvényeket egymásba ágyazhatod:

def A:
    def B(n): n + 1;
    B(10)
    ;
A
# => 11

Itt a B függvény csak az A törzsében látható.

Scope

Egy függvény új scope-ot vezet be a változók és a beágyazott függvények számára.

Argumentumok

A függvény argumentumait pontosvesszők választják el egymástól, nem vesszők. Például egy olyan függvény, amely kap egy számot, majd hozzáad egy számot és megszoroz egy számmal:

def add_mul(adder; multiplier): (. + adder) * multiplier;

10 | add_mul(5; 4)    # => 60
Note

A pontosvesszőre azért van szükség, mert a vesszőnek már van egy funkciója a jq-ban: olyan operátor, amely stream-eket kapcsol össze.

Ha vesszőt használsz pontosvessző helyett, azzal két hívást próbálsz indítani egy 1 argumentumos add_mul függvény felé, amely nem létezik, ezért már az első próbált hívásnál hibára fut:

10 | add_mul(5, 4)
# error: add_mul/1 is not defined
Az argumentumok kifejezések

A függvények argumentumai filterek, nem értékek. Ebben az értelemben úgy viselkednek, mint amit más nyelvek callbacknek neveznek:

Az add_mul függvényt példaként használva:

10 | add_mul(. + 5; . - 2)    # => 200

Mi történik itt?

  • az adder argumentum a . + 5 kifejezést kapja
    • amikor a függvény a . + adder műveletet végzi, az . + . + 5 lesz
    • ennek az értéke 25 lesz, mivel . == 10
  • hasonlóképpen a multiplier argumentum a . - 2 kifejezés
    • ennek az értéke 8
    • így az eredmény 25 * 8 == 200
Argumentumok értékként

Néha szeretnéd egy argumentumból változót „materializálni”:

def my_func(arg):
    arg as $arg
    | other stuff ...
;

Erre van egy rövidített írásmód:

def my_func($arg):
    other stuff ...
;

Vedd figyelembe, hogy ez csupán „szintaktikai cukor”: az arg név $ nélkül is a függvény scope-jában marad.

Aritás

A függvényeknek van egy aritásuk, vagyis az általuk felvett argumentumok száma.

A függvények ugyanazt a nevet használhatják különböző aritásokkal. A beépített range függvény jól mutatja ezt: a range/1, range/2 és range/3 mind létezhet egymás mellett.

Ez hasznos lehet olyan rekurzív függvények definiálásához, amelyek argumentumokon keresztül hordozzák az állapotot. Például a map így is megvalósítható lenne:

def my_map($accumulator; func):
    if length == 0
        then $accumulator
        else first as $elem | .[1:] | my_map($accumulator + [$elem | func]; func)
    end
    ;

def my_map(func):
    my_map([]; func)
    ;

[1, 2, 3, 4] | my_map(. * 10)   # => [10, 20, 30, 40]

Rekurzió

A jq elvégzi a farokhívás-optimalizálást, de csak 0 aritású függvények esetében.

Modulok

A jq modul egy olyan fájl, amely csak függvényeket tartalmaz. A modulokat az include vagy az import paranccsal illeszted be egy jq programba.

Utasítások

Ebben a feladatban egy távirányítású autóval fogsz játszani, amelyre végre összegyűjtöttél annyi pénzt, hogy megvedd.

Az autók tele (100%-os) akkumulátorral indulnak. Valahányszor elvezeted az autót a távirányítóval, 20 métert tesz meg, és az akkumulátor egy százalékát meríti le. Az autó beceneve a létrehozásáig nem ismert.

A távirányítású autónak van egy menő LED-kijelzője, amely két adatot mutat:

  • A megtett teljes távolságot, amely így jelenik meg: "<METERS> meters".
  • Az akkumulátor hátralévő töltöttségét, amely így jelenik meg: "Battery at <PERCENTAGE>%".

Ha az akkumulátor 0%-on van, nem tudod tovább vezetni az autót, és az akkumulátor-kijelző ezt mutatja: "Battery empty".

1. Hozz létre egy vadonatúj távirányítású autót

Valósítsd meg a new_remote_control_car/0 függvényt, amely egy vadonatúj távirányítású autó objektumot ad vissza:

new_remote_control_car
# => {
#      "battery_percentage": 100,
#      "distance_driven_in_meters": 0,
#      "nickname": null
#    }

2. Hozz létre egy vadonatúj távirányítású autót becenévvel

Valósítsd meg a new_remote_control_car/1 függvényt, amely egy vadonatúj, megadott becenevű távirányítású autó objektumot ad vissza:

new_remote_control_car("Blue")
# => {
#      "battery_percentage": 100,
#      "distance_driven_in_meters": 0,
#      "nickname": "Blue"
#    }

3. Jelenítsd meg a távolságot

Valósítsd meg a display_distance/0 függvényt, amely bemenetként egy autó objektumot kap, és visszaadja a LED-kijelzőn megjelenő távolságot jelző szöveget:

new_remote_control_car | display_distance
# => "0 meters"

4. Jelenítsd meg az akkumulátor töltöttségét

Valósítsd meg a display_battery/0 függvényt, amely bemenetként egy autó objektumot kap, és visszaadja a LED-kijelzőn megjelenő akkumulátor-töltöttséget jelző szöveget:

new_remote_control_car | display_battery
# => "Battery at 100%"

Ha az akkumulátor 0%-on van, az akkumulátor-kijelző ezt mutatja: „Battery empty”.

5. A vezetés megváltoztatja az akkumulátor töltöttségét és a megtett távolságot

Valósítsd meg a drive/0 függvényt, amely:

  • bemenetként egy autó objektumot kap
  • 20 méterrel növeli a megtett méterek számát
  • az akkumulátor 1%-át meríti le
  • a módosított autó objektumot adja vissza
new_remote_control_car("Red") | drive
# => {
#      "battery_percentage": 99,
#      "distance_driven_in_meters": 20,
#      "nickname": "Red"
#    }

6. Vedd figyelembe a lemerült akkumulátorral való vezetést

Módosítsd a drive/0 függvényt úgy, hogy ne növelje a megtett távolságot, és ne csökkentse az akkumulátor töltöttségét, amikor az akkumulátor lemerült (0%-on van):

{
  battery_percentage: 0,
  distance_driven_in_meters: 2000,
  nickname: "Red"
} | drive
# => {
#      "battery_percentage": 0,
#      "distance_driven_in_meters": 2000,
#      "nickname": "Red"
#    }
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
jq Exercism

Készen állsz elkezdeni a(z) Távirányítós autó feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) jq nyelvet 12 fogalom75 feladat segítségével, valódi emberi mentorálással, mindez ingyen.