Διαδρομές
/
Julia
Julia
/
Ασκήσεις
/
Επίπεδα καταγραφής
Επίπεδα καταγραφής

Επίπεδα καταγραφής

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

Εισαγωγή

Μια String στη Julia είναι μια διατεταγμένη ακολουθία χαρακτήρων. Όπως επισημαίνει το εγχειρίδιο: "Φυσικά, το πραγματικό πρόβλημα αρχίζει όταν αναρωτιέται κανείς τι είναι ένας χαρακτήρας."

Μεγάλο μέρος αυτής της πολυπλοκότητας καλύπτεται με περισσότερες λεπτομέρειες στο Concept Chars, αλλά εν συντομία:

  • Όλες οι συμβολοσειρές στη Julia είναι Unicode.
  • Οι συμβολοσειρές που τυγχάνει να είναι και ASCII (τα αγγλικά γράμματα A έως Z σε κεφαλαία και πεζά, τα ψηφία και μερικοί χαρακτήρες στίξης) είναι εύκολες στον χειρισμό.
  • Με τα περισσότερα άλλα συστήματα γραφής του κόσμου είναι δυνατόν να δουλέψεις, αλλά χρειάζονται περισσότερη προσοχή.

Κυριολεκτικά συμβολοσειρών

Γενικά, οι συμβολοσειρές περικλείονται σε διπλά εισαγωγικά " ". Τα μονά εισαγωγικά ' ' χρησιμοποιούνται μόνο για Chars.

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

julia> """
       Multiline
       
       """
"Multiline\nString\n"

Διαφυγή χαρακτήρων

Όπως οι περισσότερες γλώσσες από τη C και μετά, η Julia χρησιμοποιεί την ανάστροφη κάθετο \ για διαφυγή:

  1. Για να εισάγεις χαρακτήρες που δεν εκτυπώνονται, όπως τον χαρακτήρα αλλαγής γραμμής \n στο προηγούμενο παράδειγμα.
  2. Για να προστατεύσεις χαρακτήρες που διαφορετικά θα είχαν ειδική σημασία, όπως το \$ (δες παρακάτω).

Χρήση θέσεων

Κατ' αρχήν, οι θέσεις σε μια συμβολοσειρά λειτουργούν ακριβώς όπως στα διανύσματα:

julia> s[1], s[5]
('J', 'a')

Αυτό λειτουργεί σαφώς για μια συμβολοσειρά ASCII όπως η "Julia", αλλά αγνοεί τις περισσότερες γλώσσες του κόσμου.

Σκέψου έναν από τους χαρακτήρες στο Beowulf, που γράφτηκε στα αρχαία αγγλικά πριν από περίπου 15 αιώνες.

Το "Hrōðgār" έχει σαφώς 7 χαρακτήρες, αλλά δεν είναι όλοι τους ASCII.

julia> king = "Hrōðgār"
"Hrōðgār"

julia> length(king)
7

julia> isascii(king)
false

# collect() converts to a Char vector:
julia> collect(king)
7-element Vector{Char}:
 'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)
 'ō': Unicode U+014D (category Ll: Letter, lowercase)
 'ð': Unicode U+00F0 (category Ll: Letter, lowercase)
 'g': ASCII/Unicode U+0067 (category Ll: Letter, lowercase)
 'ā': Unicode U+0101 (category Ll: Letter, lowercase)
 'r': ASCII/Unicode U+0072 (category Ll: Letter, lowercase)

Η χρήση θέσεων σε μια τέτοια συμβολοσειρά ξεκινά καλά, αλλά κάποια στιγμή χαλάει:

julia> king[3]
'ō': Unicode U+014D (category Ll: Letter, lowercase)

julia> king[4]
ERROR: StringIndexError: invalid index [4], valid nearby indices [3]=>'ō', [5]=>'ð'

Το πρόβλημα είναι ότι η χρήση θέσεων με αυτόν τον τρόπο μετρά bytes, οι οποίοι για συμβολοσειρές που δεν είναι ASCII δεν έχουν σχέση 1:1 με τους χαρακτήρες. Ένας χαρακτήρας Unicode/UTF-8 μπορεί να χρειάζεται έως και 4 byte για να αναπαρασταθεί, και το Concept Chars θα το εξερευνήσει περαιτέρω.

Κατασκευή συμβολοσειρών

Συνένωση

