Konzept-Übungen sind Übungen, die darauf ausgelegt sind, bestimmte (Programmier-)Konzepte zu vermitteln. Die Konzepte, die in den Konzept-Übungen vermittelt werden, bilden einen Syllabus. Weitere Informationen dazu, wie du einen Syllabus entwirfst, findest du in der Syllabus-Dokumentation.
Du kannst schnell eine neue Konzept-Übung anlegen, indem du die folgenden Befehle aus dem Stammverzeichnis des Tracks ausführst:
bin/fetch-configlet
bin/configlet create --concept-exercise <slug>
Weitere Informationen findest du in der configlet create-Dokumentation
Die Metadaten einer Konzept-Übung werden im Schlüssel exercises.concept in der config.json-Datei definiert. Die Metadaten definieren die UUID, den Slug und mehr für die Übung.
{
"exercises": {
"concept": [
{
"uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
"slug": "cars-assemble",
"name": "Cars, Assemble!",
"concepts": ["if-statements", "numbers"],
"prerequisites": ["basics"]
}
]
}
}
Jede Konzept-Übung hat ihr eigenes Verzeichnis innerhalb des Verzeichnisses exercises/concept des Tracks. Der Name des Verzeichnisses der Konzept-Übung muss mit der Eigenschaft slug der Konzept-Übung übereinstimmen, wie sie in der config.json-Datei definiert ist.
Eine Konzept-Übung hat vier Arten von Dateien:
Diese Dateien werden den Lernenden gezeigt, um die Übung zu erklären.
.docs/introduction.md: stellt die Konzepte vor, die die Übung den Lernenden vermittelt (erforderlich).docs/instructions.md: enthält die Anweisungen für die Übung (erforderlich).docs/hints.md: gibt den Lernenden Hinweise, damit sie bei einer Übung wieder weiterkommen (erforderlich)Diese Dateien werden den Lernenden nicht gezeigt, sondern dienen dazu, die Metadaten der Übung zu definieren.
.meta/config.json: enthält Meta-Informationen zur Übung (erforderlich).meta/design.md: beschreibt das Design der Übung (erforderlich)Diese Dateien beschreiben Ansätze für die Übung.
.approaches/introduction.md: Einführung in die gebräuchlichsten Ansätze für die Übung (optional).approaches/config.json: Metadaten für die Ansätze (optional).approaches/<approach-slug>/content.md: Beschreibung des Ansatzes (optional).approaches/<approach-slug>/snippet.txt: Snippet, das den Ansatz vorstellt (optional)Diese Dateien beschreiben Artikel für die Übung.
.articles/config.json: Metadaten für die Artikel (optional).articles/<article-slug>/content.md: Beschreibung des Artikels (optional).articles/<article-slug>/snippet.md: Snippet, das den Artikel vorstellt (optional)Die sprachspezifischen Dateien, wie die Implementierungs- und Testdateien. Die Namen dieser Dateien sind trackspezifisch.
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-Implementierung)
├── CarsAssemble.cs (Stub-Implementierung)
└── CarsAssemblyTests.cs (Tests)
Wir setzen bei neuen Übungen auf einen „optimistischen Merge"-Ansatz, bei dem Tracks Übungen in einem „Work in Progress"-Zustand entwickeln können. Der minimale gültige Zustand, der configlet besteht und das Mergen erlaubt, ist:
config.json des Tracks, bei dem status auf wip gesetzt ist..meta/config.json-Datei.docs/introduction.md.docs/instructions.md.docs/hints.md.docs/introduction.md
Zweck: Die Konzepte vorstellen, die die Übung den Lernenden vermittelt.
Vorhandensein: Erforderlich
about.md-Dokument des Konzepts.Ein Beispiel: Die Einführung zu einer „Strings"-Übung könnte einen String einfach als „Folge von Unicode-Zeichen" oder als „Reihe von Bytes" beschreiben, den Nutzenden zeigen, wie man einen String erstellt, und erklären, dass ein String Methoden hat, mit denen man ihn bearbeiten kann. Sofern die Lernenden nicht noch detaillierteres Wissen brauchen, um die Übung zu lösen, sollten diese kurze Erklärung (zusammen mit einem Beispiel für die Syntax) ausreichen, damit sie die Übung lösen können.
# 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
Zweck: Vorlage, aus der eine introduction.md-Datei erzeugt wird.
Vorhandensein: Optional
Das Dokument introduction.md führt die Lernenden in die Konzepte der Übung ein. Jedes Konzept hat außerdem sein eigenes introduction.md-Dokument, das außerhalb des Kontexts einer Übung nicht angezeigt wird.
Wenn die Einführung des Konzepts wortwörtlich in die Einführung der Übung übernommen werden soll, kann eine introduction.md.tpl-Datei verwendet werden. Diese Datei erlaubt es, über Platzhalter auf die Konzept-Einführungen zu verweisen: %{concept:<concept-slug>}.
configlet kann eine introduction.md-Datei aus einer Vorlagendatei erzeugen. In der erzeugten Datei werden die Konzept-Platzhalter durch den Inhalt von introduction des Konzepts ersetzt.
Die Exercism-Website kennt nur das Dokument introduction.md. Es liegt in der Verantwortung des Tracks, die introduction.md zu erzeugen, wenn eine Vorlagendatei verwendet wird.
Tracks können für jede Übung entscheiden, ob sie eine Vorlage verwenden oder nicht. In manchen Fällen ist es vielleicht nicht optimal, die Einführung des Konzepts wortwörtlich zu übernehmen. Entscheide dich immer für das, was den Lernenden die beste Lernerfahrung bietet.
# Introduction
%{concept:variables}
.docs/instructions.md
Zweck: Die Anweisungen für die Übung bereitstellen.
Vorhandensein: Erforderlich
Diese Datei ist in zwei Teile aufgeteilt.
Jede Aufgabe muss folgendem Standard entsprechen:
## 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),Wir legen großen Wert darauf, dass die Inhalte von Exercism für alle sicher sind, und entscheiden deshalb bei der Frage, ob eine Geschichte angemessen ist oder nicht, lieber vorsichtig. Wir sind sorgfältig damit, was wir mergen, aber uns ist klar, dass es schwer ist, zu erkennen, was als problematisch aufgefasst werden könnte. Deshalb gehen wir immer davon aus, dass du in guter Absicht handelst, und tun in der Überprüfung unser Bestes, um Probleme auf nicht konfrontative Weise zu erkennen. Wenn du eine Geschichte mit uns abklären möchtest, erwähne bitte @exercism/leadership, und wir schauen sie uns gemeinsam an. Hier sind einige Richtlinien:
# 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
Zweck: Den Lernenden Hinweise geben, damit sie bei einer Übung wieder weiterkommen.
Vorhandensein: Erforderlich
## General stehen.instructions.md entsprechen (z. B. ## 2. Do Y).## 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`).Die Hinweise anzusehen ist kein „empfohlener" Weg, und wir raten (sanft) davon ab, sie zu nutzen, es sei denn, die Lernenden kommen ohne sie nicht weiter. Insofern lohnt es sich zu bedenken, dass die Lernenden beim Lesen ein wenig verwirrt oder überfordert und vielleicht frustriert sein werden.
# 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
Zweck: Das Design der Übung beschreiben.
Vorhandensein: Erforderlich
Diese Datei enthält Informationen zum Design der Übung, darunter etwa ihr Ziel, ihre Lernziele, was nicht vermittelt werden soll und mehr. Diese Informationen lassen sich dem zugehörigen GitHub-Issue der Übung entnehmen.
Sie existiert, um künftige Maintainer oder Mitwirkende über den Umfang und die Grenzen einer Übung zu informieren und so dem natürlichen Trend entgegenzuwirken, Übungen mit der Zeit immer komplexer zu machen.
# 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
Zweck: Enthält Meta-Informationen zur Übung.
Vorhandensein: Erforderlich
Diese Datei enthält Meta-Informationen zur Übung:
authors: Die GitHub-Benutzernamen des Autors bzw. der Autoren der Übung (erforderlich)
contributors: Die GitHub-Benutzernamen der Mitwirkenden an der Übung (optional)
forked_from: Von welcher Übung bzw. welchen Übungen sie geforkt wurde (erforderlich, wenn die Übung geforkt ist)files: Die Speicherorte der in dieser Übung verwendeten Dateien, relativ zum Verzeichnis der Übung (erforderlich)
solution: die Stub-Implementierungsdatei(en) (erforderlich)test: die Testdatei(en) (erforderlich)exemplar: die Exemplar-Implementierungsdatei(en) (erforderlich)editor: weitere Dateien, die im Editor schreibgeschützt angezeigt werden (optional)invalidator: Dateien, durch deren Änderung eine Lösung veraltet (optional)language_versions: Anforderungen an die Sprachversion (optional)blurb: Eine kurze Beschreibung dieser Übung. Die Länge muss <= 350 sein. Markdown wird nicht unterstützt (erforderlich)source: Die Quelle, auf der diese Übung basiert (optional)source_url: Die URL der Quelle, auf der diese Übung basiert (optional)representer: Meta-Informationen dazu, wie der Representer diese Datei verarbeitet (optional)
version: Eine Ganzzahl für die Version des Representers, die für die Übung verwendet werden soll (erforderlich, wenn der übergeordnete Schlüssel vorhanden ist)icon: Der Slug des Icons (siehe die vollständige Liste der Icons). Wenn nicht angegeben, wird der Slug der Übung verwendet (optional)custom: Beliebige übungsspezifische, nicht standardisierte Daten. Kann verwendet werden, um das Verhalten der Track-Tools pro Übung anzupassen (optional)Wenn jemand sowohl Autor als auch Mitwirkender ist, führe diese Person nur als Autor auf.
{
"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"
}
Angenommen, der Nutzer FSharpForever hat eine Übung namens log-levels für den F#-Track geschrieben. PythonProfessor passt die Übung für den Python-Track an. Später verbessert der Nutzer GladToHelp die Übung.
{
"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
}
}
Beachte:
forked_from korrekt ist.language_versions ist ein freier String, den Tracks nach Belieben verwenden und interpretieren können..approaches/introduction.md
Zweck: Einführung in die gebräuchlichsten Ansätze für die Übung
Vorhandensein: Optional
Diese Datei beschreibt die gebräuchlichsten Ansätze für die Übung. Weitere Informationen dazu, was in diese Datei gehört, findest du in der Dokumentation.
# 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
Zweck: Metadaten für die Ansätze
Vorhandensein: Optional (erforderlich, wenn eine Ansatz-Einführung oder ein Ansatz existiert)
Diese Datei enthält Meta-Informationen zu den Ansätzen der Übung:
introduction: Die GitHub-Benutzernamen der Autoren der Ansatz-Einführung der Übung (optional)
authors: Die GitHub-Benutzernamen der Autoren der Ansatz-Einführung der Übung (erforderlich)
contributors: Die GitHub-Benutzernamen der Mitwirkenden an der Ansatz-Einführung der Übung (optional)
approaches: Ein Array, das die ausführlichen Ansätze auflistet (optional)
uuid: eine V4-UUID, die den Ansatz eindeutig identifiziert. Die UUID muss sowohl innerhalb des Tracks als auch über alle Tracks hinweg eindeutig sein und darf sich nie ändernslug: der Slug des Ansatzes, ein String in Kleinbuchstaben im Kebab-Case. Der Slug muss über alle Ansatz-Slugs innerhalb des Tracks hinweg eindeutig sein. Die Länge muss <= 255 sein.title: der Titel des Ansatzes. Die Länge muss <= 255 sein.blurb: Eine kurze Beschreibung dieses Ansatzes. Die Länge muss <= 350 sein. Markdown wird nicht unterstützt (erforderlich)authors: Die GitHub-Benutzernamen der Autoren des Ansatzes der Übung (erforderlich)
contributors: Die GitHub-Benutzernamen der Mitwirkenden am Ansatz der Übung (optional)
tags: Gib die Bedingungen an, unter denen eine Einsendung mit einem Ansatz verknüpft wird. (optional)
all: Ein Array von Tags, die alle in einer Einsendung vorhanden sein müssen (optional, es sei denn, any hat keine Elemente)any: Ein Array von Tags, von denen mindestens einer in einer Einsendung vorhanden sein muss (optional, es sei denn, all hat keine Elemente)not: keiner der Tags darf in einer Einsendung vorhanden sein (optional){
"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
Zweck: Ausführliche Beschreibung des Ansatzes
Vorhandensein: Optional (erforderlich für Ansätze)
Diese Datei enthält eine ausführliche Beschreibung des Ansatzes. Weitere Informationen dazu, was in diese Datei gehört, findest du in der Dokumentation.
# 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
Zweck: Snippet, das den Ansatz vorstellt
Vorhandensein: Optional (erforderlich für Ansätze)
Diese Datei enthält ein kleines Snippet, das den Ansatz vorstellt. Das Snippet wird auf der Seite „Dig Deeper" einer Übung angezeigt.
Die Anzahl der Zeilen muss <= 8 sein.
Weitere Informationen dazu, was in diese Datei gehört, findest du in der Dokumentation.
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
Zweck: Metadaten für die Artikel
Vorhandensein: Optional (erforderlich, wenn ein Artikel existiert)
Diese Datei enthält Meta-Informationen zu den Artikeln der Übung:
articles: Ein Array, das die ausführlichen Artikel auflistet (optional)
uuid: eine V4-UUID, die den Artikel eindeutig identifiziert. Die UUID muss sowohl innerhalb des Tracks als auch über alle Tracks hinweg eindeutig sein und darf sich nie ändernslug: der Slug des Artikels, ein String in Kleinbuchstaben im Kebab-Case. Der Slug muss über alle Artikel-Slugs innerhalb des Tracks hinweg eindeutig sein. Die Länge muss <= 255 sein.title: der Titel des Artikels. Die Länge muss <= 255 sein.blurb: Eine kurze Beschreibung dieses Artikels. Die Länge muss <= 350 sein. Markdown wird nicht unterstützt (erforderlich)authors: Die GitHub-Benutzernamen der Autoren des Artikels der Übung (erforderlich)
contributors: Die GitHub-Benutzernamen der Mitwirkenden am Artikel der Übung (optional)
{
"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
Zweck: Ausführliche Beschreibung des Ansatzes
Vorhandensein: Optional (erforderlich für Ansätze)
Diese Datei enthält eine ausführliche Beschreibung des Ansatzes. Weitere Informationen dazu, was in diese Datei gehört, findest du in der Dokumentation.
# 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
Zweck: Snippet, das den Ansatz vorstellt
Vorhandensein: Optional (erforderlich für Artikel)
Diese Datei enthält ein kleines Snippet, das den Artikel vorstellt. Das Snippet wird auf der Seite „Dig Deeper" einer Übung angezeigt.
Die Anzahl der Zeilen muss <= 8 sein.
Weitere Informationen dazu, was in diese Datei gehört, findest du in der Dokumentation.
| Method | Mean | Allocated |
| -----: | --------: | --------: |
| Linq | 29.133 ns | 80 B |
| Array | 4.806 ns | - |
Zweck: Den Lernenden einen Ausgangspunkt bieten.
Vorhandensein: Erforderlich
"files.solution" der .meta/config.json-Datei angegeben werden.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
Zweck: Die Korrektheit einer Lösung überprüfen.
Vorhandensein: Erforderlich
instructions.md-Datei verwenden."files.test" der .meta/config.json-Datei angegeben werden.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
Zweck: Die Ziel-Implementierung bereitstellen, auf die die Lernenden hinarbeiten sollen.
Vorhandensein: Erforderlich
"files.exemplar" der .meta/config.json-Datei angegeben werden.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
Zweck: Sicherstellen, dass die Tests ausgeführt werden können.
Vorhandensein: Erforderlich, wenn die Standarddateien nicht ausreichen, um die Tests auszuführen
Manche Sprachen benötigen zusätzliche Dateien, damit die Tests laufen. Beispiele dafür sind die Projektdateien von C# und die package.json-Dateien von Node, ohne die es nicht möglich ist, die Tests auszuführen.
Manche Dateien sind nicht spezifisch für einzelne Übungen, sondern gelten für alle Übungen. Weitere Informationen findest du in der Dokumentation.
Konzept-Übungen sollten nach ihrer Geschichte bzw. ihrem Thema benannt werden, nicht nach ihren Konzepten.
Gute Beispiele für Namen:
Tim from MarketingLucian's Luscious LasagnaCalculator ConundrumUnzulässige Namen:
Booleans: verwendet einen Konzeptnamen statt eines Namens einer GeschichteExercise #1: eine Übung ist keine Geschichte bzw. kein ThemaWenn du eine Übung ohne größere Änderungen forkst, verwende nach Möglichkeit den ursprünglichen Namen.
Jede Übung hat außerdem einen Slug, eine normalisierte Version des Übungsnamens nach den folgenden Regeln:
[a-z0-9-]+)two-fer statt 2-fer)Gute Beispiele für Slugs:
tim-from-marketinglucians-luscious-lasagnacalculator-conundrumUnzulässige Slugs:
TIM-FROM-MARKETING: verwendet keine Kleinbuchstaben (d. h. tim-from-marketing)TimFromMarketing: verwendet kein Kebab-Case (d. h. tim-from-marketing)floating-point-numbers: verwendet einen Konzeptnamen statt eines Namens einer GeschichteEs gibt einen Unterschied darin, wie die Übungsdokumentation den Lernenden angezeigt wird, wenn sie den Editor im Browser statt der Kommandozeile verwenden. Weitere Informationen findest du in diesem Dokument.
Jede Übung hat ein zugehöriges Icon.
Standardmäßig ist das angezeigte Icon dasjenige, dessen Name mit dem Slug der Übung übereinstimmt.
Du kannst das überschreiben, indem du die Eigenschaft icon in der .meta/config.json-Datei der Übung angibst.
Wenn du eine bestehende Übung forkst, gibt es für diese Übung wahrscheinlich schon ein Icon. Falls nicht, eröffne bitte ein Issue im Repository website-icons.