Schedule generation transforms room reservations into confirmed academic schedules. The system uses the Builder pattern with a Facade to create different types of schedules (normal, lab, virtual, or blocked) while applying validation rules.
State Requirement: The reservation must be in reservado state. Attempting to generate a schedule from an already ocupado or cancelado reservation will fail.
import requestsdef get_semester_schedules(semester: int): """Get all schedules for a semester.""" url = f"http://localhost:8000/horarios-por-semestre/{semester}" response = requests.get(url) data = response.json() print(f"Semester {semester}: {data['total_horarios']} schedules") # Group by day by_day = {} for horario in data['horarios']: day = horario['dia'] if day not in by_day: by_day[day] = [] by_day[day].append(horario) # Display by day for day, schedules in sorted(by_day.items()): print(f"\n{day}:") for s in schedules: print(f" {s['hora_inicio']}-{s['hora_fin']}: " f"{s['asignatura_id']} in {s['aula_id']}") return dataschedules = get_semester_schedules(1)
import requestsdef generate_with_precheck(prog_id: str): """Generate schedule with pre-validation.""" # Step 1: Get reservation details prog_response = requests.get(f"http://localhost:8000/programaciones/{prog_id}") prog = prog_response.json() if prog['estado'] != 'reservado': print(f"Cannot generate: reservation is {prog['estado']}") return None # Step 2: Verify course exists data_response = requests.get("http://localhost:8000/datos") data = data_response.json() asignatura = next( (a for a in data['asignaturas'] if a['id'] == prog['asignatura_id']), None ) if not asignatura: print(f"Course {prog['asignatura_id']} not found") return None # Step 3: Verify room exists and is active aula = next( (a for a in data['aulas'] if a['id'] == prog['aula_id']), None ) if not aula or aula.get('estado') != 'activo': print(f"Room {prog['aula_id']} not available") return None # Step 4: Generate schedule print("Pre-validation passed. Generating schedule...") schedule_response = requests.post( f"http://localhost:8000/crear-horario-desde-programacion/{prog_id}" ) result = schedule_response.json() if result['success']: print(f"Success! Schedule ID: {result['horario']['id']}") return result else: print(f"Generation failed: {result['error']}") return None# Usageresult = generate_with_precheck("PROG005")
import requestsfrom collections import defaultdictdef detect_schedule_conflicts(semester: int) -> List[Dict]: """Detect scheduling conflicts in a semester.""" # Get all schedules response = requests.get( f"http://localhost:8000/horarios-por-semestre/{semester}" ) data = response.json() schedules = data['horarios'] conflicts = [] # Group by room and day room_schedules = defaultdict(lambda: defaultdict(list)) for schedule in schedules: room_id = schedule['aula_id'] day = schedule['dia'] room_schedules[room_id][day].append(schedule) # Check for time overlaps for room_id, days in room_schedules.items(): for day, day_schedules in days.items(): # Sort by start time day_schedules.sort(key=lambda s: s['hora_inicio']) for i in range(len(day_schedules) - 1): current = day_schedules[i] next_schedule = day_schedules[i + 1] # Check overlap if current['hora_fin'] > next_schedule['hora_inicio']: conflicts.append({ 'room': room_id, 'day': day, 'schedule1': { 'id': current['horario_id'], 'time': f"{current['hora_inicio']}-{current['hora_fin']}", 'course': current['asignatura_id'] }, 'schedule2': { 'id': next_schedule['horario_id'], 'time': f"{next_schedule['hora_inicio']}-{next_schedule['hora_fin']}", 'course': next_schedule['asignatura_id'] } }) if conflicts: print(f"Found {len(conflicts)} conflicts:") for conflict in conflicts: print(f"\n{conflict['room']} on {conflict['day']}:") print(f" {conflict['schedule1']['time']}: {conflict['schedule1']['course']}") print(f" {conflict['schedule2']['time']}: {conflict['schedule2']['course']}") else: print("No conflicts detected") return conflicts# Check for conflictsconflicts = detect_schedule_conflicts(1)