¡Te damos la bienvenida a este reto!

1

Empezando con Python desde 0

Día 1

2

Variables, funciones y sintaxis básica

3

Tipos de datos: Numbers, Strings y Diccionarios

4

Playground - Retorna el tipo

Día 2

5

Operadores

6

Playground - Calcula la propina

Día 3

7

Condicionales

8

Playground - Averigua si un año es bisiesto

9

Ciclos

10

Playground - Dibuja un triangulo usando bucles

Día 4

11

Listas

12

Encuentra a los gatitos más famosos

13

Diccionarios

14

Obtén el promedio de los estudiantes

15

Tuplas

16

Obten la información de los paquetes

Día 5

17

Calcula la cantidad de letras en una oración

18

Encuentra el mayor palíndromo

Día 6

19

Sets

20

Encuentre la intersección de conjuntos

Día 7

21

List comprehension

22

Encuentra palabras con dos vocales

23

Dictionary Comprehension

24

Calcula la longitud de las palabras

Día 8

25

Funciones Lambda

26

Filtra mensajes de un user específico

27

Higher order functions

28

Crea tu propio método map

Día 9

29

Manejo de Errores y excepciones

30

Maneja correctamente los errores

31

Maneja las excepciones

Día 10

32

Playground - Crea un task manager usando closures

Día 11

33

Lectura de archivos de texto y CSV

Día 12

34

Programación orientada a objetos

35

Crea un auto usando clases

Día 13

36

Abstracción en Python

37

Playground - Crea un sistema de carrito de compras

38

Encapsulamiento en Python

39

Playground - Encapsula datos de los usuarios

Día 14

40

Herencia en Python

41

Playground - Jerarquía de animales usando herencia

Día 15

42

Polimorfismo en Python

43

Playground - Implementa un sistema de pagos

Día 16

44

Estructuras de datos en Python

45

Playground - Crea tu propia lista en python

46

Hash tables en Python

47

Playground - Implementación de una HashTable para Contactos

Día 17

48

Maps en Python

49

Playground - Crea un task manager con Maps

Día 18

50

Singly Linked List en Python

51

Playground - Implementación de una singly linked list

Día 19

52

Stacks en Python

53

Playground - Implementación de un stack

Día 20

54

Queues en Python

55

Playground - Implementación de una queue

Día 21

56

¡Lo lograste!

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Playground - Crea un task manager usando closures

32/56

Aportes 42

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

me costó bastante este ejercicio, no que con los otros no tuviera alguna dificultad, pero se resolvían con solo pensar un poco, pero en este caso no sabia o recordaba el uso de funciones internas como metodos de una funcion externa y no encontraba la clase de los cursos basicos de python que he tomado donde los explicaban. Luchando con la tentacion de ir directo a la respuestas de los compañeros y ver, finalmente logré hacerlo como un poco de ensayo y error, algo de logica e intuición, pero culminar todo el ejercicio me tomó como 6 horas en total, si fuese un prueba tecnica, pues dudo que hubiese aprobado

     for item in arrayTasks:
       if (item['id'] ==value) or(item['name'] ==value):
         item['completed']=True
   
  
  def getSortedTasksByPriority():
    # Tu código aquí 👇
    sortedTasks =[]
    for i in range(1, 2):
      if arrayTasks[i]['priority'] < arrayTasks[i-1]['priority']:
        sortedTasks.append(arrayTasks[i])
        sortedTasks.append(arrayTasks[i-1])
      else:
        sortedTasks.append(arrayTasks[i-1])
        sortedTasks.append(arrayTasks[i])
    return sortedTasks  


  
  def filterTasksByTag(tag):
    # Tu código aquí 👇
    return [task for task in arrayTasks if tag in task['tags']]

  def updateTask(taskId, updates):
    # Tu código aquí 👇
    for i in range(len(arrayTasks)):
      if arrayTasks[i]['id']==taskId:
        for key, value in updates.items():
          arrayTasks[i][key]=value
         
 
  return {'addTask': addTask, 'getTasks': getTasks, 'removeTask': removeTask, 'getPendingTasks':getPendingTasks, 'getCompletedTasks': getCompletedTasks, 'markTaskAsCompleted':markTaskAsCompleted, 'getSortedTasksByPriority':getSortedTasksByPriority, 'filterTasksByTag':filterTasksByTag, 'updateTask' :updateTask}

Hola, Aqui esta una Solucion con Pruebas Internas para Validacion de cada uno de los Metodos propuestos por el Ejercicio: Saludos

def createTaskPlanner():
  tasks = []

  def addTask(task):
    task['completed'] = False
    tasks.append(task)

  def removeTask(value):
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        tasks.remove(task)
        break

  def getTasks():
    return tasks

  def getPendingTasks():
    return [task for task in tasks if not task['completed']]

  def getCompletedTasks():
    return [task for task in tasks if task['completed']]

  def markTaskAsCompleted(value):
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        task['completed'] = True
        break

  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda task: task['priority'])

  def filterTasksByTag(tag):
    return [task for task in tasks if tag in task['tags']]

  def updateTask(taskId, updates):
    for task in tasks:
      if task['id'] == taskId:
        for key, value in updates.items():
          task[key] = value
        break

  return {
    'addTask': addTask,
    'removeTask': removeTask,
    'getTasks': getTasks,
    'getPendingTasks': getPendingTasks,
    'getCompletedTasks': getCompletedTasks,
    'markTaskAsCompleted': markTaskAsCompleted,
    'getSortedTasksByPriority': getSortedTasksByPriority,
    'filterTasksByTag': filterTasksByTag,
    'updateTask': updateTask,
  }
  
planner = createTaskPlanner()

planner['addTask']({
    'id': 1,
    'name': 'Comprar leche',
    'priority': 1,
    'tags': ['shopping', 'home']
})

planner['addTask']({
    'id': 2,
    'name': 'Llamar a Juan',
    'priority': 3,
    'tags': ['personal']
})

planner['addTask']({
    'id': 3,
    'name': 'Probar a Fondo el Codigo de Python',
    'priority': 2,
    'tags': ['Codigo','Python', 'Curso']
})

planner['markTaskAsCompleted']('Llamar a Juan')

def print_dictionaries(dictionaries):
  for dictionary in dictionaries:
    for key, value in dictionary.items():
      print(key, "=", value)
    print()

def print_title(title):
  print("°"*20, title , "°"*20)

print_title("Tareas Completadas")
print_dictionaries(planner['getCompletedTasks']())
print_title("Tareas Pendientes")
print_dictionaries(planner['getPendingTasks']())

planner['markTaskAsCompleted']('Comprar leche')
print_title("Marcando Tarea 3 Como Completada")
print_title("Tareas Completadas")
print_dictionaries(planner['getCompletedTasks']())
print_title("Tareas Pendientes")
print_dictionaries(planner['getPendingTasks']())

print_title("Tareas Ordenadas por Prioridad")
print_dictionaries(planner['getSortedTasksByPriority']())

print_title("Tareas Filtradas por Etiqueta: Python")
print_dictionaries(planner['filterTasksByTag']('Python'))

print_title("Tareas Filtradas por Etiqueta: personal")
print_dictionaries(planner['filterTasksByTag']('personal'))

print_title("Tareas Filtradas por Etiqueta del Ejemplo 2: shopping")
print_dictionaries(planner['filterTasksByTag']('shopping'))

print_title("Tareas Tareas Totales")
print_dictionaries(planner['getTasks']())
print_title("Removiendo Tarea con ID: 2")
planner['removeTask'](2)
print_title("Tareas Tareas Totales")
print_dictionaries(planner['getTasks']())

Lo que mas me costó entender en esta ocación fue conocer y entender que son y como funcionaban los clousure y como se retornan las funciones anidadas de la función principal.

def createTaskPlanner():
  tasks = []

  def _findTask(key, value):
    for task in tasks:
      if task[key] == value:
        return task    

  def addTask(task):
    task["completed"] = False
    tasks.append(task)

  def removeTask(value):
    if type(value) == int:
      tasks.remove(_findTask("id", value))
    elif type(value) == str:
      tasks.remove(_findTask("name", value))

  def getTasks():
    return tasks
  
  def getPendingTasks():
    pendingTasks = []
    for task in tasks:
      if task["completed"] == False:
        pendingTasks.append(task)
    return pendingTasks
  
  def getCompletedTasks():
    completedTasks = []
    for task in tasks:
      if task["completed"] == True:
        completedTasks.append(task)
    return completedTasks
  
  def markTaskAsCompleted(value):
    if type(value) == int:
      _findTask("id", value)["completed"] = True
    elif type(value) == str:
      _findTask("name", value)["completed"] = True
  
  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda task: task["priority"])
  
  def filterTasksByTag(tag):
    taskByTag = []
    for task in tasks:
      for tagElement in task["tags"]:
        if tagElement == tag:
          taskByTag.append(task)
    return taskByTag
  
  def updateTask(taskId, updates):
    _findTask("id", taskId).update(updates)
  
  return {
    "addTask": addTask,
    "getTasks": getTasks,
    "removeTask": removeTask,
    "getPendingTasks": getPendingTasks,
    "getCompletedTasks": getCompletedTasks,
    "markTaskAsCompleted": markTaskAsCompleted,
    "getSortedTasksByPriority": getSortedTasksByPriority,
    "filterTasksByTag": filterTasksByTag,
    "updateTask": updateTask
  }

