14. ¿Qué hora es?

 

14. ¿Qué Hora Es? - Enseñando a tu Asistente a Decir la Hora

Explicación para principiantes:
¡Es hora de enseñarle a tu asistente su primera habilidad útil! Vamos a hacer que reconozca cuándo preguntas la hora y responda correctamente. Esto es como enseñarle a un niño a decir la hora: primero debe entender la pregunta, luego mirar el reloj, y finalmente responder claramente.

Objetivo de esta lección:

  • Hacer que el asistente detecte cuándo preguntas la hora

  • Obtener la hora actual del sistema

  • Formatear la hora para que suene natural

  • Responder tanto por voz como por texto

Analogía:
Tu asistente es como un recepcionista de hotel:

  • Escucha: "¿Qué hora es?"

  • Procesa: Mira el reloj de la pared

  • Responde: "Son las 3 de la tarde"


🎯 Paso 1: Entender Cómo Funciona la Detección de Intenciones

El Proceso Completo:

text

Tu Voz → "¿Qué hora es?" → Audio → Texto → Detecta "hora" → Obtiene hora actual → Formatea → Responde

  🎤        📝             🎵        📝         🔍 "hora"      ⏰ Sistema         ✏️        🔊

Código de Detección Básica:

python

# 1. Escuchas: "¿Qué hora es?"

comando = escuchar()  # Esto devuelve: "qué hora es"


# 2. Buscar la palabra clave "hora" en el comando

if 'hora' in comando:

    # 3. Si encuentra "hora", ejecutar función para decir la hora

    decir_hora()

Explicación visual del if:

python

comando = "qué hora es"      # Lo que dijiste

            ↓

'buscando' in comando?       # ¿Está "hora" en "qué hora es"?

            ↓

'hora' in "qué hora es"      # ← ¡SÍ está! → Ejecuta decir_hora()

            ↓

✅ HORA ENCONTRADA → decir_hora() se ejecuta


🔧 Paso 2: Crear la Función decir_hora()

Versión Básica:

python

import datetime


def decir_hora():

    """Obtiene y dice la hora actual"""

    # Obtener hora actual del sistema

    hora_actual = datetime.datetime.now()

    

    # Formatear como HH:MM (ej: "15:30")

    hora_formateada = hora_actual.strftime("%H:%M")

    

    # Decir la hora

    print(f"⏰ Son las {hora_formateada}")

    hablar(f"Son las {hora_formateada}")

Versión Mejorada (más natural):

python

def decir_hora_mejorada():

    """Dice la hora de forma más natural"""

    ahora = datetime.datetime.now()

    hora = ahora.hour

    minutos = ahora.minute

    

    # Convertir a formato de 12 horas

    if hora > 12:

        hora_12 = hora - 12

        periodo = "de la tarde"

    elif hora == 12:

        hora_12 = 12

        periodo = "del mediodía"

    elif hora == 0:

        hora_12 = 12

        periodo = "de la madrugada"

    else:

        hora_12 = hora

        periodo = "de la mañana"

    

    # Decir "en punto", "y media", etc.

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

    elif minutos == 45:

        mensaje = f"Son las {hora_12 + 1} menos cuarto {periodo}"

    else:

        mensaje = f"Son las {hora_12} con {minutos} minutos {periodo}"

    

    print(f"⏰ {mensaje}")

    hablar(mensaje)


📚 Paso 3: Entender datetime y strftime()

¿Qué es datetime?

Es una librería que viene con Python que maneja fechas y horas. No necesitas instalarla.

python

import datetime


# Crear objeto con la fecha y hora actuales

ahora = datetime.datetime.now()


# Partes de la fecha/hora:

print(f"Año: {ahora.year}")        # 2024

print(f"Mes: {ahora.month}")       # 1 (enero)

print(f"Día: {ahora.day}")         # 23

print(f"Hora: {ahora.hour}")       # 15 (3 PM)

