Διαδρομές
/
jq
jq
/
Ασκήσεις
/
Τηλεκατευθυνόμενο αυτοκίνητο
Τηλεκατευθυνόμενο αυτοκίνητο

Τηλεκατευθυνόμενο αυτοκίνητο

Άσκηση εκμάθησης

Εισαγωγή

Συναρτήσεις

Μπορείς να ορίσεις τις δικές σου προσαρμοσμένες συναρτήσεις στο jq για να ενσωματώσεις όποια λογική χρειάζεσαι. Οι συναρτήσεις λειτουργούν ακριβώς όπως οι ενσωματωμένες: παίρνουν μια είσοδο και παράγουν μηδέν, μία ή περισσότερες εξόδους.

Ορισμός συνάρτησης

Μπορείς να ορίσεις μια συνάρτηση jq χρησιμοποιώντας την εξής σύνταξη:

# no arguments
def funcname: expression;

# or with arguments
def funcname(args): expression;
  • ξεκινάει με τη λέξη-κλειδί def,
  • άνω κάτω τελεία πριν από το σώμα της συνάρτησης,
  • το σώμα αποτελείται από μία μόνο έκφραση,
  • τελειώνει με ερωτηματικό,
  • όπως και στην υπόλοιπη σύνταξη του jq, μπορείς να χρησιμοποιήσεις όποια κενά θέλεις για ευαναγνωσιμότητα.

Πού να βάζεις τις συναρτήσεις

Οι συναρτήσεις πρέπει να ορίζονται πριν χρησιμοποιηθούν: αυτό είναι σφάλμα:

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

Αυτό σημαίνει ότι πρέπει να τοποθετείς τις συναρτήσεις στην αρχή του κώδικα jq, πριν από την "κύρια" έκφραση.

Εμφωλευμένες συναρτήσεις

Οι συναρτήσεις μπορούν να είναι εμφωλευμένες:

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

Εδώ, η συνάρτηση B είναι ορατή μόνο στο σώμα της A.

Εμβέλεια

Μια συνάρτηση εισάγει μια νέα εμβέλεια για μεταβλητές και εμφωλευμένες συναρτήσεις.

Ορίσματα

Τα ορίσματα συνάρτησης χωρίζονται με ερωτηματικά και όχι με κόμματα. Για παράδειγμα, μια συνάρτηση που παίρνει έναν αριθμό, και μετά προσθέτει έναν αριθμό και πολλαπλασιάζει με έναν αριθμό:

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

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

Τα ερωτηματικά είναι απαραίτητα επειδή το κόμμα έχει ήδη σκοπό στο jq: έναν τελεστή που ενώνει ροές.

Χρησιμοποιώντας κόμμα αντί για ερωτηματικό, θα επιχειρηθεί να γίνουν δύο κλήσεις σε μια συνάρτηση add_mul με ένα όρισμα, η οποία δεν υπάρχει και επομένως θα αποτύχει στην πρώτη απόπειρα κλήσης:

10 | add_mul(5, 4)
# error: add_mul/1 is not defined
Τα ορίσματα είναι εκφράσεις

Τα ορίσματα συνάρτησης είναι φίλτρα, όχι τιμές. Με αυτή την έννοια, λειτουργούν όπως αυτό που άλλες γλώσσες περιγράφουν ως callbacks:

Χρησιμοποιώντας τη συνάρτηση add_mul ως παράδειγμα:

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

Τι συμβαίνει εδώ;

  • το όρισμα adder παίρνει την έκφραση . + 5
    • όταν η συνάρτηση κάνει . + adder, αυτό γίνεται . + . + 5
    • αυτό αξιολογείται σε 25 αφού . == 10
  • παρομοίως, το όρισμα multiplier είναι η έκφραση . - 2
    • αυτό αξιολογείται σε 8
    • μετά το αποτέλεσμα είναι 25 * 8 == 200
Ορίσματα ως τιμές

Μερικές φορές θα θέλεις να "υλοποιήσεις" ένα όρισμα σε μια μεταβλητή:

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

Υπάρχει μια συντομογραφία για αυτό:

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

Σημείωσε ότι αυτό είναι απλώς "συντακτική ζάχαρη": το όνομα arg χωρίς $ είναι ακόμα στην εμβέλεια της συνάρτησης.

Πλήθος ορισμάτων

Οι συναρτήσεις έχουν ένα πλήθος ορισμάτων: τον αριθμό των ορισμάτων που δέχονται.

Οι συναρτήσεις μπορούν να χρησιμοποιήσουν το ίδιο όνομα με διαφορετικά πλήθη ορισμάτων. Η ενσωματωμένη συνάρτηση range το δείχνει αυτό: τα range/1, range/2 και range/3 συνυπάρχουν.

