Διαδρομές
/
Julia
Julia
/
Ασκήσεις
/
Παρατηρητής πουλιών
Παρατηρητής πουλιών

Παρατηρητής πουλιών

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

Εισαγωγή

Στην έννοια Vectors, είπαμε ότι "οι πίνακες βρίσκονται στην καρδιά της γλώσσας Julia" και ότι ένα διάνυσμα είναι μονοδιάστατο.

Δεδομένου αυτού, θα μπορούσαμε εύλογα να ελπίζουμε ότι η γλώσσα παρέχει πολλούς ευέλικτους και ισχυρούς τρόπους για να κάνουμε πράγματα με διανύσματα, ό,τι κι αν σημαίνει αυτό.

Συναρτήσεις που περιμένουν διάνυσμα ως είσοδο

Κάποιες πολύ απλές συναρτήσεις δέχονται ένα διάνυσμα ως είσοδο και επιστρέφουν μια βαθμωτή τιμή ως έξοδο.

v = [2, 3, 4]
length(v)  # => 3
sum(v)  # => 9

Αριθμητική

Ας υποθέσουμε ότι έχεις ένα αριθμητικό διάνυσμα και θέλεις να αφαιρέσεις το 0.5 από κάθε τιμή.

julia> v = [1.2, 1.5, 1.7]
3-element Vector{Float64}:
 1.2
 1.5
 1.7

julia> v - 0.5
ERROR: MethodError: no method matching -(::Vector{Float64}, ::Float64)

Αυτό αποτυγχάνει, οπότε τι γίνεται αν αφαιρέσουμε ένα άλλο διάνυσμα;

julia> v - [0.5, 0.5, 0.5]
3-element Vector{Float64}:
 0.7
 1.0
 1.2

Πετυχημένο, αλλά αρκετά κουραστικό και απαιτητικό σε μνήμη όσο τα διανύσματα μεγαλώνουν.

Ευτυχώς, η Julia έχει μια "μαγική" τελεία για να λύσει αυτό το πρόβλημα πολύ απλά: το v .- 0.5 είναι το μόνο που χρειάζεσαι.

Η επόμενη ενότητα εξηγεί το γιατί.

Μετάδοση

Λοιπόν, το v - 0.5 αποτυγχάνει, αλλά το v .- 0.5 πετυχαίνει, και πρέπει να καταλάβουμε τι κάνει η τελεία.

Δύο πράγματα, που συνδυάζονται για να δώσουν το επιθυμητό αποτέλεσμα.

1. Εφαρμογή στοιχείο προς στοιχείο

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

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

julia> sqrt.([1, 4, 9])
3-element Vector{Float64}:
 1.0
 2.0
 3.0

2. Επέκταση μονοσυνόλων

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

julia> v .- [0.5, 0.5, 0.5]
3-element Vector{Float64}:
 0.7
 1.0
 1.2

Τι γίνεται όμως με διανύσματα άνισου μήκους;

julia> v .- [0.5, 0.5]
ERROR: DimensionMismatch: arrays could not be broadcast to a common size

julia> v .- [0.5,]
3-element Vector{Float64}:
 0.7
 1.0
 1.2

Γενικά, τα άνισα μήκη αποτελούν σφάλμα, εκτός όταν το ένα έχει μήκος 1 (τεχνικά, διάσταση μονοσυνόλου).

Τα μονοσύνολα όπως το [0.5,] ή απλώς το 0.5 επεκτείνονται αυτόματα στο απαραίτητο μήκος με επανάληψη. Αυτό βρίσκεται στην καρδιά του broadcasting.

Προσπέλαση με θέση

Η επιλογή στοιχείων ενός διανύσματος με τη θέση τους έχει συζητηθεί σε προηγούμενες έννοιες.

a = collect('A':'Z')  # => 26-element Vector{Char}

# index with an integer
a[2]  # => 'B'

# index with a range
 a[12:2:18]  # => ['L', 'N', 'P, 'R']
 
 # index with another vector
 a[ [1, 3, 5] ]  # => ['A', 'C', 'E']

Λογική προσπέλαση με θέση

Είναι επίσης δυνατό να επιλέξεις στοιχεία που ικανοποιούν κάποια λογική έκφραση (τεχνικά, ένα "κατηγόρημα"). Αυτό συνήθως απαιτεί μετάδοση.

julia> a[a .< 'D']
3-element Vector{Char}:
 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
 'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
 'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)