Esta muy dificil, me tarde dias y mas en resolver

UnboundLocalError: cannot access local variable ‘tasks’ where it is not associated with a value

pero al final lo termine

def createTaskPlanner():
  tasks = []

  def addTask(task):
    task['completed'] = False
    tasks.append(task)
    
  def removeTask(value):
    nonlocal tasks # para acceder a la variable tasks del ambito exterior
    tasks = [task for task in tasks if task['id'] != value or task['name'] != value]

  def getTasks():
    return tasks
  
  def getPendingTasks():
    nonlocal tasks
    return [task for task in tasks if task['completed'] == False]
  
  def getCompletedTasks():
    nonlocal tasks
    return [task for task in tasks if task['completed'] == True]
  
  def markTaskAsCompleted(value):
    nonlocal tasks # para acceder a la variable tasks del ambito exterior
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        task['completed'] = True
  
  def getSortedTasksByPriority():
    sortedTask = []
    sortedTask = sorted(tasks,key=lambda task: task['priority'])
    return sortedTask
  
  def filterTasksByTag(tag):
    return [task for task in tasks if tag in task['tags']]
  
  def updateTask(taskId, updates):
    for task in tasks:
      if task['id']==taskId:
        for key, value in updates.items():
          task[key]=value
  
  return {'addTask': addTask,
  'removeTask': removeTask,
  'getTasks': getTasks,
  'getPendingTasks': getPendingTasks,
  'getCompletedTasks': getCompletedTasks,
  'markTaskAsCompleted': markTaskAsCompleted,
  'getSortedTasksByPriority': getSortedTasksByPriority,
  'filterTasksByTag': filterTasksByTag,
  'updateTask': updateTask
  }

Esta práctica está bastante completa, me demore, pero muy buena.

**Reto del día superado.** ```python def createTaskPlanner(): tasks = list() def addTask(task): task['completed'] = False tasks.append(task) def removeTask(value): for task in tasks: if task['id'] == value: tasks.remove(task) elif task['name'] == value: tasks.remove(task) return def getTasks(): return tasks def getPendingTasks(): return [task for task in tasks if task['completed'] == False] def getCompletedTasks(): return [task for task in tasks if task['completed'] == True] def markTaskAsCompleted(value): for task in tasks: if task['id'] == value or task['name'] == value: task['completed'] = True break return def getSortedTasksByPriority(): new_tasks = [task for task in tasks] priority = lambda task: task['priority'] new_tasks.sort(key=priority) return new_tasks def filterTasksByTag(tag): return [task for task in tasks if tag in task['tags']] def updateTask(taskId, updates): for task in tasks: if task['id'] == taskId: task.update(updates) return return {'addTask': addTask, 'removeTask': removeTask, 'getTasks': getTasks, 'getPendingTasks': getPendingTasks, 'getCompletedTasks': getCompletedTasks, 'markTaskAsCompleted': markTaskAsCompleted, 'getSortedTasksByPriority': getSortedTasksByPriority, 'filterTasksByTag': filterTasksByTag, 'updateTask': updateTask } ```
Mi código: def createTaskPlanner(): tasks = \[] def addTask(task): task\["completed"] = False tasks.append(task) return tasks def removeTask(value): for task in tasks: if task\["id"] == value or task\["name"] == value: tasks.remove(task) return tasks def getTasks(): return tasks def getPendingTasks(): return list(filter((lambda x:x\["completed"] == True), tasks)) def getCompletedTasks(): return list(filter((lambda x:x\["completed"] != False), tasks)) def markTaskAsCompleted(value): for task in tasks: if task\["id"] == value or task\["name"] == value: task\["completed"] = True return tasks def getSortedTasksByPriority(): return sorted(tasks, key = lambda x:x\["priority"]) def filterTasksByTag(tag): list\_tag = \[] for task in tasks: for tag1 in task\["tags"]: if tag1 == tag: list\_tag.append(task) return(list\_tag) def updateTask(taskId, updates): for task in tasks: if task\["id"] == taskId: for key, value in updates.items(): task\[key] = value return tasks return {"addTask":addTask, "removeTask":removeTask, "getTasks":getTasks, "getPendingTasks":getPendingTasks, "getCompletedTasks":getCompletedTasks, "markTaskAsCompleted":markTaskAsCompleted, "getSortedTasksByPriority":getSortedTasksByPriority, "filterTasksByTag":filterTasksByTag, "updateTask":updateTask}
C:> C:> C:> C:> C:> C:> C:> C:> ```js def createTaskPlanner(): tareas=[] def addTask(task): task["completed"] = False tareas.append(task) return 0 def removeTask(value): for tarea in tareas[:]: if tarea["id"]==value or tarea["name"]==value: tareas.remove(tarea) return 0 def getTasks(): return tareas def getPendingTasks(): incompleta = lambda tarea: tarea["completed"] == False pendientes=list(filter(incompleta, tareas)) return pendientes def getCompletedTasks(): completada = lambda tarea: tarea["completed"] == True terminadas=list(filter(completada, tareas)) return terminadas pass def markTaskAsCompleted(value): for tarea in tareas[:]: if tarea["id"]==value or tarea["name"]==value: tarea["completed"]=True return 0 def getSortedTasksByPriority(): temp=[] temp=tareas temp.sort(key=lambda tarea: tarea["priority"]) return temp def filterTasksByTag(tag): filtradas=[] for tarea in tareas: if tag in tarea["tags"]: filtradas.append(tarea) return filtradas def updateTask(taskId, updates): for tarea in tareas: if tarea["id"]==taskId: for clave, valor in updates.items(): tarea[clave]=valor return 0 return {"markTaskAsCompleted":markTaskAsCompleted,"getCompletedTasks":getCompletedTasks ,"updateTask":updateTask, "filterTasksByTag":filterTasksByTag,"addTask": addTask, "getTasks": getTasks, "removeTask": removeTask, "getPendingTasks": getPendingTasks, "getSortedTasksByPriority":getSortedTasksByPriority} ```


.
.
.
.
.

<code> 
def createTaskPlanner():
  taskList = []
  
  def addTask(task):
    task['completed'] = False
    taskList.append(task)

  def removeTask(value):
    index_list = None
    for index, dictionary in enumerate(taskList):
        if dictionary.get('id') == value or dictionary.get('name') == value:
            index_list = index
            break
    
    if index_list is not None:
        taskList.pop(index_list)

  def getTasks():
    return taskList

  
  def getPendingTasks():
    return [dictionary for dictionary in taskList if dictionary.get('completed') == False]

  
  def getCompletedTasks():
    return [dictionary for dictionary in taskList if dictionary.get('completed') == True] 
  
  def markTaskAsCompleted(value):
      matching_dictionaries = [dictionary for dictionary in taskList if dictionary.get('id') == value or dictionary.get('name') == value]
      if matching_dictionaries:
            matching_dictionaries[0]['completed'] = True
  
  def getSortedTasksByPriority():
    return sorted(taskList, key=lambda k: k['priority'])
  
  def filterTasksByTag(tag):
    return [dictionary for dictionary in taskList if tag in dictionary['tags']]

  def updateTask(taskId, updates):
    matching_dictionaries = [dictionary for dictionary in taskList if dictionary.get('id') == taskId]
    if matching_dictionaries:
      for key, value in updates.items():
        matching_dictionaries[0][key] = value
   
  return {
      "addTask" : addTask,
      "removeTask" : removeTask,
      "getTasks" : getTasks, 
      "getPendingTasks" : getPendingTasks,
      "getCompletedTasks" : getCompletedTasks,
      "markTaskAsCompleted" : markTaskAsCompleted,
      "getSortedTasksByPriority" : getSortedTasksByPriority,
      "filterTasksByTag" : filterTasksByTag,
      "updateTask" : updateTask
  }