Πολλές γλώσσες χρησιμοποιούν το + ως τελεστή συνένωσης συμβολοσειρών, αλλά όχι η Julia. Τουλάχιστον το μήνυμα σφάλματος είναι βοηθητικό.

julia> "s1 " + "s2"
ERROR: MethodError: no method matching +(::String, ::String)
The function `+` exists, but no method is defined for this combination of argument types.
String concatenation is performed with * 

julia> "s1 " * "s2"
"s1 s2"

Η συνάρτηση string() συνενώνει οποιονδήποτε αριθμό συμβολοσειρών.

julia> string("lots ", "of ", "bits")
"lots of bits"

Η συνάρτηση join() κάνει το ίδιο, και επίσης δέχεται ένα διάνυσμα συμβολοσειρών και τις συνενώνει με έναν δεδομένο διαχωριστικό (με προεπιλογή το "").

julia> join(["lots", "of", "bits"], "_")
"lots_of_bits"

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

Επανάληψη

Απλό:

julia> repeat("Abc", 5)
"AbcAbcAbcAbcAbc"

Παρεμβολή

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

Στη Julia, οι τιμές που παρεμβάλλονται προηγούνται από το $.

julia> myvar = 42
42

julia> "myvar evaluates to $myvar"
"myvar evaluates to 42"

julia> r = 5.3
5.3

julia> "A circle of radius $r has area $(π * r^2)"
"A circle of radius 5.3 has area 88.24733763933729"

Οι παρενθέσεις απαιτούνται όταν η παράλειψή τους θα ήταν διφορούμενη, αλλά είναι προαιρετικές για ένα μόνο αναγνωριστικό που ακολουθείται από κενό διάστημα.

Για να συμπεριλάβεις ένα $ στη συμβολοσειρά, κάνε διαφυγή με \$.

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

@sprintf()

Για πιο λεπτομερή έλεγχο της σύνθεσης συμβολοσειρών, η Julia αντιγράφει τη συνάρτηση sprintf από τη C (και από αρκετές μεταγενέστερες γλώσσες: η Wikipedia αναφέρει περίπου 30).

Στη Julia, αυτό υλοποιείται ως macro μέσα στο module Printf, εξ ου και το πρόθεμα @.

julia> using Printf

julia> r = 5.3
5.3

julia> @sprintf("A circle of radius %.1f has area %.2f", r, π * r^2)
"A circle of radius 5.3 has area 88.25"

Συναρτήσεις συμβολοσειρών

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

Μήκος

Πόσο μάκρος έχει μια συμβολοσειρά; Μερικές φορές εξαρτάται από το πώς μετράς.

Η απλή περίπτωση είναι οι συμβολοσειρές ASCII, όπου κάθε χαρακτήρας καταλαμβάνει 1 byte.

julia> string_asc = "Julia"
"Julia"

julia> length(string_asc)
5

julia> sizeof(string_asc)
5

Η συνάρτηση length() επιστρέφει τον αριθμό των χαρακτήρων, και η συνάρτηση sizeof() τον αριθμό των bytes.

Αυτή η διάκριση γίνεται σημαντική με άλλα σύνολα χαρακτήρων:

julia> king = "Hrōðgār"
"Hrōðgār"

julia> length(king)
7

julia> sizeof(king)
10

Διαχωρισμός

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

Σε γενικές γραμμές, χρησιμοποιούμε τη συνάρτηση split(). Ο διαχωριστής έχει ως προεπιλογή το (οποιοδήποτε) κενό διάστημα, αλλά μπορείς να ορίσεις και άλλους.

julia> split("my little string")
3-element Vector{SubString{String}}:
 "my"
 "little"
 "string"

julia> split("My_snake_case_string", "_")
4-element Vector{SubString{String}}:
 "My"
 "snake"
 "case"
 "string"

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

Εύρεση και αντικατάσταση

Περιέχει μια συμβολοσειρά μια δεδομένη υποσυμβολοσειρά; Παραδόξως, υπάρχουν δύο συναρτήσεις για να το ελέγξεις: οι occursin() και contains() διαφέρουν μόνο στη σειρά των ορισμάτων τους.

julia> needle = "Julia"
"Julia"

julia> haystack = "Python, Julia and R"
"Python, Julia and R"

julia> occursin(needle, haystack)
true

julia> contains(haystack, needle)
true