print(f"Minutos: {ahora.minute}")  # 45

print(f"Segundos: {ahora.second}") # 30

¿Qué es strftime()?

Significa "string format time" (formatear tiempo como texto). Te permite crear formatos personalizados:

python

# Formatos comunes:

formato = ahora.strftime("%H:%M")        # "15:45" (24 horas)

formato = ahora.strftime("%I:%M %p")     # "03:45 PM" (12 horas)

formato = ahora.strftime("%d/%m/%Y")     # "23/01/2024" (fecha)


# Tabla de códigos útiles:

# %H - Hora (00-23)   %I - Hora (01-12)   %p - AM/PM

# %M - Minutos (00-59)

# %S - Segundos (00-59)

# %d - Día (01-31)    %m - Mes (01-12)    %Y - Año (2024)

# %A - Día de semana  %B - Mes completo

Ejercicio práctico:

python

import datetime


ahora = datetime.datetime.now()


# Prueba estos formatos:

print(ahora.strftime("Hoy es %A, %d de %B de %Y"))

print(ahora.strftime("Son las %I:%M %p"))

print(ahora.strftime("Fecha: %d/%m/%Y - Hora: %H:%M:%S"))


🔄 Paso 4: Integrar Todo en el Asistente Principal

Código Completo Integrado:

python

"""

ASISTENTE VIRTUAL - VERSIÓN CON DETECCIÓN DE HORA

"""


import speech_recognition as sr

import pyttsx3

import datetime


# ========== CONFIGURACIÓN INICIAL ==========

listener = sr.Recognizer()

engine = pyttsx3.init()


# Configurar voz en español si está disponible

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)

        break


engine.setProperty('rate', 180)    # Velocidad normal

engine.setProperty('volume', 0.9)  # Volumen alto


# ========== 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"""

    hablar("¡Bienvenido! Soy tu asistente virtual. ¿En qué puedo ayudarte?")


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()

            

            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 ""


# ========== FUNCIÓN PARA DECIR LA HORA ==========

def decir_hora():

    """Obtiene y dice la hora actual de forma natural"""

    ahora = datetime.datetime.now()

    hora = ahora.hour

    minutos = ahora.minute

    

    # Diccionario para convertir números a palabras

    numeros_a_palabras = {

        1: "una", 2: "dos", 3: "tres", 4: "cuatro", 5: "cinco",

        6: "seis", 7: "siete", 8: "ocho", 9: "nueve", 10: "diez",

        11: "once", 12: "doce", 13: "trece", 14: "catorce",

        15: "quince", 16: "dieciséis", 17: "diecisiete",

        18: "dieciocho", 19: "diecinueve", 20: "veinte"

    }

    

    # 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

    

    # Obtener hora en palabras

    hora_palabra = numeros_a_palabras.get(hora_12, str(hora_12))

    

    # Formatear minutos de forma natural

    if minutos == 0:

        mensaje = f"Son las {hora_palabra} en punto {periodo}"

    elif minutos == 30:

        mensaje = f"Son las {hora_palabra} y media {periodo}"

    elif minutos == 15:

        mensaje = f"Son las {hora_palabra} y cuarto {periodo}"

    elif minutos == 45:

        siguiente_hora = hora_12 + 1 if hora_12 < 12 else 1

        siguiente_hora_palabra = numeros_a_palabras.get(siguiente_hora, str(siguiente_hora))

        mensaje = f"Son las {siguiente_hora_palabra} menos cuarto {periodo}"

    elif minutos < 30:

        minutos_palabra = numeros_a_palabras.get(minutos, str(minutos))

        mensaje = f"Son las {hora_palabra} y {minutos_palabra} minutos {periodo}"

    else:

        minutos_faltantes = 60 - minutos

        siguiente_hora = hora_12 + 1 if hora_12 < 12 else 1

        siguiente_hora_palabra = numeros_a_palabras.get(siguiente_hora, str(siguiente_hora))

        minutos_palabra = numeros_a_palabras.get(minutos_faltantes, str(minutos_faltantes))

        mensaje = f"Son las {siguiente_hora_palabra} menos {minutos_palabra} minutos {periodo}"

    

    # Decir la hora

    hablar(mensaje)

    

    # También mostrar formato digital

    hora_digital = ahora.strftime("%H:%M")

    print(f"📱 ({hora_digital})")


