🎲 Listas, TinyDB y Aleatorio

Guía de referencia para guardar datos, elegir elementos al azar y construir las funcionalidades de SonRISAS en App Inventor

📋 Listas

¿Qué es una Lista?

Una lista es una colección ordenada de elementos

Ejemplos de la vida real:

🛒
Lista de la compra: pan, leche, fruta, galletas
🎵
Playlist: canción 1, canción 2, canción 3...
👥
Lista de amigas: Ana, Lucía, María, Paula

En App Inventor

Usamos el bloque make a list para crear listas

Lo encontrarás en el cajón Lists

Cada elemento tiene una posición (índice). El primero es el 1, el segundo el 2, etc.

Bloques de Listas

Los bloques de listas están en el cajón "Lists"

make a list

make a list
item: "hola"
item: "adiós"

Crea una lista con los elementos que le des

select list item

select list item
list: miLista
index: 2

Obtiene el elemento en la posición indicada

length of list

length of list
list: miLista

Devuelve cuántos elementos tiene la lista

add items to list

add items to list
list: miLista
item: "nuevo"

Añade un elemento al final de la lista

🗃️ TinyDB

¿Qué es TinyDB?

TinyDB es la memoria permanente de tu app

🧠

Sin TinyDB

Cuando cierras la app, se pierde todo

Como escribir en una pizarra que se borra sola

💾

Con TinyDB

Los datos se guardan para siempre

Como escribir en un cuaderno que guardas

TinyDB funciona con etiquetas (tags)

Cada dato se guarda con un nombre (etiqueta) para poder encontrarlo después:

Etiqueta: "quotes"
Valor: lista de frases
Etiqueta: "activities"
Valor: lista de actividades

Bloques de TinyDB

Solo necesitas dos bloques principales

StoreValue - Guardar datos 💾

TinyDB1.StoreValue
tag = "quotes"
valueToStore = mi lista de frases

Guarda un valor (puede ser una lista) con una etiqueta

GetValue - Recuperar datos 📖

TinyDB1.GetValue
tag = "quotes"
valueIfTagNotThere = lista vacía

Recupera el valor guardado. Si no existe, devuelve el valor por defecto.

Cargar Datos al Inicio

Cuando la app se abre por primera vez, necesitamos cargar los datos iniciales

¿Cuándo cargar? En Screen1.Initialize

Este evento se ejecuta cada vez que la app se abre. Pero solo queremos cargar los datos la primera vez.

Pasos en bloques:

cuando Screen1.Initialize

si length of list(TinyDB1.GetValue("quotes", make a list())) = 0

entonces TinyDB1.StoreValue(

tag = "quotes"

value = make a list(

"It's never too late to make a new friend"

"A smile can change someone's day"

"You are important to someone"

... more quotes ...

)

)

El if comprueba si la lista está vacía (longitud = 0). Si TinyDB ya tiene los datos guardados devuelve la lista completa y no los sobreescribe. Si es la primera vez que se abre la app, devuelve una lista vacía y los inicializa.

🎲 Números Aleatorios

¿Qué es un Número Aleatorio?

Un número aleatorio es un número elegido al azar

Ejemplo de la vida real:

🎲
Lanzar un dado: sale un número entre 1 y 6 al azar
🎰
Sorteo: se elige un número entre 1 y 100 al azar
🎵
Reproducción aleatoria: se elige una canción al azar de la playlist

En App Inventor: random integer

random integer from 1 to 6

Genera un número al azar entre los dos valores

Lo encuentras en el cajón Math (Matemáticas)

La Combinación Mágica

Juntamos 3 piezas para elegir un elemento al azar de una lista

📋

1. La lista

Recuperamos la lista de TinyDB

🎲

2. Número al azar

Generamos un índice aleatorio

3. Seleccionar

Elegimos el elemento en esa posición

En bloques:

select list item (

list: TinyDB1.GetValue("quotes")

index: random integer from 1 to length of list

)

