Metadata-Version: 2.4
Name: ccbh-grader
Version: 1.0.0
Summary: Autograders didácticos para enseñar programación en Python desde Google Colab
Author: CCBH
License: MIT
Project-URL: Homepage, https://github.com/claudiacbh/ccbh-grader
Project-URL: Repository, https://github.com/claudiacbh/ccbh-grader
Keywords: educacion,python,colab,autograder,programacion
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: Spanish
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Education :: Testing
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: libs
Requires-Dist: numpy; extra == "libs"
Requires-Dist: pandas; extra == "libs"
Requires-Dist: matplotlib; extra == "libs"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ipython>=8; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: nbconvert; extra == "dev"
Requires-Dist: ipykernel; extra == "dev"
Requires-Dist: numpy; extra == "dev"
Requires-Dist: pandas; extra == "dev"
Requires-Dist: matplotlib; extra == "dev"
Dynamic: license-file

# ccbh-grader

Autograders didácticos para enseñar programación en Python a estudiantes de
pregrado, pensados para usarse desde **Google Colab**.

El estudiante escribe su programa tal como lo aprende en clase —con `input()` y
`print()`— y el cuaderno le dice al instante si funciona, con retroalimentación
que acompaña en lugar de regañar. Al final obtiene su calificación, por ejemplo
`17 / 20`.

## Los módulos

