Exercícios de prática


Os exercícios de prática são exercícios concebidos para permitir que os estudantes resolvam um problema arbitrário, com o objetivo de usarem os conceitos que aprenderam até agora.

Queres adicionar o teu primeiro exercício de prática a um percurso? Consulta a documentação para adicionar exercícios de prática ou vê o nosso vídeo explicativo 👇

Note

Podes criar rapidamente a estrutura de um novo exercício de prática executando os seguintes comandos a partir do diretório raiz do percurso:

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

Para mais informações, consulta a documentação do configlet create

Metadados

Os metadados de um exercício de prática são definidos na chave exercises.practice do ficheiro config.json. Os metadados definem o UUID, o slug e muito mais do exercício.

Exemplo

{
  "exercises": {
    "practice": [
      {
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "slug": "leap",
        "name": "Leap",
        "practices": ["if-statements", "numbers", "operator-precedence"],
        "prerequisites": ["if-statements", "numbers"],
        "difficulty": 1
      }
    ]
  }
}

practices

A chave practices deve listar os slugs dos conceitos que este exercício de prática permite ativamente que um estudante pratique.

  • Aparecem na interface como «Pratica este conceito em: TwoFer, Leap, etc»
  • Tenta escolher entre 3 e 8 exercícios que pratiquem cada conceito.
  • Tenta escolher pelo menos dois exercícios que permitam praticar os fundamentos de um conceito.
  • Alguns conceitos são muito comuns (por exemplo, strings). Nesses casos, recomendamos escolher alguns bons exercícios que façam as pessoas pensar nesses conceitos de formas interessantes. Por exemplo, exercícios que exijam UTF-8, concatenação de strings, enumeração de carateres, etc., são todos bons exemplos.

prerequisites

A chave prerequisites lista os conceitos que um estudante tem de ter concluído para poder aceder a este exercício de prática.

  • Aparecem na interface como «Aprende Strings para desbloquear TwoFer»
  • Deve incluir todos os conceitos que um estudante precisa de ter abordado para conseguir completar o exercício de pelo menos uma forma idiomática. Por exemplo, para o exercício TwoFer em Ruby, os pré-requisitos podem incluir strings, optional-params, implicit-return.
  • Para exercícios que possam ser completados com conceitos alternativos (por exemplo, um exercício que se pode resolver com loops ou recursion), o maintainer deve escolher a abordagem com que quer desbloquear o exercício, tendo em conta a progressão do estudante ao longo do percurso. Por exemplo, no caso dos ciclos/recursão, pode achar que este exercício é uma boa prática inicial de loops ou que prefere deixá-lo para mais tarde, para ensinar recursão. Também pode recorrer a um analyzer para incentivar o estudante a experimentar uma abordagem alternativa: «Bom trabalho a resolver isto com ciclos. Talvez também gostes de experimentar resolvê-lo com recursão.»

Ficheiros

Cada exercício de prática tem o seu próprio diretório dentro do diretório exercises/practice do percurso. O nome do diretório do exercício de prática tem de corresponder à propriedade slug do exercício de prática, conforme definido no ficheiro config.json.

Um exercício de prática tem quatro tipos de ficheiros:

Ficheiros de documentação

Estes ficheiros são apresentados ao estudante para ajudar a explicar o exercício.

  • .docs/introduction.md: apresenta o contexto e os antecedentes do exercício (opcional)
  • .docs/introduction.append.md: texto de introdução adicional para acrescentar depois da introdução existente (opcional)
  • .docs/instructions.md: fornece as instruções do exercício (obrigatório)
  • .docs/instructions.append.md: texto de introdução adicional para acrescentar depois das instruções existentes (opcional)
  • .docs/hints.md: fornece pistas ao estudante para o ajudar a desbloquear-se no exercício (opcional)

Ficheiros de metadados

Estes ficheiros não são apresentados ao estudante, mas são usados para definir os metadados do exercício.

  • .meta/config.json: contém informações de metadados sobre o exercício (obrigatório)
  • .meta/design.md: descreve a conceção do exercício (opcional)
  • .meta/tests.toml: contém informações sobre os testes implementados (opcional)

Ficheiros de abordagens

Estes ficheiros descrevem abordagens para o exercício.

  • .approaches/introduction.md: introdução às abordagens mais comuns para o exercício (opcional)
  • .approaches/config.json: metadados das abordagens (opcional)
  • .approaches/<approach-slug>/content.md: descrição da abordagem (opcional)
  • .approaches/<approach-slug>/snippet.txt: snippet que exemplifica a abordagem (opcional)