El random integer va desde 1 hasta el largo de la lista, así nunca pide una posición que no existe.

🎨 Diseño Común (todas las pantallas)

Antes de programar, todas las pantallas necesitan la misma estructura base y barra de título

Paso 1: Contenedor principal

Cada pantalla necesita un VerticalArrangement que contenga todos los demás elementos

Cómo añadirlo en App Inventor

1️⃣
En la parte de arriba a la derecha, seleccionar Designer
2️⃣
En la columna de la izquierda (Palette), ir a la sección Layout
3️⃣
Arrastrar VerticalArrangement al Viewer
4️⃣
En Properties, cambiar BackgroundColor a #FFFFD1
Si ya tenéis elementos en la pantalla, añadid el VerticalArrangement como primer elemento y moved todo lo demás dentro de él arrastrándolo.

Paso 2: Barra de título (TitleBar)

El primer elemento dentro del contenedor es la barra de título, común a todas las pantallas (menos la de inicio de Elia)

Crear la barra de título

1️⃣
Dentro del VerticalArrangement, arrastrar un HorizontalArrangement (Palette → Layout). Renombrarlo a TitleBar
2️⃣
En Properties: Height = 10%, Width = Fill parent
3️⃣
Dentro de TitleBar, añadir un Image (Palette → User Interface) con la imagen home.png — sirve para volver al inicio
4️⃣
Al lado del Image, añadir un Label (Palette → User Interface) con el título de la pantalla

Subir la imagen home.png a App Inventor: en la columna de la derecha (Media), pulsar Upload File

home.png
home.png

Paso 3: Propiedades del Label de título

El Label del título tiene estas propiedades comunes: FontSize = 40, FontTypeface = serif

El texto y color de fondo cambian según la pantalla:

💬
Motivation
Ana
#FFC166
📇
Agenda
Elia
#D29FDC
😊
Mood Tracker
Daniela
#FFFF84
🤝
Activities
Lena
#84D0FF

Resumen de propiedades del Label de título:

Text: el título de tu pantalla (ver arriba) FontSize: 40 FontTypeface: serif BackgroundColor: el color de tu pantalla (ver arriba)
La pantalla de inicio de Elia (Screen1) no lleva barra de título porque es la pantalla principal con los botones de navegación a las demás secciones.

📇 Agenda de Contactos

Concepto

La funcionalidad principal del MVP: guardar contactos cercanos y recordar contactar con ellos

Pantalla Principal

👤 Grandma Ana
👤 Uncle Pedro
👤 Friend María
+ Add Contact
Toca un nombre → popup

Popup al tocar contacto

Uncle Pedro
📞 Call ⚙️ Manage
Cancel

Pantalla Editar

Name
Grandma Ana
Phone
+34 612 345 678
Remind every...
1 day 3 days 7 days
💾 Save 🗑️ Delete

Flujo del usuario

1️⃣
Pulsa "Add Contact" → se abre una lista con todos los contactos del teléfono (ListPicker + extensión PhoneNumberTools)
2️⃣
Elige un contacto → se guarda el nombre y teléfono en TinyDB
3️⃣
Toca un contacto en la lista → aparece popup con 📞 Call y ⚙️ Manage
4️⃣
Si elige "⚙️ Manage" → pantalla para editar o eliminar ese contacto
5️⃣
Al abrir la app, si toca recordatorio → aparece aviso con botones para llamar/SMS

Pantalla Principal: Componentes

Componentes visibles

ListView
ListViewContacts — muestra la lista de contactos guardados
ListPicker
ListPickerAddContact — botón "Add Contact" que muestra la lista de contactos del teléfono

Componentes no visibles