def createTaskPlanner():
    # Tu código aquí 👇
    tareas = []
    
    def addTask(task):
        # Tu código aquí 👇
        task["completed"] = False
        tareas.append(task)

    def removeTask(value):
        # Tu código aquí 👇
        for tarea in tareas:
            if tarea["id"] == value or tarea["name"] == value:
                tareas.remove(tarea)

    def getTasks():
        # Tu código aquí 👇
        return tareas
    
    def getPendingTasks():
        # Tu código aquí 👇
        for tarea in tareas:
            if tarea["completed"] == False:
                return tarea
    
    def getCompletedTasks():
        # Tu código aquí 👇
        completadas = []
        for tarea in tareas:
            if tarea["completed"] == True: 
                completadas.append(tarea)
        return completadas
    
    def markTaskAsCompleted(value):
        # Tu código aquí 👇
        for tarea in tareas:
            if tarea["id"] == value or tarea["name"] == value:
                tarea["completed"] = True
        return tareas
    
    def getSortedTasksByPriority():
        # Tu código aquí 👇
        lista = []
        for tarea in tareas:
            if tarea["priority"] == 1:
                lista.append(tarea)
        for tarea in tareas:
            if tarea["priority"] == 2:
                lista.append(tarea) 
        for tarea in tareas:
            if tarea["priority"] == 3:
                lista.append(tarea)
        return lista
    
    def filterTasksByTag(tag):
        tareas_filtradas = []  # Lista para almacenar las tareas que coinciden con la etiqueta
        for tarea in tareas:
            if tag in tarea['tags']:
                tareas_filtradas.append(tarea)  # Agregar la tarea a la lista de tareas filtradas
        return tareas_filtradas
    
    def updateTask(taskId, updates):
        for tarea in tareas:
            if tarea["id"] == taskId:
                if "name" in updates:
                    tarea["name"] = updates["name"]
                if "completed" in updates:
                    tarea["completed"] = updates["completed"]
                if "priority" in updates:
                    tarea["priority"] = updates["priority"]
                if "tags" in updates:
                    tarea["tags"] = updates["tags"]
                if "notes" in updates:
                    tarea["notes"] = updates["notes"]
                if "place" in updates:
                    tarea["place"] = updates["place"]
        # return tareas
  
    return {'addTask':addTask, 
            "filterTasksByTag":filterTasksByTag,
            "getCompletedTasks":getCompletedTasks, 
            "getPendingTasks": getPendingTasks,
            "getSortedTasksByPriority":getSortedTasksByPriority,
            "getTasks":getTasks,
            'markTaskAsCompleted':markTaskAsCompleted, 
            "removeTask":removeTask,
            "updateTask":updateTask,
            }

Mi resultado:
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

def createTaskPlanner():
  # Tu código aquí 👇
  tasks = []
  def addTask(task):
    # Tu código aquí 👇
    task['completed'] = False
    tasks.append(task)
    pass

  def removeTask(value):
    # Tu código aquí 👇
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        tasks.remove(task)
        break
    pass

  def getTasks():
    # Tu código aquí 👇
    return tasks
    pass
  
  def getPendingTasks():
    # Tu código aquí 👇
    return list(filter(lambda task: not task['completed'], tasks))
    pass
  
  def getCompletedTasks():
    # Tu código aquí 👇
    return list(filter(lambda task: task['completed'], tasks))
    pass
  
  def markTaskAsCompleted(value):
    # Tu código aquí 👇
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        task['completed'] = True
        break
    pass
  
  def getSortedTasksByPriority():
    # Tu código aquí 👇
    return sorted(tasks, key = lambda task: task['priority'])
    pass
  
  def filterTasksByTag(tag):
    # Tu código aquí 👇
    return list(filter(lambda task: tag in task['tags'], tasks))
    pass
  
  def updateTask(taskId, updates):
    # Tu código aquí 👇
    for index, task in enumerate(tasks):
      if task['id'] == taskId:
        tasks[index].update(updates)
        break
    pass
  
  return {
    'addTask': addTask,
    'removeTask': removeTask,
    'getTasks': getTasks,
    'getPendingTasks': getPendingTasks,
    'getCompletedTasks': getCompletedTasks,
    'markTaskAsCompleted': markTaskAsCompleted,
    'getSortedTasksByPriority': getSortedTasksByPriority,
    'filterTasksByTag': filterTasksByTag,
    'updateTask': updateTask
  }


.
.
😅😅😅
Listo! 🐍👌🏼
.
.
.
.
.
.

#función que crea la lista de tareas
def createTaskPlanner():
  listaTareas = []

  #función que agrega una tarea a la lista
  def addTask(task):
    task["completed"] = False
    listaTareas.append(task)

  #función que elimina una tarea de la lista
  def removeTask(value):
    idTarea = filter_tasks(value)
    listaTareas.pop(idTarea)

  #función que devuelve la lista de tareas
  def getTasks():
    return listaTareas

  #función que devuelve las tareas pendientes
  def getPendingTasks():
    return list(filter(lambda i: not i["completed"], listaTareas))

  #función que devuelve las tareas completadas
  def getCompletedTasks():
    return list(filter(lambda i: i["completed"], listaTareas))

  #función que filtra el id de una tarea o por el nombre
  def filter_tasks(value):
    if isinstance(value, int):
      idx = [ i for i in range(len(listaTareas)) if listaTareas[i]["id"] == value]
    else:
      idx = [ i for i in range(len(listaTareas)) if listaTareas[i]["name"] == value]

    return idx[0]
  
  #función que marca una tarea completada
  def markTaskAsCompleted(value):
    idx = filter_tasks(value)
    listaTareas[idx]["completed"] = True

  #función que ordena tareas por prioridad
  def getSortedTasksByPriority():
   sorted_tasks = sorted(listaTareas, key=lambda i: i["priority"])
   return sorted_tasks

  #función que filtra tareas por etiqueta
  def filterTasksByTag(tag):
    by_tag = filter(lambda i: tag in i["tags"], listaTareas)
    return list(by_tag)

  #función que actualiza tareas
  def updateTask(taskId, updates):
    idx = filter_tasks(taskId)
    listaTareas[idx].update(updates)

  #regresa los métodos
  return {
    "addTask": addTask,
    "removeTask": removeTask,
    "getTasks": getTasks,
    "getPendingTasks": getPendingTasks,
    "getCompletedTasks": getCompletedTasks,
    "markTaskAsCompleted": markTaskAsCompleted,
    "getSortedTasksByPriority": getSortedTasksByPriority,
    "filterTasksByTag": filterTasksByTag,
    "updateTask": updateTask 
  }

🛡️🛡️Escudo anti-spoilers🛡️🛡️

Mi solución al reto:

def createTaskPlanner():
  tasks = [] 

  def _find(task):
    for t in tasks:
      if t['id'] == task or t['name'] == task:
        return t
    return None
   
  def addTask(task):
    task['completed'] = False
    tasks.append(task) 

  def removeTask(value):
    for t in tasks:
      tasks.remove(_find(value))

  def getTasks():
   return tasks
  
  def getPendingTasks():
    return [t for t in tasks if not t['completed']] 
  
  def getCompletedTasks():
    return [t for t in tasks if t['completed']] 
  
  def markTaskAsCompleted(value):
    for t in tasks:
      if _find(value):
        t['completed'] = True
  
  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda x: x['priority'])

  
  def filterTasksByTag(tag):
    return [t for t in tasks if tag in t['tags']] 

  
  def updateTask(taskId, updates):
    for t in tasks:
      if _find(taskId):
        t.update(updates)
  
  return {
    'addTask': addTask,
    'removeTask': removeTask,
    'getTasks': getTasks,
    'getPendingTasks': getPendingTasks,
    'getCompletedTasks': getCompletedTasks,
    'markTaskAsCompleted': markTaskAsCompleted,
    'getSortedTasksByPriority': getSortedTasksByPriority,
    'filterTasksByTag': filterTasksByTag,
    'updateTask': updateTask
  }

Estuvo genial este Playground.
Tuve que investigar y repasar notas para poder resolverlo.
Thanks, Platzi.
.
.
.
.
.
.
.
.
.
.
.

def createTaskPlanner():
    tareas = []

    def addTask(task):
        task['completed'] = False
        tareas.append(task)
        

    def removeTask(value):
        i = -1
        found = False
        while not found and i < len(tareas):
            i += 1
            if tareas[i]['id'] == value or tareas[i]['name'] == value:
                found = True
        tareas.pop(i)

    def getTasks():
        return tareas
        
    
    def getPendingTasks():
        return list(filter(lambda x: x['completed'] == False, tareas))
        
    
    def getCompletedTasks():
        return list(filter(lambda x: x['completed'] == True, tareas))

    
    def markTaskAsCompleted(value):
        i = -1
        found = False
        while not found and i < len(tareas):
            i += 1
            if tareas[i]['id'] == value or tareas[i]['name'] == value:
                found = True
        
        tareas[i]['completed'] = True
    
    def getSortedTasksByPriority():
        return sorted(tareas, key= lambda x: x['priority'])
    
    def filterTasksByTag(tag):
        return list(filter(lambda x: tag in x['tags'], tareas))
    
    def updateTask(taskId, updates):
        # Get index of task
        i = -1
        found = False
        while not found and i < len(tareas):
            i += 1
            if tareas[i]['id'] == taskId:
                found = True
        
        # Actualization
        tareas[i] = tareas[i] | updates
        
    
    return {'addTask': addTask, 'removeTask': removeTask, 'getTasks': getTasks,
            'getPendingTasks': getPendingTasks, 'getCompletedTasks': getCompletedTasks,
            'markTaskAsCompleted': markTaskAsCompleted, 'getSortedTasksByPriority': getSortedTasksByPriority,
            'filterTasksByTag': filterTasksByTag, 'updateTask':updateTask}


