15. ¿Qué día es?
15. ¿Qué Día Es? - Enseñando a tu Asistente a Decir la Fecha
Explicación para principiantes:
Ahora vamos a enseñarle a tu asistente una segunda habilidad importante: decir la fecha actual. Es como enseñarle a un niño no solo a decir la hora, sino también a saber en qué día y mes vive. ¡Tu asistente está volviéndose cada vez más útil!
Objetivo de esta lección:
Detectar cuando el usuario pregunta por la fecha
Obtener y formatear la fecha actual
Organizar mejor el código con funciones
Crear un bucle continuo para conversación
Analogía:
Tu asistente es ahora como un calendario parlante inteligente:
Escucha: "¿Qué día es hoy?"
Procesa: Mira el calendario
Responde: "Hoy es lunes, 23 de enero de 2024"
🔄 Paso 1: Reestructurar el Código para Mejor Organización
Problema del código anterior:
python
# ❌ CÓDIGO DESORGANIZADO - TODO EN EL MISMO LUGAR
while True:
comando = escuchar()
if 'hora' in comando:
# Código para hora aquí (mezclado)
hora = datetime.datetime.now().strftime("%H:%M")
hablar(f"Son las {hora}")
if 'día' in comando: # ❌ Esto causa problemas si ambos if se ejecutan
# Código para día aquí (mezclado)
dia = datetime.datetime.now().strftime("%d")
hablar(f"Es el día {dia}")
Solución: Funciones Separadas:
python
# ✅ CÓDIGO ORGANIZADO - FUNCIONES SEPARADAS
def dar_hora():
"""Función dedicada a dar la hora"""
hora = datetime.datetime.now().strftime("%H:%M")
hablar(f"Son las {hora}")
def dar_fecha():
"""Función dedicada a dar la fecha"""
fecha = datetime.datetime.now().strftime("%d/%m/%Y")
hablar(f"Hoy es {fecha}")
# Uso limpio:
while True:
comando = escuchar()
if 'hora' in comando:
dar_hora() # ¡Simple y claro!
elif 'día' in comando: # elif, no if separado
dar_fecha() # ¡Simple y claro!
¿Por qué usar elif en lugar de if?
python
# ❌ CON IFs SEPARADOS:
if 'hora' in comando:
dar_hora() # Se ejecuta si contiene "hora"
if 'día' in comando:
dar_fecha() # ¡Se ejecuta TAMBIÉN si contiene "hora" Y "día"!
# ✅ CON ELIF:
if 'hora' in comando:
dar_hora() # Solo se ejecuta esto
elif 'día' in comando:
dar_fecha() # Solo se ejecuta si NO contenía "hora"
🎯 Paso 2: Crear la Función dar_fecha() Mejorada
Versión Básica:
python
import datetime
def dar_fecha_basica():
"""Versión simple para dar la fecha"""
fecha_actual = datetime.datetime.now()
# Formato DD/MM/YYYY
fecha_formateada = fecha_actual.strftime("%d/%m/%Y")
hablar(f"La fecha actual es {fecha_formateada}")
Versión Mejorada (más natural):
python
def dar_fecha_natural():
"""Dice la fecha de forma más natural y completa"""
ahora = datetime.datetime.now()
# Diccionario de meses en español
meses = {
1: "enero", 2: "febrero", 3: "marzo", 4: "abril",
5: "mayo", 6: "junio", 7: "julio", 8: "agosto",
9: "septiembre", 10: "octubre", 11: "noviembre", 12: "diciembre"
}
# Diccionario de días de la semana
dias_semana = {
0: "lunes", 1: "martes", 2: "miércoles", 3: "jueves",
4: "viernes", 5: "sábado", 6: "domingo"
}
# Obtener partes de la fecha
dia_numero = ahora.day # Día del mes (1-31)
mes_numero = ahora.month # Mes (1-12)
año = ahora.year # Año (2024)
dia_semana_num = ahora.weekday() # Día de semana (0=lunes)
# Convertir a texto
dia_semana = dias_semana[dia_semana_num]
mes_nombre = meses[mes_numero]
# Crear mensaje natural
mensaje = f"Hoy es {dia_semana}, {dia_numero} de {mes_nombre} de {año}"
print(f"📅 {mensaje}")
hablar(mensaje)
# Mostrar también formato numérico
print(f" 📱 ({dia_numero:02d}/{mes_numero:02d}/{año})")
# Probar la función
dar_fecha_natural()
Salida esperada:
text
📅 Hoy es martes, 23 de enero de 2024
📱 (23/01/2024)
🔧 Paso 3: El Importante .lower() - ¡No Te Olvides!
Problema común:
python
# ❌ SIN .lower() - PROBLEMAS DE DETECCIÓN
comando = escuchar() # Usuario dice: "¿Qué DÍA es?"
# comando = "¿Qué DÍA es?" (con mayúsculas)
if 'día' in comando: # 'día' ≠ 'DÍA' → NO se detecta
dar_fecha() # ¡Nunca se ejecuta!
Solución:
python
# ✅ CON .lower() - DETECCIÓN CONFiable
comando = escuchar().lower() # Convertir TODO a minúsculas
# comando = "¿qué día es?" (todo minúsculas)
if 'día' in comando: # 'día' in "¿qué día es?" → ✅ SÍ se detecta
dar_fecha() # ¡Se ejecuta correctamente!
Visualización de .lower():
text
Entrada original: "¿Qué DÍA es Hoy?"
↓ .lower()
"¿qué día es hoy?" ← Todas las letras ahora son minúsculas
↓ Buscar "día"
"¿qué día es hoy?" ← ¡Ahora SÍ encuentra "día"!
↑↑↑
Lugar correcto para poner .lower():
python
# Opción 1: Al recibir el comando (RECOMENDADO)
def escuchar():
audio = listener.listen(source)
texto = listener.recognize_google(audio, language='es-ES')
return texto.lower() # ← Convertir aquí
# Opción 2: Al procesar el comando
comando = escuchar().lower() # ← Convertir aquí
# Opción 3: Dentro de la condición
if 'día' in comando.lower(): # ← Convertir aquí
🔄 Paso 4: Implementar el Bucle Infinito Correctamente
Estructura del bucle:
python
def main():
"""Función principal con bucle infinito"""
# Configuración inicial
bienvenida()
# Bucle infinito para conversación continua
while True:
print("\n" + "=" * 40)
print("Esperando tu comando...")
print("=" * 40)
# 1. Escuchar comando
comando = escuchar().lower() # ← .lower() aquí
# 2. Si no se entendió, continuar
if not comando:
continue
# 3. Procesar comando
if 'hora' in comando:
print("⏰ Detecté pregunta por la hora")
dar_hora()
elif 'día' in comando or 'fecha' in comando:
print("📅 Detecté pregunta por la fecha")
dar_fecha()
elif 'adiós' in comando or 'salir' in comando:
print("👋 Detecté comando de salida")
despedirse()
break # ← Romper el bucle para salir
else:
print("❌ Comando no reconocido")
hablar("No entendí ese comando. Puedes preguntar la hora o la fecha")
Diagrama del bucle:
text
┌─────────────────────────────────────┐
│ INICIO DEL BUCLE │
├─────────────────────────────────────┤
│ 1. Escuchar comando │
│ 2. Convertir a minúsculas │
│ 3. ¿Comando vacío? → Volver a 1 │
├─────────────────────────────────────┤
│ 4. Procesar: │
│ • ¿Contiene "hora"? → dar_hora()│
│ • ¿Contiene "día"? → dar_fecha()│
│ • ¿Contiene "adiós"? → Salir │
│ • ¿Ninguno? → Mensaje error │
├─────────────────────────────────────┤
│ 5. Volver al paso 1 (a menos que │
│ haya sido "adiós") │
└─────────────────────────────────────┘
🚀 Paso 5: Código Completo del Asistente con Hora y Fecha
python
"""
ASISTENTE VIRTUAL COMPLETO CON HORA Y FECHA
Versión organizada y mejorada
"""
import speech_recognition as sr
import pyttsx3
import datetime
# ========== CONFIGURACIÓN INICIAL ==========
listener = sr.Recognizer()
engine = pyttsx3.init()
# Configurar voz en español
voces = engine.getProperty('voices')
for voz in voces:
if 'spanish' in voz.name.lower() or 'español' in voz.name.lower():
engine.setProperty('voice', voz.id)
print(f"✅ Voz seleccionada: {voz.name}")
break
engine.setProperty('rate', 180)
engine.setProperty('volume', 0.9)
# ========== FUNCIONES BÁSICAS ==========
def hablar(texto):
"""Hace que el asistente hable"""
print(f"🤖: {texto}")
engine.say(texto)
engine.runAndWait()
def bienvenida():
"""Da la bienvenida al usuario"""
hora_actual = datetime.datetime.now().hour
if 5 <= hora_actual < 12:
saludo = "Buenos días"
elif 12 <= hora_actual < 19:
saludo = "Buenas tardes"
else:
saludo = "Buenas noches"
mensaje = f"{saludo}. Soy tu asistente virtual. Puedes preguntarme la hora o la fecha."
hablar(mensaje)
def escuchar():
"""Escucha y convierte voz a texto"""
try:
with sr.Microphone() as source:
print("\n🎤 Escuchando... (habla ahora)")
listener.adjust_for_ambient_noise(source, duration=0.5)
audio = listener.listen(source, phrase_time_limit=5)
texto = listener.recognize_google(audio, language='es-ES')
texto = texto.lower() # ← ¡IMPORTANTE! Convertir a minúsculas
print(f"👤 Tú: {texto}")
return texto
except sr.UnknownValueError:
print("❌ No te entendí")
return ""
except sr.RequestError:
print("❌ Error de conexión")
return ""
except Exception as e:
print(f"❌ Error: {e}")
return ""
# ========== FUNCIONES DE HORA Y FECHA ==========
def dar_hora():
"""Da la hora actual de forma natural"""
ahora = datetime.datetime.now()
hora = ahora.hour
minutos = ahora.minute
# Determinar período del día
if 5 <= hora < 12:
periodo = "de la mañana"
elif 12 <= hora < 19:
periodo = "de la tarde"
else:
periodo = "de la noche"
# Convertir a formato de 12 horas
if hora == 0:
hora_12 = 12
elif hora > 12:
hora_12 = hora - 12
else:
hora_12 = hora
# Formatear minutos de forma natural
if minutos == 0:
mensaje = f"Son las {hora_12} en punto {periodo}"
elif minutos == 30:
mensaje = f"Son las {hora_12} y media {periodo}"
elif minutos == 15:
mensaje = f"Son las {hora_12} y cuarto {periodo}"
else:
mensaje = f"Son las {hora_12} con {minutos} minutos {periodo}"
# Mostrar también formato digital
hora_digital = ahora.strftime("%H:%M")
print(f"⏰ Hora digital: {hora_digital}")
hablar(mensaje)
def dar_fecha():
"""Da la fecha actual de forma natural"""
ahora = datetime.datetime.now()
# Diccionarios para conversión
meses = {
1: "enero", 2: "febrero", 3: "marzo", 4: "abril",
5: "mayo", 6: "junio", 7: "julio", 8: "agosto",
9: "septiembre", 10: "octubre", 11: "noviembre", 12: "diciembre"
}
dias_semana = {
0: "lunes", 1: "martes", 2: "miércoles", 3: "jueves",
4: "viernes", 5: "sábado", 6: "domingo"
}
# Obtener partes de la fecha
dia_numero = ahora.day
mes_numero = ahora.month
año = ahora.year
dia_semana_num = ahora.weekday()
# Convertir a texto
dia_semana = dias_semana[dia_semana_num]
mes_nombre = meses[mes_numero]
# Crear mensajes diferentes según cómo pregunten
mensaje_principal = f"Hoy es {dia_semana}, {dia_numero} de {mes_nombre} de {año}"
mensaje_alternativo = f"Estamos a {dia_numero} de {mes_nombre} de {año}"
# Mostrar formato numérico también
fecha_digital = ahora.strftime("%d/%m/%Y")
print(f"📅 Fecha digital: {fecha_digital}")
# Decir la fecha
hablar(mensaje_principal)
def despedirse():
"""Función de despedida"""
mensajes = [
"¡Hasta luego! Que tengas un excelente día",
"Adiós, ha sido un placer ayudarte",
"Nos vemos pronto, que te vaya muy bien",
"Hasta la próxima, cuídate mucho"
]
import random
mensaje = random.choice(mensajes)
hablar(mensaje)
# ========== PROGRAMA PRINCIPAL ==========
def main():
"""Función principal con bucle infinito"""
print("=" * 60)
print(" ASISTENTE VIRTUAL - HORA Y FECHA")
print("=" * 60)
print("Comandos disponibles:")
print(" • Pregunta por la hora (di 'hora' o 'qué hora es')")
print(" • Pregunta por la fecha (di 'día' o 'qué día es')")
print(" • Di 'adiós' o 'salir' para terminar")
print("=" * 60)
# Bienvenida inicial
bienvenida()
# Contador de interacciones
interacciones = 0
# BUCLE INFINITO PARA CONVERSACIÓN CONTINUA
while True:
interacciones += 1
print(f"\n🔄 Interacción #{interacciones}")
print("-" * 40)
# 1. ESCUCHAR COMANDO (con .lower() para consistencia)
comando = escuchar() # Ya tiene .lower() dentro de escuchar()
# 2. SI NO SE ENTENDIÓ, CONTINUAR
if not comando:
print("⚠️ No se detectó comando, intentando de nuevo...")
continue
# 3. PROCESAR COMANDO CON ELIF (NO if separados)
if 'hora' in comando or 'horas' in comando:
print("✅ Comando detectado: HORA")
dar_hora()
elif 'día' in comando or 'fecha' in comando or 'dias' in comando:
print("✅ Comando detectado: FECHA")
dar_fecha()
elif any(palabra in comando for palabra in ['adiós', 'salir', 'chao', 'hasta luego']):
print("✅ Comando detectado: SALIR")
despedirse()
break # ← ROMPER EL BUCLE PARA SALIR
# 4. COMANDO NO RECONOCIDO
else:
print("❌ Comando no reconocido")
hablar("No entendí ese comando. Puedes preguntarme la hora, la fecha o despedirte")
# Sugerir comandos
print("\n💡 Prueba con:")
print(" • '¿Qué hora es?'")
print(" • '¿Qué día es hoy?'")
print(" • 'Adiós' para terminar")
# Mensaje final al salir del bucle
print("\n" + "=" * 60)
print("👋 Programa terminado. ¡Gracias por usar el asistente!")
print("=" * 60)
# ========== EJECUCIÓN ==========
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\n⚠️ Programa interrumpido por el usuario (Ctrl+C)")
hablar("Programa interrumpido. ¡Hasta pronto!")
except Exception as e:
print(f"\n❌ Error inesperado: {e}")
🎮 Paso 6: Ejercicios Prácticos y Mejoras
Ejercicio 1: Añadir Más Formas de Preguntar
python
# Mejora la detección para entender más variantes
def es_pregunta_hora(comando):
"""Detecta si están preguntando por la hora"""
palabras_hora = [
'hora', 'horita', 'reloj', 'tiempo actual',
'qué hora', 'dime la hora', 'necesito la hora',
'podrías decirme la hora', 'saber la hora'
]
return any(palabra in comando for palabra in palabras_hora)
def es_pregunta_fecha(comando):
"""Detecta si están preguntando por la fecha"""
palabras_fecha = [
'día', 'fecha', 'calendario', 'hoy',
'qué día', 'qué fecha', 'día de hoy',
'en qué día estamos', 'fecha actual'
]
return any(palabra in comando for palabra in palabras_fecha)
Ejercicio 2: Añadir Funcionalidad de Día de la Semana
python
def que_dia_es():
"""Responde específicamente al día de la semana"""
ahora = datetime.datetime.now()
dias_semana = {
0: "lunes", 1: "martes", 2: "miércoles", 3: "jueves",
4: "viernes", 5: "sábado", 6: "domingo"
}
dia_num = ahora.weekday()
dia_nombre = dias_semana[dia_num]
# Mensajes diferentes
if dia_num in [0, 1, 2, 3]: # Lunes a jueves
mensaje = f"Hoy es {dia_nombre}, día de trabajo"
elif dia_num == 4: # Viernes
mensaje = f"¡Hoy es {dia_nombre}! Casi fin de semana"
else: # Sábado o domingo
mensaje = f"Hoy es {dia_nombre}, día de descanso"
hablar(mensaje)
# En el main, añade:
elif 'día de la semana' in comando or 'qué día cae' in comando:
que_dia_es()
Ejercicio 3: Mostrar Próximos Días Festivos
python
def proximos_festivos():
"""Dice los próximos días festivos (ejemplo básico)"""
festivos = [
"1 de enero: Año Nuevo",
"6 de enero: Día de Reyes",
"1 de mayo: Día del Trabajo",
"15 de agosto: Asunción de la Virgen",
"12 de octubre: Día de la Hispanidad",
"1 de noviembre: Día de Todos los Santos",
"6 de diciembre: Día de la Constitución",
"8 de diciembre: Inmaculada Concepción",
"25 de diciembre: Navidad"
]
hablar("Estos son algunos días festivos importantes:")
for festivo in festivos[:3]: # Solo decir los primeros 3
print(f" • {festivo}")
hablar(festivo)
📊 Diagrama de Flujo del Asistente Mejorado
text
┌─────────────────────────────────────────────┐
│ INICIO DEL PROGRAMA │
├─────────────────────────────────────────────┤
│ 1. Configurar voz (español, velocidad) │
│ 2. Dar bienvenida personalizada │
├─────────────────────────────────────────────┤
│ BUCLE PRINCIPAL (while True) │
├─────────────────────────────────────────────┤
│ 3. Escuchar comando → Convertir a minúsculas│
│ ↓ │
│ 4. ¿Comando vacío? → Volver a escuchar │
│ ↓ │
│ 5. Procesar con ELIF: │
│ • ¿Contiene "hora"? → dar_hora() │
│ • ¿Contiene "día/fecha"? → dar_fecha() │
│ • ¿Contiene "adiós"? → despedirse() │
│ y BREAK (romper bucle) │
│ • ¿Ninguno? → Mensaje de error │
│ ↓ │
│ 6. Volver al paso 3 (excepto si fue "adiós")│
└─────────────────────────────────────────────┘
❓ Cuestionario de Repaso
Pregunta 1:
¿Por qué es importante usar elif en lugar de múltiples if separados?
A) Para que el programa sea más lento
B) Para evitar que se ejecuten múltiples funciones si el comando contiene varias palabras clave
C) Para obligar al usuario a hablar más claro
D) Para cambiar automáticamente el idioma
Respuesta correcta: B
Explicación: Si usas if separados y el usuario dice "qué hora y día es", se ejecutarían tanto dar_hora() como dar_fecha(). Con elif, solo se ejecuta la primera condición que sea verdadera.
Pregunta 2:
¿Dónde es el mejor lugar para poner .lower() al procesar comandos?
A) Solo al principio del programa
B) Dentro de la función escuchar() (al devolver el texto)
C) Nunca, porque pierde las mayúsculas
D) Solo cuando el usuario habla fuerte
Respuesta correcta: B
Explicación: Poner .lower() dentro de escuchar() asegura que TODO el texto recibido esté en minúsculas, haciendo las búsquedas consistentes sin necesidad de recordar convertirlo cada vez.
Pregunta 3:
¿Qué hace datetime.datetime.now().weekday()?
A) Devuelve el día del mes (1-31)
B) Devuelve el día de la semana (0=lunes, 6=domingo)
C) Devuelve la hora actual
D) Devuelve el número de semana del año
Respuesta correcta: B
Explicación: .weekday() devuelve un número del 0 al 6, donde 0 es lunes y 6 es domingo. Es útil para saber qué día de la semana es hoy.
Pregunta 4:
¿Cómo podemos hacer que el asistente diga "Hoy es lunes, 23 de enero de 2024" en lugar de solo "23/01/2024"?
A) Usando diccionarios para convertir números a nombres
B) Pidiendo al usuario que diga la fecha completa
C) Conectando a internet para obtener la fecha
D) Usando una librería especial de fechas
Respuesta correcta: A
Explicación: Creamos diccionarios como meses = {1: "enero", 2: "febrero"...} y dias_semana = {0: "lunes", 1: "martes"...} para convertir los números en nombres legibles.
Pregunta 5:
¿Qué hace la palabra clave break en nuestro bucle while True?
A) Pausa el programa por 1 segundo
B) Rompe (termina) el bucle infinito
C) Aumenta la velocidad del habla
D) Repite el último comando
Respuesta correcta: B
Explicación: break hace que el programa salga inmediatamente del bucle en el que está. En nuestro caso, sale del while True cuando el usuario dice "adiós".
Pregunta 6 (Bonus):
Si el usuario dice "¿Podrías decirme qué día y hora es?", ¿qué pasará con nuestro código actual?
A) Solo dirá la hora (porque "hora" aparece primero en el código)
B) Solo dirá la fecha (porque "día" aparece después)
C) Dirá ambas, hora y fecha
D) No dirá nada porque no entiende "y"
Respuesta correcta: A
Explicación: Nuestro código usa elif, por lo que cuando encuentra "hora" en el comando, ejecuta dar_hora() y NO revisa las demás condiciones. El elif de "día" nunca se evalúa.
🌟 ¡Tu Asistente Ahora es un Calendario Parlante!
Has aprendido a:
✅ Organizar el código con funciones separadas
✅ Detectar preguntas sobre la fecha
✅ Formatear fechas de forma natural
✅ Usar .lower() correctamente para detección confiable
✅ Implementar un bucle conversacional infinito
✅ Usar elif para evitar ejecuciones múltiples
Próximos pasos sugeridos:
Añade más funcionalidades: clima, noticias, calculadora
Mejora la detección: usa expresiones regulares para más precisión
Añade memoria: que recuerde tu nombre entre sesiones
Crea interfaz gráfica: con tkinter o PyQt
📌 Tarea práctica:
Ejecuta el asistente completo
Pregúntale la hora y fecha de diferentes formas
Añade la funcionalidad de decir cuántos días faltan para el fin de semana
Comparte en los comentarios qué otras preguntas sobre tiempo te gustaría que responda
🎉 ¡Tu asistente está volviéndose cada vez más inteligente!
En la próxima lección, enseñaremos a tu asistente a buscar información en internet.
https://www.youtube.com/watch?v=Pj9KbAKpQyk
https://www.youtube.com/watch?v=-0tIy8wWtzE
https://www.youtube.com/watch?v=YqSSId7xfwU
https://www.youtube.com/watch?v=MjK-j7YJ5YI
https://www.youtube.com/watch?v=l2G8-iQYfoA
https://www.youtube.com/watch?v=t-YO0XeHczU
Comentarios
Publicar un comentario