Repository: LovetheFrogs/PyCircTools (language: python)

Issue:
Create multiplexers documentation



Discussion / hints:

Fix patch:
diff --git a/CTools/Exceptions/MultiplexersExceptions.py b/CTools/Exceptions/MultiplexersExceptions.py
index 15bb830..4a17289 100644
--- a/CTools/Exceptions/MultiplexersExceptions.py
+++ b/CTools/Exceptions/MultiplexersExceptions.py
@@ -22,3 +22,15 @@ def __init__(self, requestedInput=None):
         else:
             self.msg = "Input requested does not exist."
         super().__init__(self.msg)
+
+
+class NonExistingControlSignal(MultiplexerException):
+    """
+    NonExistingControlSignal is raised when a Multiplexer/Demultiplexer doesn't have the set control signal asked for.
+    """
+    def __init__(self, requestedInput=None):
+        if requestedInput is not None:
+            self.msg = "Set control signal " + str(requestedInput) + " does not exist."
+        else:
+            self.msg = "Set control signal does not exist."
+        super().__init__(self.msg)
diff --git a/CTools/Multiplexers/Mux16to1.py b/CTools/Multiplexers/Mux16to1.py
new file mode 100644
index 0000000..3e135f1
--- /dev/null
+++ b/CTools/Multiplexers/Mux16to1.py
@@ -0,0 +1,123 @@
+from CTools.Exceptions.MultiplexersExceptions import NonExistingInput, NonExistingControlSignal
+from CTools.Exceptions.CircuitToolsExceptions import NotTruthValue
+
+
+class Mux16to1:
+    """
+    16 to 1 Multiplexer. Takes four bits as Set input.
+    """
+    def __init__(self):
+        """
+        Mux16to1 class constructor method.
+        """
+        self.input = [False] * 16
+        self.set = [False] * 4
+        self.output = self.__calculate_output()
+
+    def get_input(self, num):
+        """
+        Method get_input is used to get the value of input[num]
+
+        :param num: Number of the input you want to get. It is a number from 0 to 15.
+        :type num: int
+        :raises NonExistingInput: Raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :return: Value of the desired input (num).
+        :rtype: bool
+        """
+        if num >= len(self.input) or num < 0:
+            raise NonExistingInput(num)
+
+        return self.input[num]
+
+    def get_set(self, setNum):
+        """
+        Method get_set gets the value of the set[setNum] control signal.
+
+        :param setNum: Number of the set control signal you want to get, ranges from 0 to 4.
+        :type setNum: int
+        :raises NonExistingControlSignal: Raised when a Multiplexer/Demultiplexer doesn't have setNum control signal.
+        :return: Value of the desired set control signal (setNum).
+        :rtype: bool
+        """
+        if setNum >= len(self.set) or setNum < 0:
+            raise NonExistingControlSignal
+
+        return self.set[setNum]
+
+    def get_output(self):
+        """
+        Method get_output gets the output of the 16 to 1 Multiplexer.
+
+        :return: Value of the output.
+        :rtype: bool
+        """
+        return self.output
+
+    def set_input(self, num, value):
+        """
+        Method set_input sets a certain input to the desired value, either True or False.
+
+        :param num: Number of the input selected.
+        :type num: int
+        :param value: Desired value of the input.
+        :type value: bool
+        :raises NonExistingInput: raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :raises NotTruthValue: Raised when value's type is not bool.
+        """
+        if num >= len(self.input) or num < 0:
+            raise NonExistingInput(num)
+
+        if type(value) is not bool:
+            raise NotTruthValue
+
+        self.input[num] = value
+        self.output = self.__calculate_output()
+        return self
+
+    def set_set(self, setNum, value):
+        """
+        Method set_set sets the value of the set control signal to the desired truth value.
+
+        :param setNum: Number of the set control signal selected.
+        :type setNum: int
+        :param value: Desired value of the set control signal.
+        :type value: bool
+        :raises NonExistingControlSignal: Raised when a Multiplexer/Demultiplexer doesn't have setNum control signal.
+        :raises NotTruthValue: Raised when value's type is not bool.
+        """
+        if setNum >= len(self.set) or setNum < 0:
+            raise NonExistingControlSignal(setNum)
+
+        if type(value) is not bool:
+            raise NotTruthValue
+
+        self.set[setNum] = value
+        self.output = self.__calculate_output()
+        return self
+
+    def __calculate_output(self):
+        """
+        Private method __calculate_output calculates the output signal using the 16-to-1 mux formula.
+
+        :return: Value of the output signal.
+        :rtype: bool
+        """
+        first = not self.set[3] and not self.set[2] and not self.set[1] and not self.set[0] and self.input[0]
+        second = not self.set[3] and not self.set[2] and not self.set[1] and self.set[0] and self.input[1]
+        third = not self.set[3] and not self.set[2] and self.set[1] and not self.set[0] and self.input[2]
+        fourth = not self.set[3] and not self.set[2] and self.set[1] and self.set[0] and self.input[3]
+        fifth = not self.set[3] and self.set[2] and not self.set[1] and not self.set[0] and self.input[4]
+        sixth = not self.set[3] and self.set[2] and not self.set[1] and self.set[0] and self.input[5]
+        seventh = not self.set[3] and self.set[2] and self.set[1] and not self.set[0] and self.input[6]
+        eight = not self.set[3] and self.set[2] and self.set[1] and self.set[0] and self.input[7]
+        ninth = self.set[3] and not self.set[2] and not self.set[1] and not self.set[0] and self.input[8]
+        tenth = self.set[3] and not self.set[2] and not self.set[1] and self.set[0] and self.input[9]
+        eleventh = self.set[3] and not self.set[2] and self.set[1] and not self.set[0] and self.input[10]
+        twelfth = self.set[3] and not self.set[2] and self.set[1] and self.set[0] and self.input[11]
+        thirteenth = self.set[3] and self.set[2] and not self.set[1] and not self.set[0] and self.input[12]
+        fourteenth = self.set[3] and self.set[2] and not self.set[1] and self.set[0] and self.input[13]
+        fifteenth = self.set[3] and self.set[2] and self.set[1] and not self.set[0] and self.input[14]
+        sixteenth = self.set[3] and self.set[2] and self.set[1] and self.set[0] and self.input[15]
+
+        return first or second or third or fourth or fifth or sixth or seventh or eight or ninth or tenth or eleventh \
+            or twelfth or thirteenth or fourteenth or fifteenth or sixteenth
\ No newline at end of file
diff --git a/CTools/Multiplexers/Mux2to1.py b/CTools/Multiplexers/Mux2to1.py
index ee8c05e..4114ced 100644
--- a/CTools/Multiplexers/Mux2to1.py
+++ b/CTools/Multiplexers/Mux2to1.py
@@ -20,7 +20,7 @@ def get_input(self, num):
 
         :param num: Number of the input you want to get, either 0 or 1.
         :type num: int