.
.
.
.
.
.
.
.
.
.

Mi solución:

def createTaskPlanner():
    tasks = []

    def addTask(task):
        if 'completed' not in task:
            task['completed'] = False
        tasks.append(task)

    def removeTask(value):
        task = next((t for t in tasks if t['id'] == value or t['name'] == value), None)
        if task:
            tasks.remove(task)

    def getTasks():
        return tasks

    def getPendingTasks():
        return [task for task in tasks if not task['completed']]

    def getCompletedTasks():
        return [task for task in tasks if task['completed']]

    def markTaskAsCompleted(value):
        task = next((t for t in tasks if t['id'] == value or t['name'] == value), None)
        if task:
            task['completed'] = True

    def getSortedTasksByPriority():
        return sorted(tasks, key=lambda x: x['priority'])

    def filterTasksByTag(tag):
        return [task for task in tasks if tag in task.get('tags', [])]

    def updateTask(taskId, updates):
        task = next((t for t in tasks if t['id'] == taskId), None)
        if task:
            task.update(updates)

    return {
        'addTask': addTask,
        'removeTask': removeTask,
        'getTasks': getTasks,
        'getPendingTasks': getPendingTasks,
        'getCompletedTasks': getCompletedTasks,
        'markTaskAsCompleted': markTaskAsCompleted,
        'getSortedTasksByPriority': getSortedTasksByPriority,
        'filterTasksByTag': filterTasksByTag,
        'updateTask': updateTask
    }

Esta fue una prueba novedosa, nunca había hecho algo así, al menos combinar closures con diccionarios, aprendi algo nuevo

def createTaskPlanner():
  tasks = []

  def addTask(task):
    task['completed'] = False
    tasks.append(task)

  def removeTask(value):
    nonlocal tasks
    # print(value == tasks[0]['id'])
    tasks = [task for task in tasks if task['id'] != value and task['name'] != value]

  def getTasks():
    return tasks
  
  def getPendingTasks():
    nonlocal tasks
    tasks = [task for task in tasks if task['completed'] != True]
    return tasks

  def getCompletedTasks():
    nonlocal tasks
    completed = [task for task in tasks if task['completed'] != False]
    return completed
    
  
  def markTaskAsCompleted(value):
    # nonlocal tasks
    for i, task in enumerate(tasks):
      if task['id'] == value or task['name'] == value:
        tasks[i]['completed'] = True


  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda x: x['priority'] )

  
  def filterTasksByTag(tag):
    return list(filter(lambda x: tag in x['tags'] , tasks))
  
  def updateTask(taskId, updates):
    for i, task in enumerate(tasks):
      if task['id' ] == taskId:
        for key, value in updates.items():
          tasks[i][key] = value

  
  return {
    'addTask': addTask,
    'removeTask': removeTask,
    'getTasks': getTasks,
    'getPendingTasks':getPendingTasks,
    'getCompletedTasks': getCompletedTasks,
    'markTaskAsCompleted':markTaskAsCompleted,
    'getSortedTasksByPriority':getSortedTasksByPriority,
    'filterTasksByTag':filterTasksByTag,
    'updateTask' :updateTask
  }

Solución 😄…
.

.
.
.
.

def createTaskPlanner():
  tasks = []

  def addTask(task):
      task['completed'] = False
      tasks.append(task)

  def removeTask(value):
    item = [
      task 
      for task in tasks 
      if task['id'] == value 
      or task['name'] == value
      ][0]
    
    return tasks.remove(item) 

  def getTasks():
    return tasks
  
  def getPendingTasks():
    return [
      task 
      for task in tasks 
      if task['completed'] == False
      ]
  
  def getCompletedTasks():
    return [
      task 
      for task in tasks 
      if task['completed'] == True
      ]
  
  def markTaskAsCompleted(value):
    index = tasks.index([
      task 
      for task in tasks 
      if task['id'] == value 
      or task['name'] == value
      ][0])
    
    tasks[index]['completed'] = True
  
  def getSortedTasksByPriority():
    return sorted(
      tasks, 
      key=lambda 
      task: task['priority']
      )
  
  def filterTasksByTag(tag):
    return [
      task 
      for task in tasks 
      if tag in task['tags']
      ]
  
  def updateTask(taskId, updates):
    index = tasks.index([
      task 
      for task in tasks 
      if task['id'] == taskId 
      ][0])

    tasks[index].update(updates)
  
  return {
    'addTask': addTask,
    'removeTask': removeTask,
    'getTasks': getTasks,
    'getPendingTasks': getPendingTasks,
    'getCompletedTasks': getCompletedTasks,
    'markTaskAsCompleted': markTaskAsCompleted,
    'getSortedTasksByPriority': getSortedTasksByPriority,
    'filterTasksByTag': filterTasksByTag,
    'updateTask': updateTask
  }

ESPERO QUE MI YO DEL FUTURO DIGA, COMO ESTABAS TAN MENSO QUE NO PUDISTE CON ESTO HACE 1 O 2 AÑOS JAJAJA (AGO 2023)

def crear_planificador_de_tareas():
  tareas = []

  def agregar_tarea(tarea):
    tarea['completada'] = False 
    tareas.append(tarea)
  def remover_tarea(valor):
    if isinstance(valor, int):
      tareas[:] = [tarea for tarea in tareas if tarea['id'] != valor] 
    if isinstance(valor, str):
        tareas[:] = [tarea for tarea in tareas if tarea['nombre'] != valor]      
  def obtener_tarea():
    return tareas[:] 
  def obtener_tarea_pendiente():
    return [tarea for tarea in tareas if not tarea['compleatada']] 
  def obtener_tarea_completada():
    return [tarea for tarea in tareas if tarea['completada']]
  def marcar_tarea_como_completada(valor):
    if isinstance(valor, int):
      for tarea in tareas:
        if tarea['id'] == valor:
          tarea['completada'] = True 
          break
    elif isinstance(valor, str):
      for tarea in tareas:
        if tarea['nombre'] == valor:
          tarea['completada'] = True
          break      
  def obtener_ordenamiento_de_tarea_por_prioridad():
    return sorted(tareas, key=lambda tarea: tarea['prioridad'])
  def filtrar_tarea_por_etiquetado(etiqueta):
    return [tarea for tarea in tareas if etiqueta in tarea['etiquetas']]
  def actualizar_tarea(tarea_id, updates):
    for tarea in tareas:
      if tarea['id'] == tarea_id:
        tarea.update(updates)
        break
        
  return {
    'agregar_tarea': agregar_tarea,
    'remover_tarea': remover_tarea,
    'obtener_tarea': obtener_tarea,
    'obtener_tarea_pendiente': obtener_tarea_pendiente,
    'obtener_tarea_completada': obtener_tarea_completada,
    'marcar_tarea_como_completada': marcar_tarea_como_completada,
    'obtener_ordenamiento_de_tarea_por_prioridad': obtener_ordenamiento_de_tarea_por_prioridad,
    'filtrar_tarea_por_etiquetado': filtrar_tarea_por_etiquetado,
    'actualizar_tarea': actualizar_tarea,
  }

planner = crear_planificador_de_tareas()

planner['agregar_tarea']({
    'id': 1,
    'nombre': 'Comprar leche',
    'prioridad': 1,
    'etiquetas': ['shopping', 'home']
})

planner['agregar_tarea']({
    'id': 2,
    'nombre': 'Llamar a Juan',
    'prioridad': 3,
    'etiquetas': ['personal']
})

planner['marcar_tarea_como_completada']('Llamar a Juan')

print(planner['obtener_tarea_completada']())

PRODUCCION:

[{‘id’: 2, ‘nombre’: ‘Llamar a Juan’, ‘prioridad’: 3, ‘etiquetas’: [‘personal’], ‘completada’: True}]

Ejercicio Complicado pero gracias a sus aporte y orientaciones,me ayudo:

def createTaskPlanner():
tasks = []
def addTask(task):
task[‘completed’] = False
tasks.append(task)
def removeTask(value):
nonlocal tasks
tasks = [task for task in tasks if task[‘id’] != value or task[‘name’] != value]
def getTasks():
return tasks
def getPendingTasks():
nonlocal tasks
return [task for task in tasks if task[‘completed’] == False]
def getCompletedTasks():
nonlocal tasks
return [task for task in tasks if task[‘completed’] == True]
def markTaskAsCompleted(value):
nonlocal tasks
for task in tasks:
if task[‘id’] == value or task[‘name’] == value:
task[‘completed’] = True
def getSortedTasksByPriority():
sortedTask = []
sortedTask = sorted(tasks,key=lambda task: task[‘priority’])
return sortedTask
def filterTasksByTag(tag):
return [task for task in tasks if tag in task[‘tags’]]
def updateTask(taskId, updates):
for task in tasks:
if task[‘id’]==taskId:
for key, value in updates.items():
task[key]=value
return {‘addTask’: addTask,
‘removeTask’: removeTask,
‘getTasks’: getTasks,
‘getPendingTasks’: getPendingTasks,
‘getCompletedTasks’: getCompletedTasks,
‘markTaskAsCompleted’: markTaskAsCompleted,
‘getSortedTasksByPriority’: getSortedTasksByPriority,
‘filterTasksByTag’: filterTasksByTag,
‘updateTask’: updateTask
}
print(createTaskPlanner())

Un ejercicio interesante, les comparto una de las tantas soluciones que puede tener

https://github.com/userforpyhon47/python_pip/blob/main/computational_statistic/task_manager.py

Este ejercicio está muy muy chévere, no había visto algo igual.

def createTaskPlanner():
  tasks = []

  def addTask(task):
    task['completed'] = False
    tasks.append(task)

  def removeTask(value):
    i = 0
    while i < len(tasks):
      if tasks[i]['id'] == value or tasks[i]['name'] == value:
        tasks.remove(tasks[i])
        continue
      i += 1

  def getTasks():
    return tasks

  def getPendingTasks():
    return [task for task in tasks if not task['completed']]

  def getCompletedTasks():
    return [task for task in tasks if task['completed']]

  def markTaskAsCompleted(value):
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        task['completed'] = True

  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda task: task['priority'])

  def filterTasksByTag(tag):
    return list(filter(lambda task: tag in task['tags'], tasks))

  def updateTask(taskId, updates):
    task = next((task for task in tasks if task['id'] == taskId), None)
    if task:
      task.update(updates)

  return {
      'addTask': addTask,
      'removeTask': removeTask,
      'getTasks': getTasks,
      'getPendingTasks': getPendingTasks,
      'getCompletedTasks': getCompletedTasks,
      'markTaskAsCompleted': markTaskAsCompleted,
      'getSortedTasksByPriority': getSortedTasksByPriority,
      'filterTasksByTag': filterTasksByTag,
      'updateTask': updateTask
  }

Re-extremo pero satisfactorio:

def createTaskPlanner():
  # Tu código aquí 👇
  tareas = []
  

  def addTask(task):
    task['completed'] = False
    tareas.append(task)
    

  def removeTask(value):    
    elementos = [element for element in tareas 
                 if element['id']==value or element['name']==value]
    return tareas.remove(elementos[0]) #remueve el elemento de la lista 'tareas'

  def getTasks():
    return tareas
  
  def getPendingTasks():
    elementos = [element for element in tareas 
                 if element['completed']==False]
    return elementos
  
  def getCompletedTasks():
    elementos = [element for element in tareas 
                 if element['completed']==True]
    return elementos
  
  def markTaskAsCompleted(value):
    elementos = [element for element in tareas 
                 if element['id']==value or element['name']==value]
    elementos[0]["completed"] = True
  
  def getSortedTasksByPriority():
    sorted_list = sorted(tareas, key=lambda element: element['priority'])
    return sorted_list
  
  def filterTasksByTag(tag):
    filtro = list(filter(lambda element: tag in element['tags'], tareas))
    return filtro
  
  def updateTask(taskId, updates):
    for element in tareas:
      if element['id']==taskId:
        for key, value in updates.items():
          element[key] = value

    
  
  return {
      'addTask': addTask,
      'removeTask' : removeTask,
      'getTasks' :getTasks,
      'getPendingTasks' : getPendingTasks, 
      'getCompletedTasks' : getCompletedTasks, 
      'markTaskAsCompleted' : markTaskAsCompleted, 
      'getSortedTasksByPriority' : getSortedTasksByPriority,
      'filterTasksByTag' : filterTasksByTag, 
      'updateTask' : updateTask
  }


Esta si que me tomo bastante tiempo, tuve que investigar sobre closures ya que no sabia nada 😕

def createTaskPlanner():
  arr = []

  def addTask(task):
    task['completed'] = False
    arr.append(task)

  def removeTask(value):
    for t in arr:
      if t['id'] == value or t['name'] == value:
        arr.remove(t)

  def getTasks():
    return arr
  
  def getPendingTasks():
    return list(filter(lambda t: t['completed'] == False, arr))
  
  def getCompletedTasks():
    return list(filter(lambda t: t['completed'] == True, arr))

  def markTaskAsCompleted(value):
    for t in arr:
      if t['id'] == value or t['name'] == value:
        t['completed'] = True
  
  def getSortedTasksByPriority():
    return sorted(arr, key=lambda t: t['priority'])
  
  def filterTasksByTag(tag):
    return list(filter(lambda t: tag in t['tags'], arr))
  
  def updateTask(taskId, updates):
    for t in arr:
      if t['id'] == taskId:
        t.update(updates)
  
  return {
        "addTask": addTask,
        "removeTask": removeTask,
        "getTasks": getTasks,
        "getPendingTasks": getPendingTasks,
        "getCompletedTasks": getCompletedTasks,
        "markTaskAsCompleted": markTaskAsCompleted,
        "getSortedTasksByPriority": getSortedTasksByPriority,
        "filterTasksByTag": filterTasksByTag,
        "updateTask": updateTask,
    }

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

def createTaskPlanner():
  task_list = []
  def findIdx(value):
    task_idx = [ idx for idx, task in enumerate(task_list) if task['id'] == value or task['name'] == value]
    return task_idx[0] # devuelve idx de la primera ocurrencia
    
  def addTask(task):
    task['completed'] = False
    task_list.append(task)

  def removeTask(value):
    task_list.pop(findIdx(value))

  def getTasks():
    return task_list
  
  def getPendingTasks():
    return list(filter(lambda x: not x['completed'] , task_list))
  
  def getCompletedTasks():
    return list(filter(lambda x: x['completed'] , task_list))
    
  
  def markTaskAsCompleted(value):
    task_list[findIdx(value)]['completed'] = True
  
  def getSortedTasksByPriority():
    sorted_tasks = sorted(task_list, key=lambda x: x['priority'], reverse=False)
    return sorted_tasks
  
  def filterTasksByTag(tag):
    return [ task for task in task_list if tag in task['tags']]
  
  def updateTask(taskId, updates):
    for k,v in updates.items():
      task_list[findIdx(taskId)][k] = v
  
  return { 
    'addTask': addTask, 
    'getTasks':getTasks,
    'removeTask':removeTask,
    'getPendingTasks':getPendingTasks,
    'getCompletedTasks':getCompletedTasks,
    'markTaskAsCompleted':markTaskAsCompleted,
    'getSortedTasksByPriority':getSortedTasksByPriority,
    'filterTasksByTag':filterTasksByTag,
    'updateTask':updateTask
  }

Acabo de hacer una solución con numpy ya que mencionó arrays y pues Phyton no tiene arrays sino listas, no pasa las pruebas pero quedó lindo, se los comparto

def createTaskPlanner():
    import numpy as np
    Task_array = np.array([], dtype=[('id', int), ('name', str), ('priority', int), ('tags', list), ('completed', bool)])
    
    def addTask(task):
        nonlocal Task_array

        if Task_array.size == 0:
            # Si el array no existe, creamos uno nuevo con la nueva fila
            Task_array = np.array([tuple(task.values()) + (False,)], dtype=Task_array.dtype)
        else:
            # Si el array ya existe, agregamos la nueva fila
            nueva_fila_array = np.array([tuple(task.values()) + (False,)], dtype=Task_array.dtype)
            Task_array = np.append(Task_array, nueva_fila_array)
        return Task_array
    
    def removeTask(value):
      
      nonlocal Task_array
      
      if Task_array is not None:
          index= None
          for idx, task in enumerate(Task_array):
              if value == task['id'] or value == task['name']:
                  index = idx
                  break 
              
      if index is not None:
          Task_array = np.delete(Task_array,index, axis =0) 
      
      return Task_array
              
    
    def getTasks():
        return Task_array
  
    def getPendingTasks():
        if Task_array is not None:
            index= [idx for idx, task in enumerate(Task_array) if not task['completed']]
            return Task_array[index]
        return []
    
    def getCompletedTasks():
        if Task_array is not None:
            index= [idx for idx, task in enumerate(Task_array) if task['completed']]
            return Task_array[index]
        return []
        
    def markTaskAsCompleted(value):
        nonlocal Task_array
                
        if Task_array is not None:
            index= None
            for idx, task in enumerate(Task_array):
                if value == task['id'] or value == task['name']:
                    index = idx
                    break 
                
        if index is not None:
            Task_array[index,4] = True
        
        return Task_array
    
    
    def getSortedTasksByPriority():
        if Task_array is not None:
            sorted_task = np.sort(Task_array, order='priority')
            return sorted_task
        return []

            
    def filterTasksByTag(tag):
        if Task_array is not None:
            index= [idx for idx,task in enumerate(Task_array) if tag in task['tags']]
            return Task_array[index]
        return []
        
    
    def updateTask(taskId, updates):
        global Task_array
        if Task_array is not None:
            for idx, task in enumerate(Task_array):
                if task['id'] == taskId:
                    for key, value in updates.items():
                        if key in task.dtype.names:
                            Task_array[idx][key] = value
                    return Task_array
                return {}
            return{}
            
    return {'addTask': addTask, 
                'removeTask': removeTask,
                'getTasks': getTasks,
                'getPendingTasks': getPendingTasks,
                'getCompletedTasks': getCompletedTasks,
                'markTaskAsCompleted': markTaskAsCompleted,
                'getSortedTasksByPriority': getSortedTasksByPriority,
                'filterTasksByTag': filterTasksByTag,
                'updateTask': updateTask}