Ficheiros de artigos

Estes ficheiros descrevem artigos para o exercício.

  • .articles/config.json: metadados dos artigos (opcional)
  • .articles/<article-slug>/content.md: descrição do artigo (opcional)
  • .articles/<article-slug>/snippet.md: snippet que exemplifica o artigo (opcional)

Ficheiros do exercício

Os ficheiros específicos da linguagem, como os ficheiros de implementação e de testes. Os nomes destes ficheiros são específicos de cada percurso.

  • Conjunto de testes: verifica a correção de uma solução.
  • Implementação stub: fornece um ponto de partida para os estudantes.
  • Implementação de exemplo: fornece uma implementação de exemplo que passa em todos os testes.
  • Ficheiros adicionais: garantem que os testes podem ser executados.

Exemplo

exercises
└── practice
    └── isogram
        ├── .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
        |   ├── tests.toml
        |   └── Example.cs (example implementation)
        ├── Isogram.cs (stub implementation)
        └── IsogramTests.cs (tests)

Ficheiro: .docs/introduction.md

Objetivo: Apresentar ao estudante o contexto e os antecedentes do exercício.

Presença: Obrigatório se o exercício implementar um exercício de Problem Specifications com um ficheiro introduction.md

Se o exercício implementar um exercício de Problem Specifications, o conteúdo deste ficheiro deve corresponder ao ficheiro introduction.md do exercício de Problem Specifications. O configlet tem uma funcionalidade para sincronizar automaticamente o conteúdo deste ficheiro.

Se o exercício não se basear num exercício de Problem Specifications, tem em conta o seguinte:

Damos muito valor a tornar o conteúdo do Exercism seguro para todos e, por isso, muitas vezes pecamos por excesso de cautela ao decidir se uma história é apropriada ou não. Embora tenhamos cuidado com o que fazemos merge, sabemos que é difícil ter consciência do que pode ser visto como problemático. Por isso, partimos sempre do princípio de que estás a agir de boa-fé e fazemos o possível por detetar qualquer problema durante a revisão de forma não confrontacional. Se quiseres verificar uma história connosco, menciona @exercism/leadership e vemo-la juntos. Aqui ficam alguns pontos orientadores:

  • Tenta garantir que a história é acolhedora e que todos a conseguem compreender. Se a história tiver piadas internas ou calão regional, tenta pensar em frases alternativas.
  • Tenta escrever exemplos que sejam inclusivos para todos. Por exemplo, considera usar nomes de outras culturas e de géneros variados.
  • Pergunta-te se conheces pessoalmente alguém que se ofenderia com a história. Se for o caso, considera alterá-la para o evitar.

Exemplo

# Introduction

Bob is a lackadaisical teenager. In conversation, his responses are very limited.

Ficheiro: .docs/introduction.append.md

Objetivo: Texto de introdução adicional para acrescentar depois da introdução existente.

Presença: Opcional

Em alguns casos (raros), podes querer ampliar o ficheiro introduction.md do exercício, por exemplo quando o exercício tem testes implementados que não são abrangidos pelas instruções existentes.

Um percurso que não queira que o Bob suporte mensagens não-ASCII pode acrescentar o seguinte:

# Introduction append

## Note

As part of his teenage rebellion, Bob has decided to only communicate using ASCII.

Os ficheiros append devem começar com um cabeçalho H1. Este cabeçalho não é apresentado, mas deve estar presente. O cabeçalho H1 é frequentemente seguido de um cabeçalho H2, que ajuda a separar o conteúdo genérico do conteúdo específico do percurso.

Ficheiro: .docs/instructions.md

Objetivo: Fornecer as instruções do exercício.

Presença: Obrigatório

Se o exercício implementar um exercício de Problem Specifications, o conteúdo deste ficheiro deve corresponder ao ficheiro instructions.md do exercício de Problem Specifications (ou ao ficheiro description.md, se não existir um ficheiro instructions.md). O configlet tem uma funcionalidade para sincronizar automaticamente o conteúdo deste ficheiro.

Se o exercício não se basear num exercício de Problem Specifications, tem em conta o seguinte:

Damos muito valor a tornar o conteúdo do Exercism seguro para todos e, por isso, muitas vezes pecamos por excesso de cautela ao decidir se uma história é apropriada ou não. Embora tenhamos cuidado com o que fazemos merge, sabemos que é difícil ter consciência do que pode ser visto como problemático. Por isso, partimos sempre do princípio de que estás a agir de boa-fé e fazemos o possível por detetar qualquer problema durante a revisão de forma não confrontacional. Se quiseres verificar uma história connosco, menciona @exercism/leadership e vemo-la juntos. Aqui ficam alguns pontos orientadores:

  • Tenta garantir que a história é acolhedora e que todos a conseguem compreender. Se a história tiver piadas internas ou calão regional, tenta pensar em frases alternativas.
  • Tenta escrever exemplos que sejam inclusivos para todos. Por exemplo, considera usar nomes de outras culturas e de géneros variados.
  • Pergunta-te se conheces pessoalmente alguém que se ofenderia com a história. Se for o caso, considera alterá-la para o evitar.

Exemplo

# Instructions

Bob answers 'Sure.' if you ask him a question, such as "How are you?".

He answers 'Whoa, chill out!' if you YELL AT HIM (in all capitals).

He answers 'Calm down, I know what I'm doing!' if you yell a question at him.

He says 'Fine. Be that way!' if you address him without actually saying anything.

He answers 'Whatever.' to anything else.

Ficheiro: .docs/instructions.append.md

Objetivo: Texto de instruções adicional para acrescentar depois das instruções existentes.

Presença: Opcional

Em alguns casos (raros), podes querer ampliar o ficheiro instructions.md do exercício, por exemplo quando o exercício tem testes implementados que não são abrangidos pelas instruções existentes.

# Instructions append

## Note

Bob's conversational partner is a purist when it comes to written communication and always follows normal rules regarding sentence punctuation in English.

Os ficheiros append devem começar com um cabeçalho H1. Este cabeçalho não é apresentado, mas deve estar presente. O cabeçalho H1 é frequentemente seguido de um cabeçalho H2, que ajuda a separar o conteúdo genérico do conteúdo específico do percurso.

Ficheiro: .docs/hints.md

Objetivo: Fornecer pistas ao estudante para o ajudar a desbloquear-se num exercício.

Presença: Opcional

  • Se o estudante ficar bloqueado, permitimos-lhe clicar num botão para pedir uma pista, que mostrará a parte relevante do ficheiro.
  • As pistas devem ser apresentadas como listas de pontos sob cabeçalhos.
  • As pistas devem ser suficientes para desbloquear quase todos os estudantes.
  • As pistas não devem revelar a solução; devem antes apontar para um recurso que a descreva (por exemplo, uma ligação para a documentação da função a usar).
  • As pistas podem usar exemplos de código para explicar conceitos, mas não para esboçar a solução. Por exemplo, num exercício de listas, podem mostrar um snippet de como funciona determinada função de listas, mas não de forma a poder ser copiado e colado diretamente na solução.
  • As pistas têm de aparecer como uma lista Markdown sob um cabeçalho ## General.
  • Se não houver pistas, o cabeçalho deve ser omitido.

Ver as pistas não será um caminho «recomendado» e vamos desencorajar (suavemente) o seu uso, a não ser que o estudante não consiga avançar sem elas. Por isso, vale a pena ter em conta que o estudante que as lê estará um pouco confuso/sobrecarregado e talvez frustrado.

Exemplo

## General

- There are many [built-in methods][integers] to simplify working with integers.

[integers]: https://ruby-doc.org/core-2.7.0/Integer.html

Ficheiro: .meta/design.md

Objetivo: Descrever a conceção do exercício.

Presença: Opcional

Este ficheiro contém informações sobre a conceção do exercício, incluindo coisas como o seu objetivo, os seus objetivos de ensino, o que não ensinar, e mais.

Existe para informar futuros maintainers ou contributors sobre o âmbito e as limitações de um exercício, de modo a evitar a tendência natural para tornar os exercícios mais complexos com o tempo.

Exemplo

# Design

## Goal

The goal of this exercise is help students practice how to work with strings.

## Notes

This exercise does not contain any error handling tests.

Ficheiro: .meta/config.json

Objetivo: Contém informações de metadados sobre o exercício.

Presença: Obrigatório

