Διαδρομές
/
jq
jq
/
Ασκήσεις
/
Στατιστικά βαθμών
Στατιστικά βαθμών

Στατιστικά βαθμών

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

Εισαγωγή

Reduce

Ας υποθέσουμε ότι θέλουμε να αθροίσουμε έναν πίνακα αριθμών. Υπάρχουν πολλοί τρόποι για να πετύχουμε αυτόν τον σκοπό.

  • Σε πολλές γλώσσες, αυτό το πρόβλημα εκφράζεται ως βρόχος με μια μεταβλητή συσσώρευσης.

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

    function Add(X, Sum=0):
      if X is empty then
        return Sum
      else
        return Add(rest(X), Sum + first(X))
      end
    end
    

    Αυτή η μέθοδος διαίρεσης του προβλήματος σε μικρότερα κομμάτια μπορεί επίσης να περιγραφεί ως "αναγωγή προς τη βασική περίπτωση".

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

Στη jq, αυτή η διαδικασία υλοποιείται στο φίλτρο reduce. Σε άλλες γλώσσες, μπορεί να ονομάζεται "fold", "fold-left", "inject" ή "aggregate".

Η έκφραση reduce της jq μοιάζει με αυτό.

reduce STREAM_EXPRESSION as $var (INITIAL_VALUE; UPDATE_EXPRESSION)
  • Το STREAM_EXPRESSION είναι ένα stream στοιχείων, καθένα από τα οποία αποθηκεύεται με τη σειρά του στη μεταβλητή $var.
  • Το INITIAL_VALUE είναι η αρχική τιμή του συσσωρευμένου αποτελέσματος (γνωστή ως "συσσωρευτής").
  • Το UPDATE_EXPRESSION συνδυάζει ("διπλώνει") την τρέχουσα τιμή ($var) στον συσσωρευτή.
    • Στο πλαίσιο αυτής της έκφρασης, το . είναι η τιμή του συσσωρευτή.
    • Το αποτέλεσμα της έκφρασης αποθηκεύεται στον συσσωρευτή για χρήση στην επόμενη επανάληψη.
    • Μετά την τελευταία επανάληψη, το συσσωρευμένο αποτέλεσμα είναι το αποτέλεσμα του reduce.

Ας δούμε ένα παράδειγμα: το άθροισμα των αριθμών ενός πίνακα. Το φίλτρο add κάνει ακριβώς αυτό, αλλά θα δούμε πώς να το υλοποιήσουμε.

Αν χρησιμοποιήσουμε το [10, 20, 30, 40] ως είσοδο και πάρουμε το μηδέν ως αρχική κατάσταση, να πώς μοιάζει κάθε βήμα.

# κατάσταση στοιχείο reducer αποτέλεσμα
1 0 10 0 + 10 10
2 10 20 10 + 20 30
3 30 30 30 + 30 60
4 60 40 60 + 40 100

Στη σύνταξη της jq, αυτό μοιάζει με τον παρακάτω κώδικα.

0 + 10 | . + 20 | . + 30 | . + 40

Μπορούμε να το εκφράσουμε αυτό με το φίλτρο reduce.

[10, 20, 30, 40] | reduce .[] as $n (0; . + $n)     # => 100
Note

Το ενσωματωμένο add στην πραγματικότητα υλοποιείται με το reduce, αλλά χρησιμοποιεί το "null" ως αρχική κατάσταση (σε null μπορεί να προστεθεί οποιοσδήποτε τύπος δεδομένων).

def add: reduce .[] as $x (null; . + $x);

Μερικά πράγματα που πρέπει να έχεις κατά νου

  • Στην έκφραση αναγωγής, το . είναι ο συσσωρευτής. Αν η είσοδος είναι κάποιο αντικείμενο που πρέπει να αναφέρεις μέσα στη συνάρτηση αναγωγής, θα πρέπει να το αποθηκεύσεις σε μια μεταβλητή.

    {"apple": 10, "banana": 16, "carrot": 4}
    | . as $obj
    | reduce (keys | .[]) as $key (0; . + $obj[$key])     # => 30
    
  • Ο συσσωρευτής μπορεί να είναι οποιουδήποτε τύπου δεδομένων. Για παράδειγμα, μπορεί να θέλεις να αντιστρέψεις έναν πίνακα.

    ["A", "B", "C", "D"]
    | reduce .[] as $elem ([]; [$elem] + .)       # => ["D", "C", "B", "A"]
    

Οδηγίες

Είσαι δάσκαλος. Στο τέλος της χρονιάς, έχεις υπολογίσει έναν αριθμητικό βαθμό για κάθε μαθητή σου. Τώρα πρέπει να τον μετατρέψεις σε βαθμό με γράμμα και να μετρήσεις πόσοι μαθητές πήραν κάθε βαθμό με γράμμα

1. Μετέτρεψε έναν αριθμητικό βαθμό σε βαθμό με γράμμα

Η συνάρτηση letter_grade παίρνει ως είσοδο έναν αριθμητικό βαθμό και επιστρέφει το γράμμα. Χρησιμοποίησε αυτά τα διαστήματα:

Γράμμα Βαθμός
A 90% - 100%
B 80% - 89%
C 70% - 79%
D 60% - 69%
F 0% - 59%

Παράδειγμα:

75 | letter_grade   # => "C"

2. Μέτρησε τον αριθμό των μαθητών για κάθε βαθμό με γράμμα

Η συνάρτηση count_letter_grades παίρνει ένα αντικείμενο που αντιστοιχίζει ονόματα μαθητών στους βαθμούς τους. Η έξοδος θα είναι ένα αντικείμενο που αντιστοιχίζει κάθε βαθμό με γράμμα στον αριθμό των μαθητών που πήραν αυτόν τον βαθμό.

Παράδειγμα:

{"Joe": 78, "Jane": 93, "Richard": 72} | count_letter_grades
# => {"A": 1, "B": 0, "C": 2, "D": 0, "F": 0}

Υπάρχουν μερικοί διαφορετικοί τρόποι να το λύσεις. Χρησιμοποίησε το φίλτρο reduce για εξάσκηση.

Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
jq Exercism

Έτοιμος να ξεκινήσεις την άσκηση Στατιστικά βαθμών;

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