Ασκήσεις εννοιών


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

Note

Μπορείς να δημιουργήσεις γρήγορα τον σκελετό μιας νέας Άσκησης Έννοιας εκτελώντας τις παρακάτω εντολές από τον ριζικό κατάλογο του track:

bin/fetch-configlet
bin/configlet create --concept-exercise <slug>

Για περισσότερες πληροφορίες, δες την τεκμηρίωση του configlet create

Μεταδεδομένα

Τα μεταδεδομένα μιας Άσκησης Έννοιας ορίζονται στο κλειδί exercises.concept του αρχείου config.json. Τα μεταδεδομένα ορίζουν το UUID, το slug και άλλα στοιχεία της άσκησης.

Παράδειγμα

{
  "exercises": {
    "concept": [
      {
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "concepts": ["if-statements", "numbers"],
        "prerequisites": ["basics"]
      }
    ]
  }
}

Αρχεία

Κάθε Άσκηση Έννοιας έχει τον δικό της κατάλογο μέσα στον κατάλογο exercises/concept του track. Το όνομα του καταλόγου της Άσκησης Έννοιας πρέπει να ταιριάζει με την ιδιότητα slug της Άσκησης Έννοιας, όπως ορίζεται στο αρχείο config.json.

Μια Άσκηση Έννοιας έχει τέσσερις τύπους αρχείων:

Αρχεία τεκμηρίωσης

Αυτά τα αρχεία παρουσιάζονται στον μαθητή για να βοηθήσουν στην εξήγηση της άσκησης.

  • .docs/introduction.md: εισάγει τις έννοιες που διδάσκει η άσκηση στον μαθητή (απαιτείται)
  • .docs/instructions.md: παρέχει τις οδηγίες της άσκησης (απαιτείται)
  • .docs/hints.md: παρέχει υποδείξεις στον μαθητή για να τον βοηθήσει να ξεκολλήσει σε μια άσκηση (απαιτείται)

Αρχεία μεταδεδομένων

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

  • .meta/config.json: περιέχει μεταπληροφορίες για την άσκηση (απαιτείται)
  • .meta/design.md: περιγράφει τον σχεδιασμό της άσκησης (απαιτείται)

Αρχεία προσεγγίσεων

Αυτά τα αρχεία περιγράφουν προσεγγίσεις για την άσκηση.

  • .approaches/introduction.md: εισαγωγή στις πιο συνηθισμένες προσεγγίσεις για την άσκηση (προαιρετικό)
  • .approaches/config.json: μεταδεδομένα για τις προσεγγίσεις (προαιρετικό)
  • .approaches/<approach-slug>/content.md: περιγραφή της προσέγγισης (προαιρετικό)
  • .approaches/<approach-slug>/snippet.txt: snippet που παρουσιάζει την προσέγγιση (προαιρετικό)

Αρχεία άρθρων

Αυτά τα αρχεία περιγράφουν άρθρα για την άσκηση.

  • .articles/config.json: μεταδεδομένα για τα άρθρα (προαιρετικό)
  • .articles/<article-slug>/content.md: περιγραφή του άρθρου (προαιρετικό)
  • .articles/<article-slug>/snippet.md: snippet που παρουσιάζει το άρθρο (προαιρετικό)

Αρχεία άσκησης

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

  • Σουίτα δοκιμών: επαληθεύει την ορθότητα μιας λύσης (απαιτείται)
  • Υλοποίηση stub: παρέχει ένα σημείο εκκίνησης για τους μαθητές (απαιτείται)
  • Υλοποίηση exemplar: παρέχει μια ιδιωματική υλοποίηση που περνάει όλες τις δοκιμές (απαιτείται)
  • Πρόσθετα αρχεία: διασφαλίζουν ότι οι δοκιμές μπορούν να εκτελεστούν (προαιρετικό)

Παράδειγμα

exercises
└── concept
    └── cars-assemble
        ├── .approaches
        |   ├── for-loop
        |   |   ├── content.md
        |   |   └── snippet.txt
        |   ├── config.json
        |   └── introduction.md
        ├── .articles
        |   ├── performance
        |   |   ├── content.md
        |   |   └── snippet.md
        |   └── config.json
        ├── .docs
        |   ├── introduction.md
        |   ├── instructions.md
        |   └── hints.md
        ├── .meta
        |   ├── config.json        
        |   ├── design.md
        |   └── Exemplar.cs (υλοποίηση exemplar)
        ├── CarsAssemble.cs (υλοποίηση stub)
        └── CarsAssemblyTests.cs (δοκιμές)

Ελάχιστες έγκυρες προδιαγραφές

Προτιμάμε μια προσέγγιση "αισιόδοξης συγχώνευσης" για τις νέες ασκήσεις, όπου τα track μπορούν να αναπτύσσουν ασκήσεις σε κατάσταση "εργασία σε εξέλιξη". Η ελάχιστη έγκυρη κατάσταση, η οποία θα περάσει το configlet και θα σου επιτρέψει να συγχωνεύσεις, είναι:

  • Έγκυρη καταχώριση στο config.json του track, με το status ορισμένο σε wip.
  • Ένα έγκυρο αρχείο .meta/config.json
  • Τα παρακάτω αρχεία να υπάρχουν, αν και μπορεί να είναι κενά:
    • .docs/introduction.md
    • .docs/instructions.md
    • .docs/hints.md
    • Υλοποίηση stub
    • Αρχείο δοκιμών