Este ficheiro contém informações de metadados sobre o exercício:

  • authors: O(s) nome(s) de utilizador do GitHub do(s) autor(es) do exercício (opcional)
    • Inclui revisores se as suas revisões alterarem substancialmente o exercício (ao ponto de parecer que «chegaram lá juntos»)
  • contributors: O(s) nome(s) de utilizador do GitHub do(s) contributor(s) do exercício (opcional)
    • Inclui revisores se as suas revisões forem significativas/acionáveis/acionadas.
  • files: As localizações dos ficheiros usados neste exercício, relativas ao diretório do exercício (obrigatório)
  • language_versions Requisitos de versão da linguagem (opcional)
  • blurb: Uma descrição curta deste exercício. O comprimento tem de ser <= 350. O Markdown não é suportado (obrigatório)
  • source: A fonte em que este exercício se baseia (opcional)
  • source_url: O URL da fonte em que este exercício se baseia (opcional)
  • test_runner: Indica se as soluções deste exercício devem ser testadas no test runner. Por predefinição, assume true se não for especificado. (opcional)
  • representer: Informações de metadados relacionadas com a forma como o representer processa este ficheiro (opcional)
    • version: Um número inteiro para a versão do representer a usar para o exercício (obrigatório se a chave principal estiver presente)
  • icon: O slug do ícone (consulta a lista completa de ícones). Se não for especificado, será usado o slug do exercício (opcional)
  • custom: Quaisquer dados não padrão específicos do exercício. Pode ser usado para personalizar o comportamento das ferramentas do percurso por exercício (opcional)

Se alguém for ao mesmo tempo autor e contributor, indica essa pessoa apenas como autor.

Exemplo

{
  "authors": ["FSharpForever"],
  "files": {
    "solution": ["Bob.fs"],
    "test": ["BobTests.fs"],
    "example": [".meta/Example.fs"]
  },
  "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited"
}

Nota que:

  • A ordem dos autores e dos contributors não é significativa e não tem significado.
  • language_versions é uma string de forma livre que os percursos podem usar e interpretar como quiserem.

Ficheiro: .meta/tests.toml

Objetivo: Contém informações sobre os testes implementados.

Presença: Opcional

Este ficheiro contém informações sobre quais testes estão a ser implementados, desde que o exercício tenha testes definidos no seu ficheiro canonical-data.json dentro do repositório problem-specifications.

Existe para ajudar os maintainers a acompanhar quais testes estão implementados e para documentar (opcionalmente) porque é que determinado teste não está implementado. Também pode ser usado para detetar testes não implementados.

A ferramenta configlet trata de atualizar/sincronizar este ficheiro com os dados do repositório problem-specifications através do comando configlet sync. Ao sincronizar, o configlet pergunta, para cada teste não implementado, se deve incluir esse teste ou não.

Exemplo

# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[3e5c30a8-87e2-4845-a815-a49671ade970]
description = "empty strand"

[a0ea42a6-06d9-4ac6-828c-7ccaccf98fec]
description = "can count one nucleotide in single-character input"

[eca0d565-ed8c-43e7-9033-6cefbf5115b5]
description = "strand with repeated nucleotide"

[40a45eac-c83f-4740-901a-20b22d15a39f]
description = "strand with multiple nucleotides"

[b4c47851-ee9e-4b0a-be70-a86e343bd851]
description = "strand with invalid nucleotides"
include = false
comment = "error handling omitted on purpose"

Ficheiro: .approaches/introduction.md

Objetivo: Introdução às abordagens mais comuns para o exercício

Presença: Opcional

Este ficheiro descreve as abordagens mais comuns para o exercício. Consulta a documentação para mais informações sobre o que deve constar neste ficheiro.

Exemplo

# 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.

Ficheiro: .approaches/config.json

Objetivo: Metadados das abordagens

Presença: Opcional (obrigatório quando existe uma introdução de abordagem ou uma abordagem)

