config.json


Il file config.json descrive la configurazione della traccia. Contiene informazioni vitali come gli esercizi e i concetti della traccia.

Metadati

Le seguenti proprietà di primo livello contengono i metadati generali della traccia:

  • language: il linguaggio della traccia (ad es. "C#"). La sua lunghezza deve essere <= 255. (obbligatorio)
  • slug: il linguaggio della traccia come stringa in minuscolo e kebab-case (ad es. "csharp"). La sua lunghezza deve essere <= 255. (obbligatorio)
  • active: un valore boolean che indica se la traccia è attiva (cioè se gli studenti possono unirsi alla traccia sul sito) (obbligatorio)
  • blurb: una breve descrizione del linguaggio. La sua lunghezza deve essere <= 400. (obbligatorio)
  • version: la versione del file config.json (attualmente fissa a 3) (obbligatorio)
  • online_editor: un oggetto che descrive le impostazioni usate per l'editor online: (obbligatorio)
    • indent_style: "space" oppure "tab" (obbligatorio)
    • indent_size: la dimensione dell'indentazione come numero intero (ad es. 4) (obbligatorio)
    • highlightjs_language: l'identificatore del linguaggio per Highlight.js (vedi la lista completa degli identificatori) (opzionale)
  • status: un oggetto che descrive quali funzionalità della v3 devono essere abilitate: (obbligatorio)
    • concept_exercises: un valore boolean che indica se gli esercizi di concetto sono stati creati (obbligatorio). Quando è true, l'interfaccia del sito di Exercism cambia per indicare che gli esercizi di concetto sono disponibili per la traccia.
    • test_runner: un valore boolean che indica se un test runner è stato implementato (obbligatorio). Quando è true, facciamo passare le soluzioni inviate attraverso la nostra infrastruttura di test e mostriamo i risultati sul sito. Il sito permette anche agli studenti di avviare un'esecuzione dei test direttamente dall'editor online.
    • representer: un valore boolean che indica se un representer è stato implementato (obbligatorio)
    • analyzer: un valore boolean che indica se un analyzer è stato implementato (obbligatorio)
  • files: i pattern per le posizioni dei file usati in un esercizio, relativi alla directory dell'esercizio. (opzionale)
    • solution: pattern dei file di implementazione stub (opzionale)
    • test: pattern dei file di test (opzionale)
    • example: pattern dei file di implementazione di esempio (opzionale)
    • exemplar: pattern dei file di implementazione exemplar (opzionale)
    • editor: pattern aggiuntivi dei file dell'editor di sola lettura (opzionale)
  • test_runner: un oggetto che descrive il test runner della traccia (se presente): (obbligatorio se status.test_runner è true)
    • average_run_time: un valore number intero per il numero di secondi che il test runner impiega in media per l'esecuzione (ad es. 4) (obbligatorio se status.test_runner è true)
  • approaches: un oggetto con i metadati sugli approcci della traccia: (obbligatorio se la traccia ha degli approcci)
    • snippet_extension: un valore stringa usato per l'estensione del file dello snippet (ad es. rb) (obbligatorio se la traccia ha degli approcci)

File

Questa chiave serve a specificare le posizioni dei file a livello di traccia. Anziché costringere i maintainer a impostare manualmente la chiave files nei file config.json degli esercizi, configlet può popolarla automaticamente usando questi pattern a livello di traccia.

I pattern dei file definiti nell'oggetto files supportano i seguenti segnaposto:

  • %{kebab_slug}: lo slug dell'esercizio in kebab-case (ad es. bit-manipulation)
  • %{snake_slug}: lo slug dell'esercizio in snake_case (ad es. bit_manipulation)
  • %{camel_slug}: lo slug dell'esercizio in camelCase (ad es. bitManipulation)
  • %{pascal_slug}: lo slug dell'esercizio in PascalCase (ad es. BitManipulation)

Verrà aggiunto a configlet il supporto per usare questi pattern per popolare la chiave files nel file .meta/config.json di un esercizio.