planner = createTaskPlanner()

planner['addTask']({
    'id': 1,
    'name': 'Comprar leche',
    'priority': 1,
    'tags': ['shopping', 'home']
})

planner['addTask']({
    'id': 2,
    'name': 'Llamar a Juan',
    'priority': 3,
    'tags': ['personal']
})

planner['markTaskAsCompleted']('Llamar a Juan')

print(planner['getCompletedTasks']())

planner['addTask']({
    'id': 1,
    'name': 'Comprar leche',
    'priority': 1,
    'tags': ['shopping', 'home']
})

planner['addTask']({
    'id': 2,
    'name': 'Llamar a Juan',
    'priority': 3,
    'tags': ['personal']
})

print(planner['filterTasksByTag']('shopping'))

Mi resultado
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

def createTaskPlanner():
  tasks = []

  def addTask(task):
    task['completed'] = False
    tasks.append(task)

  def removeTask(value):
    nonlocal tasks
    lenList = len(tasks)
    tasks = [task for task in tasks if task['id'] != value and task['name'] != value]
    if len(tasks) == lenList:
      raise ValueError('Tarea no encontrada')

  def getTasks():
    return tasks

  def getPendingTasks():
    return [task for task in tasks if task['completed'] == False]

  def getCompletedTasks():
    return [task for task in tasks if task['completed'] == True]

  def markTaskAsCompleted(value):
    for task in tasks:
      if task['id'] == value or task['name'] == value:
        task['completed'] = True

  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda i: i['priority'])

  def filterTasksByTag(tag):
    return list(filter(lambda x: tag in x['tags'], tasks))

  def updateTask(taskId, updates):
    for task in tasks:
      if task['id'] == taskId:
        task.update(updates)

  return {
    'addTask': addTask,
    'removeTask': removeTask,
    'getTasks': getTasks,
    'getPendingTasks': getPendingTasks,
    'getCompletedTasks': getCompletedTasks,
    'markTaskAsCompleted': markTaskAsCompleted,
    'getSortedTasksByPriority': getSortedTasksByPriority,
    'filterTasksByTag': filterTasksByTag,
    'updateTask': updateTask
  }


Aquí, mi solución. Fue un reto divertido y aplique lo aprendido en manejo de errores y en dictionary y list comprehension.

def createTaskPlanner():
  tasks = []

  def addTask(task):
    if task == {}:
      raise ValueError("No hay ninguna tarea")
    task["completed"]=False
    tasks.append(task)

  def removeTask(value):
    task = next((task for task in tasks if task['id']==value or task['name']==value), None)
    if task == None:
      raise Exception("No existe dicha tarea")
    else:
      tasks.remove(task)   

  def getTasks():
    if len(tasks)==0:
      raise ValueError("No hay ninguna tarea")
    return tasks
  
  def getPendingTasks():
    if len(tasks)==0:
      raise ValueError("No hay ninguna tarea")
    pending_tasks = list(filter(lambda task:task['completed']==False,tasks))
    if len(pending_tasks)==0:
      raise Exception("No hay tareas pendientes")
    return pending_tasks
  
  def getCompletedTasks():
    if len(tasks)==0:
      raise ValueError("No hay ninguna tarea")
    completed_tasks = list(filter(lambda task:task['completed']==True,tasks))
    if len(completed_tasks)==0:
      raise Exception("No hay tareas pendientes")
    return completed_tasks
  
  def markTaskAsCompleted(value):
    task = next((task for task in tasks if task['id']==value or task['name']==value), None)
    if task is None:
      raise Exception("No existe dicha tarea")
    else:
      task['completed']=True
  
  def getSortedTasksByPriority():
    if len(tasks)==0:
      raise ValueError("No hay ninguna tarea")
    sorted_tasks= sorted(tasks,key=lambda task:task['priority'])
    return sorted_tasks
  
  def filterTasksByTag(tag):
    if len(tasks)==0:
      raise ValueError("No hay ninguna tarea")
    tasks_by_tag=list(filter(lambda task:tag in task['tags'],tasks))
    if len(tasks_by_tag)==0:
      raise Exception(f"No existen tareas con el tag: {tag}")
    return tasks_by_tag
  
  def updateTask(taskId, updates):
    task = next((task for task in tasks if task['id']==taskId), None)
    if task is None:
      raise Exception(f"No existe la tarea con el id:{taskId}")
    else:
      for prop in updates:
        task[prop]=updates[prop]
  
  return {
    'addTask':addTask,
    'removeTask':removeTask,
    'getTasks': getTasks,
    'getPendingTasks':getPendingTasks,
    'getCompletedTasks':getCompletedTasks,
    'markTaskAsCompleted':markTaskAsCompleted,
    'getSortedTasksByPriority':getSortedTasksByPriority,
    'filterTasksByTag':filterTasksByTag,
    'updateTask':updateTask
  }

Este si estuvo complicado mas la parte de actualizar.

def createTaskPlanner():
  tasks = []

  def addTask(task):
    newTask = {
      "id": task["id"],
      "name": task["name"],
      "priority": task["priority"],
      "tags": task["tags"],
      "completed": False
    }
    tasks.append(newTask)
    pass

  def removeTask(value):
    removed = [t for t in tasks if t['id'] != value and t['name'] != value]
    tasks.clear()
    tasks.extend(removed)
    return tasks
    pass

  def getTasks():
    return tasks
    pass
  
  def getPendingTasks():
    return [task for task in tasks if task['completed'] == False]
    pass
  
  def getCompletedTasks():
    return [task for task in tasks if task['completed'] == True]
    pass
  
  def markTaskAsCompleted(value):
    findedTask = [task for task in tasks if task['id'] == value or task['name'] == value]
    if len(findedTask) > 0:
      findedTask = findedTask[0]
      findedTask['completed'] = True
      return [findedTask for task in tasks if task['id'] == findedTask['id']]
    pass
  
  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda task: task['priority'])
    pass
  
  def filterTasksByTag(tag):
    return [task for task in tasks if tag in task['tags']]
    pass
  
  def updateTask(taskId, updates):
    findedTask = [task for task in tasks if task['id'] == taskId]
    if len(findedTask) > 0:
      temp = findedTask[0]
      for key, value in updates.items():
          temp[key] = value
      filtered = [task for task in tasks if taskId != task['id']]
      filtered.append(temp)
      tasks.clear()
      tasks.extend(filtered)
      return tasks
    else:
      return []
    pass
  
  return {
    "addTask": addTask,
    "removeTask": removeTask,
    "getTasks": getTasks,
    "getPendingTasks": getPendingTasks,
    "getCompletedTasks": getCompletedTasks,
    "markTaskAsCompleted": markTaskAsCompleted,
    "getSortedTasksByPriority": getSortedTasksByPriority,
    "filterTasksByTag": filterTasksByTag,
    "updateTask": updateTask
  }

Me demoré demasiado haciendo este reto, pero creó que valió la pena


Código

def createTaskPlanner():
    tasks = []

    def addTask(task):
        task['completed'] = False
        tasks.append(task)

    def removeTask(value):
        for task in tasks:
            if task['id'] == value or task['name'] == value:
                tasks.remove(task)
                break

    def getTasks():
        return tasks

    def getPendingTasks():
        return [task for task in tasks if not task['completed']]

    def getCompletedTasks():
        return [task for task in tasks if task['completed']]

    def markTaskAsCompleted(value):
        for task in tasks:
            if task['id'] == value or task['name'] == value:
                task['completed'] = True
                break

    def getSortedTasksByPriority():
        return sorted(tasks, key=lambda task: task['priority'])

    def filterTasksByTag(tag):
        return [task for task in tasks if tag in task['tags']]

    def updateTask(taskId, updates):
        for task in tasks:
            if task['id'] == taskId:
                for key, value in updates.items():  # Corregir .items() en lugar de .items
                    task[key] = value
                break

    return {
        'addTask': addTask,
        'removeTask': removeTask,
        'getTasks': getTasks,
        'getPendingTasks': getPendingTasks,
        'getCompletedTasks': getCompletedTasks,
        'markTaskAsCompleted': markTaskAsCompleted,
        'getSortedTasksByPriority': getSortedTasksByPriority,
        'filterTasksByTag': filterTasksByTag,
        'updateTask': updateTask
    }