Αρχείο: .docs/introduction.md

Σκοπός: Να εισαγάγει τις έννοιες που διδάσκει η άσκηση στον μαθητή.

Παρουσία: Απαιτείται

  • Οι πληροφορίες που παρέχονται πρέπει να δίνουν στον μαθητή τόσο πλαίσιο όσο χρειάζεται για να βρει τη λύση μόνος του.
  • Πρέπει να παρέχονται μόνο οι πληροφορίες που χρειάζονται για να κατανοήσει κανείς τα βασικά της έννοιας και να λύσει την άσκηση. Οι επιπλέον πληροφορίες πρέπει να αφήνονται για το έγγραφο about.md της έννοιας.
  • Οι σύνδεσμοι πρέπει να χρησιμοποιούνται με φειδώ, αν χρησιμοποιούνται καθόλου. Ενώ ένας σύνδεσμος που εξηγεί ένα σύνθετο θέμα όπως η αναδρομή μπορεί να είναι χρήσιμος, για τις περισσότερες έννοιες οι σύνδεσμοι θα παρέχουν περισσότερες πληροφορίες από τις αναγκαίες, οπότε στόχος πρέπει να είναι η σύντομη εξήγηση επιτόπου.
  • Πρέπει να χρησιμοποιούνται οι σωστοί τεχνικοί όροι, ώστε ο μαθητής να μπορεί να αναζητήσει εύκολα περισσότερες πληροφορίες.
  • Τα παραδείγματα κώδικα πρέπει να χρησιμοποιούνται μόνο για την εισαγωγή νέας σύνταξης (δε θα πρέπει να χρειάζεται να ψάξουν οι μαθητές στο διαδίκτυο για παραδείγματα σύνταξης). Σε άλλες περιπτώσεις, δώσε περιγραφές ή συνδέσμους αντί για κώδικα.

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

Παράδειγμα

# Introduction

There are two primary ways to assign objects to names in Ruby - using variables or constants. Variables are always written in snake case. A variable can reference different objects over its lifetime. For example, `my_first_variable` can be defined and redefined many times using the `=` operator:

```ruby
my_first_variable = 1
my_first_variable = "Some string"
my_first_variable = SomeComplexObject.new
```

Αρχείο: .docs/introduction.md.tpl

Σκοπός: Πρότυπο από το οποίο δημιουργείται ένα αρχείο introduction.md.

Παρουσία: Προαιρετικό

Το έγγραφο introduction.md εισάγει τις έννοιες της άσκησης στον μαθητή. Κάθε έννοια έχει επίσης το δικό της introduction.md έγγραφο, το οποίο δεν εμφανίζεται έξω από το πλαίσιο μιας άσκησης.

Αν η εισαγωγή της έννοιας πρέπει να συμπεριληφθεί αυτούσια στην εισαγωγή της άσκησης, μπορεί να χρησιμοποιηθεί ένα αρχείο introduction.md.tpl. Αυτό το αρχείο επιτρέπει την αναφορά σε εισαγωγές εννοιών μέσω placeholders: %{concept:<concept-slug>}.

Το configlet μπορεί να δημιουργήσει ένα αρχείο introduction.md από ένα αρχείο προτύπου. Στο παραγόμενο αρχείο, τα placeholders των εννοιών θα αντικατασταθούν από το περιεχόμενο του introduction της έννοιας.

Η ιστοσελίδα του Exercism γνωρίζει μόνο το έγγραφο introduction.md. Είναι ευθύνη του track να δημιουργήσει το introduction.md όταν χρησιμοποιείται αρχείο προτύπου.

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

Παράδειγμα

# Introduction

%{concept:variables}

Αρχείο: .docs/instructions.md

Σκοπός: Να παρέχει τις οδηγίες της άσκησης.

Παρουσία: Απαιτείται

Αυτό το αρχείο χωρίζεται σε δύο μέρη.

  1. Το πρώτο μέρος εξηγεί την "ιστορία" ή το "θέμα" της άσκησης. Σε γενικές γραμμές δεν πρέπει να περιέχει δείγματα κώδικα.
  2. Το δεύτερο μέρος παρέχει σαφείς οδηγίες για το τι πρέπει να κάνει ο μαθητής, με τη μορφή μίας ή περισσότερων εργασιών.