# ========== PROGRAMA PRINCIPAL ==========

def main():

    """Función principal del asistente"""

    print("=" * 50)

    print("       ASISTENTE VIRTUAL - DETECTOR DE HORA")

    print("=" * 50)

    

    # Dar bienvenida

    bienvenida()

    

    # Bucle principal

    while True:

        # Escuchar comando

        comando = escuchar()

        

        # Si no se entendió, continuar

        if not comando:

            continue

        

        # Detectar si pregunta por la hora

        if 'hora' in comando:

            print("⏰ Detecté que preguntas por la hora...")

            decir_hora()

        

        # Detectar si quiere salir

        elif 'adiós' in comando or 'salir' in comando:

            hablar("Hasta luego, que tengas un buen día")

            break

        

        # Comando no reconocido

        else:

            hablar(f"Dijiste: '{comando}'. Solo sé decir la hora por ahora. Di 'hora' o 'adiós'")


# Ejecutar el programa

if __name__ == "__main__":

    main()


🎮 Paso 5: Pruebas y Ejercicios Prácticos

Prueba 1: Ver Funcionamiento Básico

python

# Prueba rápida sin micrófono

def prueba_hora_sin_microfono():

    """Prueba la función de hora sin usar micrófono"""

    print("🔍 PRUEBA: Diciendo la hora actual")

    decir_hora()


# Ejecutar prueba

prueba_hora_sin_microfono()

Prueba 2: Simular Diferentes Comandos

python

def simulador_comandos():

    """Simula diferentes comandos para probar"""

    comandos_de_prueba = [

        "¿Qué hora es?",

        "dime la hora por favor",

        "necesito saber la hora",

        "hora actual",

        "qué hora tenemos",

        "adiós",

        "hola",

        "cómo estás"

    ]

    

    for comando in comandos_de_prueba:

        print(f"\n🎤 Comando simulado: '{comando}'")

        

        if 'hora' in comando.lower():

            print("✅ Detectó 'hora' → Ejecutando decir_hora()")

            decir_hora()

        elif 'adiós' in comando.lower():

            print("👋 Detectó 'adiós' → Terminando")

            break

        else:

            print("❌ No detectó 'hora' ni 'adiós' → Ignorando")


simulador_comandos()

Ejercicio 1: Mejorar la Detección

python

# Añade más formas de detectar que preguntan por la hora

palabras_clave_hora = [

    'hora', 'horario', 'reloj', 'tiempo actual',

    'qué hora', 'dime la hora', 'necesito la hora'

]


def detectar_pregunta_hora(comando):

    """Detecta si están preguntando por la hora"""

    comando = comando.lower()

    

    for palabra in palabras_clave_hora:

        if palabra in comando:

            return True

    

    return False


# Modifica el main para usar esta función

if detectar_pregunta_hora(comando):

    decir_hora()

Ejercicio 2: Añadir Fecha

python

def decir_fecha():

    """Dice la fecha actual"""

    ahora = datetime.datetime.now()

    

    # Diccionario de meses

    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 semana

    dias_semana = {

        0: "lunes", 1: "martes", 2: "miércoles", 3: "jueves",

        4: "viernes", 5: "sábado", 6: "domingo"

    }

    

    dia_numero = ahora.day

    mes_nombre = meses[ahora.month]

    año = ahora.year

    dia_semana = dias_semana[ahora.weekday()]

    

    mensaje = f"Hoy es {dia_semana}, {dia_numero} de {mes_nombre} de {año}"

    

    print(f"📅 {mensaje}")

    hablar(mensaje)


