diff --git a/src/UBUVoiceAssistant/GUI/chat_window.py b/src/UBUVoiceAssistant/GUI/chat_window.py
index ef89029..eb3b673 100644
--- a/src/UBUVoiceAssistant/GUI/chat_window.py
+++ b/src/UBUVoiceAssistant/GUI/chat_window.py
@@ -1,3 +1,5 @@
+"""Module for the chat window GUI
+"""
 from threading import Thread
 import subprocess
 import sys
@@ -16,11 +18,13 @@
 
 
 class ChatWindow(QtWidgets.QMainWindow):
-    def __init__(self, bus: MessageBusClient, ws: WebService) -> None:
+    """Class for the Chat window GUI
+    """
+    def __init__(self, bus: MessageBusClient, webservice: WebService) -> None:
         super().__init__(parent=None)
         uic.loadUi("./UBUVoiceAssistant/GUI/forms/chat-window.ui", self)
         self.bus = bus
-        self.ws = ws
+        self.webservice = webservice
         self.user_utterance = ""
         self.mycroft_response = ""
         self.mic_muted = False
@@ -29,8 +33,10 @@ def __init__(self, bus: MessageBusClient, ws: WebService) -> None:
         self.next_message = 0
         self.intent_labels = []
 
-        self.mic_icon = QtGui.QIcon(QtGui.QPixmap("UBUVoiceAssistant/imgs/mic.svg"))
-        self.mic_muted_icon = QtGui.QIcon(QtGui.QPixmap("UBUVoiceAssistant/imgs/mic_muted.svg"))
+        self.mic_icon = QtGui.QIcon(
+            QtGui.QPixmap("UBUVoiceAssistant/imgs/mic.svg"))
+        self.mic_muted_icon = QtGui.QIcon(
+            QtGui.QPixmap("UBUVoiceAssistant/imgs/mic_muted.svg"))
 
         self.color: List[Union[int, float]] = list(
             self.palette().color(QtGui.QPalette.ColorRole.Background).getRgb())
@@ -73,6 +79,8 @@ def __init__(self, bus: MessageBusClient, ws: WebService) -> None:
         #         os.path.abspath(os.getcwd())+"/UBUVoiceAssistant/GUI/forms/chat_window_html"))
 
     def set_elements_web(self):
+        """Sets the initial elements for the HTML webview
+        """
         print(self.color)
         js_color = "document.body.style.backgroundColor = 'rgba(" + ','.join(
             map(str, self.color)) + ")';"
@@ -84,7 +92,8 @@ def set_elements_web(self):
         message += "· " + _("Tell me about the forums of (course)\n")
         message += "· " + _("Tell me my grades\n")
         message += "· " + _("Tell me about the events of (course)\n")
-        message += "· " + _("Tell me about the events on (month) (day) (year)\n")
+        message += "· " + \
+            _("Tell me about the events on (month) (day) (year)\n")
         message += "· " + _("Tell me about the changes of (course)\n")
         message += "· " + _("Tell me the grades of (course)\n")
         message += "· " + _("Read the latest messages\n")
@@ -99,11 +108,19 @@ def set_elements_web(self):
         self.web.page().runJavaScript(js_string)
 
     def update_texts(self):
+        """Sets the localized texts for the UI
+        """
         self.btnConfig.setText(_("Manage skills"))
         self.btnSend.setText(_("Send"))
         self.tbxInput.setPlaceholderText(_("Type your command here..."))
 
     def update_chat(self, source: str, message: str):
+        """Adds the new message to the chat
+
+        Args:
+            source (str): "u" when coming from user, "r" when coming from Mycroft
+            message (str): The message text
+        """
         js_string = "var chat = document.getElementById('chat-window');\n"
         js_string += "var msg = document.createElement('li');\n"
         if source == "u":
@@ -116,12 +133,24 @@ def update_chat(self, source: str, message: str):
         self.web.page().runJavaScript(js_string)
 
     def handle_speak(self, message: Message):
+        """Sets the Mycroft response variable when a message comes
+
+        Args:
+            message (Message): Mycroft bus message
+        """
         self.mycroft_response = message.data.get("utterance")
 
     def handle_utterance(self, message: Message):
+        """Sets the user message variable when you send a message
+
+        Args:
+            message (Message): User bus message
+        """
         self.user_utterance = message.data["utterances"][0]
 
     def check_for_chat_update(self):
+        """Checks if a new message arrives and updates the UI
+        """
         if self.user_utterance:
             self.update_chat("u", self.user_utterance)
             self.user_utterance = ""
@@ -130,6 +159,11 @@ def check_for_chat_update(self):
             self.mycroft_response = ""
 
     def closeEvent(self, event: QtGui.QCloseEvent) -> None:
+        """Handles when the user tries to close the window
+
+        Args:
+            event (QtGui.QCloseEvent): Qt Close Event
+        """
         self.close_window = MessageBox(_("Are you sure?"))
         self.close_window.setStandardButtons(
             QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
@@ -148,19 +182,33 @@ def closeEvent(self, event: QtGui.QCloseEvent) -> None:
             event.ignore()
 
     def finish_exit(self):
+        """Exits the program
+        """
         sys.exit(0)
 
     def keyPressEvent(self, event):
+        """This is executed when the user press a key
+
+        Args:
+            event: Qt Keypress event
+        """
         if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
             self.on_send_pressed()
 
     def on_send_pressed(self):
+        """This runs when the user press enter or clicks the button on the UI
+        """
         self.user_utterance = self.tbxInput.text()
         self.bus.emit(Message('recognizer_loop:utterance', {
                       'utterances': [self.user_utterance]}))
         self.tbxInput.setText('')
 
     def on_mic_pressed(self, startup: bool = False):
+        """This runs when the user clicks the mic button
+
+        Args:
+            startup (bool, optional): True if this is running at startup. Defaults to False.
+        """
         # Switch between muted and unmuted when the mic is pressed
         if self.mic_muted or startup:
             self.mic_muted = False
@@ -176,14 +224,19 @@ def on_mic_pressed(self, startup: bool = False):
             self.bus.emit(Message('mycroft.mic.mute'))
 
     def on_skills_pressed(self):
+        """This runs when you press the "manage skills" button. Shows the new window
+        """
 
         self.skills_dialog = QtWidgets.QDialog(self)
         self.skills_dialog.setWindowTitle('Mycroft Skills')
         self.skills_dialog.resize(600, 600)
 
-        self.pushButton_manage_skills = QtWidgets.QPushButton(self.skills_dialog)
-        self.pushButton_manage_skills.setGeometry(QtCore.QRect(470, 10, 120, 40))
-        self.pushButton_manage_skills.clicked.connect(self.on_manage_skills_pressed)
+        self.pushButton_manage_skills = QtWidgets.QPushButton(
+            self.skills_dialog)
+        self.pushButton_manage_skills.setGeometry(
+            QtCore.QRect(470, 10, 120, 40))
+        self.pushButton_manage_skills.clicked.connect(
+            self.on_manage_skills_pressed)
 
         self.pushButton_manage_skills.setText(_("Save"))
 
@@ -202,14 +255,17 @@ def on_skills_pressed(self):
         # Create checkboxes for every skill in self.active_skills
         for count, name in enumerate(self.active_skills):
             check_box = QtWidgets.QCheckBox(scroll_area_widget_skills)
-            spacer = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+            spacer = QtWidgets.QSpacerItem(
+                40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
             check_box.setText(name)
             check_box.setChecked(True)
             logo = QtWidgets.QLabel(scroll_area_widget_skills)
             if 'ubu' in name:
-                logo.setPixmap(QtGui.QPixmap('UBUVoiceAssistant/imgs/ubu_logo.jpg').scaled(20, 20))
+                logo.setPixmap(QtGui.QPixmap(
+                    'UBUVoiceAssistant/imgs/ubu_logo.jpg').scaled(20, 20))
             else:
-                logo.setPixmap(QtGui.QPixmap('UBUVoiceAssistant/imgs/Mycroft_logo.png').scaled(20, 20))
+                logo.setPixmap(QtGui.QPixmap(
+                    'UBUVoiceAssistant/imgs/Mycroft_logo.png').scaled(20, 20))
             self.active_skills_checkBoxes.append(check_box)
             skills_grid_layout.addWidget(logo, count, 0)
             skills_grid_layout.addWidget(check_box, count, 1)
@@ -221,9 +277,11 @@ def on_skills_pressed(self):
             check_box.setText(name)
             logo = QtWidgets.QLabel(scroll_area_widget_skills)
             if 'ubu' in name:
-                logo.setPixmap(QtGui.QPixmap('UBUVoiceAssistant/imgs/ubu_logo.jpg').scaled(20, 20))
+                logo.setPixmap(QtGui.QPixmap(
+                    'UBUVoiceAssistant/imgs/ubu_logo.jpg').scaled(20, 20))
             else:
-                logo.setPixmap(QtGui.QPixmap('UBUVoiceAssistant/imgs/Mycroft_logo.png').scaled(20, 20))
+                logo.setPixmap(QtGui.QPixmap(
+                    'UBUVoiceAssistant/imgs/Mycroft_logo.png').scaled(20, 20))
             self.inactive_skills_checkBoxes.append(check_box)
             skills_grid_layout.addWidget(logo, count, 0)
             skills_grid_layout.addWidget(check_box, count, 1)
@@ -233,24 +291,28 @@ def on_skills_pressed(self):
 
     def on_manage_skills_pressed(self):
         """ Adds the checked skills to self.active_skills and the unchecked to
-            self.inactive_skills and activates or deactivates those skills.
+            self.inactive_skills and activates or deactivates those skills when pressing save.
         """
         deactivated = []
         activated = []
-        for cb in self.active_skills_checkBoxes:
-            if not cb.isChecked():
-                self.bus.emit(Message('skillmanager.deactivate', {'skill': cb.text()}))
-                deactivated.append(cb.text())
-
-        for cb in self.inactive_skills_checkBoxes:
-            if cb.isChecked():
-                self.bus.emit(Message('skillmanager.activate', {'skill': cb.text()}))
-                activated.append(cb.text())
-
-        self.active_skills = [skill for skill in self.active_skills if skill not in deactivated]
+        for checkbox in self.active_skills_checkBoxes:
+            if not checkbox.isChecked():
+                self.bus.emit(
+                    Message('skillmanager.deactivate', {'skill': checkbox.text()}))
+                deactivated.append(checkbox.text())
+
+        for checkbox in self.inactive_skills_checkBoxes:
+            if checkbox.isChecked():
+                self.bus.emit(
+                    Message('skillmanager.activate', {'skill': checkbox.text()}))
+                activated.append(checkbox.text())
+
+        self.active_skills = [
+            skill for skill in self.active_skills if skill not in deactivated]
         self.active_skills.extend(activated)
 
-        self.inactive_skills = [skill for skill in self.inactive_skills if skill not in activated]
+        self.inactive_skills = [
+            skill for skill in self.inactive_skills if skill not in activated]
         self.inactive_skills.extend(deactivated)
 
         self.skills_dialog.hide()
@@ -258,6 +320,9 @@ def on_manage_skills_pressed(self):
 
 
 class CloseMycroft(QtCore.QThread):
+    """Thread to close Mycroft"""
     def run(self):
+        """Closes Mycroft and emits a signal when finished
+        """
         subprocess.run("/usr/lib/mycroft-core/stop-mycroft.sh", shell=True)
         self.finished.emit()
diff --git a/src/UBUVoiceAssistant/GUI/link_mycroft.py b/src/UBUVoiceAssistant/GUI/link_mycroft.py
index 8ffceb1..9892940 100644
--- a/src/UBUVoiceAssistant/GUI/link_mycroft.py
+++ b/src/UBUVoiceAssistant/GUI/link_mycroft.py
@@ -18,7 +18,7 @@
 class LinkMycroft(QtWidgets.QMainWindow):
     """Class for the linking Mycroft to web UI
     """
-    
+
     closed_signal = pyqtSignal()
 
     def __init__(self, bus: MessageBusClient) -> None:
@@ -45,9 +45,10 @@ def __init__(self, bus: MessageBusClient) -> None:
 
         self.file = open("/var/log/mycroft/skills.log", "r")
         self.file.seek(0, 2)  # Goes to the end of the file
-        self.bus.emit(Message("recognizer_loop:utterance",  
-                          {'utterances': [_("pair my device")]}))
-        # On other languages different than English, we must send again the phrase for it to start pairing
+        self.bus.emit(Message("recognizer_loop:utterance",
+                              {'utterances': [_("pair my device")]}))
+        # On other languages different than English, we must send again the phrase for it
+        # to start pairing
         bus.on("configuration.updated", self.pairing_done)
         self.timer = QTimer()
         self.timer.timeout.connect(self.add_pairing_code)  # type: ignore
@@ -58,21 +59,31 @@ def __init__(self, bus: MessageBusClient) -> None:
         self.setFixedSize(self.size())
 
     def pairing_done(self, event):
+        """This function gets triggered when we finish pairing Mycroft.
+
+        Args:
+            event: Mycroft pairing event
+        """
         self.done = True
         self.file.close()
         self.close()
 
     def add_pairing_code(self):
+        """Sets the pairing code and shows it on the UI
+        """
         self.lblCode.setText(self.code)
 
     def read_pairing_code(self):
+        """Reads the skills file and sets the pairing code to a variable
+        """
         while not self.done:
             print("Reading...")
             line = self.file.readline()
             if line:
                 print(line)
                 matches = re.findall(
-                    "(?<=" + re.escape("PairingSkill | ") + ")[a-zA-Z0-9 ]*: [A-Z0-9]{6}(?=\n)", line)
+                    "(?<=" + re.escape("PairingSkill | ") + ")[a-zA-Z0-9 ]*: [A-Z0-9]{6}(?=\n)",
+                    line)
                 print(matches)
                 if matches:
                     self.code = matches[0][-6:]
@@ -80,8 +91,11 @@ def read_pairing_code(self):
                 time.sleep(1)
 
     def update_texts(self):
+        """Sets the localized texts in the UI
+        """
         self.lblWelcome.setText(_("Welcome!"))
-        self.lblFirstRun.setText(_("It's your first time using Mycroft, so please follow these instructions"))
+        self.lblFirstRun.setText(
+            _("It's your first time using Mycroft, so please follow these instructions"))
         self.btnPrev.setText(_("Previous"))
         self.btnNext.setText(_("Next"))
         self.lblRegisterAddDevice.setText(
@@ -90,6 +104,8 @@ def update_texts(self):
         self.lblInfoCode.setText(_("Input this code on the website"))
 
     def go_next(self):
+        """This function gets executed when the user clicks the next button
+        """
         self.hide_all_elements()
         self.page = min(2, self.page + 1)
         if self.page == 1:
@@ -105,6 +121,8 @@ def go_next(self):
             self.btnPrev.setEnabled(True)
 
     def go_previous(self):
+        """This function gets executed when the user click the previous version
+        """
         self.hide_all_elements()
         self.page = max(0, self.page - 1)
         if self.page == 1:
@@ -119,6 +137,8 @@ def go_previous(self):
             self.btnNext.setEnabled(True)
 
     def hide_all_elements(self):
+        """Hides all images and texts when switching pages
+        """
         self.imgSelectVoice.setVisible(False)
         self.imgAddDevice.setVisible(False)
         self.picInputCode.setVisible(False)
@@ -132,6 +152,11 @@ def hide_all_elements(self):
         self.btnNext.setEnabled(False)
 
     def closeEvent(self, event: QtGui.QCloseEvent) -> None:
+        """This get triggered when closing the window
+
+        Args:
+            event (QtGui.QCloseEvent): Qt Close event
+        """
         if self.done:
             self.closed_signal.emit()
             time.sleep(2)  # type: ignore
@@ -144,7 +169,8 @@ def closeEvent(self, event: QtGui.QCloseEvent) -> None:
             print(self.close_res)
             if self.close_res == QtWidgets.QMessageBox.Yes:
                 self.timer.stop()
-                self.closing_window = ProgressBox(_("Closing Mycroft, please wait..."))
+                self.closing_window = ProgressBox(
+                    _("Closing Mycroft, please wait..."))
                 self.closing_window.show()
                 self.closing_thread = CloseMycroft()
                 self.closing_thread.finished.connect(  # type: ignore
@@ -154,10 +180,16 @@ def closeEvent(self, event: QtGui.QCloseEvent) -> None:
                 event.ignore()
 
     def finish_exit(self):
+        """Exits the program
+        """
         sys.exit(0)
 
 
 class CloseMycroft(QThread):
+    """A thread to close Mycroft when exiting
+    """
     def run(self):
+        """Closes Mycroft and emits the event
+        """
         subprocess.run("/usr/lib/mycroft-core/stop-mycroft.sh", shell=True)
         self.finished.emit()
diff --git a/src/UBUVoiceAssistant/GUI/main.py b/src/UBUVoiceAssistant/GUI/main.py
index ddeb5ef..00709d6 100644
--- a/src/UBUVoiceAssistant/GUI/main.py
+++ b/src/UBUVoiceAssistant/GUI/main.py
@@ -1,24 +1,24 @@
 """Module for the main UI
 """
+import subprocess
 import sys
-import time
+from os import path
+from threading import Thread
 
-from PyQt5.QtGui import QIcon
-from ..GUI.link_mycroft import LinkMycroft
 import requests
-import subprocess
 import simplejson
-from threading import Thread
-from os import path
-from PyQt5 import QtWidgets, uic, QtCore
 from mycroft_bus_client import MessageBusClient
-from ..webservice.web_service import WebService
-from .message_box import MessageBox
-from .progress_box import ProgressBox
+from PyQt5 import QtCore, QtWidgets, uic
+from PyQt5.QtGui import QIcon
+
+from ..GUI.link_mycroft import LinkMycroft
 from ..util.lang import Translator
-from ..util.util import create_server_socket
 from ..util.settings import Settings
+from ..util.util import create_server_socket
+from ..webservice.web_service import WebService
 from .chat_window import ChatWindow
+from .message_box import MessageBox
+from .progress_box import ProgressBox
 
 translator = Translator()
 _ = translator.translate
@@ -69,6 +69,8 @@ def on_lang_changed(self, value: int) -> None:
         self.update_texts()
 
     def on_login(self):
+        """This runs when the user clicks the login button or press enter
+        """
         user = str(self.tbxUser.text())
         password = self.tbxPassword.text()
         host = str(self.tbxHost.text())
@@ -76,11 +78,11 @@ def on_login(self):
         if not host:
             host = "https://ubuvirtual.ubu.es"
 
-        self.ws = WebService()
-        self.ws.set_host(host)
+        self.webservice = WebService()
+        self.webservice.set_host(host)
 
         try:
-            self.ws.set_url_with_token(user, password)
+            self.webservice.set_url_with_token(user, password)
         # If the credentials are incorrect
         except KeyError:
             MessageBox(_("Invalid Moodle username or password.")).exec_()
@@ -91,24 +93,24 @@ def on_login(self):
         except (requests.exceptions.ConnectionError, simplejson.errors.JSONDecodeError):
             MessageBox(_("Connection error. Please check that the URL is correct, your Internet connection is working and the server is up.")).exec_()
             return
-        
+
         if self.chkUser.isChecked():
             self.cfg["user"] = user
         if self.chkHost.isChecked():
             self.cfg["host"] = host
         self.cfg["lang"] = translator.get_current_language()[0]
         self.cfg.save_settings()
-        self.ws.initialize_useful_data()
+        self.webservice.initialize_useful_data()
 
         # If Moodle lang is different from the selected
-        if not translator.check_language_supported(self.ws.get_lang()):
+        if not translator.check_language_supported(self.webservice.get_lang()):
             MessageBox(_("This language is not supported by your Moodle server")).exec_()
-        self.ws.set_user_courses()
+        self.webservice.set_user_courses()
 
         self.starting_window = ProgressBox(_("Starting Mycroft, please wait..."))
         self.starting_window.show()
 
-        server_socket = Thread(target=create_server_socket, args=[self.ws])
+        server_socket = Thread(target=create_server_socket, args=[self.webservice])
         server_socket.setDaemon(True)
         server_socket.start()
 
@@ -129,6 +131,8 @@ def update_texts(self) -> None:
         self.lblUser.setText(_("Username"))
 
     def start_mycroft(self):
+        """Starts Mycroft and checks for when it's ready
+        """
         def f_mycroft_started(event):
             self.mycroft_started = True
 
@@ -158,17 +162,24 @@ def check_mycroft_started(self):
             self.new_window.closed_signal.connect(self.check_mycroft_started)
         else:
             if not self.finished:
-                self.new_window = ChatWindow(self.bus, self.ws)
+                self.new_window = ChatWindow(self.bus, self.webservice)
                 self.new_window.show()
                 self.new_window.tbxInput.setFocus()
                 self.hide()
                 self.finished = True
 
     def set_reconnect_1s(self, event = None):
+        """Set the bus reconnect time to 1 second
+        """
         print("Set reconnect time")
         self.bus.retry = 0.5
 
     def keyPressEvent(self, event):
+        """This happens when the user press a key
+
+        Args:
+            event: Qt Keypress event
+        """
         if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
             self.on_login()
 
diff --git a/src/UBUVoiceAssistant/GUI/progress_box.py b/src/UBUVoiceAssistant/GUI/progress_box.py
index 4a6a0cf..eccbc6f 100644
--- a/src/UBUVoiceAssistant/GUI/progress_box.py
+++ b/src/UBUVoiceAssistant/GUI/progress_box.py
@@ -1,6 +1,6 @@
 """Module for infinite progress bars
 """
-from PyQt5 import QtWidgets, QtCore
+from PyQt5 import QtWidgets
 
 
 class ProgressBox(QtWidgets.QProgressDialog):
@@ -17,6 +17,12 @@ def __init__(self, text: str):
         self.done = False
 
     def closeEvent(self, event) -> None:
+        """This event gets triggered when trying to close the Window. We ignore them if we haven't
+            finished yet
+
+        Args:
+            event: Qt Close event
+        """
         if not self.done:
             event.ignore()
         else:
diff --git a/src/UBUVoiceAssistant/model/conversation.py b/src/UBUVoiceAssistant/model/conversation.py
index 2f7d57d..b7e2334 100644
--- a/src/UBUVoiceAssistant/model/conversation.py
+++ b/src/UBUVoiceAssistant/model/conversation.py
@@ -1,13 +1,15 @@
+"""Module for the conversation class"""
 from typing import Dict
 from .user import User
 from .message import Message
 
 
 class Conversation():
+    """Class for the Moodle conversations"""
     def __init__(self, json: dict) -> None:
         self.__conversation_id: int = json["id"]
         self.__isread: bool = json["isread"]
-        if self.__isread == True:
+        if self.__isread is True:
             self.__unreadcount = 0
         else:
             self.__unreadcount = json["unreadcount"]
@@ -25,22 +27,57 @@ def __init__(self, json: dict) -> None:
             self.__messages[message["id"]] = Message(message)
 
     def get_conversation_id(self) -> int:
+        """Gets the conversation id
+
+        Returns:
+            int: conversation id
+        """
         return self.__conversation_id
 
     def get_isread(self) -> bool:
+        """Gets if the conversation is read
+
+        Returns:
+            bool: true if is read, false if not
+        """
         return self.__isread
 
     def get_unreadcount(self) -> int:
+        """Gets the number of unread messages
+
+        Returns:
+            int: unread messages count
+        """
         return self.__unreadcount
 
     def get_name(self) -> str:
+        """Gets the name for the conversation
+
+        Returns:
+            str: conversation name
+        """
         return self.__name
-    
+
     def get_subname(self) -> str:
+        """Gets the subname for the conversation
+
+        Returns:
+            str: conversation subname
+        """
         return self.__subname
 
     def get_members(self) -> Dict[int, User]:
+        """Gets the members of the conversation
+
+        Returns:
+            Dict[int, User]: Dictionary userid, user
+        """
         return self.__members
-    
+
     def get_messages(self) -> Dict[int, Message]:
-        return self.__messages
\ No newline at end of file
+        """Gets the messages in a conversation
+
+        Returns:
+            Dict[int, Message]: Dictionary messageid, message
+        """
+        return self.__messages
diff --git a/src/UBUVoiceAssistant/model/course.py b/src/UBUVoiceAssistant/model/course.py
index 3f7f1e9..b069a9e 100644
--- a/src/UBUVoiceAssistant/model/course.py
+++ b/src/UBUVoiceAssistant/model/course.py
@@ -27,7 +27,7 @@ def __init__(self, course):
         self.__forums = []
         self.__participants: Dict[int, "User"] = {}
 
-    def get_id(self) -> int: # TODO revisar
+    def get_id(self) -> int:
         """Gets the Course id
 
         Returns:
@@ -92,13 +92,22 @@ def set_forums(self, forums: List[Forum]):
         self.__forums = forums
 
     def set_participants(self, participants: Union[List["User"], Dict[int, "User"]]):
-        if isinstance(participants, List):
+        """Sets the participants of the course
+
+        Args:
+            participants (List[User] or Dict[int, User]): List of users or dictionary of userid, user
+        """
+        if isinstance(participants, list):
             self.__participants = {}
-            for p in participants:
-                self.__participants[p.get_id()] = p
+            for participant in participants:
+                self.__participants[participant.get_id()] = participant
             return
-        else:
-            self.__participants = participants
-    
+        self.__participants = participants
+
     def get_participants(self) -> Dict[int, "User"]:
+        """Gets the list of participants
+
+        Returns:
+            Dict[int, User]: Dictionary of userid, user
+        """
         return self.__participants
diff --git a/src/UBUVoiceAssistant/model/discussion.py b/src/UBUVoiceAssistant/model/discussion.py
index c32e70a..0fd5dd4 100644
--- a/src/UBUVoiceAssistant/model/discussion.py
+++ b/src/UBUVoiceAssistant/model/discussion.py
@@ -15,7 +15,7 @@ def __init__(self, discussion):
         self.__discussion_id = discussion['discussion']
         self.__name = discussion['name']
 
-    def get_id(self) -> int: # TODO Check type
+    def get_id(self) -> int:
         """Gets the id of the discussion
 
         Returns:
diff --git a/src/UBUVoiceAssistant/model/forum.py b/src/UBUVoiceAssistant/model/forum.py
index 3c26a37..561eb75 100644
--- a/src/UBUVoiceAssistant/model/forum.py
+++ b/src/UBUVoiceAssistant/model/forum.py
@@ -20,7 +20,7 @@ def __init__(self, forum, discussions):
         self.__name = forum['name']
         self.__discussions = discussions
 
-    def get_id(self) -> int: # TODO Revisar si es correcto
+    def get_id(self) -> int:
         """Gets the id of the Forum
 
         Returns:
diff --git a/src/UBUVoiceAssistant/model/grade_item.py b/src/UBUVoiceAssistant/model/grade_item.py
index 50c0c10..a5daa5f 100644
--- a/src/UBUVoiceAssistant/model/grade_item.py
+++ b/src/UBUVoiceAssistant/model/grade_item.py
@@ -16,11 +16,11 @@ def __init__(self, grade):
         self.__name = grade['itemname']
         self.__type = grade['itemtype']
 
-    def get_value(self): # TODO Check type of value
+    def get_value(self):
         """Gets the grade value
 
         Returns:
-            [type]: Value of the grade
+            int, str: Value of the grade
         """
         return self.__value
 
@@ -32,11 +32,11 @@ def get_name(self) -> str:
         """
         return self.__name
 
-    def get_type(self): # TODO Check type of type
+    def get_type(self):
         """Gets the type of grade
 
         Returns:
-            [type]: type of grade
+            type of grade
         """
         return self.__type
 
diff --git a/src/UBUVoiceAssistant/model/message.py b/src/UBUVoiceAssistant/model/message.py
index 067a95f..d2c48d9 100644
--- a/src/UBUVoiceAssistant/model/message.py
+++ b/src/UBUVoiceAssistant/model/message.py
@@ -1,6 +1,11 @@
+"""Module for the message class
+"""
 from bs4 import BeautifulSoup
 
+
 class Message():
+    """Class for the messages
+    """
     def __init__(self, json: dict) -> None:
         self.__message_id: int = json["id"]
         self.__useridfrom: int = json["useridfrom"]
@@ -8,16 +13,41 @@ def __init__(self, json: dict) -> None:
         self.__timecreated: int = json["timecreated"]
 
     def get_message_id(self) -> int:
+        """Gets the message id
+
+        Returns:
+            int: message id
+        """
         return self.__message_id
-    
+
     def get_useridfrom(self) -> int:
+        """Gets the user id who sent this message
+
+        Returns:
+            int: user id
+        """
         return self.__useridfrom
-    
+
     def get_text(self) -> str:
+        """Gets the raw text of the message
+
+        Returns:
+            str: text
+        """
         return self.__text
 
     def get_timecreated(self) -> int:
+        """Gets the timestamp of the message
+
+        Returns:
+            int: unix time of the message
+        """
         return self.__timecreated
 
     def get_clean_text(self) -> str:
-        return BeautifulSoup(self.__text, "html.parser").get_text()
\ No newline at end of file
+        """Gets the text of the message, without any HTML tags
+
+        Returns:
+            str: text
+        """
+        return BeautifulSoup(self.__text, "html.parser").get_text()
diff --git a/src/UBUVoiceAssistant/model/user.py b/src/UBUVoiceAssistant/model/user.py
index 28967d7..22f1465 100644
--- a/src/UBUVoiceAssistant/model/user.py
+++ b/src/UBUVoiceAssistant/model/user.py
@@ -21,7 +21,7 @@ def __init__(self, user: Union[int, dict]):
         """
         self.__courses: Dict[int, Course] = {}
         self.__final_grades: List[GradeItem] = []
-        if isinstance(user, int) or isinstance(user, str):
+        if isinstance(user, (int, str)):
             self.__user_id = user
             self.__fullname = ""
         else:
@@ -89,7 +89,17 @@ def set_final_grades(self, grades: List[GradeItem]):
         self.__final_grades = grades
 
     def set_fullname(self, name: str):
+        """Sets the user fullname
+
+        Args:
+            name (str): fullname
+        """
         self.__fullname = name
 
     def get_fullname(self) -> str:
+        """Gets the user fullname
+
+        Returns:
+            str: fullname
+        """
         return self.__fullname
diff --git a/src/UBUVoiceAssistant/skills/ubu-calendar b/src/UBUVoiceAssistant/skills/ubu-calendar
index fa717ef..d88de64 160000
--- a/src/UBUVoiceAssistant/skills/ubu-calendar
+++ b/src/UBUVoiceAssistant/skills/ubu-calendar
@@ -1 +1 @@
-Subproject commit fa717ef59e4522baac72e16d7b2331de9e0c7ed2
+Subproject commit d88de64bbb76cdd92ec656167f19d31aec6d1be9
diff --git a/src/UBUVoiceAssistant/skills/ubu-course b/src/UBUVoiceAssistant/skills/ubu-course
index b922c2b..055f4d7 160000
--- a/src/UBUVoiceAssistant/skills/ubu-course
+++ b/src/UBUVoiceAssistant/skills/ubu-course
@@ -1 +1 @@
-Subproject commit b922c2b9d82453f62b35f04c3fe8e8d565b32ed6
+Subproject commit 055f4d704bf17e380196635d2dff7603c8832a56
diff --git a/src/UBUVoiceAssistant/skills/ubu-grades b/src/UBUVoiceAssistant/skills/ubu-grades
index 6a948a5..233a3f2 160000
--- a/src/UBUVoiceAssistant/skills/ubu-grades
+++ b/src/UBUVoiceAssistant/skills/ubu-grades
@@ -1 +1 @@
-Subproject commit 6a948a5ea9e440ee2f2c06aa82e7f142d2c77da2
+Subproject commit 233a3f2c1e9d9d00e2c135ff28dc5db08a301960
diff --git a/src/UBUVoiceAssistant/skills/ubu-help b/src/UBUVoiceAssistant/skills/ubu-help
index 4167150..008cdee 160000
--- a/src/UBUVoiceAssistant/skills/ubu-help
+++ b/src/UBUVoiceAssistant/skills/ubu-help
@@ -1 +1 @@
-Subproject commit 416715095e1a448f6635b6662dfca743ab9a1ff8
+Subproject commit 008cdee8c366f844cb6ebd845f1512d566b103df
diff --git a/src/UBUVoiceAssistant/skills/ubu-messages b/src/UBUVoiceAssistant/skills/ubu-messages
index 24b760c..a91a18a 160000
--- a/src/UBUVoiceAssistant/skills/ubu-messages
+++ b/src/UBUVoiceAssistant/skills/ubu-messages
@@ -1 +1 @@
-Subproject commit 24b760cb099990321e886b1e09e1e00a25a0b7a2
+Subproject commit a91a18a8d1126ab1f146a5c183a5fa541b45dde8
diff --git a/src/UBUVoiceAssistant/util/lang.py b/src/UBUVoiceAssistant/util/lang.py
index ba8cd40..5b7ddcd 100644
--- a/src/UBUVoiceAssistant/util/lang.py
+++ b/src/UBUVoiceAssistant/util/lang.py
@@ -102,7 +102,23 @@ def update_mycroft_config(self) -> None:
             json.dump(mycroft_cfg, mycroft_cfg_file)
 
     def get_language_index(self, lang_code: str) -> int:
+        """Gets the position for the language
+
+        Args:
+            lang_code (str): Language code, similar to es_ES
+
+        Returns:
+            int: The position in the list of loaded languages
+        """
         return self._available_langs.index(lang_code)
 
     def check_language_supported(self, lang: str) -> bool:
+        """Checks if the language is supported on Moodle
+
+        Args:
+            lang (str): Language code from Moodle, similar to es
+
+        Returns:
+            bool: true if the language is supported, false if not
+        """
         return lang == self.get_current_language()[0].split("_")[0]
diff --git a/src/UBUVoiceAssistant/util/singleton.py b/src/UBUVoiceAssistant/util/singleton.py
index cc5e590..e198107 100644
--- a/src/UBUVoiceAssistant/util/singleton.py
+++ b/src/UBUVoiceAssistant/util/singleton.py
@@ -1,3 +1,5 @@
+"""Module for the singleton class
+"""
 class Singleton(type): # https://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
     """Singleton class
     """
diff --git a/src/UBUVoiceAssistant/util/util.py b/src/UBUVoiceAssistant/util/util.py
index a9e98f3..d23c72a 100644
--- a/src/UBUVoiceAssistant/util/util.py
+++ b/src/UBUVoiceAssistant/util/util.py
@@ -3,7 +3,6 @@
 import pickle
 import socket
 import re
-from os import environ
 from typing import List, Optional
 from ..model.course import Course
 from .settings import Settings
@@ -16,13 +15,14 @@
                 '&uacute;': 'ú', '\xa0': ' '}
 
 
-def create_server_socket(unserialized_data, host=SOCKET_HOST, port=SOCKET_PORT):  # TODO Document
-    """Creates a server socket
+def create_server_socket(unserialized_data, host=SOCKET_HOST, port=SOCKET_PORT):
+    """Creates a server socket. This is used to send the webservice object from the frontend
+        to the backend
 
     Args:
-        unserialized_data ([type]): [description]
-        host ([type], optional): [description]. Defaults to SOCKET_HOST.
-        port ([type], optional): [description]. Defaults to SOCKET_PORT.
+        unserialized_data ([type]): unserialized data to send
+        host ([type], optional): ip to bind the socket to. Defaults to SOCKET_HOST.
+        port ([type], optional): port to listen. Defaults to SOCKET_PORT.
     """
     server_socket = socket.socket()
     server_socket.bind((host, port))
@@ -33,15 +33,15 @@ def create_server_socket(unserialized_data, host=SOCKET_HOST, port=SOCKET_PORT):
         client_socket.send(data)
 
 
-def get_data_from_server(host=SOCKET_HOST, port=SOCKET_PORT):  # TODO Document
-    """Gets data from the server.
+def get_data_from_server(host=SOCKET_HOST, port=SOCKET_PORT):
+    """Gets data from the server. This is used to get the webservice object in the skills
 
     Args:
-        host ([type], optional): [description]. Defaults to SOCKET_HOST.
-        port ([type], optional): [description]. Defaults to SOCKET_PORT.
+        host ([type], optional): host where it's the socket. Defaults to SOCKET_HOST.
+        port ([type], optional): port where it's the socket. Defaults to SOCKET_PORT.
 
     Returns:
-        [type]: [description]
+        Unserialized data. This will usually be a webservice
     """
     client_socket = socket.socket()
     client_socket.connect((host, port))
@@ -87,7 +87,7 @@ def translate_moodle_words(string: str) -> str:
     return string
 
 
-def get_course_id_by_name(course_to_find: str, user_courses: List[Course]) -> Optional[Course]:
+def get_course_id_by_name(course_to_find: str, user_courses: List[Course]) -> Optional[str]:
     """Finds a course by its name
 
     Args:
@@ -104,6 +104,15 @@ def get_course_id_by_name(course_to_find: str, user_courses: List[Course]) -> Op
 
 
 def reorder_name(fullname: str) -> str:
+    """Reorders the name from "surname, name" to "name surname". Doesn't change anything if there
+        is no comma in the text.
+
+    Args:
+        fullname (str): fullname to reorder
+
+    Returns:
+        str: ordered fullname
+    """
     try:
         lastname, firstname = fullname.split(", ")
         return " ".join([firstname, lastname])
diff --git a/src/UBUVoiceAssistant/webservice/web_service.py b/src/UBUVoiceAssistant/webservice/web_service.py
index 9804d4a..1c56e9a 100644
--- a/src/UBUVoiceAssistant/webservice/web_service.py
+++ b/src/UBUVoiceAssistant/webservice/web_service.py
@@ -1,6 +1,6 @@
 """WebService file
 """
-from typing import Dict, List, Optional, Union
+from typing import Dict, List, Union
 
 import requests
 
@@ -249,6 +249,11 @@ def get_forum_discussion_posts(self, discussionid):
         return req
 
     def get_conversations(self) -> List[Conversation]:
+        """Gets the list of conversations for the user
+
+        Returns:
+            List[Conversation]: List of conversations
+        """
         url = (self.__url_with_token + "core_message_get_conversations")
         params = {"userid": self.get_user().get_id()}
         req = requests.get(url, params).json()
@@ -258,13 +263,18 @@ def get_conversations(self) -> List[Conversation]:
         return result
 
     def get_conversations_with_messages(self) -> List[Conversation]:
-        convers = self.get_conversations()
+        """Gets the list of conversations with messages for the user
+
+        Returns:
+            List[Conversation]: List of conversations
+        """
+        conversations = self.get_conversations()
         url = (self.__url_with_token + "core_message_get_conversation")
         result: List[Conversation] = []
-        for c in convers:
+        for conversation in conversations:
             params = {
                 "userid": self.get_user().get_id(),
-                "conversationid": c.get_conversation_id(),
+                "conversationid": conversation.get_conversation_id(),
                 "includecontactrequests": 0,
                 "includeprivacyinfo": 0
             }
@@ -273,24 +283,44 @@ def get_conversations_with_messages(self) -> List[Conversation]:
         return result
 
     def send_message_to_conversation(self, message: str, conversation: int):
+        """Sends a message to an already existing conversation
+
+        Args:
+            message (str): Message text
+            conversation (int): Conversation id
+        """
         url = (self.__url_with_token + "core_message_send_messages_to_conversation")
         params: Dict[str, Union[str, int]] = {
             "conversationid": conversation,
             "messages[0][text]": message,
             "messages[0][textformat]": 2 # PLAIN
         }
-        req = requests.get(url, params).json()
+        requests.get(url, params)
 
     def send_message_to_user(self, message: str, user: int):
+        """Sends a message to another user
+
+        Args:
+            message (str): Message text
+            user (int): User id
+        """
         url = (self.__url_with_token + "core_message_send_instant_messages")
         params: Dict[str, Union[str, int]] = {
             "messages[0][touserid]": user,
             "messages[0][text]": message,
             "messages[0][textformat]": 2 # PLAIN
         }
-        req = requests.get(url, params).json()
+        requests.get(url, params)
 
     def check_can_message_user(self, user: int) -> bool:
+        """Checks if the user can message another user
+
+        Args:
+            user (int): User id
+
+        Returns:
+            bool: True if you can message that user, false if not
+        """
         url = (self.__url_with_token + "core_message_get_member_info")
         params = {
             "referenceuserid": self.__user.get_id(),
@@ -301,6 +331,15 @@ def check_can_message_user(self, user: int) -> bool:
         return bool(req[0]["canmessage"])
 
     def get_participants_by_course(self, course: int) -> List[User]:
+        """Gets the list of participants in a course. In UBUVirtual, if you are a student, you
+            can only see the teachers.
+
+        Args:
+            course (int): Course id
+
+        Returns:
+            List[User]: List of participants
+        """
         url = (self.__url_with_token + "core_enrol_get_enrolled_users")
         params = {"courseid": course}
         req = requests.get(url, params).json()