| Módulo | Notebook | Temas | Puntos |
|---|---|---|---|
| 0 · Introducción a Python y Colab | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/00_introduccion.ipynb) | celdas y Markdown, `print`, comentarios, variables, tipos, `input`, operadores, `math` | 15 |
| 1 · Condicionales y lógica booleana | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/01_condicionales_y_logica_booleana.ipynb) | `if`, `else`, `elif`, `and`, `or`, `not`, `%`, anidamiento | 20 |
| 2 · Ciclos | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/02_ciclos.ipynb) | `for`, `range`, acumuladores, contadores, `while`, centinelas, ciclos anidados | 20 |
| 3 · Funciones | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/03_funciones.ipynb) | `def`, parámetros, `return`, funciones sin retorno, funciones que llaman a otras | 15 |
| 4 · Listas | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/04_listas.ipynb) | indexado, recorrido, `append`, `insert`, `remove`, `pop`, `sort` vs `sorted`, rebanadas | 15 |
| 5 · Conjuntos y diccionarios | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/05_conjuntos_y_diccionarios.ipynb) | crear, acceder, escribir e iterar; `\|`, `&`, `-`; `get`, `keys`, `values`, `items` | 15 |
| 6 · NumPy | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/06_numpy.ipynb) | `array`, `arange`, `linspace`, vectorización, filtros booleanos, 2D, `axis` | 12 |
| 7 · Pandas | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/07_pandas.ipynb) | `Series`, `DataFrame`, `read_csv`, filtrar, ordenar, columnas calculadas, `groupby` | 12 |
| 8 · Matplotlib | [Abrir en Colab](https://colab.research.google.com/github/claudiacbh/ccbh-grader/blob/main/notebooks/08_matplotlib.ipynb) | `plot`, `bar`, `barh`, `scatter`, `hist`, leyendas, `figsize`, subplots | 12 |

Cada pregunta vale un punto. Los intentos son ilimitados y siempre vale el
último.

El módulo 0 no da nada por sabido: arranca explicando qué es una celda de Colab.
Los módulos 0 al 5 solo necesitan Python. Los de NumPy, Pandas y Matplotlib usan
esas bibliotecas, que en Colab ya vienen instaladas.

## Cómo se usa

Al comienzo del notebook:

```python
!pip install ccbh-grader -q

from ccbh_grader.condicionales import AutoGrader   # o ccbh_grader.ciclos
ag = AutoGrader()
```

Para responder una pregunta, el estudiante escribe su programa debajo de la
línea mágica:

```python
%%responder 3
edad = int(input("Digite su edad: "))
if edad < 18:
    print("Usted es menor de edad")
else:
    print("Usted es mayor de edad")
```

Y recibe la respuesta de inmediato:

```
✅ ¡Muy bien! Pregunta 3 resuelta.

   Probé tu programa con 3 casos y todos funcionaron:
     Digite su edad: 15
     Usted es menor de edad
     ...
```

Cuando algo todavía no sale, aparecen el caso que falló y las pistas del
ejercicio:

```
🤔 Vas por buen camino, pero un caso todavía no da.

   Probé tu programa con edad = 18 y no encontré "mayor de edad" en lo que imprimiste.

     Esto fue lo que pasó:
       Digite su edad: 18
       Usted es menor de edad
     Lo que se esperaba  :  Usted es mayor de edad

   💡 Fíjate en el borde exacto: a los 18 años ya se es mayor de edad.
      ¿Tu comparación debería ser `<` o `<=`?

   Ajusta esta misma celda y vuélvela a ejecutar. ¡Tú puedes! 🚀
```

Al final del cuaderno:

```python
ag.reporte()
```

## Cómo funciona por dentro

- **El programa del estudiante no se ejecuta de forma interactiva.** El
  autograder lo corre varias veces con entradas simuladas, así que `input()`
  nunca deja el notebook esperando y el estudiante ve su programa probado con
  varios casos.
- **Cada tema se califica como corresponde.** Los primeros módulos comparan lo
  que el programa imprime; el de funciones llama a la función del estudiante y
  mira lo que devuelve; los de estructuras de datos comparan listas, conjuntos,
  diccionarios, arreglos y tablas; y el de Matplotlib **inspecciona la gráfica**
  —el tipo, los datos y las etiquetas—, además de mostrársela al estudiante para
  que vea su propio trabajo.
- **Los ciclos infinitos se detienen solos**, en menos de un segundo, con un
  mensaje que explica qué revisar. Escribir un `while` sin incremento es parte
  de aprender; colgar el entorno de Colab, no.
- **La comparación es generosa con la forma y estricta con el fondo.** Escribir
  "válida" o "valida", con mayúsculas o sin ellas, no cambia si el razonamiento
  estuvo bien.
- **Las estructuras se verifican leyendo el código (AST), no buscando
  palabras.** Un `while` mencionado en un comentario no cuenta como un `while`.
- **El avance vive solo en memoria**, mientras dure la sesión de Colab. No se
  guardan archivos ni datos personales: el autograder no pide el nombre del
  estudiante.
- **La teoría vive en los notebooks**, no en la biblioteca. Para cambiar la
  explicación de un ejercicio basta con editar el `.ipynb`; no hay que volver a
  publicar el paquete.

## Para el docente

### Desarrollo

```bash
make setup-dev    # crea .venv e instala el proyecto con sus dependencias
make test         # ejecuta la suite completa
make build        # arma el paquete en dist/
make publish      # sube a PyPI con twine
```

`make notebooks` ejecuta los nueve cuadernos de punta a punta con `nbconvert`.

La suite de pruebas cubre, entre otras cosas, que **la solución de referencia de
las 136 preguntas dé puntaje perfecto en su módulo**, que los errores típicos
fallen con la pista adecuada, que un ciclo infinito no cuelgue nada, y que los
enunciados de los notebooks pidan exactamente los mensajes, las variables y las
funciones que el autograder califica.

### Agregar una pregunta o un módulo

La receta está en [CLAUDE.md](CLAUDE.md), junto con la arquitectura, los
mecanismos de calificación disponibles y las trampas conocidas.

### Antes de publicar

Mientras el paquete no esté en PyPI, los notebooks pueden instalarlo así:

```python
!pip install git+https://github.com/claudiacbh/ccbh-grader.git -q
```

## Licencia

MIT. Ver [LICENSE](LICENSE).