# Añade detección de fecha en el main

if 'fecha' in comando or 'día' in comando:

    decir_fecha()


📊 Diagrama de Flujo de la Detección de Hora

text

┌─────────────────────────────────────────────────────┐

│          PROGRAMA PRINCIPAL (while True)            │

├─────────────────────────────────────────────────────┤

│ 1. Escuchar comando: escuchar() → "qué hora es"     │

│    ↓                                                │

│ 2. Convertir a minúsculas: "qué hora es"           │

│    ↓                                                │

│ 3. Buscar palabra clave:                            │

│    ¿"hora" está en "qué hora es"?                  │

│    ↓                                                │

│    ✅ SÍ → decir_hora()                            │

│    ❌ NO → siguiente paso                          │

├─────────────────────────────────────────────────────┤

│           FUNCIÓN decir_hora() INTERNA              │

├─────────────────────────────────────────────────────┤

│ 4. Obtener hora actual: datetime.datetime.now()    │

│    ↓                                                │

│ 5. Extraer partes: hora=15, minutos=30             │

│    ↓                                                │

│ 6. Determinar período: tarde                       │

│    ↓                                                │

│ 7. Convertir a 12h: 15 → 3                         │

│    ↓                                                │

│ 8. Formatear naturalmente:                         │

│    "Son las 3 y media de la tarde"                 │

│    ↓                                                │

│ 9. Hablar: hablar(mensaje)                         │

│    ↓                                                │

│ 10. Volver al bucle principal                       │

└─────────────────────────────────────────────────────┘


🐛 Paso 6: Solución de Problemas Comunes

Problema 1: "No detecta cuando digo 'hora'"

Causa: El comando no contiene exactamente "hora"

Solución:

python

# Mejor detección

comando = comando.lower()  # Asegurar minúsculas

comando = comando.replace('?', '').replace('¿', '')  # Quitar signos


# Buscar varias variantes

if any(palabra in comando for palabra in ['hora', 'horas', 'horita']):

    decir_hora()

Problema 2: "La hora sale en inglés"

Causa: La voz está configurada en inglés

Solución:

python

# Forzar voz en español

def configurar_voz_espanol():

    engine = pyttsx3.init()

    voces = engine.getProperty('voices')

    

    for i, voz in enumerate(voces):

        print(f"Voz {i}: {voz.name}")

        if 'spanish' in voz.name.lower() or 'español' in voz.name.lower():

            engine.setProperty('voice', voz.id)

            print(f"✅ Voz española seleccionada: {voz.name}")

            break

    

    return engine

Problema 3: "Responde a otras palabras que contienen 'hora'"

Causa: Detecta "hora" en cualquier contexto

Solución:

python

# Detección más inteligente

def es_pregunta_hora(comando):

    """Determina si realmente están preguntando por la hora"""

    palabras = comando.split()

    

    # Patrones de pregunta por hora

    patrones = [

        ['qué', 'hora'],

        ['dime', 'hora'],

        ['decir', 'hora'],

        ['saber', 'hora'],

        ['hora', 'es']

    ]

    

    for patron in patrones:

        if all(p in palabras for p in patron):

            return True

    

    return False


# Uso:

if es_pregunta_hora(comando):

    decir_hora()


🚀 Paso 7: Versión Avanzada con Múltiples Habilidades

python

"""

ASISTENTE VIRTUAL CON MÚLTIPLES HABILIDADES

Incluye hora, fecha, saludos y más

"""


import speech_recognition as sr

import pyttsx3

import datetime

import random