Este ficheiro contém informações de metadados sobre as abordagens do exercício:

  • introduction: O(s) nome(s) de utilizador do GitHub do(s) autor(es) da introdução das abordagens do exercício (opcional)

    • authors: O(s) nome(s) de utilizador do GitHub do(s) autor(es) da introdução das abordagens do exercício (obrigatório)
      • Inclui revisores se as suas revisões alterarem substancialmente a introdução das abordagens do exercício (ao ponto de parecer que «chegaram lá juntos»)
    • contributors: O(s) nome(s) de utilizador do GitHub do(s) contributor(s) da introdução das abordagens do exercício (opcional)
      • Inclui revisores se as suas revisões forem significativas/acionáveis/acionadas.
  • approaches: Um array que lista as abordagens detalhadas (opcional)

    • uuid: um UUID V4 que identifica a abordagem de forma única. O UUID tem de ser único tanto dentro do percurso como em todos os percursos, e nunca pode mudar
    • slug: o slug da abordagem, que é uma string em minúsculas, em kebab-case. O slug tem de ser único entre todos os slugs de abordagens do percurso. O comprimento tem de ser <= 255.
    • title: o título da abordagem. O comprimento tem de ser <= 255.
    • blurb: Uma descrição curta desta abordagem. O comprimento tem de ser <= 350. O Markdown não é suportado (obrigatório)
    • authors: O(s) nome(s) de utilizador do GitHub do(s) autor(es) da abordagem do exercício (obrigatório)
      • Inclui revisores se as suas revisões alterarem substancialmente a abordagem do exercício (ao ponto de parecer que «chegaram lá juntos»)
    • contributors: O(s) nome(s) de utilizador do GitHub do(s) contributor(s) da abordagem do exercício (opcional)
      • Inclui revisores se as suas revisões forem significativas/acionáveis/acionadas.
    • tags: Especifica as condições em que uma submissão é associada a uma abordagem. (opcional)
      • all: Um array de tags que têm de estar todas presentes numa submissão (opcional, a menos que any não tenha elementos)
      • any: Um array de tags das quais pelo menos uma tem de estar presente numa submissão (opcional, a menos que all não tenha elementos)
      • not: nenhuma das tags pode estar presente numa submissão (opcional)

Exemplo

{
  "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"]
    }
  ]
}

Ficheiro: .approaches/<approach-slug>/content.md

Objetivo: Descrição detalhada da abordagem

Presença: Opcional (obrigatório para abordagens)

Este ficheiro contém uma descrição detalhada da abordagem. Consulta a documentação para mais informações sobre o que deve constar neste ficheiro.

Exemplo

# 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.

Ficheiro: .approaches/<approach-slug>/snippet.txt

Objetivo: Snippet que exemplifica a abordagem

Presença: Opcional (obrigatório para abordagens)

Este ficheiro contém um pequeno snippet que exemplifica a abordagem. O snippet é mostrado na página dig deeper de um exercício.

O número de linhas tem de ser <= 8.

Consulta a documentação para mais informações sobre o que deve constar neste ficheiro.

Exemplo

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);

Ficheiro: .article/config.json

Objetivo: Metadados dos artigos

Presença: Opcional (obrigatório quando existe um artigo)

Este ficheiro contém informações de metadados sobre os artigos do exercício:

  • articles: Um array que lista os artigos detalhados (opcional)
    • uuid: um UUID V4 que identifica o artigo de forma única. O UUID tem de ser único tanto dentro do percurso como em todos os percursos, e nunca pode mudar
    • slug: o slug do artigo, que é uma string em minúsculas, em kebab-case. O slug tem de ser único entre todos os slugs de artigos do percurso. O comprimento tem de ser <= 255.
    • title: o título do artigo. O comprimento tem de ser <= 255.
    • blurb: Uma descrição curta deste artigo. O comprimento tem de ser <= 350. O Markdown não é suportado (obrigatório)
    • authors: O(s) nome(s) de utilizador do GitHub do(s) autor(es) do artigo do exercício (obrigatório)
      • Inclui revisores se as suas revisões alterarem substancialmente o artigo do exercício (ao ponto de parecer que «chegaram lá juntos»)
    • contributors: O(s) nome(s) de utilizador do GitHub do(s) contributor(s) do artigo do exercício (opcional)
      • Inclui revisores se as suas revisões forem significativas/acionáveis/acionadas.

Exemplo

{
  "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"]
    }
  ]
}

Ficheiro: .articles/<article-slug>/content.md

Objetivo: Descrição detalhada da abordagem

Presença: Opcional (obrigatório para abordagens)

Este ficheiro contém uma descrição detalhada da abordagem. Consulta a documentação para mais informações sobre o que deve constar neste ficheiro.

Exemplo

# 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 |         - |

Ficheiro: .articles/<article-slug>/snippet.txt

Objetivo: Snippet que exemplifica a abordagem

Presença: Opcional (obrigatório para artigos)

Este ficheiro contém um pequeno snippet que exemplifica o artigo. O snippet é mostrado na página dig deeper de um exercício.

O número de linhas tem de ser <= 8.

Consulta a documentação para mais informações sobre o que deve constar neste ficheiro.

Exemplo

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

Ficheiro: Implementação stub

Objetivo: Fornecer um ponto de partida para os estudantes.

