config.json


El archivo config.json describe la configuración del track. Contiene información esencial, como los ejercicios y los conceptos del track.

Metadatos

Las siguientes propiedades de nivel superior contienen metadatos generales del track:

  • language: el lenguaje del track (por ejemplo, "C#"). Su longitud debe ser <= 255. (obligatorio)
  • slug: el lenguaje del track como un string en minúsculas en formato kebab-case (por ejemplo, "csharp"). Su longitud debe ser <= 255. (obligatorio)
  • active: un valor boolean que indica si el track está activo (es decir, si los estudiantes pueden unirse al track en el sitio web) (obligatorio)
  • blurb: una descripción breve del lenguaje. Su longitud debe ser <= 400. (obligatorio)
  • version: la versión del archivo config.json (actualmente fijada en 3) (obligatorio)
  • online_editor: un objeto que describe la configuración que se usa para el editor en línea: (obligatorio)
    • indent_style: "space" o "tab" (obligatorio)
    • indent_size: el tamaño de la indentación como un número entero (por ejemplo, 4) (obligatorio)
    • highlightjs_language: el identificador de lenguaje para Highlight.js (consulta la lista completa de identificadores) (opcional)
  • status: un objeto que describe qué funcionalidades v3 deben habilitarse: (obligatorio)
    • concept_exercises: un valor boolean que indica si se han creado los ejercicios de concepto (obligatorio). Cuando es true, la interfaz del sitio web de Exercism cambia para indicar que hay ejercicios de concepto disponibles para el track.
    • test_runner: un valor boolean que indica si se ha implementado un ejecutor de pruebas (obligatorio). Cuando es true, hacemos pasar las soluciones enviadas por nuestra infraestructura de pruebas y mostramos los resultados en el sitio web. El sitio web también permite que los estudiantes inicien una ejecución de pruebas desde el editor en línea.
    • representer: un valor boolean que indica si se ha implementado un representador (obligatorio)
    • analyzer: un valor boolean que indica si se ha implementado un analizador (obligatorio)
  • files: los patrones que indican las ubicaciones de los archivos que se usan en un ejercicio, relativas al directorio del ejercicio. (opcional)
    • solution: patrón de archivo(s) de implementación inicial (opcional)
    • test: patrón de archivo(s) de prueba (opcional)
    • example: patrón de archivo(s) de implementación de ejemplo (opcional)
    • exemplar: patrón de archivo(s) de implementación ejemplar (opcional)
    • editor: patrones de archivo(s) adicionales de solo lectura para el editor (opcional)
  • test_runner: un objeto que describe el ejecutor de pruebas del track (si lo hay): (obligatorio si status.test_runner es true)
    • average_run_time: un valor number entero para la cantidad de segundos que tarda el ejecutor de pruebas en ejecutarse en promedio (por ejemplo, 4) (obligatorio si status.test_runner es true)
  • approaches: un objeto con metadatos sobre los enfoques del track: (obligatorio si el track tiene algún enfoque)
    • snippet_extension: un string que se usa para la extensión del archivo de fragmento (por ejemplo, rb) (obligatorio si el track tiene algún enfoque)

Archivos

Esta clave se usa para especificar las ubicaciones de archivos de todo el track. En lugar de que los mantenedores tengan que establecer manualmente la clave files en los archivos config.json de los ejercicios, configlet puede rellenarla automáticamente usando estos patrones de todo el track.

Los patrones de archivos definidos en el objeto files admiten los siguientes marcadores:

  • %{kebab_slug}: el slug del ejercicio en kebab-case (por ejemplo, bit-manipulation)
  • %{snake_slug}: el slug del ejercicio en snake_case (por ejemplo, bit_manipulation)
  • %{camel_slug}: el slug del ejercicio en camelCase (por ejemplo, bitManipulation)
  • %{pascal_slug}: el slug del ejercicio en PascalCase (por ejemplo, BitManipulation)

Se agregará a configlet la capacidad de usar estos patrones para rellenar la clave files en el archivo .meta/config.json de un ejercicio.

Ejemplo

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

Ejercicios

La clave exercises de nivel superior es un objeto con tres claves posibles:

  • concept: es un array que lista los ejercicios de concepto del track
  • practice: es un array que lista los ejercicios de práctica del track
  • foregone: es un array que lista los slugs de los ejercicios que el track no implementará

Ejercicios de concepto