class AsistenteMultifuncional:

    def __init__(self, nombre="Alex"):

        self.nombre = nombre

        self.engine = pyttsx3.init()

        self.listener = sr.Recognizer()

        self.configurar_voz()

    

    def configurar_voz(self):

        """Configura la voz del asistente"""

        voces = self.engine.getProperty('voices')

        

        # Buscar voz en español

        for voz in voces:

            if 'spanish' in voz.name.lower() or 'español' in voz.name.lower():

                self.engine.setProperty('voice', voz.id)

                print(f"✅ Voz: {voz.name}")

                break

        

        self.engine.setProperty('rate', 180)

        self.engine.setProperty('volume', 0.9)

    

    def hablar(self, texto):

        """Hace que el asistente hable"""

        print(f"🤖 {self.nombre}: {texto}")

        self.engine.say(texto)

        self.engine.runAndWait()

    

    def escuchar(self):

        """Escucha comandos del usuario"""

        try:

            with sr.Microphone() as source:

                print("\n🎤 Escuchando... (habla ahora)")

                self.listener.adjust_for_ambient_noise(source, duration=0.5)

                audio = self.listener.listen(source, phrase_time_limit=5)

                

                texto = self.listener.recognize_google(audio, language='es-ES')

                texto = texto.lower()

                

                print(f"👤 Tú: {texto}")

                return texto

        except:

            return ""

    

    def procesar_hora(self, comando):

        """Procesa comandos relacionados con la hora"""

        ahora = datetime.datetime.now()

        hora = ahora.hour

        minutos = ahora.minute

        

        # Respuestas diferentes según cómo pregunten

        if 'exacta' in comando:

            mensaje = f"La hora exacta es {hora} horas con {minutos} minutos"

        elif 'mucho' in comando or 'tarde' in comando:

            if hora < 12:

                mensaje = "Todavía es temprano, es de mañana"

            elif hora < 18:

                mensaje = "Es de tarde, pero no es muy tarde"

            else:

                mensaje = "Sí, ya es bastante tarde, es de noche"

        else:

            # Formato normal

            if minutos == 0:

                mensaje = f"Son las {hora} en punto"

            elif minutos == 30:

                mensaje = f"Son las {hora} y media"

            else:

                mensaje = f"Son las {hora} con {minutos} minutos"

        

        self.hablar(mensaje)

    

    def ejecutar(self):

        """Ejecuta el asistente"""

        self.hablar(f"Hola, soy {self.nombre}. Pregúntame la hora, la fecha o simplemente salúdame.")

        

        while True:

            comando = self.escuchar()

            

            if not comando:

                continue

            

            # Detectar diferentes tipos de comandos

            if any(palabra in comando for palabra in ['hora', 'horita', 'reloj']):

                self.procesar_hora(comando)

            

            elif any(palabra in comando for palabra in ['fecha', 'día', 'calendario']):

                ahora = datetime.datetime.now()

                fecha = ahora.strftime("%d de %B de %Y")

                self.hablar(f"Hoy es {fecha}")

            

            elif any(palabra in comando for palabra in ['hola', 'buenos', 'saludos']):

                saludos = ["¡Hola!", "¡Buenas!", "¿Qué tal?", "Encantado de verte"]

                self.hablar(random.choice(saludos))

            

            elif any(palabra in comando for palabra in ['adiós', 'chao', 'hasta luego']):

                despedidas = ["Adiós", "Hasta luego", "Nos vemos", "Que tengas un buen día"]

                self.hablar(random.choice(despedidas))

                break

            

            else:

                self.hablar("No entendí eso. Puedes preguntarme la hora, la fecha o saludarme")


# Crear y ejecutar el asistente

if __name__ == "__main__":

    asistente = AsistenteMultifuncional(nombre="Cronos")

    asistente.ejecutar()


❓ Cuestionario de Repaso

Pregunta 1:

¿Qué hace la línea if 'hora' in comando: en nuestro código?

  • A) Cambia la hora del sistema

  • B) Verifica si la palabra "hora" está en el comando del usuario

  • C) Detiene el programa

  • D) Aumenta la velocidad del habla