Notifier
Notifier1 — popup con Call/SMS al tocar un contacto + recordatorios
PhoneCall
PhoneCall1 — para hacer llamadas
TinyDB
TinyDB1 — almacena contactos y configuración
Clock
Clock1 — para operaciones con fechas (recordatorios)
Extension
PhoneNumberTools1 — extensión (io.mohamed.PhoneNumbersTools) que carga la lista de contactos del teléfono
La pantalla principal es muy sencilla: solo la lista, un botón para añadir y otro para gestionar. Al tocar un nombre, aparece un popup centrado con las opciones de llamar o enviar SMS.

Estructura de datos en TinyDB

"contacts" lista de nombres: ["Grandma Ana", "Uncle Pedro", ...]
"contact_phone_Grandma Ana" "+34 612 345 678"
"contact_days_Grandma Ana" 3 (recordar cada 3 días)
"contact_last_Grandma Ana" "2026-02-25" (fecha del último recordatorio)
Usamos el nombre del contacto como parte del tag. Así cada contacto tiene sus propios datos separados.

Añadir Contactos

Usamos la extensión PhoneNumberTools + ListPicker para mostrar solo contactos reales del teléfono

⚠️ ¿Por qué no usamos ContactPicker?

El componente nativo ContactPicker tiene un bug en Android 13+ que muestra el selector de archivos en vez de los contactos. La solución es usar la extensión PhoneNumberTools (io.mohamed.PhoneNumbersTools) para cargar los contactos del teléfono y un ListPicker para que el usuario elija.

Flujo con extensión + ListPicker

1️⃣
Al iniciar la pantalla, la extensión carga todos los contactos del teléfono en dos listas: nombres y teléfonos
2️⃣
Los nombres se asignan al ListPickerAddContact como elementos
3️⃣
El usuario pulsa "Add Contact" → el ListPicker abre la lista de nombres
4️⃣
El usuario elige un nombre → usamos SelectionIndex para obtener el teléfono de la lista paralela
5️⃣
Guardamos nombre y teléfono en TinyDB

Variables globales necesarias

global phoneBookNames = make a list()   // nombres originales (con duplicados)

global phoneBookPhones = make a list()  // teléfonos originales (índice paralelo)

global uniqueNames = make a list()    // nombres sin duplicados y ordenados (para el ListPicker)

Paso 1 — Cargar contactos al iniciar la pantalla:

cuando Screen1.Initialize:

call PhoneNumberTools1.GetContactNameListAsync

call PhoneNumberTools1.GetPhoneNumberListAsync

call loadContactList   // cargar contactos guardados en TinyDB

call checkReminders   // comprobar si hay que recordar contactar con alguien

Paso 2 — Guardar listas cuando la extensión termina de cargar:

cuando PhoneNumberTools1.GotContactNameList(nameList):

set global phoneBookNames = nameList

 

// Eliminar duplicados

set global uniqueNames = make a list()

para cada name en nameList:

si not is in list?(name, uniqueNames):

add items to list(uniqueNames, name)

 

// Ordenar alfabéticamente y asignar al ListPicker

set ListPickerAddContact.Elements = list sort(uniqueNames)

 

cuando PhoneNumberTools1.GotContactPhoneList(phoneList):

set global phoneBookPhones = phoneList

Paso 3 — Cuando el usuario elige un contacto:

cuando ListPickerAddContact.AfterPicking:

set name = ListPickerAddContact.Selection

// Buscar el teléfono por nombre en la lista original

set index = index in list(name, global phoneBookNames)

set phone = select list item(global phoneBookPhones, index)

 

// Recuperar lista actual de contactos guardados

set contactList = TinyDB1.GetValue("contacts", make a list())

 

// Añadir nuevo contacto

add items to list(contactList, name)

TinyDB1.StoreValue("contacts", contactList)

 

// Guardar teléfono y configuración por defecto

TinyDB1.StoreValue(join("contact_phone_", name), phone)

TinyDB1.StoreValue(join("contact_days_", name), 3)

TinyDB1.StoreValue(join("contact_last_", name), Clock1.FormatDate(Clock1.Now()))

 