Για να είσαι πιο συγκεκριμένος ως προς τη θέση:

julia> startswith(haystack, "Python")
true

julia> endswith(haystack, "Python")
false

Για να βρεις τις θέσεις έναρξης και λήξης μιας υποσυμβολοσειράς, έχουμε αρκετές συναρτήσεις:

  • findfirst()
  • findlast()
  • findprev()
  • findnext()
julia> findfirst(needle, haystack)
9:13

Για να αντικαταστήσεις υποσυμβολοσειρές, δώσε τις αλλαγές με τη σύνταξη x => y.

julia> replace("abc", "a"=>"b", "b"=>"c", "c"=>"a")
"bca"

Από τη Julia 1.7, η συνάρτηση replace μπορεί να δεχτεί οποιονδήποτε αριθμό αλλαγών, με την εγγύηση ότι κανένας χαρακτήρας δε θα αλλαχθεί περισσότερες από μία φορές κατά την αντικατάσταση.

Η σύνταξη x => y ονομάζεται pair, ένας σημαντικός τύπος στη Julia που καλύπτεται με περισσότερες λεπτομέρειες στο Concept Dicts and Pairs.

Κενά διαστήματα

Συχνά χρειάζεται να αφαιρέσουμε τα αρχικά ή/και τα τελικά κενά διαστήματα από μια συμβολοσειρά.

Οι συναρτήσεις για αυτό είναι οι lstrip() (αριστερά), rstrip() (δεξιά), strip() (και τα δύο).

julia> strip("\n\t  useful_bit\n\n")
"useful_bit"

Αλλαγή πεζών/κεφαλαίων

Αυτές οι συναρτήσεις έχουν ονόματα που εξηγούνται σχεδόν από μόνα τους:

julia> s = repeat("aBcD ", 5)
"aBcD aBcD aBcD aBcD aBcD "

julia> uppercase(s)
"ABCD ABCD ABCD ABCD ABCD "

julia> lowercase(s)
"abcd abcd abcd abcd abcd "

julia> titlecase(s)  # Initial letter of each word uppercase
"Abcd Abcd Abcd Abcd Abcd "

Οδηγίες

Σε αυτή την άσκηση θα επεξεργάζεσαι γραμμές καταγραφής.

Κάθε γραμμή καταγραφής είναι μια συμβολοσειρά με την εξής μορφή: "[<LEVEL>]: <MESSAGE>".

Υπάρχουν τρία διαφορετικά επίπεδα καταγραφής:

  • INFO
  • WARNING
  • ERROR

Έχεις τρεις εργασίες, καθεμία από τις οποίες θα παίρνει μια γραμμή καταγραφής και θα σου ζητά να κάνεις κάτι με αυτήν.

1. Πάρε το μήνυμα από μια γραμμή καταγραφής

Υλοποίησε τη συνάρτηση message ώστε να επιστρέφει το μήνυμα μιας γραμμής καταγραφής:

julia> message("[ERROR]: Invalid operation")
"Invalid operation"

Τυχόν κενά στην αρχή ή στο τέλος πρέπει να αφαιρούνται:

julia> message("[WARNING]:  Disk almost full\r\n")
"Disk almost full"

2. Πάρε το επίπεδο καταγραφής από μια γραμμή καταγραφής

Υλοποίησε τη συνάρτηση log_level ώστε να επιστρέφει το επίπεδο καταγραφής μιας γραμμής καταγραφής, το οποίο πρέπει να επιστρέφεται με πεζά γράμματα:

julia> log_level("[ERROR]: Invalid operation")
"error"

3. Αναδιαμόρφωσε μια γραμμή καταγραφής

Υλοποίησε τη συνάρτηση reformat που αναδιαμορφώνει τη γραμμή καταγραφής, βάζοντας πρώτα το μήνυμα και μετά το επίπεδο καταγραφής μέσα σε παρενθέσεις:

julia> reformat("[INFO]: Operation completed")
"Operation completed (info)"

Σημείωση: Όλες οι συμβολοσειρές σε αυτή την άσκηση είναι στα αγγλικά και περιορίζονται στο σύνολο χαρακτήρων ASCII. Οι επόμενες έννοιες θα σου δώσουν την ευκαιρία να δουλέψεις με χαρακτήρες Unicode.

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

Έτοιμος να ξεκινήσεις την άσκηση Επίπεδα καταγραφής;

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