planner = createTaskPlanner()

planner['addTask']({
    'id': 1,
    'name': 'Comprar leche',
    'priority': 1,
    'tags': ['shopping', 'home']
})

planner['addTask']({
    'id': 2,
    'name': 'Llamar a Juan',
    'priority': 3,
    'tags': ['personal']
})

planner['markTaskAsCompleted'](2)

print(planner['getCompletedTasks']())

Estuvo bueno!

Les dejo mi solución

.
.
.
.
.
.
.
.
.

def createTaskPlanner():
  task_list = []

  def addTask(task):
    task['completed'] = False 
    task_list.append(task)

  def removeTask(value):
    for task in task_list:
      if task['name'] == value or task['id'] == value:
        task_list.remove(task)
        break

  def getTasks():
    return task_list
  
  def getPendingTasks():
    return [task for task in task_list if not task['completed']]
  
  def getCompletedTasks():
    return [task for task in task_list if task['completed']]  
  
  def markTaskAsCompleted(value):
    for task in task_list:
      if task['id'] == value or task['name'] == value:
        task['completed'] = True
  
  def getSortedTasksByPriority():
    return sorted(task_list, key=lambda task: task['priority'])
  
  def filterTasksByTag(tag):
    return [task for task in task_list if tag in task['tags'] ] 
  
  def updateTask(taskId, updates):
    for task in task_list:
      if task['id'] == taskId:
        task.update(updates)
  
  return {'addTask': addTask,
        'removeTask': removeTask,
        'getTasks': getTasks,
        'getPendingTasks': getPendingTasks,
        'getCompletedTasks': getCompletedTasks,
        'markTaskAsCompleted': markTaskAsCompleted,
        'getSortedTasksByPriority': getSortedTasksByPriority,
        'filterTasksByTag': filterTasksByTag,
        'updateTask': updateTask}

Aqui mi solucion:
.
.
.
.
.
.
.
.

def createTaskPlanner():
  # Tu código aquí 👇
  
  list_taks = []

  def addTask(task):
    # Tu código aquí 👇
    task['completed'] = False
    list_taks.append(task)
    

  def removeTask(value):
    # Tu código aquí 👇
    for item in list_taks:
      if item['id'] == value or item['name'] == value:
        list_taks.remove(item) 

  def getTasks():
    # Tu código aquí 👇
    return list_taks
  
  def getPendingTasks():
    # Tu código aquí 👇
    return [item for item in list_taks if item['completed'] == False]
  
  def getCompletedTasks():
    # Tu código aquí 👇
    return [item for item in list_taks if item['completed'] == True]

  def markTaskAsCompleted(value):
    # Tu código aquí 👇
    for item in list_taks:
      if item['id'] == value or item['name'] == value:
        item['completed'] = True


  def getSortedTasksByPriority():
    # Tu código aquí 👇
    taks_priority = list_taks.copy()
    taks_priority.sort(key=lambda x: x['priority'])
    return taks_priority
  
  def filterTasksByTag(tag):
    # Tu código aquí 👇
    tags_list = []
    for item in list_taks:
      for i in range(len(item['tags'])):
        if item['tags'][i] == tag:
          tags_list.append(item)
    return tags_list
    
  
  def updateTask(taskId, updates):
    # Tu código aquí 👇
    for i in range(len(list_taks)):
      if list_taks[i]['id'] == taskId:
        list_taks[i].update(updates)

  return {'addTask': addTask, 'removeTask': removeTask, 'getTasks': getTasks, 'getPendingTasks': getPendingTasks, 'getCompletedTasks': getCompletedTasks, 'getSortedTasksByPriority': getSortedTasksByPriority, 'markTaskAsCompleted': markTaskAsCompleted, 'filterTasksByTag': filterTasksByTag, 'updateTask': updateTask}
def createTaskPlanner():

    tasks = []

    def addTask(task):
        task['completed'] = False
        tasks.append(task)
        pass

    def removeTask(value):
        for task in tasks:
            if value == task['id'] or value == task['name']:
                tasks.remove(task)
                break
        pass

    def getTasks():
        return tasks
        pass

    def getPendingTasks():
        return [task for task in tasks if task['completed'] == False]
        pass

    def getCompletedTasks():
        return list(filter(lambda x: x['completed'] == True, tasks))
        pass

    def markTaskAsCompleted(value):
        for task in tasks:
            if value == task['id'] or value == task['name']:
                task['completed'] = True
                break
        pass

    def getSortedTasksByPriority():
        return sorted(tasks, key=lambda x: x['priority'])
        pass

    def filterTasksByTag(tag):
        return list(filter(lambda x: tag in x['tags'], tasks))
        pass

    def updateTask(taskId, updates):
        for task in tasks:
            if task['id'] == taskId:
                task.update(updates)
                break
        pass

    return {
        'addTask': addTask,
        'removeTask': removeTask,
        'getTasks': getTasks,
        'getPendingTasks': getPendingTasks,
        'getCompletedTasks': getCompletedTasks,
        'markTaskAsCompleted': markTaskAsCompleted,
        'getSortedTasksByPriority': getSortedTasksByPriority,
        'filterTasksByTag': filterTasksByTag,
        'updateTask': updateTask
    }

Mi solución 💻 🐍


.
.
.
.

El ejercicio planteado en este playground es bastante completo, implementé varios de los conceptos que vimos en los días anteriores.
Solo le agregaría una lectura sobre closures antes del playground.

def createTaskPlanner():
  all_tasks = list()

  def filter_tasks(value):
    if isinstance(value, int):
      idx = [ i for i in range(len(all_tasks)) if all_tasks[i]["id"] == value]
    else:
      idx = [ i for i in range(len(all_tasks)) if all_tasks[i]["name"] == value]

    return idx[0]

  def addTask(task):
    task["completed"] = False
    all_tasks.append(task)

  def removeTask(value):
    idx = filter_tasks(value)
    all_tasks.pop(idx)

  def getTasks():
    return all_tasks
  
  def getPendingTasks():
    return list(filter(lambda task: not task["completed"], all_tasks))
  
  def getCompletedTasks():
    return list(filter(lambda task: task["completed"], all_tasks))
  
  def markTaskAsCompleted(value):
    idx = filter_tasks(value)
    all_tasks[idx]["completed"] = True
  
  def getSortedTasksByPriority():
   sorted_tasks = sorted(all_tasks, key=lambda task: task["priority"])
   return sorted_tasks
  
  def filterTasksByTag(tag):
    by_tag = filter(lambda task: tag in task["tags"], all_tasks)
    return list(by_tag)
  
  def updateTask(taskId, updates):
    idx = filter_tasks(taskId)
    all_tasks[idx].update(updates)
  
  return {
    "addTask": addTask,
    "removeTask": removeTask,
    "getTasks": getTasks,
    "getPendingTasks": getPendingTasks,
    "getCompletedTasks": getCompletedTasks,
    "markTaskAsCompleted": markTaskAsCompleted,
    "getSortedTasksByPriority": getSortedTasksByPriority,
    "filterTasksByTag": filterTasksByTag,
    "updateTask": updateTask 
  }


*
*
*
*
*

def createTaskPlanner():
    tasks_list = []

    def addTask(task):
        task["completed"] = False
        tasks_list.append(task)

    def removeTask(value):
        for elem in tasks_list:
          if elem['id'] == value or elem['name'] == value:
            tasks_list.remove(elem)

    def getTasks():
        return tasks_list

    def getPendingTasks():
        return list(filter(lambda elem: elem['completed'] == False, tasks_list))

    def getCompletedTasks():
        return list(filter(lambda elem: elem['completed'] == True, tasks_list))

    def markTaskAsCompleted(value):
        for elem in tasks_list:
            if elem['id'] == value or elem['name'] == value:
                elem['completed'] = True

    def getSortedTasksByPriority():
        sorted_list = tasks_list[::]
        sorted_list.sort(key=lambda task: task['id'], reverse=True)
        return sorted_list

    def filterTasksByTag(tag):
         return list(filter(lambda elem: tag in elem['tags'], tasks_list))

    def updateTask(taskId, updates):
        for i in range(len(tasks_list)):
          if taskId ==  tasks_list[i]['id']:
            tasks_list[i].update(updates)

    return {
        "addTask": addTask,
        "removeTask": removeTask,
        "getTasks": getTasks,
        "getPendingTasks": getPendingTasks,
        "getCompletedTasks": getCompletedTasks,
        "markTaskAsCompleted": markTaskAsCompleted,
        "getSortedTasksByPriority": getSortedTasksByPriority,
        "filterTasksByTag": filterTasksByTag,
        "updateTask": updateTask,
    }