Esempio

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  }
}

Esercizi

La chiave di primo livello exercises è un oggetto con tre possibili chiavi:

  • concept: un array che elenca gli esercizi di concetto della traccia
  • practice: un array che elenca gli esercizi di pratica della traccia
  • foregone: un array che elenca gli slug degli esercizi che la traccia non implementerà

Esercizi di concetto

Ogni esercizio di concetto è una voce nell'array exercises.concept. Gli esercizi sono ordinati sul sito nello stesso ordine in cui sono elencati in questo file e dovrebbero corrispondere all'ordine tipico in cui dovrebbero essere risolti. I seguenti campi compongono un esercizio di concetto:

  • uuid: un UUID V4 che identifica univocamente l'esercizio. L'UUID deve essere univoco sia all'interno della traccia sia in tutte le tracce, e non deve mai cambiare
  • slug: lo slug dell'esercizio, che è una stringa in minuscolo e kebab-case. Lo slug deve essere univoco tra tutti gli slug degli esercizi di concetto e di pratica all'interno della traccia. La sua lunghezza deve essere <= 255.
  • name: il nome dell'esercizio. La sua lunghezza deve essere <= 255.
  • concepts: un array di slug di concetti insegnati da questo esercizio di concetto
  • prerequisites: un array di slug di concetti che devono essere sbloccati prima che uno studente possa iniziare questo esercizio
  • status (opzionale): lo stato dell'esercizio, che è uno tra "wip", "beta" "active" o "deprecated"; se non specificato, il valore predefinito è "active"
    • wip: un esercizio in fase di sviluppo, non pronto per il pubblico. Gli esercizi con questo tag non verranno mostrati agli studenti nell'interfaccia né usati per la logica di sblocco. Possono essere visibili ai maintainer.
    • beta: indica esercizi attivi che sono nuovi e sui quali vorremmo ricevere un feedback. Sul sito mostriamo un'etichetta beta per questi esercizi, con un invito all'azione: "Dacci il tuo feedback".
    • active: lo stato normale degli esercizi attivi
    • deprecated: esercizi che non vengono più mostrati agli studenti che non li hanno iniziati (non utilizzabili in questa fase). Per maggiori informazioni, vedi Esercizi deprecati.

Esempio

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

Esempio di esercizio in fase di sviluppo

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

Esercizi di pratica

Ogni esercizio di pratica è una voce nell'array exercises.practice. I seguenti campi compongono un esercizio di pratica:

  • uuid: un UUID V4 che identifica univocamente l'esercizio. L'UUID deve essere univoco sia all'interno della traccia sia in tutte le tracce, e non deve mai cambiare
  • slug: lo slug dell'esercizio, che è una stringa in minuscolo e kebab-case. Lo slug deve essere univoco tra tutti gli slug degli esercizi di concetto e di pratica all'interno della traccia. La sua lunghezza deve essere <= 255.
  • name: il nome dell'esercizio. La sua lunghezza deve essere <= 255.
  • practices: un array di slug di concetti che l'esercizio aiuta gli studenti a esercitare
  • prerequisites: un array di slug di concetti che devono essere sbloccati prima che uno studente possa iniziare l'esercizio
  • difficulty: un numero che indica la difficoltà dell'esercizio. Il numero deve essere compreso tra 1 (il più facile) e 10 (il più difficile). Il sito interpreta la difficoltà come segue:
    • 1, 2, 3: facile
    • 4, 5, 6, 7: media
    • 8, 9, 10: difficile
  • status (opzionale): lo stato dell'esercizio, che è "wip", "beta", "active" oppure "deprecated"; se non specificato, il valore predefinito è "active"
    • wip: un esercizio in fase di sviluppo, non pronto per il pubblico. Gli esercizi con questo tag non verranno mostrati agli studenti nell'interfaccia né usati per la logica di sblocco. Possono essere visibili ai maintainer.
    • beta: indica esercizi attivi che sono nuovi e sui quali vorremmo ricevere un feedback. Sul sito mostriamo un'etichetta beta per questi esercizi, con un invito all'azione: "Dacci il tuo feedback"
    • active: lo stato normale degli esercizi attivi
    • deprecated: esercizi che non vengono più mostrati agli studenti che non li hanno iniziati (non utilizzabili in questa fase).