Cada ejercicio de concepto es una entrada del array exercises.concept. Los ejercicios se ordenan en el sitio web en el mismo orden en que aparecen en este archivo, y deben coincidir con el orden típico en que conviene resolverlos. Un ejercicio de concepto se compone de los siguientes campos:

  • uuid: un UUID V4 que identifica el ejercicio de forma única. El UUID debe ser único tanto dentro del track como en todos los tracks, y nunca debe cambiar
  • slug: el slug del ejercicio, que es un string en minúsculas en formato kebab-case. El slug debe ser único entre todos los slugs de ejercicios de concepto y de práctica del track. Su longitud debe ser <= 255.
  • name: el nombre del ejercicio. Su longitud debe ser <= 255.
  • concepts: un array de slugs de conceptos que enseña este ejercicio de concepto
  • prerequisites: un array de slugs de conceptos que deben estar desbloqueados antes de que un estudiante pueda empezar este ejercicio
  • status (opcional): el estado del ejercicio, que es uno de "wip", "beta", "active" o "deprecated"; su valor predeterminado es "active" si no se especifica
    • wip: un ejercicio en desarrollo que aún no está listo para el público. Los ejercicios con esta etiqueta no se muestran a los estudiantes en la interfaz ni se usan para la lógica de desbloqueo. Pueden aparecer para los mantenedores.
    • beta: indica que son ejercicios activos, nuevos y sobre los que nos gustaría recibir comentarios. En el sitio mostramos una etiqueta beta en estos ejercicios, con una llamada a la acción que dice «Por favor, envíanos tus comentarios».
    • active: el estado normal de los ejercicios activos
    • deprecated: ejercicios que ya no se muestran a los estudiantes que no los han empezado (no se pueden usar en esta etapa). Consulta los ejercicios obsoletos para obtener más información.

Ejemplo

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

Ejemplo de un ejercicio en desarrollo

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

Ejercicios de práctica

Cada ejercicio de práctica es una entrada del array exercises.practice. Un ejercicio de práctica se compone de los siguientes campos:

  • uuid: un UUID V4 que identifica el ejercicio de forma única. El UUID debe ser único tanto dentro del track como en todos los tracks, y nunca debe cambiar
  • slug: el slug del ejercicio, que es un string en minúsculas en formato kebab-case. El slug debe ser único entre todos los slugs de ejercicios de concepto y de práctica del track. Su longitud debe ser <= 255.
  • name: el nombre del ejercicio. Su longitud debe ser <= 255.
  • practices: un array de slugs de conceptos que el ejercicio ayuda a los estudiantes a practicar
  • prerequisites: un array de slugs de conceptos que deben estar desbloqueados antes de que un estudiante pueda empezar el ejercicio
  • difficulty: un número que indica la dificultad del ejercicio. El número debe estar en el rango de 1 (la más fácil) a 10 (la más difícil). El sitio web interpreta la dificultad así:
    • 1,2,3: fácil
    • 4,5,6,7: media
    • 8,9,10: difícil
  • status (opcional): el estado del ejercicio, que es "wip", "beta", "active" o "deprecated"; su valor predeterminado es "active" si no se especifica
    • wip: un ejercicio en desarrollo que aún no está listo para el público. Los ejercicios con esta etiqueta no se muestran a los estudiantes en la interfaz ni se usan para la lógica de desbloqueo. Pueden aparecer para los mantenedores.
    • beta: indica que son ejercicios activos, nuevos y sobre los que nos gustaría recibir comentarios. En el sitio mostramos una etiqueta beta en estos ejercicios, con una llamada a la acción que dice «Por favor, envíanos tus comentarios»
    • active: el estado normal de los ejercicios activos
    • deprecated: ejercicios que ya no se muestran a los estudiantes que no los han empezado (no se pueden usar en esta etapa).

El «orden recomendado» de los ejercicios de práctica en el sitio web corresponde al orden de los ejercicios en el array practice.

Ejemplo

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

Ejemplo de 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"
      },
      ...
    ]
  }
}

Ejercicios descartados

Si un track sabe que no quiere implementar un ejercicio definido en el repositorio de Problem Specifications, el slug de ese ejercicio se puede agregar a la clave exercises.foregone. configlet ignorará los ejercicios descartados cuando genere la lista de ejercicios no implementados del track.

Algunas razones por las que un track podría no querer implementar un ejercicio son:

  • Puede que el lenguaje no permita implementar el ejercicio de forma razonable. Por ejemplo, el ejercicio lens-person requiere que el lenguaje admita lenses.
  • El tema del ejercicio no encaja con el lenguaje. Por ejemplo, en algunos lenguajes de alto nivel, un ejercicio de manipulación de bits de bajo nivel puede no tener sentido.

Ejemplo

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

Conceptos

Cada concepto es una entrada del array concepts de nivel superior. Un concepto se compone de los siguientes campos:

  • uuid: un UUID V4 que identifica el concepto de forma única. El UUID debe ser único tanto dentro del track como en todos los tracks, y nunca debe cambiar
  • slug: el slug del concepto, que es un string en minúsculas en formato kebab-case. El slug debe ser único entre todos los conceptos del track. Su longitud debe ser <= 255.
  • name: el nombre del concepto. Su longitud debe ser <= 255.
  • tags: especifica las condiciones para que una solución enviada se vincule a un enfoque. (opcional)
    • all: un array de etiquetas que deben estar todas presentes en una solución enviada (opcional, a menos que any no tenga elementos)
    • any: un array de etiquetas de las cuales al menos una debe estar presente en una solución enviada (opcional, a menos que all no tenga elementos)
    • not: ninguna de las etiquetas debe estar presente en una solución enviada (opcional)