// Actualizar la lista visible

call loadContactList

Procedimiento: loadContactList

procedimiento loadContactList:

set contactList = TinyDB1.GetValue("contacts", make a list())

set ListViewContacts.Elements = contactList

ListPicker se comporta como un botón: al pulsarlo abre automáticamente la lista de elementos asignada. El texto del botón puede ser "➕ Add Contact". A diferencia del ContactPicker nativo, funciona correctamente en todas las versiones de Android.

Llamar y Gestionar

Al tocar un contacto, aparece un popup centrado con dos opciones claras

Mostrar popup al tocar un contacto:

cuando ListViewContacts.AfterPicking:

set global selectedContact = ListViewContacts.Selection

Notifier1.ShowChooseDialog(

message: selectedContact

title: "¿Qué quieres hacer?"

button1Text: "📞 Call"

button2Text: "⚙️ Manage"

cancelable: true

)

Ejecutar la acción elegida:

cuando Notifier1.AfterChoosing(choice):

 

si choice = "📞 Call":

set phone = TinyDB1.GetValue(join("contact_phone_", global selectedContact))

set PhoneCall1.PhoneNumber = phone

PhoneCall1.MakePhoneCall

 

si choice = "⚙️ Manage":

open another screen with start value

screenName: "EditContactScreen"

startValue: global selectedContact

ShowChooseDialog crea un popup centrado en la pantalla. Es mucho más claro para personas mayores que buscar botones en la pantalla. Si el usuario toca fuera del popup, se cierra (cancelable = true). Con este diseño no hace falta una pantalla intermedia de gestión: desde el popup se va directamente a editar el contacto seleccionado.

Pantalla Editar Contacto

Pantalla separada (EditContactScreen) para modificar nombre, teléfono y frecuencia

Componentes en Designer

TextBox
TextBoxName — nombre a mostrar
TextBox
TextBoxPhone — número de teléfono
ListPicker
ListPickerDays — frecuencia de recordatorio (texto: "⏰ Cada X días")
Button
ButtonSave — "💾 Save" (guardar cambios)
Button
ButtonDelete — "🗑️ Delete" (eliminar contacto)
TinyDB
TinyDB1 — leer y guardar datos del contacto

Variables globales (en el cajón Variables):

initialize global contactName = ""

initialize global currentDays = 3

initialize global newName = ""

Cargar datos al abrir EditContactScreen:

cuando EditContactScreen.Initialize:

set global contactName = get start value

set TextBoxName.Text = contactName

set TextBoxPhone.Text = TinyDB1.GetValue(join("contact_phone_", contactName))

set global currentDays = TinyDB1.GetValue(join("contact_days_", contactName), 3)

set ListPickerDays.Elements = make a list("1", "3", "7")

set ListPickerDays.Text = join("⏰ Cada ", currentDays, " días")

⏰ Elegir frecuencia:

cuando ListPickerDays.AfterPicking:

set global currentDays = number(ListPickerDays.Selection)

set ListPickerDays.Text = join("⏰ Cada ", currentDays, " días")

💾 Guardar cambios:

cuando ButtonSave.Click:

set newName = TextBoxName.Text

 

// Si cambió el nombre, actualizar la lista y mover datos

si newName contactName:

set contactList = TinyDB1.GetValue("contacts", make a list())

set idx = index in list(contactName, contactList)

replace list item(contactList, idx, newName)

TinyDB1.StoreValue("contacts", contactList)

 

// Mover contact_last_ al nuevo nombre

TinyDB1.StoreValue(join("contact_last_", newName), TinyDB1.GetValue(join("contact_last_", contactName), ""))

 

// Borrar claves antiguas

TinyDB1.StoreValue(join("contact_phone_", contactName), "")

TinyDB1.StoreValue(join("contact_days_", contactName), "")

TinyDB1.StoreValue(join("contact_last_", contactName), "")

 