Sul sito, l'"Ordine consigliato" degli esercizi di pratica corrisponde all'ordine degli esercizi nell'array practice.

Esempio

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

Esempio di beta

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

Esercizi esclusi

Se una traccia sa di non voler implementare un esercizio definito nel repository problem-specifications, lo slug di quell'esercizio può essere aggiunto alla chiave exercises.foregone. Nel generare l'elenco degli esercizi non implementati della traccia, configlet ignorerà gli esercizi esclusi.

I motivi per cui una traccia potrebbe non voler implementare un esercizio possono essere:

  • L'esercizio non può essere implementato ragionevolmente nel linguaggio. Ad esempio, l'esercizio lens-person richiede che il linguaggio supporti le lenti.
  • L'argomento dell'esercizio non si adatta al linguaggio. Ad esempio, per alcuni linguaggi di alto livello, un esercizio di manipolazione dei bit di basso livello potrebbe non avere senso.

Esempio

{
  "exercises": {
    "foregone": [
      "lens-person"
    ]
  }
}

Concetti

Ogni concetto è una voce nell'array di primo livello concepts. I seguenti campi compongono un concetto:

  • uuid: un UUID V4 che identifica univocamente il concetto. L'UUID deve essere univoco sia all'interno della traccia sia in tutte le tracce, e non deve mai cambiare
  • slug: lo slug del concetto, che è una stringa in minuscolo e kebab-case. Lo slug deve essere univoco tra tutti i concetti all'interno della traccia. La sua lunghezza deve essere <= 255.
  • name: il nome del concetto. La sua lunghezza deve essere <= 255.
  • tags: specifica le condizioni in base alle quali una soluzione inviata viene collegata a un approccio. (opzionale)
    • all: un array di tag che devono essere tutti presenti in una soluzione inviata (opzionale, a meno che any non abbia elementi)
    • any: un array di tag di cui almeno uno deve essere presente in una soluzione inviata (opzionale, a meno che all non abbia elementi)
    • not: nessuno dei tag deve essere presente in una soluzione inviata (opzionale)

Esempio

{
  "concepts": [
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers",
      "tags": {
        "all": [
          "concept:number"
        ]
      }
    }
  ]
}

Funzionalità principali

Le funzionalità principali di un linguaggio descrivono in modo conciso quali sono le caratteristiche più importanti del linguaggio. Servono a presentare agli studenti potenziali le funzionalità più interessanti di un linguaggio. I titoli dovrebbero usare il meno possibile il gergo tecnico, tenendo presente che gli studenti potrebbero non sapere cosa significhi un gergo specifico di un linguaggio prima di impararlo.

Le funzionalità principali sono specificate nel campo di primo livello key_features, definito come un array di oggetti con i seguenti campi:

  • title: un'intestazione concisa per la funzionalità principale. La sua lunghezza deve essere <= 25. Markdown non è supportato.
  • content: una descrizione della funzionalità principale. La sua lunghezza deve essere <= 100. Markdown non è supportato.
  • icon: l'icona da mostrare per la funzionalità. Puoi scegliere l'icona che ritieni adatta, indipendentemente dal suo nome. Si possono usare le seguenti icone:
    • community
    • concurrency
    • cross-platform
    • documentation
    • dynamically-typed
    • easy
    • embeddable
    • evolving
    • expressive
    • extensible
    • fast
    • fun
    • functional
    • garbage-collected
    • general-purpose
    • homoiconic
    • immutable
    • interactive
    • interop
    • multi-paradigm
    • portable
    • powerful
    • productive
    • safe
    • scientific
    • small
    • stable
    • statically-typed
    • tooling
    • web
    • widely-used