Ejemplo

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

Características clave

Las características clave de un lenguaje describen de forma concisa cuáles son sus características más importantes. Su objetivo es dar a conocer a posibles estudiantes las características más interesantes de un lenguaje. Los títulos deben procurar usar la menor cantidad posible de jerga técnica, teniendo en cuenta que es posible que los estudiantes aún no sepan qué significa la jerga específica de un lenguaje antes de aprenderlo.

Las características clave se especifican en el campo key_features de nivel superior, que se define como un array de objetos con los siguientes campos:

  • title: un encabezado conciso para la característica clave. Su longitud debe ser <= 25. No se admite Markdown.
  • content: una descripción de la característica clave. Su longitud debe ser <= 100. No se admite Markdown.
  • icon: el ícono que se muestra para la característica. Puedes elegir el ícono que te parezca adecuado, sin importar su nombre. Se pueden usar los siguientes íconos:
    • 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

Puedes ver el aspecto visual de estos íconos en la sección de íconos de características clave.

Se deben especificar exactamente 6 características clave.

Ejemplo

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

Etiquetas

Los tracks se pueden anotar con etiquetas, lo que permite buscar tracks con una determinada combinación de etiquetas.

Un track debería elegir sus etiquetas según el uso general de su lenguaje. Por ejemplo, imagina a un estudiante pensando: «Me gustaría dedicarme al aprendizaje automático, ¿qué lenguaje debería elegir?» o «Me gustaría aprender programación funcional, ¿qué lenguaje debería escoger?». Si tu lenguaje sería un buen candidato, ponle esa etiqueta. Si tu lenguaje admite algunas ideas funcionales, pero rara vez se usan, o solo unas pocas personas hacen aprendizaje automático con él, pero es poco común, no apliques esas etiquetas.

Las etiquetas se especifican en el campo tags de nivel superior, que se define como un array de strings. Se pueden usar las siguientes etiquetas (agrupadas por categoría):

Paradigmas

  • paradigm/array: el lenguaje es un lenguaje de programación de arrays
  • paradigm/declarative: el lenguaje admite un estilo de programación declarativo
  • paradigm/functional: el lenguaje admite un estilo de programación funcional
  • paradigm/imperative: el lenguaje admite un estilo de programación imperativo
  • paradigm/logic: el lenguaje admite un estilo de programación basado en lógica
  • paradigm/object_oriented: el lenguaje admite un estilo de programación orientado a objetos
  • paradigm/procedural: el lenguaje admite un estilo de programación procedimental
  • paradigm/stack-oriented: el lenguaje admite un estilo de programación orientado a la pila

Tipado

  • typing/static: el lenguaje usa tipado estático
  • typing/gradual: el lenguaje usa tipado gradual
  • typing/dynamic: el lenguaje usa tipado dinámico
  • typing/strong: el lenguaje usa tipado fuerte
  • typing/weak: el lenguaje usa tipado débil

Modo de ejecución

  • execution_mode/compiled: el código se compila primero antes de ejecutarse
  • execution_mode/interpreted: el código se interpreta directamente

Plataforma

  • platform/windows: se ejecuta en Windows
  • platform/mac: se ejecuta en Mac
  • platform/linux: se ejecuta en Linux
  • platform/ios: se ejecuta en iOS
  • platform/android: se ejecuta en Android
  • platform/web: se ejecuta en el navegador

Entorno de ejecución

  • runtime/standalone_executable: se ejecuta como un ejecutable independiente
  • runtime/language_specific: se ejecuta en un entorno de ejecución específico del lenguaje
  • runtime/clr: se ejecuta en Common Language Runtime (.NET)
  • runtime/jvm: se ejecuta en la JVM (Java)
  • runtime/beam: se ejecuta en BEAM (Erlang)
  • runtime/wasmtime: se ejecuta en Wasmtime (WebAssembly)

Usos

  • used_for/artificial_intelligence: inteligencia artificial
  • used_for/backends: backends
  • used_for/cross_platform_development: desarrollo multiplataforma
  • used_for/embedded_systems: sistemas embebidos
  • used_for/financial_systems: sistemas financieros
  • used_for/frontends: frontends
  • used_for/games: juegos
  • used_for/guis: interfaces gráficas de usuario
  • used_for/mobile: dispositivos móviles
  • used_for/robotics: robótica
  • used_for/scientific_calculations: cálculos científicos
  • used_for/scripts: scripts
  • used_for/web_development: desarrollo web

Ten en cuenta que no hay problema en incluir varias etiquetas de una misma categoría.

Ejemplo

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

Ejemplo

Este es un ejemplo de cómo puede verse un archivo config.json válido:

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