Αυτό μπορεί να είναι χρήσιμο για τον ορισμό αναδρομικών συναρτήσεων που μεταφέρουν κατάσταση μέσω ορισμάτων. Για παράδειγμα, η map θα μπορούσε να υλοποιηθεί ως εξής:

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]

Αναδρομή

Το jq θα εκτελέσει βελτιστοποίηση ουράς, αλλά μόνο για συναρτήσεις με 0 ορίσματα.

Ενότητες

Μια ενότητα jq είναι ένα αρχείο που περιέχει μόνο συναρτήσεις. Οι ενότητες συμπεριλαμβάνονται σε ένα πρόγραμμα jq με τις εντολές include ή import.

Οδηγίες

Σε αυτή την άσκηση θα παίξεις με ένα τηλεκατευθυνόμενο αυτοκίνητο, που επιτέλους μάζεψες αρκετά χρήματα για να αγοράσεις.

Τα αυτοκίνητα ξεκινούν με γεμάτες (100%) μπαταρίες. Κάθε φορά που οδηγείς το αυτοκίνητο χρησιμοποιώντας το τηλεχειριστήριο, διανύει 20 μέτρα και καταναλώνει ένα τοις εκατό της μπαταρίας. Το παρατσούκλι του αυτοκινήτου δεν είναι γνωστό μέχρι να δημιουργηθεί.

Το τηλεκατευθυνόμενο αυτοκίνητο έχει μια φανταχτερή οθόνη LED που δείχνει δύο πληροφορίες:

  • Η συνολική απόσταση που έχει διανύσει, εμφανιζόμενη ως: "<METERS> meters".
  • Η υπολειπόμενη φόρτιση μπαταρίας, εμφανιζόμενη ως: "Battery at <PERCENTAGE>%".

Αν η μπαταρία είναι στο 0%, δεν μπορείς πια να οδηγήσεις το αυτοκίνητο και η ένδειξη μπαταρίας θα δείχνει "Battery empty".

1. Δημιούργησε ένα ολοκαίνουργιο τηλεκατευθυνόμενο αυτοκίνητο

Υλοποίησε τη συνάρτηση new_remote_control_car/0 ώστε να επιστρέφει ένα ολοκαίνουργιο αντικείμενο τηλεκατευθυνόμενου αυτοκινήτου:

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

2. Δημιούργησε ένα ολοκαίνουργιο τηλεκατευθυνόμενο αυτοκίνητο με παρατσούκλι

Υλοποίησε τη συνάρτηση new_remote_control_car/1 ώστε να επιστρέφει ένα ολοκαίνουργιο αντικείμενο τηλεκατευθυνόμενου αυτοκινήτου με ένα δεδομένο παρατσούκλι:

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

3. Εμφάνισε την απόσταση

Υλοποίησε τη συνάρτηση display_distance/0 που παίρνει ως είσοδο ένα αντικείμενο αυτοκινήτου και επιστρέφει τη συμβολοσειρά απόστασης όπως εμφανίζεται στην οθόνη LED:

new_remote_control_car | display_distance
# => "0 meters"

4. Εμφάνισε το ποσοστό μπαταρίας

Υλοποίησε τη συνάρτηση display_battery/0 που παίρνει ως είσοδο ένα αντικείμενο αυτοκινήτου και επιστρέφει τη συμβολοσειρά ποσοστού μπαταρίας όπως εμφανίζεται στην οθόνη LED:

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

Αν η μπαταρία είναι στο 0%, η ένδειξη μπαταρίας θα δείχνει "Battery empty".

5. Η οδήγηση αλλάζει την μπαταρία και την απόσταση που διανύθηκε

Υλοποίησε τη συνάρτηση drive/0 που:

  • παίρνει ως είσοδο ένα αντικείμενο αυτοκινήτου
  • αυξάνει κατά 20 τα μέτρα που διανύθηκαν
  • καταναλώνει 1% της μπαταρίας
  • επιστρέφει το τροποποιημένο αντικείμενο αυτοκινήτου
new_remote_control_car("Red") | drive
# => {
#      "battery_percentage": 99,
#      "distance_driven_in_meters": 20,
#      "nickname": "Red"
#    }

6. Λάβε υπόψη την οδήγηση με άδεια μπαταρία

Ενημέρωσε τη συνάρτηση drive/0 ώστε να μην αυξάνει την απόσταση που διανύθηκε ούτε να μειώνει το ποσοστό μπαταρίας όταν η μπαταρία είναι άδεια (στο 0%):

{
  battery_percentage: 0,
  distance_driven_in_meters: 2000,
  nickname: "Red"
} | drive
# => {
#      "battery_percentage": 0,
#      "distance_driven_in_meters": 2000,
#      "nickname": "Red"
#    }
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
jq Exercism

Έτοιμος να ξεκινήσεις την άσκηση Τηλεκατευθυνόμενο αυτοκίνητο;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις jq με 12 έννοιες75 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.