Respuesta correcta: B
Explicación: El operador in verifica si una cadena está contenida en otra. if 'hora' in comando: es True si el usuario dijo algo que contiene "hora".


Pregunta 2:

¿Qué devuelve datetime.datetime.now().strftime("%H:%M") cuando son las 3:30 PM?

  • A) "03:30"

  • B) "15:30"

  • C) "3:30 PM"

  • D) "15:30:00"

Respuesta correcta: B
*Explicación: %H da la hora en formato 24 horas (00-23), y %M da los minutos. 3:30 PM = 15:30 en formato 24 horas.*


Pregunta 3:

¿Por qué convertimos el comando a minúsculas con .lower() antes de buscar "hora"?

  • A) Para que el programa sea más rápido

  • B) Para que detecte tanto "HORA" como "hora" como "Hora"

  • C) Para ahorrar memoria

  • D) Para que la voz suene mejor

Respuesta correcta: B
Explicación: En Python, "HORA" y "hora" son diferentes. .lower() convierte todo a minúsculas para que la búsqueda no distinga mayúsculas/minúsculas.


Pregunta 4:

Si el usuario dice "¿Podrías decirme la hora por favor?", ¿nuestro código detectará que pregunta por la hora?

  • A) No, porque no dice exactamente "qué hora es"

  • B) Sí, porque contiene la palabra "hora"

  • C) Solo si decimos "hora" tres veces

  • D) Depende de la hora del día

Respuesta correcta: B
Explicación: Nuestro código busca la palabra "hora" en cualquier parte del comando, así que "¿Podrías decirme la hora por favor?" activará la función decir_hora().


Pregunta 5:

¿Qué ventaja tiene crear una función decir_hora() separada en lugar de poner todo el código en el if?

  • A) Hace el programa más lento

  • B) Permite reusar el código y hace el programa más organizado

  • C) Obliga al usuario a decir "por favor"

  • D) Cambia automáticamente el idioma

Respuesta correcta: B
Explicación: Las funciones permiten organizar el código en bloques reutilizables. Podemos llamar a decir_hora() desde diferentes lugares si es necesario.


Pregunta 6 (Bonus):

Si son las 14:45, ¿qué dirá nuestra función decir_hora_mejorada()?

  • A) "Son las 2:45 PM"

  • B) "Son las 3 menos cuarto de la tarde"

  • C) "Son las 14 horas con 45 minutos"

  • D) "Son las dos y cuarenta y cinco"

Respuesta correcta: B
*Explicación: 14:45 = 2:45 PM en formato 12h. Como son 45 minutos (15 minutos para la próxima hora), decimos "3 menos cuarto" o "2:45". Nuestra función mejorada dice "Son las 3 menos cuarto de la tarde".*


✅ ¡Tu Asistente Ahora Sabe Decir la Hora!

Has aprendido a:

  1. ✅ Detectar cuando el usuario pregunta por la hora

  2. ✅ Obtener la hora actual del sistema

  3. ✅ Formatear la hora para que suene natural

  4. ✅ Responder tanto por texto como por voz

  5. ✅ Manejar diferentes formas de preguntar

Próximos pasos sugeridos:

  1. Añade la fecha como nueva funcionalidad

  2. Mejora la detección para entender más variantes

  3. Añade un temporizador o alarma

  4. Configura diferentes husos horarios

📌 Tarea práctica:

  1. Ejecuta el asistente completo

  2. Pregúntale la hora de 3 formas diferentes

  3. Añade la funcionalidad de decir la fecha

  4. Comparte en los comentarios qué otras funcionalidades te gustaría añadir

🎉 ¡Tu asistente está volviéndose cada vez más útil!
En la próxima lección, enseñaremos a tu asistente a buscar información en Wikipedia.



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

Entradas más populares de este blog

1-7. Transforma tu audio a texto

10. Haz que tu asistente hable

8. NUEVO - Solución si tu micrófono no está captando tu audio