Σε πιο σύνθετες εκφράσεις οι τελείες τείνουν να πολλαπλασιάζονται (αλλά είναι μικρές και εύκολες στην πληκτρολόγηση).

julia> a[a .< 'D' .|| a .> 'W']
6-element Vector{Char}:
 'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
 'B': ASCII/Unicode U+0042 (category Lu: Letter, uppercase)
 'C': ASCII/Unicode U+0043 (category Lu: Letter, uppercase)
 'X': ASCII/Unicode U+0058 (category Lu: Letter, uppercase)
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'Z': ASCII/Unicode U+005A (category Lu: Letter, uppercase)

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

julia> n = 3:10
3:10

julia> n[isodd.(n)]
4-element Vector{Int64}:
 3
 5
 7
 9

Οδηγίες

Είσαι ένας φανατικός παρατηρητής πουλιών που καταγράφει πόσα πουλιά επισκέφτηκαν τον κήπο σου τις τελευταίες επτά μέρες.

Έχεις έξι εργασίες, όλες σχετικές με τον αριθμό των πουλιών που επισκέφτηκαν τον κήπο σου.

1. Έλεγξε πόσα πουλιά επισκέφτηκαν σήμερα

Υλοποίησε τη συνάρτηση today() ώστε να επιστρέφει πόσα πουλιά επισκέφτηκαν τον κήπο σου σήμερα. Οι αριθμοί των πουλιών είναι ταξινομημένοι ανά μέρα, με το πρώτο στοιχείο να είναι ο αριθμός της παλαιότερης μέρας και το τελευταίο στοιχείο τον σημερινό αριθμό.

julia> birds_per_day = [2, 5, 0, 7, 4, 1]
julia> today(birds_per_day)
1

2. Αύξησε τον σημερινό αριθμό

Υλοποίησε τη συνάρτηση increment_todays_count() ώστε να αυξάνει τον σημερινό αριθμό:

julia> birds_per_day = [2, 5, 0, 7, 4, 1]
julia> increment_todays_count(birds_per_day)
[2, 5, 0, 7, 4, 2]

3. Έλεγξε αν υπήρξε μέρα χωρίς επισκέψεις πουλιών

Υλοποίησε τη συνάρτηση has_day_without_birds() που επιστρέφει true αν υπήρξε μέρα κατά την οποία μηδέν πουλιά επισκέφτηκαν τον κήπο· αλλιώς, επέστρεψε false:

julia> birds_per_day = [2, 5, 0, 7, 4, 1]
julia> has_day_without_birds(birds_per_day)
true

4. Υπολόγισε τον αριθμό των πουλιών που επισκέφτηκαν τον κήπο για τις πρώτες μέρες

Υλοποίησε τη συνάρτηση count_for_first_days() που επιστρέφει τον αριθμό των πουλιών που επισκέφτηκαν τον κήπο σου από την αρχή της εβδομάδας, αλλά περιορίζει τον αριθμό στις συγκεκριμένες μέρες από την αρχή της εβδομάδας.

julia> birds_per_day = [2, 5, 0, 7, 4, 1]
julia> count_for_first_days(birds_per_day, 4)
14

5. Υπολόγισε τον αριθμό των πολυάσχολων ημερών

Κάποιες μέρες είναι πιο πολυάσχολες από άλλες. Πολυάσχολη μέρα είναι εκείνη κατά την οποία πέντε ή περισσότερα πουλιά επισκέφτηκαν τον κήπο σου. Υλοποίησε τη συνάρτηση busy_days() ώστε να επιστρέφει τον αριθμό των πολυάσχολων ημερών:

julia> birds_per_day = [2, 5, 0, 7, 4, 1]
julia> busy_days(birds_per_day)
2

6. Υπολόγισε τους μέσους όρους ανά ημέρα της εβδομάδας

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

Υλοποίησε τη συνάρτηση average_per_day() που επιστρέφει τον μέσο όρο για 2 εβδομάδες.

julia> week1 = [7, 2, 9, 1, 3, 0, 10]
julia> week2 = [2, 6, 4, 1, 3, 8, 9]
julia> average_per_day(week1, week2)
[4.5, 4.0, 6.5, 1.0, 4.0, 3.0, 9.5]
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Julia Exercism

Έτοιμος να ξεκινήσεις την άσκηση Παρατηρητής πουλιών;

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