Skip to content

Commit e85872f

Browse files
committed
added
0 parents  commit e85872f

File tree

9 files changed

+358
-0
lines changed

9 files changed

+358
-0
lines changed

.github/workflows/test.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ main, master ]
6+
pull_request:
7+
branches: [ main, master ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@v3
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v4
19+
with:
20+
python-version: '3.11'
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install pytest
26+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
27+
28+
- name: Run tests
29+
run: |
30+
pytest tests/ -v --tb=short

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
venv/
8+
env/
9+
ENV/
10+
build/
11+
dist/
12+
*.egg-info/
13+
14+
# IDEs
15+
.vscode/
16+
.idea/
17+
*.swp
18+
*.swo
19+
20+
# OS
21+
.DS_Store
22+
Thumbs.db
23+
24+
# Pytest
25+
.pytest_cache/
26+
.coverage
27+
htmlcov/

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12.7

README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# AI Engineering - Week 1: RAG Fundamentals
2+
3+
## 📋 Objetivo del Proyecto
4+
Implementar un sistema básico de RAG (Retrieval-Augmented Generation) usando embeddings y búsqueda semántica.
5+
6+
## 🚀 Instrucciones
7+
8+
### 1. Fork este repositorio
9+
Haz click en "Fork" arriba a la derecha para crear tu propia copia.
10+
11+
### 2. Clona tu fork
12+
```bash
13+
git clone https://github.com/TU-USUARIO/mb-python-week-01-test.git
14+
cd mb-python-week-01-test
15+
```
16+
17+
### 3. Crea y activa virtual environment
18+
```bash
19+
python3 -m venv venv
20+
source venv/bin/activate # En Windows: venv\Scripts\activate
21+
```
22+
23+
### 4. Instala dependencias
24+
```bash
25+
pip install -r requirements.txt
26+
```
27+
28+
### 5. Completa el código
29+
Implementa las funciones en `src/main.py` siguiendo los comentarios.
30+
31+
### 6. Prueba localmente
32+
```bash
33+
pytest tests/ -v
34+
```
35+
36+
Todos los tests deben pasar (✅ 10 passed).
37+
38+
### 7. Push y verifica
39+
```bash
40+
git add .
41+
git commit -m "Completar proyecto week 1"
42+
git push origin main
43+
```
44+
45+
GitHub Actions correrá los tests automáticamente. Verifica que todos pasen (✅ green check).
46+
47+
### 8. Envía en la plataforma
48+
Copia la URL de tu repo y pégala en la plataforma de Nieva AI para verificación automática.
49+
50+
## ✅ Criterios de Aprobación
51+
- ✅ Todos los tests deben pasar (100%)
52+
- ✅ El código debe estar bien documentado
53+
- ✅ Debe ser un fork de este template oficial
54+
55+
## 🧪 Tests Incluidos
56+
57+
### `calculate_cosine_similarity`
58+
- Vectores idénticos → similitud 1.0
59+
- Vectores ortogonales → similitud 0.0
60+
- Vectores opuestos → similitud -1.0
61+
- Test con similitud conocida
62+
63+
### `find_most_similar`
64+
- Encuentra documento idéntico
65+
- Encuentra documento más cercano
66+
- Maneja un solo documento
67+
68+
### `retrieve_top_k`
69+
- Retorna top 3 documentos en orden
70+
- Maneja k > número de documentos
71+
- k=1 se comporta como find_most_similar
72+
73+
## 📚 Recursos
74+
- [NumPy Documentation](https://numpy.org/doc/)
75+
- [Cosine Similarity Explained](https://en.wikipedia.org/wiki/Cosine_similarity)
76+
- [RAG Introduction](https://docs.anthropic.com/claude/docs/retrieval-augmented-generation)
77+
78+
---
79+
80+
**¿Tienes dudas?** Únete al Discord de Nieva AI.
81+

requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pytest
2+
numpy

setup.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from setuptools import setup, find_packages
2+
3+
setup(
4+
name="ai-engineering-week-1",
5+
version="1.0.0",
6+
packages=find_packages(),
7+
install_requires=[
8+
"pytest",
9+
"numpy",
10+
],
11+
)
12+

src/__init__.py

Whitespace-only changes.

src/main.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
"""
2+
AI Engineering - Week 1: RAG Fundamentals
3+
Implementa las funciones siguientes para completar el proyecto.
4+
"""
5+
6+
import numpy as np
7+
from typing import List, Tuple
8+
9+
10+
def calculate_cosine_similarity(vec1: np.ndarray, vec2: np.ndarray) -> float:
11+
"""
12+
Calcula la similitud coseno entre dos vectores.
13+
14+
Args:
15+
vec1: Primer vector (numpy array)
16+
vec2: Segundo vector (numpy array)
17+
18+
Returns:
19+
float: Similitud coseno (entre -1 y 1)
20+
21+
Ejemplo:
22+
>>> vec1 = np.array([1, 2, 3])
23+
>>> vec2 = np.array([4, 5, 6])
24+
>>> calculate_cosine_similarity(vec1, vec2)
25+
0.9746318461970762
26+
"""
27+
# TODO: Implementa el cálculo de similitud coseno
28+
# Fórmula: (vec1 · vec2) / (||vec1|| * ||vec2||)
29+
30+
raise NotImplementedError("Implementa esta función")
31+
32+
33+
def find_most_similar(
34+
query_embedding: np.ndarray,
35+
document_embeddings: List[np.ndarray]
36+
) -> int:
37+
"""
38+
Encuentra el índice del documento más similar a la query.
39+
40+
Args:
41+
query_embedding: Embedding de la consulta
42+
document_embeddings: Lista de embeddings de documentos
43+
44+
Returns:
45+
int: Índice del documento más similar
46+
47+
Ejemplo:
48+
>>> query = np.array([1, 0, 0])
49+
>>> docs = [np.array([0, 1, 0]), np.array([1, 0, 0]), np.array([0, 0, 1])]
50+
>>> find_most_similar(query, docs)
51+
1
52+
"""
53+
# TODO: Encuentra el documento con mayor similitud coseno
54+
55+
raise NotImplementedError("Implementa esta función")
56+
57+
58+
def retrieve_top_k(
59+
query_embedding: np.ndarray,
60+
document_embeddings: List[np.ndarray],
61+
k: int = 3
62+
) -> List[int]:
63+
"""
64+
Recupera los k documentos más similares.
65+
66+
Args:
67+
query_embedding: Embedding de la consulta
68+
document_embeddings: Lista de embeddings de documentos
69+
k: Número de documentos a recuperar
70+
71+
Returns:
72+
List[int]: Índices de los k documentos más similares (ordenados)
73+
74+
Ejemplo:
75+
>>> query = np.array([1, 0, 0])
76+
>>> docs = [np.array([0, 1, 0]), np.array([1, 0, 0]), np.array([0.9, 0.1, 0])]
77+
>>> retrieve_top_k(query, docs, k=2)
78+
[1, 2]
79+
"""
80+
# TODO: Encuentra los top k documentos más similares
81+
82+
raise NotImplementedError("Implementa esta función")

tests/test_main.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
"""
2+
Tests para Week 1: RAG Fundamentals
3+
NO MODIFIQUES ESTE ARCHIVO
4+
"""
5+
6+
import pytest
7+
import numpy as np
8+
from src.main import (
9+
calculate_cosine_similarity,
10+
find_most_similar,
11+
retrieve_top_k
12+
)
13+
14+
15+
class TestCosineSimilarity:
16+
"""Tests para calculate_cosine_similarity"""
17+
18+
def test_identical_vectors(self):
19+
"""Vectores idénticos deben tener similitud 1.0"""
20+
vec = np.array([1, 2, 3])
21+
similarity = calculate_cosine_similarity(vec, vec)
22+
assert np.isclose(similarity, 1.0), "Vectores idénticos deben tener similitud 1.0"
23+
24+
def test_orthogonal_vectors(self):
25+
"""Vectores ortogonales deben tener similitud 0.0"""
26+
vec1 = np.array([1, 0, 0])
27+
vec2 = np.array([0, 1, 0])
28+
similarity = calculate_cosine_similarity(vec1, vec2)
29+
assert np.isclose(similarity, 0.0), "Vectores ortogonales deben tener similitud 0.0"
30+
31+
def test_opposite_vectors(self):
32+
"""Vectores opuestos deben tener similitud -1.0"""
33+
vec1 = np.array([1, 2, 3])
34+
vec2 = np.array([-1, -2, -3])
35+
similarity = calculate_cosine_similarity(vec1, vec2)
36+
assert np.isclose(similarity, -1.0), "Vectores opuestos deben tener similitud -1.0"
37+
38+
def test_known_similarity(self):
39+
"""Test con similitud conocida"""
40+
vec1 = np.array([1, 2, 3])
41+
vec2 = np.array([4, 5, 6])
42+
similarity = calculate_cosine_similarity(vec1, vec2)
43+
expected = 0.9746318461970762
44+
assert np.isclose(similarity, expected), f"Esperado {expected}, obtenido {similarity}"
45+
46+
47+
class TestFindMostSimilar:
48+
"""Tests para find_most_similar"""
49+
50+
def test_exact_match(self):
51+
"""Debe encontrar el documento idéntico"""
52+
query = np.array([1, 0, 0])
53+
docs = [
54+
np.array([0, 1, 0]),
55+
np.array([1, 0, 0]), # Exacto
56+
np.array([0, 0, 1])
57+
]
58+
result = find_most_similar(query, docs)
59+
assert result == 1, "Debe encontrar el documento idéntico (índice 1)"
60+
61+
def test_closest_match(self):
62+
"""Debe encontrar el documento más cercano"""
63+
query = np.array([1, 0, 0])
64+
docs = [
65+
np.array([0, 1, 0]),
66+
np.array([0.5, 0.5, 0]),
67+
np.array([0.9, 0.1, 0]) # Más cercano
68+
]
69+
result = find_most_similar(query, docs)
70+
assert result == 2, "Debe encontrar el documento más cercano (índice 2)"
71+
72+
def test_single_document(self):
73+
"""Con un solo documento, debe retornar índice 0"""
74+
query = np.array([1, 2, 3])
75+
docs = [np.array([4, 5, 6])]
76+
result = find_most_similar(query, docs)
77+
assert result == 0, "Con un solo documento debe retornar 0"
78+
79+
80+
class TestRetrieveTopK:
81+
"""Tests para retrieve_top_k"""
82+
83+
def test_top_3(self):
84+
"""Debe retornar los top 3 documentos en orden"""
85+
query = np.array([1, 0, 0])
86+
docs = [
87+
np.array([0, 1, 0]), # Menos similar
88+
np.array([1, 0, 0]), # Más similar (índice 1)
89+
np.array([0.9, 0.1, 0]), # 2do más similar (índice 2)
90+
np.array([0.8, 0.2, 0]), # 3ro más similar (índice 3)
91+
np.array([0, 0, 1]) # Menos similar
92+
]
93+
result = retrieve_top_k(query, docs, k=3)
94+
assert len(result) == 3, "Debe retornar exactamente 3 documentos"
95+
assert result[0] == 1, "El más similar debe ser índice 1"
96+
assert result[1] == 2, "El 2do debe ser índice 2"
97+
assert result[2] == 3, "El 3ro debe ser índice 3"
98+
99+
def test_k_larger_than_docs(self):
100+
"""Si k > número de docs, retorna todos los docs"""
101+
query = np.array([1, 0, 0])
102+
docs = [
103+
np.array([1, 0, 0]),
104+
np.array([0, 1, 0])
105+
]
106+
result = retrieve_top_k(query, docs, k=5)
107+
assert len(result) == 2, "Debe retornar todos los documentos disponibles"
108+
109+
def test_k_equals_1(self):
110+
"""Con k=1 debe comportarse como find_most_similar"""
111+
query = np.array([1, 0, 0])
112+
docs = [
113+
np.array([0, 1, 0]),
114+
np.array([1, 0, 0]),
115+
np.array([0, 0, 1])
116+
]
117+
result = retrieve_top_k(query, docs, k=1)
118+
assert len(result) == 1, "Debe retornar exactamente 1 documento"
119+
assert result[0] == 1, "Debe ser el documento más similar (índice 1)"
120+
121+
122+
if __name__ == "__main__":
123+
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)