-        :raises NonExistingInput: raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :raises NonExistingInput: Raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
         :return: Value of the desired input (num).
         :rtype: bool
         """
@@ -90,4 +90,4 @@ def __calculate_output(self):
         :return: Value of the output signal.
         :rtype: bool
         """
-        return (self.input[0] and not(self.set)) or (self.input[1] and self.set)
+        return (self.input[0] and not self.set) or (self.input[1] and self.set)
diff --git a/CTools/Multiplexers/Mux4to1.py b/CTools/Multiplexers/Mux4to1.py
new file mode 100644
index 0000000..9473b88
--- /dev/null
+++ b/CTools/Multiplexers/Mux4to1.py
@@ -0,0 +1,109 @@
+from CTools.Exceptions.MultiplexersExceptions import NonExistingInput, NonExistingControlSignal
+from CTools.Exceptions.CircuitToolsExceptions import NotTruthValue
+
+
+class Mux4to1:
+    """
+    4 to 1 Multiplexer. Takes two bits as a Set input.
+    """
+    def __init__(self):
+        """
+        Mux4to1 class constructor method.
+        """
+        self.input = [False] * 4
+        self.set = [False] * 2
+        self.output = self.__calculate_output()
+
+    def get_input(self, num):
+        """
+        Method get_input is used to get the value of input[num]
+
+        :param num: Number of the input you want to get. It is a number from 0 to 3.
+        :type num: int
+        :raises NonExistingInput: Raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :return: Value of the desired input (num).
+        :rtype: bool
+        """
+        if num >= len(self.input) or num < 0:
+            raise NonExistingInput(num)
+
+        return self.input[num]
+
+    def get_set(self, setNum):
+        """
+        Method get_set gets the value of the set[setNum] control signal.
+
+        :param setNum: Number of the set control signal you want to get, either 0 or 1.
+        :type setNum: int
+        :raises NonExistingControlSignal: Raised when a Multiplexer/Demultiplexer doesn't have setNum control signal.
+        :return: Value of the desired set control signal (setNum).
+        :rtype: bool
+        """
+        if setNum >= len(self.set) or setNum < 0:
+            raise NonExistingControlSignal
+
+        return self.set[setNum]
+
+    def get_output(self):
+        """
+        Method get_output gets the output of the 4 to 1 Multiplexer.
+
+        :return: Value of the output.
+        :rtype: bool
+        """
+        return self.output
+
+    def set_input(self, num, value):
+        """
+        Method set_input sets a certain input to the desired value, either True or False.
+
+        :param num: Number of the input selected.
+        :type num: int
+        :param value: Desired value of the input.
+        :type value: bool
+        :raises NonExistingInput: raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :raises NotTruthValue: Raised when value's type is not bool.
+        """
+        if num >= len(self.input) or num < 0:
+            raise NonExistingInput(num)
+
+        if type(value) is not bool:
+            raise NotTruthValue
+
+        self.input[num] = value
+        self.output = self.__calculate_output()
+        return self
+
+    def set_set(self, setNum, value):
+        """
+        Method set_set sets the value of the set control signal to the desired truth value.
+
+        :param setNum: Number of the set control signal selected.
+        :type setNum: int
+        :param value: Desired value of the set control signal.
+        :type value: bool
+        :raises NonExistingControlSignal: Raised when a Multiplexer/Demultiplexer doesn't have setNum control signal.
+        :raises NotTruthValue: Raised when value's type is not bool.
+        """
+        if setNum >= len(self.set) or setNum < 0:
+            raise NonExistingControlSignal(setNum)
+
+        if type(value) is not bool:
+            raise NotTruthValue
+
+        self.set[setNum] = value
+        self.output = self.__calculate_output()
+        return self
+
+    def __calculate_output(self):
+        """
+        Private method __calculate_output calculates the output signal using the 4-to-1 mux formula.
+
+        :return: Value of the output signal.
+        :rtype: bool
+        """
+        first_minterm = not self.set[0] and not self.set[1] and self.input[0]
+        second_minterm = self.set[0] and not self.set[1] and self.input[1]
+        third_minterm = not self.set[0] and self.set[1] and self.input[2]
+        fourth_minterm = self.set[0] and self.set[1] and self.input[3]
+        return first_minterm or second_minterm or third_minterm or fourth_minterm
diff --git a/CTools/Multiplexers/Mux8to1.py b/CTools/Multiplexers/Mux8to1.py
new file mode 100644
index 0000000..46b3389
--- /dev/null
+++ b/CTools/Multiplexers/Mux8to1.py
@@ -0,0 +1,114 @@
+from CTools.Exceptions.MultiplexersExceptions import NonExistingInput, NonExistingControlSignal
+from CTools.Exceptions.CircuitToolsExceptions import NotTruthValue
+
+
+class Mux8to1:
+    """
+    8 to 1 Multiplexer. Takes three bits as Set input.
+    """
+    def __init__(self):
+        """
+        Mux8to1 class constructor method.
+        """
+        self.input = [False] * 8
+        self.set = [False] * 3
+        self.output = self.__calculate_output()
+
+    def get_input(self, num):
+        """
+        Method get_input is used to get the value of input[num]
+
+        :param num: Number of the input you want to get. It is a number from 0 to 7.
+        :type num: int
+        :raises NonExistingInput: Raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :return: Value of the desired input (num).
+        :rtype: bool
+        """
+        if num >= len(self.input) or num < 0:
+            raise NonExistingInput(num)
+
+        return self.input[num]
+
+    def get_set(self, setNum):
+        """
+        Method get_set gets the value of the set[setNum] control signal.
+
+        :param setNum: Number of the set control signal you want to get, ranges from 0 to 3.
+        :type setNum: int
+        :raises NonExistingControlSignal: Raised when a Multiplexer/Demultiplexer doesn't have setNum control signal.
+        :return: Value of the desired set control signal (setNum).
+        :rtype: bool
+        """
+        if setNum >= len(self.set) or setNum < 0:
+            raise NonExistingControlSignal
+
+        return self.set[setNum]
+
+    def get_output(self):
+        """
+        Method get_output gets the output of the 8 to 1 Multiplexer.
+
+        :return: Value of the output.
+        :rtype: bool
+        """
+        return self.output
+
+    def set_input(self, num, value):
+        """
+        Method set_input sets a certain input to the desired value, either True or False.
+
+        :param num: Number of the input selected.
+        :type num: int
+        :param value: Desired value of the input.
+        :type value: bool
+        :raises NonExistingInput: raised when a Multiplexer/Demultiplexer doesn't have the input asked for.
+        :raises NotTruthValue: Raised when value's type is not bool.
+        """
+        if num >= len(self.input) or num < 0:
+            raise NonExistingInput(num)
+
+        if type(value) is not bool:
+            raise NotTruthValue
+
+        self.input[num] = value
+        self.output = self.__calculate_output()
+        return self
+
+    def set_set(self, setNum, value):
+        """
+        Method set_set sets the value of the set control signal to the desired truth value.
+
+        :param setNum: Number of the set control signal selected.
+        :type setNum: int
+        :param value: Desired value of the set control signal.
+        :type value: bool
+        :raises NonExistingControlSignal: Raised when a Multiplexer/Demultiplexer doesn't have setNum control signal.
+        :raises NotTruthValue: Raised when value's type is not bool.
+        """
+        if setNum >= len(self.set) or setNum < 0:
+            raise NonExistingControlSignal(setNum)
+
+        if type(value) is not bool:
+            raise NotTruthValue
+
+        self.set[setNum] = value
+        self.output = self.__calculate_output()
+        return self
+
+    def __calculate_output(self):
+        """
+        Private method __calculate_output calculates the output signal using the 8-to-1 mux formula.
+
+        :return: Value of the output signal.
+        :rtype: bool
+        """
+        first = not self.set[2] and not self.set[1] and not self.set[0] and self.input[0]
+        second = not self.set[2] and not self.set[1] and self.set[0] and self.input[1]
+        third = not self.set[2] and self.set[1] and not self.set[0] and self.input[2]
+        fourth = not self.set[2] and self.set[1] and self.set[0] and self.input[3]
+        fifth = self.set[2] and not self.set[1] and not self.set[0] and self.input[4]
+        sixth = self.set[2] and not self.set[1] and self.set[0] and self.input[5]
+        seventh = self.set[2] and self.set[1] and not self.set[0] and self.input[6]
+        eight = self.set[2] and self.set[1] and self.set[0] and self.input[7]
+
+        return first or second or third or fourth or fifth or sixth or seventh or eight
diff --git a/CTools/Multiplexers/__init__.py b/CTools/Multiplexers/__init__.py
index 38604cd..8365d73 100644
--- a/CTools/Multiplexers/__init__.py
+++ b/CTools/Multiplexers/__init__.py
@@ -5,3 +5,6 @@
 """
 
 from CTools.Multiplexers.Mux2to1 import *
+from CTools.Multiplexers.Mux4to1 import *
+from CTools.Multiplexers.Mux8to1 import *
+from CTools.Multiplexers.Mux16to1 import *
diff --git a/README.md b/README.md
index d273d96..a62d928 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # PyCircTools
 
-PyCircTools is a python package wich contains tools to build circuits using python 3. It is a work in progress, and will be updated frequently to add more
+PyCircTools is a python package which contains tools to build circuits using python 3. It is a work in progress, and will be updated frequently to add more
 modules. 
 
 ## Table of contents
@@ -31,12 +31,32 @@ modules.
         * [2.5.1. Attributes](#nor-attributes)
         * [2.5.2. Constructor](#nor-constructor)
         * [2.5.3. Methods](#nor-methods)
+- [3. Multiplexers Module](#multiplexers)
+    + [3.1. 2-to-1 Multiplexer](#2-1-mux)
+        * [3.1.1. Attributes](#2-1-attributes)
+        * [3.1.2. Constructor](#2-1-constructor)
+        * [3.1.3. Methods](#2-1-methods)
+    + [3.2. 4-to-1 Multiplexer](#4-1-mux)
+        * [3.2.1. Attributes](#4-1-attributes)
+        * [3.2.2. Constructor](#4-1-constructor)
+        * [3.2.3. Methods](#4-1-methods)
+    + [3.3. 8-to-1 Multiplexer](#8-1-mux)
+        * [3.3.1. Attributes](#8-1-attributes)
+        * [3.3.2. Constructor](#8-1-constructor)
+        * [3.3.3. Methods](#8-1-methods)
+    + [3.4. 16-to-1 Multiplexer](#16-1-mux)
+        * [3.4.1. Attributes](#16-1-attributes)
+        * [3.4.2. Constructor](#16-1-constructor)
+        * [3.4.3. Methods](#16-1-methods)
 - [Exceptions](#exceptions)
     + [PyCircTools Exceptions](#ctools-exceptions)
         * [NotTruthValue](#not-truth-value)
     + [Logic gates Exceptions](#logic-gates-exceptions)
         * [NonPositiveInput](#non-positive-input)
         * [NotAnInput](#not-an-input)
+    + [Multiplexer](#multiplexers-exceptions)
+        * [NonExistingInput](#non-existing-input)
+        * [NonExistingControlSignal](#non-existing-control-signal)
 - [About](#about)
 
 <a name="installing-CTools"></a>
@@ -57,13 +77,13 @@ at the start of your code, and substitute subpackage with the package you want,
 ## Logic Gates Module
 
 Here is an in depth explanation for the PyCircTools.LogicGates module. LogicGates adds implementation for common logic gates used in circuit design. It allows
-to create gates with as many inputs as the user decides (except for the NOT gate). For further reference about each of the gates, check it's section in 
+to create gates with as many inputs as the user decides (except for the NOT gate). For further reference about each of the gates, check its section in 
 this README.
 
 <a name="not-gate"></a>
 ### NOT gate
 
-The **NOT gate** is a simple logic gate wich simply inverts the input. It implements the logical negation (¬) and has one input and one output. The NOT 
+The **NOT gate** is a simple logic gate which simply inverts the input. It implements the logical negation (¬) and has one input and one output. The NOT 
 gate symbol and truth table is shown below.
 
 <p align="center"><img src="https://user-images.githubusercontent.com/102818341/174762309-03ead86b-bdb4-4d99-9597-c7d13ac67949.png" alt="NOT gate"></p>
@@ -84,7 +104,7 @@ The NOT gate has the following attributes:
 The constructor of the NOT gate has the following format: <br>
 
 <p align="center" style="bold" ><b>Not()</b></p>
-Wich doesn't take any parameters and returns a NOT gate with its Input set to True and has its output calculated by the not gate <a href="#not-calculate-output">calculate output method)</a>
+Which doesn't take any parameters and returns a NOT gate with its Input set to True and has its output calculated by the not gate <a href="#not-calculate-output">calculate output method)</a>
 
 <a name="not-methods"></a>
 #### Methods
@@ -98,11 +118,11 @@ Gets the input of the gate. It returns a bool containing the requested value.
 Gets the output of the gate. It returns a bool containing the requested value.
 
 - **set_input(bool _value_):**
-Sets the input of the gate to the truth value _'value'_, wich is passed as a parameter.
+Sets the input of the gate to the truth value _'value'_, which is passed as a parameter.
 
 <a name="not-calculate-output"></a>
 - **__calculate_output():**
-Private method wich calculates the output of the gate. This output is:
+Private method which calculates the output of the gate. This output is:
 ```
 not(input)
 ```
@@ -110,7 +130,7 @@ not(input)
 <a name="and-gate"></a>
 ### AND gate
 
-The **AND gate** is a logic gate with two or more inputs that implements the logical conjunction (^). It's output is True only when all of the inputs are True. If any of them is set to False, the output willthen be False. Below you can find the AND truth table.
+The **AND gate** is a logic gate with two or more inputs that implements the logical conjunction (^). It's output is True only when all the inputs are True. If any of them is set to False, the output will then be False. Below you can find the AND truth table.
 
 <p align="center"><img src="https://user-images.githubusercontent.com/102818341/174772306-1a861819-1046-41d4-80d0-f84d58155e99.png" alt="AND gate"></p>
 
@@ -130,7 +150,7 @@ The AND gate has the following attributes:
 The constructor of the AND gate has the following format: <br>
 
 <p align="center"><b>And(int <i>inputNumber</i>)</b></p>
-Wich takes the inputNumber parameter, an integer set to two by default wich can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the and gate <a href="#and-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
+Which takes the inputNumber parameter, an integer set to two by default which can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the and gate <a href="#and-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
 
 <a name="and-methods"></a>
 #### Methods
@@ -144,23 +164,23 @@ Gets the number of inputs of the gate. It returns an int containing the requeste
 - **set_input(int _num_, bool _value_):**
 Sets the input _'num'_ to the truth value _'value'_. Both of them are passed as parameters to the method.
 - **add_input():**
-Adds a new input to the gate, wich defaults to False and updates both output and numOfInputs.
+Adds a new input to the gate, which defaults to False and updates both output and numOfInputs.
 - **remove_input():**
 Removes the last input and updates both output and numOfInputs.
 <a name="and-calculate-output"></a>
 - **__calculate_output():**
-Private method wich calculates the output of the gate. This output is: 
+Private method which calculates the output of the gate. This output is: 
 ```
 (input_n and input_n+1)
 ```
-for all of the inputs of the gate.
+for all the inputs of the gate.
 
 <a name="nand-gate"></a>
 ### NAND gate
 
-The **NAND gate** is a logic gate with two or more inputs wich produces a False output only when all of its inputs are True. Its output is True in any other case. In other words, its output is calculated by negating the conjunction of all inputs of the gate. Below you can find the NAND truth table.
+The **NAND gate** is a logic gate with two or more inputs which produces a False output only when all of its inputs are True. Its output is True in any other case. In other words, its output is calculated by negating the conjunction of all inputs of the gate. Below you can find the NAND truth table.
 
-<p align="center"><img src="https://user-images.githubusercontent.com/102818341/174785289-c57e3f8a-eaf3-4c5c-9dcd-98d83f8b2ce4.png" alt="NAND gate"></a>
+<p align="center"><img src="https://user-images.githubusercontent.com/102818341/174785289-c57e3f8a-eaf3-4c5c-9dcd-98d83f8b2ce4.png" alt="NAND gate"></p>
 
 <a name="nand-attributes"></a>
 #### Attributes
@@ -179,7 +199,7 @@ The NAND gate has the following attributes:
 The constructor of the NAND gate has the following format: <br>
 
 <p align="center"><b>Nand(int <i>inputNumber</i>)</b></p>
-Wich takes the inputNumber parameter, an integer set to two by default wich can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the nand gate <a href="#nand-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
+Which takes the inputNumber parameter, an integer set to two by default which can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the nand gate <a href="#nand-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
 
 <a name="nand-methods"></a>
 #### Methods
@@ -193,23 +213,23 @@ Gets the number of inputs of the gate. It returns an int containing the requeste
 - **set_input(int _num_, bool _value_):**
 Sets the input _'num'_ to the truth value _'value'_. Both of them are passed as parameters to the method.
 - **add_input():**
-Adds a new input to the gate, wich defaults to False and updates both output and numOfInputs.
+Adds a new input to the gate, which defaults to False and updates both output and numOfInputs.
 - **remove_input():**
 Removes the last input and updates both output and numOfInputs.
 <a name="nand-calculate-output"></a>
 - **__calculate_output():**
-Private method wich calculates the output of the gate. This output is 
+Private method which calculates the output of the gate. This output is 
 ```
 not(input_n and input_n+1) 
 ```
-for all of the inputs of the gate.
+for all the inputs of the gate.
 
 <a name="or-gate"></a>
 ### OR gate
 
-The **OR gate** is a logic gate with two or more inputs wich implements the logical disjunction (∨). It's output is True if any of the inputs is True, and False only when all of the gate's inputs are set to False. Below you can find the OR gate truth table.
+The **OR gate** is a logic gate with two or more inputs which implements the logical disjunction (∨). Its output is True if any of the inputs is True, and False only when all the gate's inputs are set to False. Below you can find the OR gate truth table.
 
-<p align="center"><img src="https://user-images.githubusercontent.com/102818341/174787252-49747650-4a1c-415e-ae3d-6a42064133b6.png" alt="OR gate"></a>
+<p align="center"><img src="https://user-images.githubusercontent.com/102818341/174787252-49747650-4a1c-415e-ae3d-6a42064133b6.png" alt="OR gate"></p>
 
 <a name="or-attributes"></a>
 #### Attributes
@@ -228,7 +248,7 @@ The OR gate has the following attributes:
 The constructor of the OR gate has the following format: <br>
 
 <p align="center"><b>Or(int <i>inputNumber</i>)</b></p>
-Wich takes the inputNumber parameter, an integer set to two by default wich can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the or gate <a href="#or-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
+Which takes the inputNumber parameter, an integer set to two by default which can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the or gate <a href="#or-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
 
 <a name="or-methods"></a>
 #### Methods
@@ -242,23 +262,23 @@ Gets the number of inputs of the gate. It returns an int containing the requeste
 - **set_input(int _num_, bool _value_):**
 Sets the input _'num'_ to the truth value _'value'_. Both of them are passed as parameters to the method.
 - **add_input():**
-Adds a new input to the gate, wich defaults to False and updates both output and numOfInputs.
+Adds a new input to the gate, which defaults to False and updates both output and numOfInputs.
 - **remove_input():**
 Removes the last input and updates both output and numOfInputs.
 <a name="or-calculate-output"></a>
 - **__calculate_output():**
-Private method wich calculates the output of the gate. This output is 
+Private method which calculates the output of the gate. This output is 
 ```
 (input_n or input_n+1)
 ```
-for all of the inputs of the gate.
+for all the inputs of the gate.
 
 <a name="xor-gate"></a>
 ### XOR gate
 
 The **XOR gate**is a logic gate with two or more inputs whose output is True when the number of True inputs is odd. In any other case, the output value is False. Below you can find the OR gate truth table.
 
-<p align="center"><img src="https://user-images.githubusercontent.com/102818341/174814299-a7bfc87a-8274-44d7-a4ac-d0845aafca40.png" alt="XOR gate"></a>
+<p align="center"><img src="https://user-images.githubusercontent.com/102818341/174814299-a7bfc87a-8274-44d7-a4ac-d0845aafca40.png" alt="XOR gate"></p>
 
 <a name="xor-attributes"></a>
 #### Attributes
@@ -277,7 +297,7 @@ The XOR gate has the following attributes:
 The constructor of the XOR gate has the following format: <br>
 
 <p align="center"><b>Xor(int <i>inputNumber</i>)</b></p>
-Wich takes the inputNumber parameter, an integer set to two by default wich can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the xor gate <a href="#xor-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
+Which takes the inputNumber parameter, an integer set to two by default which can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the xor gate <a href="#xor-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
 
 <a name="xor-methods"></a>
 #### Methods
@@ -291,21 +311,21 @@ Gets the number of inputs of the gate. It returns an int containing the requeste
 - **set_input(int _num_, bool _value_):**
 Sets the input _'num'_ to the truth value _'value'_. Both of them are passed as parameters to the method.
 - **add_input():**
-Adds a new input to the gate, wich defaults to False and updates both output and numOfInputs.
+Adds a new input to the gate, which defaults to False and updates both output and numOfInputs.
 - **remove_input():**
 Removes the last input and updates both output and numOfInputs.
 <a name="xor-calculate-output"></a>
 - **__calculate_output():**
-Private method wich calculates the output of the gate. This output is 
+Private method which calculates the output of the gate. This output is 
 ```
 [(input_n and not(input_n+1)) or (not(input_n) and input_n+1)] 
 ```
-for all of the inputs of the gate.
+for all the inputs of the gate.
 
 <a name="nor-gate"></a>
 ### NOR gate
 
-The **NOR gate** is a logic gate wich can take two or more inputs. Its output is True only when all of the inputs are False. If any of the inputs is True, the output will be False. In other words, its output is calculated by negating the disjunction of all inputs of the gate. Below you can find the NOR gate truth table.
+The **NOR gate** is a logic gate which can take two or more inputs. Its output is True only when all the inputs are False. If any of the inputs is True, the output will be False. In other words, its output is calculated by negating the disjunction of all inputs of the gate. Below you can find the NOR gate truth table.
 
 <p align="center"><img src="https://user-images.githubusercontent.com/102818341/174819379-e17db12b-5324-4145-be96-d4699ed8a03f.png" alt="NOR gate"></p>
 
@@ -326,7 +346,7 @@ The NOR gate has the following attributes:
 The constructor of the NOR gate has the following format: <br>
 
 <p align="center"><b>Nor(int <i>inputNumber</i>)</b></p>
-Wich takes the inputNumber parameter, an integer set to two by default wich can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the Nor gate <a href="#nor-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
+Which takes the inputNumber parameter, an integer set to two by default which can be changed to have more inputs to the gate. The Input will be initialized to a list of False values, containing as many values as inputs specified, Output will be calculated by the Nor gate <a href="#nor-calculate-output">calculate output method</a> and numOfInputs will take the same value as the parameter inputNumber.
 
 <a name="nor-methods"></a>
 #### Methods
@@ -340,21 +360,231 @@ Gets the number of inputs of the gate. It returns an int containing the requeste
 - **set_input(int _num_, bool _value_):**
 Sets the input _'num'_ to the truth value _'value'_. Both of them are passed as parameters to the method.
 - **add_input():**
-Adds a new input to the gate, wich defaults to False and updates both output and numOfInputs.
+Adds a new input to the gate, which defaults to False and updates both output and numOfInputs.
 - **remove_input():**
 Removes the last input and updates both output and numOfInputs.
 <a name="nor-calculate-output"></a>
 - **__calculate_output():**
-Private method wich calculates the output of the gate. This output is 
+Private method which calculates the output of the gate. This output is 
 ```
 not(input_n or input_n+1)
 ```
-for all of the inputs of the gate.
+for all the inputs of the gate.
+
+<a name="multiplexers"></a>
+## Multiplexers Module
+
+Here is an in depth explanation for the PyCircTools.Multiplexers module. Multiplexers adds implementation for multiplexers ranging from 2-to-1 to 16-to-1. 
+For further reference about each of the multiplexers, check its section in this README.
+
+<a name="2-to-1-mux"></a>
+### 2-to-1 Multiplexer
+
+The **2-to-1** Multiplexer adds the implementation for this circuit element. Below you will find a picture depicting this mux and its equation.
+
+<p align="center"><img src="https://user-images.githubusercontent.com/102818341/175434169-d87df6e6-0002-40e9-a2a2-5f79e669dc30.png", alt="2-to-1 Multiplexer"></p>
+
+<a name="2-1-attributes"></a>
+#### Attributes
+
+The 2-to-1 Multiplexer has the following attributes:
+
+| Name | Description | Type |
+| - | - | - |
+| **input** | Input of the multiplexer | list[bool] |
+| **set** | Set control signals of the multiplexer | bool |
+| **output** | Output of the multiplexer | bool |
+
+Note that for this multiplexer, the number of inputs is two and the number of control signals is one.
+
+<a name="2-1-constructor"></a>
+#### Constructor
+
+The constructor of the 2-to-1 Multiplexer has the following format: <br>
+
+<p align="center" style="bold" ><b>Mux2to1()</b></p>
+Which doesn't take any parameters and returns a 2-to-1 Multiplexer with its two inputs set to False, its set control signal set to False and output calculated by the 2-to-1 Mux gate <a href="#2-1-cal-output">calculate output method</a>
+
+<a name="2-1-methods"></a>
+#### Methods
+
+The 2-to-1 Multiplexer has the following methods:
+
+- **get_input(int _num_):**
+Gets the value of the input _num_. It returns the boolean value in input[num].
+
+- **get_set():**
+Gets the value of the set control signal. It returns a bool with the requested value.
+
+- **get_output():**
+Gets the output of the mux. It returns a bool containing the requested value.
+
+- **set_input(int _num_, bool _value_):**
+Sets the input[num] of the mux to the truth value _'value'_, which is passed as a parameter.
+
+- **set_set(bool _value_):**
+Sets the value of the set control signal to _'value'_.
+
+<a name="2-1-cal-output"></a>
+- **__calculate_output():**
+Private method which calculates the output of the mux. This output is showed in <a href="#2-to-1-mux">2-to-1 Multiplexer chapter.</a>
+
+<a name="4-to-1-mux"></a>
+### 4-to-1 Multiplexer
+
+The **4-to-1** Multiplexer adds the implementation for this circuit element. Below you will find a picture depicting this mux and its equation.
+
+<p align="center"><img src="https://user-images.githubusercontent.com/102818341/175567422-867f9575-1fa2-4e06-af2a-723f05c48155.png", alt="4-to-1 Multiplexer"></p>
+
+<a name="4-1-attributes"></a>
+#### Attributes
+
+The 4-to-1 Multiplexer has the following attributes:
+
+| Name | Description | Type |
+| - | - | - |
+| **input** | Input of the multiplexer | list[bool] |
+| **set** | Set control signals of the multiplexer | list[bool] |
+| **output** | Output of the multiplexer | bool |
+
+Note that for this multiplexer, the number of inputs is four and the number of control signals is two.
+
+<a name="4-1-constructor"></a>
+#### Constructor
+
+The constructor of the 4-to-1 Multiplexer has the following format: <br>
+
+<p align="center" style="bold" ><b>Mux4to1()</b></p>
+Which doesn't take any parameters and returns a 4-to-1 Multiplexer with its four inputs set to False, its set control signals set to False and output calculated by the 4-to-1 Mux gate <a href="#4-1-cal-output">calculate output method</a>
+
+<a name="4-1-methods"></a>
+#### Methods
+
+The 4-to-1 Multiplexer has the following methods:
+
+- **get_input(int _num_):**
+Gets the value of the input _num_. It returns the boolean value in input[num].
+
+- **get_set(int _setNum_):**
+Gets the value of the set control signal _setNum_. It returns a bool with the requested value.
+
+- **get_output():**
+Gets the output of the mux. It returns a bool containing the requested value.
+
+- **set_input(int _num_, bool _value_):**
+Sets the input[num] of the mux to the truth value _'value'_, which is passed as a parameter.
+
+- **set_set(int _setNum_, bool _value_):**
+Sets the value of the set control signal set[setNum] to _'value'_. Both are passed as parameters.
+
+<a name="4-1-cal-output"></a>
+- **__calculate_output():**
+Private method which calculates the output of the mux. This output is showed in <a href="#4-to-1-mux">4-to-1 Multiplexer chapter.</a>
+
+<a name="8-to-1-mux"></a>
+### 8-to-1 Multiplexer
+
+The **8-to-1** Multiplexer adds the implementation for this circuit element. It has 8 inputs and the output value is selected by the input number in the set signal.
+
+<a name="8-1-attributes"></a>
+#### Attributes
+
+The 8-to-1 Multiplexer has the following attributes:
+
+| Name | Description | Type |
+| - | - | - |
+| **input** | Input of the multiplexer | list[bool] |
+| **set** | Set control signals of the multiplexer | list[bool] |
+| **output** | Output of the multiplexer | bool |
+
+Note that for this multiplexer, the number of inputs is eight and the number of control signals is three.
+
+<a name="8-1-constructor"></a>
+#### Constructor
+
+The constructor of the 8-to-1 Multiplexer has the following format: <br>
+
+<p align="center" style="bold" ><b>Mux8to1()</b></p>
+Which doesn't take any parameters and returns an 8-to-1 Multiplexer with its four inputs set to False, its set control signals set to False and output calculated by the 8-to-1 Mux gate <a href="#8-1-cal-output">calculate output method</a>
+
+<a name="8-1-methods"></a>
+#### Methods
+
+The 8-to-1 Multiplexer has the following methods:
+
+- **get_input(int _num_):**
+Gets the value of the input _num_. It returns the boolean value in input[num].
+
+- **get_set(int _setNum_):**
+Gets the value of the set control signal _setNum_. It returns a bool with the requested value.
+
+- **get_output():**
+Gets the output of the mux. It returns a bool containing the requested value.
+
+- **set_input(int _num_, bool _value_):**
+Sets the input[num] of the mux to the truth value _'value'_, which is passed as a parameter.
+
+- **set_set(int _setNum_, bool _value_):**
+Sets the value of the set control signal set[setNum] to _'value'_. Both are passed as parameters.
+
+<a name="8-1-cal-output"></a>
+- **__calculate_output():**
+Private method which calculates the output of the mux. This output is showed in <a href="#8-to-1-mux">8-to-1 Multiplexer chapter.</a>
+
+<a name="16-to-1-mux"></a>
+### 16-to-1 Multiplexer
+
+The **16-to-1** Multiplexer adds the implementation for this circuit element. It has 16 inputs and the output value is selected by the input number in the set signal.
+
+<a name="16-1-attributes"></a>
+#### Attributes
+
+The 16-to-1 Multiplexer has the following attributes:
+
+| Name | Description | Type |
+| - | - | - |
+| **input** | Input of the multiplexer | list[bool] |
+| **set** | Set control signals of the multiplexer | list[bool] |
+| **output** | Output of the multiplexer | bool |
+
+Note that for this multiplexer, the number of inputs is sixteen and the number of control signals is four.
+
+<a name="16-1-constructor"></a>
+#### Constructor
+
+The constructor of the 8-to-1 Multiplexer has the following format: <br>
+
+<p align="center" style="bold" ><b>Mux16to1()</b></p>
+Which doesn't take any parameters and returns a 16-to-1 Multiplexer with its sixteen inputs set to False, its set control signals set to False and output calculated by the 16-to-1 Mux gate <a href="#16-1-cal-output">calculate output method</a>
+
+<a name="16-1-methods"></a>
+#### Methods
+
+The 16-to-1 Multiplexer has the following methods:
+
+- **get_input(int _num_):**
+Gets the value of the input _num_. It returns the boolean value in input[num].
+
+- **get_set(int _setNum_):**
+Gets the value of the set control signal _setNum_. It returns a bool with the requested value.
+
+- **get_output():**
+Gets the output of the mux. It returns a bool containing the requested value.
+
+- **set_input(int _num_, bool _value_):**
+Sets the input[num] of the mux to the truth value _'value'_, which is passed as a parameter.
+
+- **set_set(int _setNum_, bool _value_):**
+Sets the value of the set control signal set[setNum] to _'value'_. Both are passed as parameters.
+
+<a name="16-1-cal-output"></a>
+- **__calculate_output():**
+Private method which calculates the output of the mux. This output is showed in <a href="#16-to-1-mux">16-to-1 Multiplexer chapter.</a>
 
 <a name="exceptions"></a>
 ## Exceptions
 
-CTools implements the following Exceptions. They are divided depending on wich module they are intended to use.
+CTools implements the following Exceptions. They are divided depending on which module they are intended to use.
 
 <a name="ctools-exceptions"></a>
 ### PyCircTools Exceptions
@@ -383,6 +613,21 @@ of inputs of any logic gate.
 
 NotAnInput is raised when the selected input does not exist.
 
+<a name="muliplexers-exceptions"></a>
+### Multiplexers Exceptions
+
+These are the exceptions used in the PyCircTools.Multiplexers module. An explanation of each one follows below.
+
+<a name="non-existing-input"></a>
+#### NonExistingInput
+
+NonExistingInput is raised when a Multiplexer/Demultiplexer doesn't have the input asked for. It can take an int as an input. This input _'requestedInput'_ is the number which caused the exception.
+
+<a name="non-existing-control-signal"></a>
+#### NonExistingControlSignal
+
+NonExistingControlSignal is raised when a Multiplexer/Demultiplexer doesn't have the set control signal asked for.
+
 <a name="about"></a>
 ## About
 


Test patch:
diff --git a/tests/Multiplexers_tests/test_Mux16to1.py b/tests/Multiplexers_tests/test_Mux16to1.py
new file mode 100644
index 0000000..107d347
--- /dev/null
+++ b/tests/Multiplexers_tests/test_Mux16to1.py
@@ -0,0 +1,97 @@
+import itertools
+
+from CTools import NotTruthValue, NonExistingControlSignal, NonExistingInput
+from CTools.Multiplexers import Mux16to1
+
+
+def generate_inputs(num):
+    vals = []
+    for i in itertools.product([False, True], repeat=num):
+        vals.append(i)
+
+    return vals
+
+
+def get_expected(val):
+    if val[0] == 0 and val[1] == 0 and val[2] == 0 and val[3] == 0:
+        return 15
+    if val[0] == 0 and val[1] == 0 and val[2] == 0 and val[3] == 1:
+        return 14
+    if val[0] == 0 and val[1] == 0 and val[2] == 1 and val[3] == 0:
+        return 13
+    if val[0] == 0 and val[1] == 0 and val[2] == 1 and val[3] == 1:
+        return 12
+    if val[0] == 0 and val[1] == 1 and val[2] == 0 and val[3] == 0:
+        return 11
+    if val[0] == 0 and val[1] == 1 and val[2] == 0 and val[3] == 1:
+        return 10
+    if val[0] == 0 and val[1] == 1 and val[2] == 1 and val[3] == 0:
+        return 9
+    if val[0] == 0 and val[1] == 1 and val[2] == 1 and val[3] == 1:
+        return 8
+    if val[0] == 1 and val[1] == 0 and val[2] == 0 and val[3] == 0:
+        return 7
+    if val[0] == 1 and val[1] == 0 and val[2] == 0 and val[3] == 1:
+        return 6
+    if val[0] == 1 and val[1] == 0 and val[2] == 1 and val[3] == 0:
+        return 5
+    if val[0] == 1 and val[1] == 0 and val[2] == 1 and val[3] == 1:
+        return 4
+    if val[0] == 1 and val[1] == 1 and val[2] == 0 and val[3] == 0:
+        return 3
+    if val[0] == 1 and val[1] == 1 and val[2] == 0 and val[3] == 1:
+        return 2
+    if val[0] == 1 and val[1] == 1 and val[2] == 1 and val[3] == 0:
+        return 1
+    if val[0] == 1 and val[1] == 1 and val[2] == 1 and val[3] == 1:
+        return 0
+
+
+def test_Mux16to1():
+    errors = []
+    mux = Mux16to1()
+    inputs = generate_inputs(16)
+    set_inputs = generate_inputs(4)
+
+    for val in inputs:
+        mux.set_input(0, val[15]).set_input(1, val[14]).set_input(2, val[13]).set_input(3, val[12])\
+            .set_input(4, val[11]).set_input(5, val[10]).set_input(6, val[9]).set_input(7, val[8])\
+            .set_input(8, val[7]).set_input(9, val[6]).set_input(10, val[5]).set_input(11, val[4])\
+            .set_input(12, val[3]).set_input(13, val[2]).set_input(14, val[1]).set_input(15, val[0])
+
+        for set_val in set_inputs:
+            mux.set_set(0, set_val[3]).set_set(1, set_val[2]).set_set(2, set_val[1]).set_set(3, set_val[0])
+            expected = val[get_expected(set_val)]
+            output = mux.get_output()
+
+            if output != expected:
+                to_append = "{}".format(str(val[15])) + ", {}".format(str(val[14])) + \
+                            ", {}".format(str(val[13])) + ", {}".format(str(val[12])) + ", {}".format(str(val[11])) + \
+                            ", {}".format(str(val[10])) + ", {}".format(str(val[9])) + ", {}".format(str(val[8])) + \
+                            ", {}".format(str(val[7])) + ", {}".format(str(val[6])) + ", {}".format(str(val[5])) + \
+                            ", {}".format(str(val[4])) + ", {}".format(str(val[3])) + ", {}".format(str(val[2])) + \
+                            ", {}".format(str(val[1])) + ", {}".format(str(val[0])) +\
+                            ", set signals {}".format(str(set_val[3])) + ", {}".format(str(set_val[2])) + \
+                            ", {}".format(str(set_val[1])) + ", {}".format(str(set_val[0])) + \
+                            " test not passed!"
+                errors.append(to_append)
+
+    try:
+        mux.set_set(5, False)
+        errors.append("Not existing set input test not passed!")
+    except NonExistingControlSignal:
+        pass
+
+    try:
+        mux.set_set(0, 5)
+        errors.append("Not truth value to set test not passed!")
+    except NotTruthValue:
+        pass
+
+    try:
+        mux.set_input(16, False)
+        errors.append("Not existing input test not passed!")
+    except NonExistingInput:
+        pass
+
+    assert not errors, "errors occurred:\n{}".format("\n".join(errors))
diff --git a/tests/Multiplexers_tests/test_Mux4to1.py b/tests/Multiplexers_tests/test_Mux4to1.py
new file mode 100644
index 0000000..e9cba7c
--- /dev/null
+++ b/tests/Multiplexers_tests/test_Mux4to1.py
@@ -0,0 +1,63 @@
+from CTools import NotTruthValue, NonExistingControlSignal, NonExistingInput
+from CTools.Multiplexers import Mux4to1
+
+
+def to_bool(value):
+    if value == 0:
+        return False
+    else:
+        return True
+
+
+def get_expected(val):
+    if val[0] == 0 and val[1] == 0:
+        return 3
+    elif val[0] == 0 and val[1] == 1:
+        return 2
+    elif val[0] == 1 and val[1] == 0:
+        return 1
+    elif val[0] == 1 and val[1] == 1:
+        return 0
+
+
+def test_Mux4to1():
+    errors = []
+    mux = Mux4to1()
+    inputs = [(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 1, 1), (0, 1, 0, 0), (0, 1, 0, 1), (0, 1, 1, 0),
+              (0, 1, 1, 1), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 1, 1), (1, 1, 0, 0), (1, 1, 0, 1),
+              (1, 1, 1, 0), (1, 1, 1, 1)]
+    set_values = [(0, 0), (0, 1), (1, 0), (1, 1)]
+    for val in inputs:
+        mux.set_input(0, to_bool(val[3])).set_input(1, to_bool(val[2])).set_input(2, to_bool(val[1]))\
+            .set_input(3, to_bool(val[0]))
+        for set_val in set_values:
+            mux.set_set(0, to_bool(set_val[1])).set_set(1, to_bool(set_val[0]))
+            expected = val[get_expected(set_val)]
+            output = mux.get_output()
+            if output != expected:
+                to_append = "{}".format(str(to_bool(val[3]))) + ", {}".format(str(to_bool(val[2]))) + \
+                            ", {}".format(str(to_bool(val[1]))) + ", {}".format(str(to_bool(val[0]))) + \
+                            ", set signals {}".format(str(to_bool(set_val[1]))) + \
+                            ", {}".format(str(to_bool(set_val[0]))) + " test not passed!"
+
+                errors.append(to_append)
+
+    try:
+        mux.set_set(2, False)
+        errors.append("Not existing set input test not passed!")
+    except NonExistingControlSignal:
+        pass
+
+    try:
+        mux.set_set(0, 5)
+        errors.append("Not truth value to set test not passed!")
+    except NotTruthValue:
+        pass
+
+    try:
+        mux.set_input(16, False)
+        errors.append("Not existing input test not passed!")
+    except NonExistingInput:
+        pass
+
+    assert not errors, "errors occurred:\n{}".format("\n".join(errors))
diff --git a/tests/Multiplexers_tests/test_Mux8to1.py b/tests/Multiplexers_tests/test_Mux8to1.py
new file mode 100644
index 0000000..84d9e1c
--- /dev/null
+++ b/tests/Multiplexers_tests/test_Mux8to1.py
@@ -0,0 +1,76 @@
+import itertools
+
+from CTools import NotTruthValue, NonExistingControlSignal, NonExistingInput
+from CTools.Multiplexers import Mux8to1
+
+
+def generate_inputs(num):
+    vals = []
+    for i in itertools.product([False, True], repeat=num):
+        vals.append(i)
+
+    return vals
+
+
+def get_expected(val):
+    if val[0] == 0 and val[1] == 0 and val[2] == 0:
+        return 7
+    if val[0] == 0 and val[1] == 0 and val[2] == 1:
+        return 6
+    if val[0] == 0 and val[1] == 1 and val[2] == 0:
+        return 5
+    if val[0] == 0 and val[1] == 1 and val[2] == 1:
+        return 4
+    if val[0] == 1 and val[1] == 0 and val[2] == 0:
+        return 3
+    if val[0] == 1 and val[1] == 0 and val[2] == 1:
+        return 2
+    if val[0] == 1 and val[1] == 1 and val[2] == 0:
+        return 1
+    if val[0] == 1 and val[1] == 1 and val[2] == 1:
+        return 0
+
+
+def test_Mux8to1():
+    errors = []
+    mux = Mux8to1()
+    inputs = generate_inputs(8)
+    set_inputs = generate_inputs(3)
+
+    for val in inputs:
+        mux.set_input(0, val[7]).set_input(1, val[6]).set_input(2, val[5]).set_input(3, val[4]).set_input(4, val[3])\
+            .set_input(5, val[2]).set_input(6, val[1]).set_input(7, val[0])
+
+        for set_val in set_inputs:
+            mux.set_set(0, set_val[2]).set_set(1, set_val[1]).set_set(2, set_val[0])
+            expected = val[get_expected(set_val)]
+            output = mux.get_output()
+
+            if output != expected:
+                to_append = "{}".format(str(val[7])) + ", {}".format(str(val[6])) + ", {}".format(str(val[5])) + \
+                            ", {}".format(str(val[4])) + ", {}".format(str(val[3])) + ", {}".format(str(val[2])) + \
+                            ", {}".format(str(val[1])) + ", {}".format(str(val[0])) +\
+                            ", set signals {}".format(str(set_val[2])) + ", {}".format(str(set_val[1])) + \
+                            ", {}".format(str(set_val[0])) + \
+                            " test not passed!"
+                errors.append(to_append)
+
+    try:
+        mux.set_set(5, False)
+        errors.append("Not existing set input test not passed!")
+    except NonExistingControlSignal:
+        pass
+
+    try:
+        mux.set_set(0, 5)
+        errors.append("Not truth value to set test not passed!")
+    except NotTruthValue:
+        pass
+
+    try:
+        mux.set_input(16, False)
+        errors.append("Not existing input test not passed!")
+    except NonExistingInput:
+        pass
+
+    assert not errors, "errors occurred:\n{}".format("\n".join(errors))