Κάθε εργασία πρέπει να συμμορφώνεται με το παρακάτω πρότυπο:

  • Να ξεκινά με επικεφαλίδα δεύτερου επιπέδου που αρχίζει με αριθμό (π.χ. ## 1. Do X, ## 2. Do Y).
  • Η επικεφαλίδα πρέπει να περιγράφει τι θα υλοποιήσεις, όχι πώς θα το υλοποιήσεις (π.χ. ## 1. Check if an appointment has already passed).
  • Να περιγράφει ποια συνάρτηση/μέθοδο πρέπει να ορίσει/υλοποιήσει ο μαθητής (π.χ. Implement method X(...) that takes an A and returns a Z),
  • Να παρέχει ένα παράδειγμα χρήσης αυτής της συνάρτησης σε κώδικα. Αυτά τα παραδείγματα πρέπει να είναι διαφορετικά από εκείνα των δοκιμών.

Δίνουμε μεγάλη αξία στο να κάνουμε το περιεχόμενο του Exercism ασφαλές για όλους και γι' αυτό συχνά είμαστε υπερβολικά προσεκτικοί όταν κρίνουμε αν μια ιστορία είναι κατάλληλη ή όχι. Ενώ προσέχουμε τι συγχωνεύουμε, αναγνωρίζουμε ότι είναι δύσκολο να αντιληφθεί κανείς τι μπορεί να θεωρηθεί προβληματικό, οπότε πάντα θα υποθέτουμε ότι ενεργείς καλή τη πίστει και θα κάνουμε ό,τι μπορούμε για να εντοπίζουμε τυχόν ζητήματα στην αξιολόγηση με μη αντιπαραθετικό τρόπο. Αν θέλεις να ελέγξεις μια ιστορία μαζί μας, ανέφερε το @exercism/leadership και θα τη δούμε μαζί. Ακολουθούν μερικά σημεία καθοδήγησης:

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

Παράδειγμα

# Instructions

In this exercise you're going to write some code to help you cook a brilliant lasagna from your favorite cooking book.

## 1. Calculate the remaining oven time in minutes

Define the `Lasagna#remaining_minutes_in_oven` method that takes the actual minutes the lasagna has been in the oven as a parameter and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task.

```ruby
lasagna = Lasagna.new
lasagna.remaining_minutes_in_oven(30)
# => 10
```

Αρχείο: .docs/hints.md

Σκοπός: Να παρέχει υποδείξεις στον μαθητή για να τον βοηθήσει να ξεκολλήσει σε μια άσκηση.

Παρουσία: Απαιτείται

  • Αν ο μαθητής κολλήσει, θα του επιτρέπουμε να κάνει κλικ σε ένα κουμπί ζητώντας μια υπόδειξη, το οποίο θα εμφανίζει το σχετικό μέρος του αρχείου.
  • Οι υποδείξεις πρέπει να είναι σε κουκκίδες κάτω από επικεφαλίδες.
  • Οι υποδείξεις πρέπει να αρκούν για να ξεμπλοκάρουν σχεδόν κάθε μαθητή.
  • Οι υποδείξεις δεν πρέπει να δίνουν τη λύση ολοκληρωμένη, αλλά να παραπέμπουν σε μια πηγή που την περιγράφει (π.χ. σύνδεσμος στην τεκμηρίωση της συνάρτησης που θα χρησιμοποιήσεις).
  • Οι υποδείξεις μπορούν να χρησιμοποιούν δείγματα κώδικα για να εξηγήσουν έννοιες, αλλά όχι για να σκιαγραφήσουν τη λύση. π.χ. σε μια άσκηση με λίστες μπορεί να δείχνουν ένα snippet για το πώς λειτουργεί μια συγκεκριμένη συνάρτηση λίστας, αλλά όχι με τρόπο που να μπορεί να αντιγραφεί και να επικολληθεί απευθείας στη λύση.
  • Γενικές υποδείξεις για την άσκηση μπορούν να εμφανίζονται ως λίστα Markdown κάτω από την επικεφαλίδα ## General.
  • Οι υποδείξεις για συγκεκριμένη εργασία πρέπει να εμφανίζονται ως λίστα Markdown κάτω από επικεφαλίδες που ταιριάζουν με την επικεφαλίδα της εργασίας στο instructions.md (π.χ. ## 2. Do Y).
  • Αν δεν υπάρχουν γενικές υποδείξεις ή υποδείξεις για μια συγκεκριμένη εργασία, οι επικεφαλίδες πρέπει να παραλείπονται. Κάθε επικεφαλίδα πρέπει να ακολουθείται από λίστα Markdown.
  • Δώσε προτεραιότητα στις υποδείξεις για συγκεκριμένη εργασία έναντι των γενικών, καθώς είναι πιο πιθανό να ξεμπλοκάρουν τον μαθητή.
  • Οι επικεφαλίδες των εργασιών πρέπει να περιγράφουν το τι της εργασίας, όχι το πώς.
  • Οι επικεφαλίδες των εργασιών πρέπει να χρησιμοποιούν την κανονική γραφή με κεφαλαίο μόνο στην αρχή (π.χ. ## 2. Check if a book can be borrowed).
  • Οι εργασίες πρέπει να είναι σαφείς ως προς τη μέθοδο/συνάρτηση/τύπο που πρέπει να υλοποιηθεί και την αναμενόμενη τιμή της (π.χ. Implement the 'canBorrowBook' function to check if a book can be borrowed. The function takes a book as its parameter and returns `true` if the book has not already been borrowed; otherwise, return `false`).

Η προβολή των υποδείξεων δε θα είναι "προτεινόμενη" διαδρομή και θα την αποθαρρύνουμε (διακριτικά), εκτός αν ο μαθητής δε μπορεί να προχωρήσει χωρίς αυτήν. Ως εκ τούτου, αξίζει να λάβεις υπόψη ότι ο μαθητής που τη διαβάζει θα είναι λίγο μπερδεμένος/καταπονημένος και ίσως απογοητευμένος.

Παράδειγμα

# Hints

## General

- You need to define a [constant][constant] which should contain the [integer][integers] value specified in the recipe.

## 1. Calculate the remaining oven time in minutes

- You need to define a [method][methods] with a single parameter for the actual time so far.

[constants]: https://www.rubyguides.com/2017/07/ruby-constants/
[integers]: https://ruby-doc.org/core-2.7.0/Integer.html
[methods]: https://launchschool.com/books/ruby/read/methods

Αρχείο: .meta/design.md

Σκοπός: Να περιγράφει τον σχεδιασμό της άσκησης.

Παρουσία: Απαιτείται

Αυτό το αρχείο περιέχει πληροφορίες για τον σχεδιασμό της άσκησης, όπως τον στόχο της, τους διδακτικούς της στόχους, τι να μη διδάσκει και άλλα. Αυτές οι πληροφορίες μπορούν να αντληθούν από το αντίστοιχο GitHub issue της άσκησης.

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

Παράδειγμα

# Design

## Goal

The goal of this exercise is to teach the student the basics of programming in Ruby.

## Learning objectives

- Know what a variable is.
- Know how to define a variable.
- Know how to update a variable.

## Out of scope

- Memory and performance characteristics.
- Method overloads.

## Concepts

The Concepts this exercise unlocks are:

- `basics`: know what a variable is; know how to define a variable; know how to update a variable.

## Prerequisites

There are no prerequisites.

Αρχείο: .meta/config.json

Σκοπός: Περιέχει μεταπληροφορίες για την άσκηση.

Παρουσία: Απαιτείται

Αυτό το αρχείο περιέχει μεταπληροφορίες για την άσκηση:

  • authors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συγγραφέα (ή των συγγραφέων) της άσκησης (απαιτείται)
    • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους αλλάζουν ουσιαστικά την άσκηση (σε βαθμό που να νιώθεις ότι "φτάσατε εκεί μαζί")
  • contributors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συνεισφέροντα (ή των συνεισφερόντων) της άσκησης (προαιρετικό)
    • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους είναι ουσιαστικές/εφαρμόσιμες/εφαρμόστηκαν.
  • forked_from: Από ποια άσκηση (ή ασκήσεις) έγινε fork (απαιτείται αν η άσκηση είναι fork)
  • files: Οι τοποθεσίες των αρχείων που χρησιμοποιούνται σε αυτή την άσκηση, σε σχέση με τον κατάλογο της άσκησης (απαιτείται)
  • language_versions: Απαιτήσεις έκδοσης γλώσσας (προαιρετικό)
  • blurb: Μια σύντομη περιγραφή αυτής της άσκησης. Το μήκος της πρέπει να είναι <= 350. Το Markdown δεν υποστηρίζεται (απαιτείται)
  • source: Η πηγή στην οποία βασίζεται αυτή η άσκηση (προαιρετικό)
  • source_url: Το URL της πηγής στην οποία βασίζεται αυτή η άσκηση (προαιρετικό)
  • representer: Μεταπληροφορίες σχετικά με το πώς ο representer επεξεργάζεται αυτό το αρχείο (προαιρετικό)
    • version: Ένας ακέραιος για την έκδοση του representer που θα χρησιμοποιηθεί για την άσκηση (απαιτείται αν υπάρχει το γονικό κλειδί)
  • icon: Το slug του εικονιδίου (δες την πλήρη λίστα εικονιδίων). Αν δεν οριστεί, θα χρησιμοποιηθεί το slug της άσκησης (προαιρετικό)
  • custom: Οποιαδήποτε δεδομένα ειδικά για την άσκηση, μη τυποποιημένα. Μπορούν να χρησιμοποιηθούν για την προσαρμογή της συμπεριφοράς των εργαλείων του track ανά άσκηση (προαιρετικό)

Αν κάποιος είναι και συγγραφέας και συνεισφέρων, καταχώρισέ τον μόνο ως συγγραφέα.

Ελάχιστο παράδειγμα

{
  "authors": ["FSharpForever"],
  "files": {
    "solution": ["Lasagna.fs"],
    "test": ["LasagnaTests.fs"],
    "exemplar": [".meta/Exemplar.fs"]
  },
  "blurb": "Learn the basics of F# by cooking Lucian's Luscious Lasagna"
}

Πλήρες παράδειγμα

Υπόθεσε ότι ο χρήστης FSharpForever έχει γράψει μια άσκηση με όνομα log-levels για το track F#. Ο PythonProfessor προσαρμόζει την άσκηση για το track Python. Αργότερα, ο χρήστης GladToHelp βελτιώνει την άσκηση.

{
  "authors": ["PythonProfessor"],
  "contributors": ["GladToHelp"],
  "files": {
    "solution": ["log_levels.py"],
    "test": ["log_levels_test.py"],
    "exemplar": [".meta/exemplar.py"],
    "editor": ["test_helper.py"]
  },
  "forked_from": ["fsharp/log-levels"],
  "language_versions": ">=3.7",
  "blurb": "Learn how to work with strings by processing log lines.",
  "source": "Wikipedia",
  "source_url": "https://en.wikipedia.org/wiki/Log_file",
  "representer": {
    "version": 2
  },
  "icon": "logs",
  "custom": {
    "parallel": true
  }
}

Σημείωσε ότι:

  • Η σειρά των συγγραφέων και των συνεισφερόντων δεν είναι σημαντική και δεν έχει κάποια σημασία.
  • Αν κάνεις fork μια άσκηση, μην αναφέρεις τους αρχικούς συγγραφείς ή συνεισφέροντες. Απλώς βεβαιώσου ότι το forked_from είναι σωστό.
  • Αν και δεν είναι συνηθισμένο, είναι δυνατό να κάνεις fork από πολλαπλές ασκήσεις.
  • Το language_versions είναι μια ελεύθερης μορφής συμβολοσειρά που τα track μπορούν να χρησιμοποιούν και να ερμηνεύουν όπως θέλουν.

Αρχείο: .approaches/introduction.md

Σκοπός: Εισαγωγή στις πιο συνηθισμένες προσεγγίσεις για την άσκηση

Παρουσία: Προαιρετικό

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

Παράδειγμα

# Introduction

The key to this exercise is to deal with C# strings being immutable, which means that a `string`'s value cannot be changed.
Therefore, to reverse a string you'll need to create a _new_ `string`.

## Using LINQ

```csharp
public static string Reverse(string input)
{
    return new string(input.Reverse().ToArray());
}
```

For more information, check the [LINQ approach][approach-linq].

## Which approach to use?

If readability is your primary concern (and it usually should be), the LINQ-based approach is hard to beat.

Αρχείο: .approaches/config.json

Σκοπός: Μεταδεδομένα για τις προσεγγίσεις

Παρουσία: Προαιρετικό (απαιτείται όταν υπάρχει εισαγωγή προσεγγίσεων ή προσέγγιση)

Αυτό το αρχείο περιέχει μεταπληροφορίες για τις προσεγγίσεις της άσκησης:

  • introduction: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συγγραφέα (ή των συγγραφέων) της εισαγωγής των προσεγγίσεων της άσκησης (προαιρετικό)

    • authors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συγγραφέα (ή των συγγραφέων) της εισαγωγής των προσεγγίσεων της άσκησης (απαιτείται)
      • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους αλλάζουν ουσιαστικά την εισαγωγή των προσεγγίσεων της άσκησης (σε βαθμό που να νιώθεις ότι "φτάσατε εκεί μαζί")
    • contributors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συνεισφέροντα (ή των συνεισφερόντων) της εισαγωγής των προσεγγίσεων της άσκησης (προαιρετικό)
      • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους είναι ουσιαστικές/εφαρμόσιμες/εφαρμόστηκαν.
  • approaches: Ένας πίνακας που απαριθμεί τις αναλυτικές προσεγγίσεις (προαιρετικό)

    • uuid: ένα UUID V4 που προσδιορίζει μοναδικά την προσέγγιση. Το UUID πρέπει να είναι μοναδικό τόσο εντός του track όσο και σε όλα τα track, και δεν πρέπει ποτέ να αλλάζει
    • slug: το slug της προσέγγισης, που είναι μια συμβολοσειρά με πεζά γράμματα σε kebab-case. Το slug πρέπει να είναι μοναδικό σε όλα τα slug προσεγγίσεων εντός του track. Το μήκος του πρέπει να είναι <= 255.
    • title: ο τίτλος της προσέγγισης. Το μήκος του πρέπει να είναι <= 255.
    • blurb: Μια σύντομη περιγραφή αυτής της προσέγγισης. Το μήκος της πρέπει να είναι <= 350. Το Markdown δεν υποστηρίζεται (απαιτείται)
    • authors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συγγραφέα (ή των συγγραφέων) της προσέγγισης της άσκησης (απαιτείται)
      • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους αλλάζουν ουσιαστικά την προσέγγιση της άσκησης (σε βαθμό που να νιώθεις ότι "φτάσατε εκεί μαζί")
    • contributors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συνεισφέροντα (ή των συνεισφερόντων) της προσέγγισης της άσκησης (προαιρετικό)
      • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους είναι ουσιαστικές/εφαρμόσιμες/εφαρμόστηκαν.
    • tags: Καθορίζουν τις συνθήκες υπό τις οποίες μια υποβολή συνδέεται με μια προσέγγιση. (προαιρετικό)
      • all: Ένας πίνακας από ετικέτες που πρέπει να υπάρχουν όλες σε μια υποβολή (προαιρετικό, εκτός αν το any δεν έχει στοιχεία)
      • any: Ένας πίνακας από ετικέτες από τις οποίες τουλάχιστον μία πρέπει να υπάρχει σε μια υποβολή (προαιρετικό, εκτός αν το all δεν έχει στοιχεία)
      • not: καμία από τις ετικέτες δεν πρέπει να υπάρχει σε μια υποβολή (προαιρετικό)

Παράδειγμα

{
  "introduction": {
    "authors": ["erikschierboom"]
  },
  "approaches": [
    {
      "uuid": "448fb2b4-18ab-4e55-aa54-ad4ed6d5f7f6",
      "slug": "span",
      "title": "Use Span<T>",
      "blurb": "Use Span<T> to efficiently reverse a string.",
      "authors": ["erikschierboom"]
    }
  ]
}

Αρχείο: .approaches/<approach-slug>/content.md

Σκοπός: Αναλυτική περιγραφή της προσέγγισης

Παρουσία: Προαιρετικό (απαιτείται για προσεγγίσεις)

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

Παράδειγμα

# Span

```csharp
Span<char> chars = stackalloc char[input.Length];
for (var i = 0; i < input.Length; i++)
{
    chars[input.Length - 1 - i] = input[i];
}
return new string(chars);
```

This `Span<T>` approach uses a `for` loop.

Αρχείο: .approaches/<approach-slug>/snippet.txt

Σκοπός: Snippet που παρουσιάζει την προσέγγιση

Παρουσία: Προαιρετικό (απαιτείται για προσεγγίσεις)

Αυτό το αρχείο περιέχει ένα μικρό snippet που παρουσιάζει την προσέγγιση. Το snippet εμφανίζεται στη σελίδα Dig Deeper μιας άσκησης.

Ο αριθμός των γραμμών του πρέπει να είναι <= 8.

Δες την τεκμηρίωση για περισσότερες πληροφορίες σχετικά με το τι πρέπει να περιέχει αυτό το αρχείο.

Παράδειγμα

Span<char> chars = stackalloc char[input.Length];
for (var i = 0; i < input.Length; i++)
{
    chars[input.Length - 1 - i] = input[i];
}
return new string(chars);

Αρχείο: .article/config.json

Σκοπός: Μεταδεδομένα για τα άρθρα

Παρουσία: Προαιρετικό (απαιτείται όταν υπάρχει άρθρο)

Αυτό το αρχείο περιέχει μεταπληροφορίες για τα άρθρα της άσκησης:

  • articles: Ένας πίνακας που απαριθμεί τα αναλυτικά άρθρα (προαιρετικό)
    • uuid: ένα UUID V4 που προσδιορίζει μοναδικά το άρθρο. Το UUID πρέπει να είναι μοναδικό τόσο εντός του track όσο και σε όλα τα track, και δεν πρέπει ποτέ να αλλάζει
    • slug: το slug του άρθρου, που είναι μια συμβολοσειρά με πεζά γράμματα σε kebab-case. Το slug πρέπει να είναι μοναδικό σε όλα τα slug άρθρων εντός του track. Το μήκος του πρέπει να είναι <= 255.
    • title: ο τίτλος του άρθρου. Το μήκος του πρέπει να είναι <= 255.
    • blurb: Μια σύντομη περιγραφή αυτού του άρθρου. Το μήκος της πρέπει να είναι <= 350. Το Markdown δεν υποστηρίζεται (απαιτείται)
    • authors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συγγραφέα (ή των συγγραφέων) του άρθρου της άσκησης (απαιτείται)
      • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους αλλάζουν ουσιαστικά το άρθρο της άσκησης (σε βαθμό που να νιώθεις ότι "φτάσατε εκεί μαζί")
    • contributors: Το όνομα χρήστη (ή τα ονόματα χρηστών) στο GitHub του συνεισφέροντα (ή των συνεισφερόντων) του άρθρου της άσκησης (προαιρετικό)
      • Συμπεριλαμβανομένων των αξιολογητών αν οι αξιολογήσεις τους είναι ουσιαστικές/εφαρμόσιμες/εφαρμόστηκαν.

Παράδειγμα

{
  "articles": [
    {
      "uuid": "6db71962-62d5-448b-a980-c20ae41013ed",
      "slug": "performance",
      "title": "Optimizing performance",
      "blurb": "Explore how to most efficiently reverse a string and what the trade-offs are.",
      "authors": ["erikschierboom"]
    }
  ]
}

Αρχείο: .articles/<article-slug>/content.md

Σκοπός: Αναλυτική περιγραφή της προσέγγισης

Παρουσία: Προαιρετικό (απαιτείται για προσεγγίσεις)

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

Παράδειγμα

# Performance

In this document, we'll find out which approach is the most performant one.

## Benchmark results

| Method |      Mean |     Error |    StdDev |    Median | Allocated |
| -----: | --------: | --------: | --------: | --------: | --------: |
|   Linq | 29.133 ns | 0.5865 ns | 0.5486 ns | 28.984 ns |      80 B |
|  Array |  4.806 ns | 0.4999 ns | 1.4739 ns |  3.967 ns |         - |

Αρχείο: .articles/<article-slug>/snippet.txt

Σκοπός: Snippet που παρουσιάζει την προσέγγιση

Παρουσία: Προαιρετικό (απαιτείται για άρθρα)

Αυτό το αρχείο περιέχει ένα μικρό snippet που παρουσιάζει το άρθρο. Το snippet εμφανίζεται στη σελίδα Dig Deeper μιας άσκησης.

Ο αριθμός των γραμμών του πρέπει να είναι <= 8.

Δες την τεκμηρίωση για περισσότερες πληροφορίες σχετικά με το τι πρέπει να περιέχει αυτό το αρχείο.

Παράδειγμα

| Method |      Mean | Allocated |
| -----: | --------: | --------: |
|   Linq | 29.133 ns |      80 B |
|  Array |  4.806 ns |         - |

Αρχείο: Υλοποίηση stub

Σκοπός: Να παρέχει ένα σημείο εκκίνησης για τους μαθητές.

Παρουσία: Απαιτείται

  • Σχεδίασε το stub έτσι ώστε ο μαθητής να ξέρει πού να προσθέσει κώδικα.
  • Όρισε stub για κάθε σύνταξη που δεν εισάγεται στην άσκηση. Για τις περισσότερες ασκήσεις, αυτό σημαίνει τον ορισμό stub συναρτήσεων/μεθόδων.
  • Για μεταγλωττιζόμενες γλώσσες, σκέψου να έχεις κώδικα που μεταγλωττίζεται, καθώς τα μηνύματα του μεταγλωττιστή μπορεί μερικές φορές να είναι δυσνόητα για μαθητές που είναι νέοι στη γλώσσα.
  • Ο κώδικας πρέπει να είναι όσο το δυνατόν πιο απλός.
  • Χρησιμοποίησε μόνο δυνατότητες της γλώσσας που εισάγονται από την άσκηση ή τα προαπαιτούμενά της (και τα δικά τους προαπαιτούμενα, κ.ο.κ.).
  • Το αρχείο stub εμφανίζεται στον μαθητή όταν προγραμματίζει μέσα στον browser και κατεβαίνει στο σύστημα αρχείων του μαθητή όταν χρησιμοποιεί τη γραμμή εντολών.
  • Οι σχετικές διαδρομές προς το αρχείο (ή τα αρχεία) υλοποίησης stub πρέπει να καθορίζονται στο κλειδί "files.solution" του αρχείου .meta/config.json.

Παράδειγμα

class Lasagna
  def remaining_minutes_in_oven(actual_minutes_in_oven)
    raise NotImplementedError, 'Please implement the Lasagna#remaining_minutes_in_oven method'
  end

  def preparation_time_in_minutes(layers)
    raise NotImplementedError, 'Please implement the Lasagna#preparation_time_in_minutes method'
  end
end

Αρχείο: Δοκιμές

Σκοπός: Να επαληθεύει την ορθότητα μιας λύσης.

Παρουσία: Απαιτείται

  • Οι δοκιμές δεν πρέπει να χρησιμοποιούν τα παραδείγματα από το αρχείο instructions.md.
  • Ο κώδικας πρέπει να είναι όσο το δυνατόν πιο απλός.
  • Χρησιμοποίησε μόνο δυνατότητες της γλώσσας που εισάγονται από τα προαπαιτούμενα της άσκησης (και τα δικά τους προαπαιτούμενα, κ.ο.κ.).
  • Το αρχείο δοκιμών δεν εμφανίζεται στον μαθητή όταν προγραμματίζει μέσα στον browser, αλλά κατεβαίνει στο σύστημα αρχείων του μαθητή όταν χρησιμοποιεί τη γραμμή εντολών.
  • Οι σχετικές διαδρομές προς το αρχείο (ή τα αρχεία) δοκιμών πρέπει να καθορίζονται στο κλειδί "files.test" του αρχείου .meta/config.json.

Παράδειγμα

require 'minitest/autorun'
require_relative 'lasagna'

class LasagnaTest < Minitest::Test
  def test_remaining_minutes_in_oven
    assert_equal 15, Lasagna.new.remaining_minutes_in_oven(25)
  end

  def test_preparation_time_in_minutes_with_one_layer
    assert_equal 2, Lasagna.new.preparation_time_in_minutes(1)
  end

  def test_preparation_time_in_minutes_with_multiple_layers
    assert_equal 8, Lasagna.new.preparation_time_in_minutes(4)
  end
end

Αρχείο: Υλοποίηση exemplar

Σκοπός: Να παρέχει την υλοποίηση-στόχο στην οποία πρέπει να στοχεύσει ο μαθητής.

Παρουσία: Απαιτείται

  • Αυτή η υλοποίηση είναι ο κώδικας-στόχος στον οποίο θέλουμε να στοχεύσει ο μαθητής.
  • Αυτός ο κώδικας θα εμφανίζεται στους μέντορες ως ο "στόχος" όταν γράφουν σχόλια
  • Η υλοποίηση πρέπει να χρησιμοποιεί μόνο δυνατότητες της γλώσσας που εισάγονται από την άσκηση ή τα προαπαιτούμενά της (και τα δικά τους προαπαιτούμενα, κ.ο.κ.).
  • Το αρχείο exemplar δεν εμφανίζεται στον μαθητή όταν προγραμματίζει μέσα στον browser και δεν κατεβαίνει στο σύστημα αρχείων του μαθητή όταν χρησιμοποιεί τη γραμμή εντολών.
  • Το αρχείο exemplar θα εμφανίζεται στους μέντορες όταν σχολιάζουν λύσεις ή representations.
  • Οι σχετικές διαδρομές προς το αρχείο (ή τα αρχεία) υλοποίησης exemplar πρέπει να καθορίζονται στο κλειδί "files.exemplar" του αρχείου .meta/config.json.

Παράδειγμα

class Lasagna
  EXPECTED_MINUTES_IN_OVEN = 40
  PREPARATION_MINUTES_PER_LAYER = 2

  def remaining_minutes_in_oven(actual_minutes_in_oven)
    EXPECTED_MINUTES_IN_OVEN - actual_minutes_in_oven
  end

  def preparation_time_in_minutes(layers)
    layers * PREPARATION_MINUTES_PER_LAYER
  end
end

Αρχείο: Πρόσθετα αρχεία

Σκοπός: Να διασφαλίζουν ότι οι δοκιμές μπορούν να εκτελεστούν.

Παρουσία: Απαιτείται αν τα προεπιλεγμένα αρχεία δεν αρκούν για να εκτελεστούν οι δοκιμές

Ορισμένες γλώσσες απαιτούν πρόσθετα αρχεία για να εκτελεστούν οι δοκιμές. Παραδείγματα είναι τα αρχεία έργου της C# και τα αρχεία package.json του Node, χωρίς τα οποία δεν θα είναι δυνατή η εκτέλεση των δοκιμών.

Κοινόχρηστα αρχεία

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

Ονομασία

Οι Ασκήσεις Εννοιών πρέπει να ονομάζονται σύμφωνα με την ιστορία/το θέμα τους, όχι σύμφωνα με τις έννοιές τους.

Καλά παραδείγματα ονομάτων:

  • Tim from Marketing
  • Lucian's Luscious Lasagna
  • Calculator Conundrum

Μη αποδεκτά ονόματα:

  • Booleans: χρησιμοποιεί το όνομα μιας έννοιας, όχι μιας ιστορίας
  • Exercise #1: μια άσκηση δεν είναι ιστορία/θέμα

Όταν κάνεις fork μια άσκηση χωρίς σημαντικές αλλαγές, χρησιμοποίησε το αρχικό όνομα όταν είναι δυνατό.

Slugs

Κάθε άσκηση έχει επίσης ένα slug, το οποίο είναι μια κανονικοποιημένη εκδοχή του ονόματος της άσκησης σύμφωνα με τους παρακάτω κανόνες:

  1. Χρησιμοποίησε πεζά γράμματα.
  2. Χρησιμοποίησε kebab-case.
  3. Χρησιμοποίησε λατινικούς αλφαριθμητικούς χαρακτήρες και παύλες (Regexp: [a-z0-9-]+)
  4. Προτίμησε τους αριθμούς γραμμένους με λέξεις αντί για ψηφία, εκτός αν υπάρχει συγκεκριμένος λόγος να προτιμήσεις το ψηφίο (π.χ. two-fer αντί για 2-fer)

Καλά παραδείγματα slug:

  • tim-from-marketing
  • lucians-luscious-lasagna
  • calculator-conundrum

Μη αποδεκτά slug:

  • TIM-FROM-MARKETING: δε χρησιμοποιεί πεζά γράμματα (δηλ. tim-from-marketing)
  • TimFromMarketing: δε χρησιμοποιεί kebab-case (δηλ. tim-from-marketing)
  • floating-point-numbers: χρησιμοποιεί το όνομα μιας έννοιας, όχι μιας ιστορίας

Παρουσίαση

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

Εικονίδιο

Κάθε άσκηση έχει ένα συνοδευτικό εικονίδιο. Από προεπιλογή, το εικονίδιο που εμφανίζεται είναι αυτό του οποίου το όνομα ταιριάζει με το slug της άσκησης. Μπορείς να το παρακάμψεις αυτό καθορίζοντας την ιδιότητα icon στο αρχείο .meta/config.json της άσκησης.

Αν κάνεις fork μια υπάρχουσα άσκηση, πιθανότατα υπάρχει ήδη εικονίδιο για αυτή την άσκηση. Αν όχι, άνοιξε ένα issue στο αποθετήριο website-icons.