Presença: Obrigatório

  • Concebe o stub de forma a que o estudante saiba onde adicionar código.
  • Para linguagens compiladas, considera ter código que compile, já que as mensagens do compilador podem, por vezes, ser difíceis de compreender para estudantes que estão a começar na linguagem.
  • O código deve ser o mais simples possível.
  • Usa apenas funcionalidades da linguagem introduzidas pelos pré-requisitos (e pelos pré-requisitos destes, e assim por diante).
  • O ficheiro stub é mostrado ao estudante quando programa no navegador e é transferido para o sistema de ficheiros do estudante quando usa a CLI.
  • Os caminhos relativos para o(s) ficheiro(s) de implementação stub têm de ser especificados na chave "files.solution" do ficheiro .meta/config.json.

Exemplo

using System;

public static class Isogram
{
    public static bool IsIsogram(string word)
    {
        throw new NotImplementedException("You need to implement this function.");
    }
}

Ficheiro: Testes

Objetivo: Verificar a correção de uma solução.

Presença: Obrigatório

  • O código deve ser o mais simples possível.
  • Usa apenas funcionalidades da linguagem introduzidas pelos pré-requisitos do exercício (e pelos pré-requisitos destes, e assim por diante).
  • O ficheiro de testes é mostrado ao estudante quando programa no navegador e é transferido para o sistema de ficheiros do estudante quando usa a CLI.
  • O Exercism privilegia que os exercícios de prática sejam concluídos segundo o Desenvolvimento Orientado a Testes. Para o conseguir, há duas opções:
    • O test runner tem de executar os testes pela ordem definida no ficheiro E o conjunto de testes tem de parar na primeira falha; ou
    • Todos os testes exceto o primeiro devem ser ignorados por predefinição.
  • Os caminhos relativos para o(s) ficheiro(s) de teste têm de ser especificados na chave "files.test" do ficheiro .meta/config.json.

Exemplo

using Xunit;

public class IsogramTest
{
    [Fact]
    public void Empty_string() =>
        Assert.True(Isogram.IsIsogram(""));

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Isogram_with_only_lower_case_characters() =>
        Assert.True(Isogram.IsIsogram("isogram"));

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_with_one_duplicated_character() =>
        Assert.False(Isogram.IsIsogram("eleven"));
}

Ficheiro: Implementação de exemplo

Objetivo: Fornecer uma implementação de exemplo que passa em todos os testes.

Presença: Obrigatório

  • Esta implementação serve para verificar que existe uma implementação que passou nos testes. Não é, propositadamente, o código-alvo que queremos que um estudante atinja.
  • Cada percurso deve verificar que a implementação de exemplo passa nos testes na sua configuração de Integração Contínua.
  • Este código não é mostrado aos mentores.
  • O ficheiro de exemplo não é mostrado ao estudante quando programa no navegador e não é transferido para o sistema de ficheiros do estudante quando usa a CLI.
  • Os caminhos relativos para o(s) ficheiro(s) de implementação de exemplo têm de ser especificados na chave "files.example" do ficheiro .meta/config.json.

Exemplo

using System.Linq;

public static class Isogram
{
    public static bool IsIsogram(string word)
    {
        var lowerCaseLetters = word.ToLower().Where(char.IsLetter).ToList();
        return lowerCaseLetters.Distinct().Count() == lowerCaseLetters.Count;
    }
}

Ficheiro: Ficheiros adicionais

Objetivo: Ficheiros adicionais de projeto, de compilação ou de apoio necessários para que os testes possam ser executados.

Presença: Obrigatório se os ficheiros predefinidos não forem suficientes para executar os testes

Algumas linguagens exigem ficheiros adicionais para que os testes sejam executados. Exemplos disso são os ficheiros de projeto do C# e os ficheiros package.json do Node, sem os quais não é possível executar os testes.

Ficheiros partilhados

Alguns ficheiros não são específicos de exercícios individuais, mas aplicam-se a todos os exercícios. Consulta a documentação para mais informações.

Apresentação

Há uma diferença na forma como a documentação de um exercício é apresentada ao estudante quando este usa o editor no navegador em vez da CLI. Consulta este documento para mais informações.

Ícone

Cada exercício tem um ícone associado. Por predefinição, o ícone apresentado é aquele cujo nome corresponde ao slug do exercício. É possível substituir esta opção especificando a propriedade icon no ficheiro .meta/config.json do exercício.

Se estiveres a implementar um exercício a partir dos metadados do problem-specifications, provavelmente já existe um ícone para esse exercício. Se não, abre uma issue no repositório website-icons.