// Guardar phone y days (con el nombre final, nuevo o igual)

TinyDB1.StoreValue(join("contact_phone_", newName), TextBoxPhone.Text)

TinyDB1.StoreValue(join("contact_days_", newName), currentDays)

 

close screen

🗑️ Eliminar contacto:

cuando ButtonDelete.Click:

set contactList = TinyDB1.GetValue("contacts", make a list())

set index = index in list(contactName, contactList)

remove list item(contactList, index)

TinyDB1.StoreValue("contacts", contactList)

 

// Borrar datos del contacto

TinyDB1.StoreValue(join("contact_phone_", contactName), "")

TinyDB1.StoreValue(join("contact_days_", contactName), "")

TinyDB1.StoreValue(join("contact_last_", contactName), "")

 

close screen

Sistema de Recordatorios

Cada vez que se abre la app, comprobamos si hay que recordar contactar con alguien

📅

1. Comprobar fechas

¿Han pasado los días configurados?

🔔

2. Mostrar aviso

Popup con botones Call/SMS

3. Resetear contador

Guardar fecha actual como "último aviso"

Procedimiento: checkReminders

procedimiento checkReminders:

set contactList = TinyDB1.GetValue("contacts", make a list())

set reminders = make a list()

set global reminderFirstContact = ""

set today = Clock1.FormatDate(Clock1.Now())

 

para cada name en contactList:

set days = TinyDB1.GetValue(join("contact_days_", name), 3)

set lastDate = TinyDB1.GetValue(join("contact_last_", name), "")

 

// Calcular días transcurridos

set elapsed = Clock1.Duration(

Clock1.MakeInstantFromMillis(Clock1.GetMillis(Clock1.MakeInstant(lastDate)))

Clock1.Now()

) / 86400000   // milisegundos en un día

 

si elapsed days:

add items to list(reminders, name)

// Resetear: guardar fecha de hoy

TinyDB1.StoreValue(join("contact_last_", name), today)

 

// Mostrar recordatorios pendientes

si length of list(reminders) > 0:

set global reminderFirstContact = select list item(reminders, 1)

set message = "Time to reach out to: "

para cada name en reminders:

message = join(message, "\n• ", name)

 

Notifier1.ShowChooseDialog(

message: message

title: "🔔 Reminder"

button1Text: "📞 Call first contact"

button2Text: "OK, thanks!"

)

🔔

"Time to reach out to:"

• Grandma Ana
• Uncle Pedro

📞 Call first OK, thanks!

Al cerrar el aviso...

La fecha se actualiza a hoy.
Si se reabre la app, no se repite el recordatorio.

Variable global necesaria (en el cajón Variables):

initialize global reminderFirstContact = ""

Responder al botón del diálogo:

cuando Notifier1.AfterChoosing(choice):

si choice = "📞 Call first contact":

set phone = TinyDB1.GetValue(join("contact_phone_", reminderFirstContact), "")

si phone "":

call PhoneCall1.MakePhoneCall

phoneNumber: phone

86400000 = milisegundos en un día (24 × 60 × 60 × 1000). Clock1.Duration devuelve milisegundos, así que dividimos para obtener días.

💬 Frases Motivadoras

Vamos a aplicar todo esto a nuestra app

Componentes en Designer

Label
LabelQuote — muestra la frase (texto grande, centrado)
Button
ButtonNewQuote — "New quote"
Button
ButtonShare — compartir por SMS
TinyDB
TinyDB1 — almacén de datos (no visible)

Cargar frases al inicio

cuando Screen1.Initialize:

si length of list(TinyDB1.GetValue("quotes", make a list())) = 0:

TinyDB1.StoreValue("quotes", make a list(

"It's never too late to make a new friend"

"A phone call can brighten someone's whole day"

"Sharing a walk is sharing happiness"

"Small gestures make big differences"

"Today is a good day to say I love you"

))

Botón Aleatorio