Este reto estuvo duro pero genial.

Me confundi un poco en la parte de updateTask, pero al final entendi que era lo que se pedia.

def createTaskPlanner():
  tareas = []

  def addTask(task):
    tarea = task
    tarea['completed'] = False
    tareas.append(tarea)
    return

  def removeTask(value):
    superior = len(tareas)
    indice = 0
    if type(value) == int:
      for i in range(superior):
        if tareas[i]['id'] == value:
          indice = i
          break
    else:
      for i in range(superior):
        if tareas[i]['name'] == value:
          indice = i
          break
    tareas.pop(indice)   
    return
  

  def getTasks():
    return tareas

  
  def getPendingTasks():
    salida = [tarea for tarea in tareas if tarea['completed'] == False]
    return salida
  
  def getCompletedTasks():
    salida = [tarea for tarea in tareas if tarea['completed'] == True]
    return salida
  
  def markTaskAsCompleted(value):
    if type(value) == int:
      for tarea in tareas:
        if tarea['id'] == value:
          tarea['completed'] = True
          break
    else:
      for tarea in tareas:
        if tarea['name'] == value:
          tarea['completed'] = True
          break      
    return
  
  def getSortedTasksByPriority():
    tareasOrdenadas = tareas.copy()
    tareasOrdenadas.sort(key = lambda x: x['priority'], reverse = False) 
    return tareasOrdenadas
  
  def filterTasksByTag(tag):
    salida = [tarea for tarea in tareas if tag in tarea['tags']]
    return salida
  
  def updateTask(taskId, updates):
    superior = len(tareas)
    i = 0
    while i < superior:
      if tareas[i]['id'] == taskId:
        updatesKeys = updates.keys()
        for llave in updatesKeys:
          tareas[i][llave] = updates[llave]
        break
      else:
        i += 1
    return
  
  return {'addTask':                  addTask,
          'removeTask':               removeTask,
          'getTasks':                 getTasks,
          'getPendingTasks':          getPendingTasks,
          'getCompletedTasks':        getCompletedTasks,
          'markTaskAsCompleted':      markTaskAsCompleted,
          'getSortedTasksByPriority': getSortedTasksByPriority,
          'filterTasksByTag':         filterTasksByTag,
          'updateTask':               updateTask}

planner = createTaskPlanner()

planner['addTask']({
    'id': 1,
    'name': 'Comprar leche',
    'priority': 1,
    'tags': ['shopping', 'home']
})

planner['addTask']({
    'id': 2,
    'name': 'Llamar a Juan',
    'priority': 3,
    'tags': ['personal']
})

planner['addTask']({
    'id': 3,
    'name': 'Estudiar',
    'priority': 3,
    'tags': ['personal']
})

planner['addTask']({
    'id': 4,
    'name': 'Cocinar',
    'priority': 3,
    'tags': ['personal']
})

planner['addTask']({
    'id': 5,
    'name': 'Caminar',
    'priority': 2,
    'tags': ['personal']
})


planner['markTaskAsCompleted']('Llamar a Juan')

print('tareas' )
print(planner['getTasks']())
print('pendientes' )
print(planner['getPendingTasks']())
print('completas' )
print(planner['getCompletedTasks']())

planner['removeTask'](3)
print('tareas' )
print(planner['getTasks']())

planner['removeTask']('Cocinar')
print('tareas' )
print(planner['getTasks']())

print('ordenadas')
print(planner['getSortedTasksByPriority']())

print('filtradas')
print(planner['filterTasksByTag']('shopping'))

print('update')
planner['updateTask'](5, {
    'name': 'Comprar huevos',
    'tags': ['personal', 'shopping']
})
print(planner['getTasks']())          
test_add_task_with_completed_property

test_remove_task_with_id

test_remove_task_with_name

test_mark_task_as_completed_with_id

test_mark_task_as_completed_with_name

test_filter_tasks_by_tag

test_get_sorted_tasks_by_priority

test_get_completed_tasks

test_update_task

¡Felicidades, todas las pruebas pasaron!


.
.
.
.
.
.
Les dejo una ayudita de como trabajar las funciones closure.

No se rindan, si se logra el reto 🙌


.
.
.
.
.

def createTaskPlanner():
  tasks = []
  def addTask(task):
    task['completed'] = False
    tasks.append(task)

  def removeTask(value):
    index = -1;
    for task in tasks:
      index +=1
      if task['name'] == value or task['id'] == value:
        break;
    if index != -1:
      del tasks[index]

  def getTasks():
    return tasks
  
  def getPendingTasks():
    return list(filter(lambda x : x['completed'] == False, tasks))
  
  def getCompletedTasks():
    return list(filter(lambda x : x['completed'] == True, tasks))
  
  def markTaskAsCompleted(value):
    for task in tasks:
      if task['name'] == value or task['id'] == value:
        task['completed'] = True
        break;
  
  def getSortedTasksByPriority():
    return sorted(tasks, key=lambda x:x['priority'] )
  
  def filterTasksByTag(tag):
    return [task for task in tasks if tag in task['tags']]
  
  def updateTask(taskId, updates):
    for task in tasks:
      if task['id'] == taskId :
        task.update(updates)
        break;

  return {
      'addTask': addTask,
      'removeTask': removeTask,
      'getTasks': getTasks,
      'getPendingTasks': getPendingTasks,
      'getCompletedTasks': getCompletedTasks,
      'markTaskAsCompleted': markTaskAsCompleted,
      'getSortedTasksByPriority': getSortedTasksByPriority,
      'filterTasksByTag': filterTasksByTag,
      'updateTask': updateTask
   }


.
.

def createTaskPlanner():
   tasks = []
   
   def addTask(task):
      task["completed"] = False
      tasks.append(task)

   def removeTask(value):
      for task in tasks:
         if task["id"] == value or task["name"] == value:
            tasks.remove(task)
            break

   def getTasks():
      return tasks

   def getPendingTasks():
      return list(filter(lambda task: task['completed'] == False, tasks))

   def getCompletedTasks():
      return list(filter(lambda task: task['completed'] == True, tasks))

   def markTaskAsCompleted(value):
      for task in tasks:
         if task["id"] == value or task["name"] == value:
            task["completed"] = True
            break

   def getSortedTasksByPriority():
      return sorted(tasks, key=lambda task: task['priority'])

   def filterTasksByTag(tag) :
      return list(filter(lambda task: tag in task['tags'] , tasks))

   def updateTask(taskId, updates):
      for task in tasks:
         if task["id"] == taskId:
            task.update(updates) 
  
   return {
      'addTask': addTask,
      'removeTask': removeTask,
      'getTasks': getTasks,
      'getPendingTasks': getPendingTasks,
      'getCompletedTasks': getCompletedTasks,
      'markTaskAsCompleted': markTaskAsCompleted,
      'getSortedTasksByPriority': getSortedTasksByPriority,
      'filterTasksByTag': filterTasksByTag,
      'updateTask': updateTask
   }

Estuvo muy interesante el playground

def createTaskPlanner():
  task_list: list = []

  def addTask(task):
    task_list.append(task)
    task['completed'] = False

  def removeTask(value):

    key = 'id'
    if type(value) is str:
      key = "name"

    index = [idx for idx, task in enumerate(task_list, 0) if task[key] == value]

    if index:
      task_list.pop(index[0])

  def getTasks():
    return task_list
  
  def getPendingTasks():
    return [idx for idx in task_list if idx['completed'] == False]
  
  def getCompletedTasks():
    return [idx for idx in task_list if idx['completed'] == True]
  
  def markTaskAsCompleted(value):
    key = 'id'
    if type(value) is str:
      key = "name"

    index = [idx for idx, task in enumerate(task_list, 0) if task[key] == value]

    if index:
      task_list[index[0]]['completed'] = True
  
  def getSortedTasksByPriority():
    priority = task_list.copy()
    priority.sort(key=lambda x: x['priority'])
    return priority
  
  def filterTasksByTag(tag):
    return [idx for idx in task_list if tag in idx['tags']]
  
  def updateTask(taskId, updates):
    index = [idx for idx, task in enumerate(task_list, 0) if task['id'] == taskId]
    for key in updates.keys():
      task_list[index[0]][key] = updates[key]
  
  return {'addTask': addTask,
          'markTaskAsCompleted': markTaskAsCompleted,
          'getPendingTasks': getPendingTasks,
          'getCompletedTasks': getCompletedTasks,
          'getTasks': getTasks,
          'removeTask': removeTask,
          'filterTasksByTag': filterTasksByTag,
          'updateTask': updateTask,
          'getSortedTasksByPriority': getSortedTasksByPriority
  }
undefined