Puoi verificare l'aspetto visivo di queste icone nella sezione delle icone delle funzionalità principali.

Devono essere specificate esattamente 6 funzionalità principali.

Esempio

{
  "key_features": [
    {
      "title": "Fault-tolerant",
      "content": "Elixir runs on the Erlang VM, known for running low-latency, distributed and fault-tolerant systems.",
      "icon": "safe"
    },
    ...
  ],
}

Tag

Le tracce possono essere annotate con dei tag, il che permette di cercare le tracce con una certa combinazione di tag.

Una traccia dovrebbe scegliere i propri tag in base all'uso generale del suo linguaggio. Ad esempio, immagina uno studente che pensa: «Vorrei fare machine learning, quale linguaggio dovrei scegliere?» oppure «Vorrei imparare la programmazione funzionale, quale linguaggio dovrei scegliere?». Se il tuo linguaggio sarebbe un buon candidato, assegnagli quel tag. Se il tuo linguaggio supporta alcune idee funzionali ma sono usate raramente, o poche persone ci fanno machine learning, ma è raro, allora non applicare quei tag.

I tag sono specificati nel campo di primo livello tags, definito come un array di stringhe. Si possono usare i seguenti tag (raggruppati per categoria):

Paradigmi

  • paradigm/array: il linguaggio è un linguaggio di programmazione ad array
  • paradigm/declarative: il linguaggio supporta uno stile di programmazione dichiarativo
  • paradigm/functional: il linguaggio supporta uno stile di programmazione funzionale
  • paradigm/imperative: il linguaggio supporta uno stile di programmazione imperativo
  • paradigm/logic: il linguaggio supporta uno stile di programmazione basato sulla logica
  • paradigm/object_oriented: il linguaggio supporta uno stile di programmazione orientato agli oggetti
  • paradigm/procedural: il linguaggio supporta uno stile di programmazione procedurale
  • paradigm/stack-oriented: il linguaggio supporta uno stile di programmazione orientato allo stack

Tipizzazione

  • typing/static: il linguaggio usa la tipizzazione statica
  • typing/gradual: il linguaggio usa la tipizzazione graduale
  • typing/dynamic: il linguaggio usa la tipizzazione dinamica
  • typing/strong: il linguaggio usa la tipizzazione forte
  • typing/weak: il linguaggio usa la tipizzazione debole

Modalità di esecuzione

  • execution_mode/compiled: il codice viene compilato prima di essere eseguito
  • execution_mode/interpreted: il codice viene interpretato direttamente

Piattaforma

  • platform/windows: funziona su Windows
  • platform/mac: funziona su Mac
  • platform/linux: funziona su Linux
  • platform/ios: funziona su iOS
  • platform/android: funziona su Android
  • platform/web: funziona nel browser

Runtime

  • runtime/standalone_executable: viene eseguito come eseguibile autonomo
  • runtime/language_specific: viene eseguito su un runtime specifico del linguaggio
  • runtime/clr: viene eseguito su Common Language Runtime (.NET)
  • runtime/jvm: viene eseguito sulla JVM (Java)
  • runtime/beam: viene eseguito su BEAM (Erlang)
  • runtime/wasmtime: viene eseguito su Wasmtime (WebAssembly)

Usato per

  • used_for/artificial_intelligence: intelligenza artificiale
  • used_for/backends: backend
  • used_for/cross_platform_development: sviluppo multipiattaforma
  • used_for/embedded_systems: sistemi embedded
  • used_for/financial_systems: sistemi finanziari
  • used_for/frontends: frontend
  • used_for/games: giochi
  • used_for/guis: GUI
  • used_for/mobile: mobile
  • used_for/robotics: robotica
  • used_for/scientific_calculations: calcoli scientifici
  • used_for/scripts: script
  • used_for/web_development: sviluppo web

Nota che è del tutto normale includere più tag di una singola categoria.

Esempio

{
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}

Esempio

Questo è un esempio di come può apparire un file config.json valido:

{
  "language": "C#",
  "slug": "csharp",
  "active": true,
  "status": {
    "concept_exercises": true,
    "test_runner": true,
    "representer": false,
    "analyzer": false
  },
  "blurb": "C# is a modern, object-oriented language with lots of great features, such as type-inference and async/await. The tooling is excellent, and there is extensive, well-written documentation.",
  "version": 3,
  "online_editor": {
    "indent_style": "space",
    "indent_size": 4,
    "highlightjs_language": "csharp"
  },
  "test_runner": {
    "average_run_time": 2
  },
  "files": {
    "solution": [
      "%{pascal_slug}.cs"
    ],
    "test": [
      "%{pascal_slug}Tests.cs"
    ],
    "example": [
      ".meta/Example.cs"
    ],
    "exemplar": [
      ".meta/Exemplar.cs"
    ]
  },
  "exercises": {
    "concept": [
      {
        "slug": "lucians-luscious-lasagna",
        "name": "Lucian's Luscious Lasagna",
        "uuid": "7d358894-4fbd-4c91-b49f-d68f1c5aa6bc",
        "concepts": [
          "basics"
        ],
        "prerequisites": []
      },
      {
        "slug": "cars-assemble",
        "name": "Cars, Assemble!",
        "uuid": "93fbc7cf-3a7e-4450-ad22-e30129c36bb9",
        "concepts": [
          "if-statements",
          "numbers"
        ],
        "prerequisites": [
          "basics"
        ],
        "status": "wip"
      }
    ],
    "practice": [
      {
        "slug": "hello-world",
        "name": "Hello, World!",
        "uuid": "6c88f46b-5acb-4fae-a6ec-b48ae3f8168f",
        "practices": [
          "strings"
        ],
        "prerequisites": [
          "basics"
        ],
        "difficulty": 1
      },
      {
        "slug": "leap",
        "name": "Leap",
        "uuid": "8ba15933-29a2-49b1-a9ce-70474bad3007",
        "practices": [
          "if-statements",
          "numbers",
          "operator-precedence"
        ],
        "prerequisites": [
          "if-statements",
          "numbers"
        ],
        "difficulty": 2,
        "status": "beta"
      }
    ]
  },
  "concepts": [
    {
      "uuid": "2eb4a463-355f-46ef-ac55-a75ec5afdf86",
      "slug": "basics",
      "name": "Basics"
    },
    {
      "uuid": "4466e33e-dcd2-4b1f-9d9d-2c4315bf5188",
      "slug": "if-statements",
      "name": "If Statements"
    },
    {
      "uuid": "b9a421b2-c5ff-4213-bd6d-b886da31ea0d",
      "slug": "numbers",
      "name": "Numbers"
    },
    {
      "uuid": "7a86561d-173b-45c0-a53c-1ffd7b9ff259",
      "slug": "strings",
      "name": "Strings"
    }
  ],
  "key_features": [
    {
      "title": "Modern",
      "content": "C# is a modern, fast-evolving language.",
      "icon": "expressive"
    },
    {
      "title": "Cross-platform",
      "content": "C# runs on almost any platform and chipset.",
      "icon": "cross-platform"
    },
    {
      "title": "Multi-paradigm",
      "content": "C# is primarily an object-oriented language, but also has lots of functional features.",
      "icon": "multi-paradigm"
    },
    {
      "title": "General purpose",
      "content": "C# can be used for a wide variety of workloads, like websites, console applications, and even games.",
      "icon": "general-purpose"
    },
    {
      "title": "Tooling",
      "content": "C# has excellent tooling, with linting and advanced refactoring options built-in.",
      "icon": "tooling"
    },
    {
      "title": "Documentation",
      "content": "Documentation is excellent and exhaustive, making it easy to get started with C#.",
      "icon": "documentation"
    }
  ],
  "tags": [
    "paradigm/declarative",
    "paradigm/functional",
    "paradigm/object_oriented",
    "platform/linux",
    "platform/windows",
    "runtime/jvm"
  ]
}