Cuando pulsen el botón, mostramos una frase al azar

cuando ButtonNewQuote.Click:

set variable list = TinyDB1.GetValue("quotes", "")

 

si length of list(list) > 0:

entonces

set LabelQuote.Text =

select list item(

list: list

index: random integer(1, length of list(list))

)

 

si no:

set LabelQuote.Text = "No quotes saved"

El if comprueba que la lista no esté vacía antes de intentar elegir. Así evitamos errores.

🤝 Actividades Compartidas

Actividades por Categorías

Queremos que el usuario elija un tipo de actividad y le sugiera una al azar

🍳

Cooking

🎲

Games

🌳

Outdoors

🎨

Creativity

¿Cómo organizar esto en TinyDB?

Necesitamos guardar una lista diferente para cada categoría.

La solución: usar prefijos en las etiquetas (tags).

Es como organizar carpetas: en vez de meter todo junto, separamos por tipo.

Prefijo = una palabra al principio del tag que indica la categoría

"activities_cooking", "activities_games", "activities_outdoors"...

Prefijos en TinyDB

Cada categoría tiene su propia etiqueta con un prefijo común

"activities_cooking" 🍳 Bake cookies together, Make an omelette, Prepare a smoothie...
"activities_games" 🎲 Play cards, Do a puzzle, Play dominoes...
"activities_outdoors" 🌳 Walk in the park, Go to a market, Visit a museum...
"activities_creativity" 🎨 Do crafts together, Look at old photos, Draw together...
Todas empiezan por "activities_" y luego el tipo. Así están organizadas y es fácil encontrarlas.

Cargar Actividades por Categoría

En Screen1.Initialize, cargamos cada categoría por separado

🍳 Cooking

si length of list(TinyDB1.GetValue("activities_cooking", make a list())) = 0:

TinyDB1.StoreValue("activities_cooking", make a list(

"Bake cookies together", "Make an omelette",

"Prepare a smoothie", "Make popcorn"

))

🌳 Outdoors

si length of list(TinyDB1.GetValue("activities_outdoors", make a list())) = 0:

TinyDB1.StoreValue("activities_outdoors", make a list(

"Walk in the park", "Go to a market",

"Visit a museum", "Sit at a terrace"

))

Lo mismo para cada categoría: games, creativity, etc.

Cada una con su tag: "activities_games", "activities_creativity"

Un Botón por Categoría

Cada botón busca en su categoría y muestra una actividad al azar

🍳 cuando ButtonCooking.Click:

set list = TinyDB1.GetValue("activities_cooking", "")

set LabelActivity.Text =

select list item(list, random integer(1, length of list(list)))

🎲 cuando ButtonGames.Click:

set list = TinyDB1.GetValue("activities_games", "")

set LabelActivity.Text =

select list item(list, random integer(1, length of list(list)))

🌳 cuando ButtonOutdoors.Click:

set list = TinyDB1.GetValue("activities_outdoors", "")

set LabelActivity.Text =

select list item(list, random integer(1, length of list(list)))

🎨 cuando ButtonCreativity.Click:

set list = TinyDB1.GetValue("activities_creativity", "")

set LabelActivity.Text =

select list item(list, random integer(1, length of list(list)))

Los bloques son iguales para cada botón, solo cambia el tag. Cada botón lee su propia lista.

😊 Registro Emocional (Mood Tracker)

Concepto

SonRISAS incluye un diario de emociones para saber cómo se siente el usuario

😊

Happy

😐

Okay

😢

Sad

¿Cómo funciona?

1️⃣
El usuario pulsa un botón cada día según cómo se siente
2️⃣
Se guardan los últimos 7 registros en TinyDB (como una lista)
3️⃣
Se muestra el historial:  😊😐😊😊😢😐😊
4️⃣
Si los últimos 3 son 😐 o 😢 → se sugiere contactar a alguien, hacer una actividad o ver frases

Componentes en Designer

Componentes principales

Button
ButtonHappy — texto: 😊 (botón grande)
Button
ButtonOkay — texto: 😐 (botón grande)
Button
ButtonSad — texto: 😢 (botón grande)
Label
LabelMoodHistory — muestra los últimos 7 emojis
Label
LabelSuggestion — texto de sugerencia (oculto por defecto)

Botones de navegación (ocultos por defecto)

Button
ButtonGoContacts — "Call someone" → pantalla agenda
Button
ButtonGoActivities — "Do an activity" → pantalla actividades
Button
ButtonGoQuotes — "Read quotes" → pantalla frases
TinyDB
TinyDB1 — almacena la lista de moods con tag "moods"

Guardar y Mostrar Historial

Al pulsar un botón de mood: comprobar si ya se registró hoy, y si no, añadir a la lista, limitar a 7 y mostrar

Procedimiento: saveMood (valor: texto)

Un solo procedimiento para los tres botones. Recibe "happy", "okay" o "sad".

procedimiento saveMood(valor):

set today = Clock1.FormatDate(Clock1.Now())

set lastMoodDate = TinyDB1.GetValue("mood_last_date", "")

 

si today = lastMoodDate:

Notifier1.ShowAlert("You already logged your mood today!")

si no:

set global moodList = TinyDB1.GetValue("moods", make a list())

add items to list(moodList, valor)

si length of list(moodList) > 7:

remove list item(moodList, index: 1)

TinyDB1.StoreValue("moods", moodList)

TinyDB1.StoreValue("mood_last_date", today)

call showMoodHistory

call checkSadness

Los tres botones llaman al mismo procedimiento:

cuando ButtonHappy.Click:  call saveMood("happy")

cuando ButtonOkay.Click:   call saveMood("okay")

cuando ButtonSad.Click:    call saveMood("sad")

Procedimiento: showMoodHistory

procedimiento showMoodHistory:

set text = ""

para cada item en moodList:

si item = "happy" → text = text + "😊"

si item = "okay" → text = text + "😐"

si item = "sad" → text = text + "😢"

set LabelMoodHistory.Text = text

Los botones ButtonOkay y ButtonSad hacen lo mismo, solo cambia el valor: "okay" o "sad".

Detectar Tristeza

Si los últimos 3 registros son "no felices" (okay o sad), sugerimos ayuda

Procedimiento: checkSadness

Necesita 4 variables globales: moodList, n, e1, e2, e3 (inicializadas a "" o 0)

procedimiento checkSadness:

set global moodList = TinyDB1.GetValue("moods", make a list())

si length of list(moodList) 3:

set global n = length of list(moodList)

set global e1 = select list item(moodList, n - 2)

set global e2 = select list item(moodList, n - 1)

set global e3 = select list item(moodList, n)

si e1 "happy" and e2 "happy" and e3 "happy":

set LabelSuggestion.Text = "It looks like you've been feeling down. How about..."

set ButtonGoContacts.Visible = true

set ButtonGoActivities.Visible = true

set ButtonGoQuotes.Visible = true

si no:

set LabelSuggestion.Text = "You're doing great! Keep smiling 😊"

set ButtonGoContacts.Visible = false

set ButtonGoActivities.Visible = false

set ButtonGoQuotes.Visible = false

😐😢😐

"It looks like you've been feeling down..."

📞 Call someone 🎲 Do an activity 💬 Read quotes

😊😐😊

"You're doing great! Keep smiling 😊"

(botones de navegación ocultos)

Vocabulario Clave 📖

Lista = colección ordenada

TinyDB = memoria permanente

Tag = etiqueta para buscar datos

Prefijo = nombre al inicio del tag

Random = aleatorio, al azar

Index = posición en la lista

ListPicker = lista desplegable para elegir un elemento

SelectionIndex = posición del elemento elegido en el ListPicker

Clock = reloj para fechas

Mood Tracker = registro emocional