diff --git a/DG_Approximation.py b/DG_Approximation.py
index 1b666e46acdec5474f362f0f3e3cc18f319ca9cd..b31aa5218ace8af33c000263ad08b5f3f06bc0f6 100644
--- a/DG_Approximation.py
+++ b/DG_Approximation.py
@@ -12,20 +12,21 @@ TODO: Combine initial projection and approx solution somehow
 TODO: Investigate why there are no weights in approx calc -> Ask
 TODO: Change order of methods
 TODO: Change code to not include self. but global variables; NO, do private \
-    or better protected instance variables instead
+    or better protected instance variables instead -> Done (all protected)
 TODO: Find better names for A, B, anything pertaining Gauss
 TODO: Write documentation for all methods
-TODO: Check whether consistency is given/possible for each class instance
+TODO: Check whether consistency is given/possible for each class instance -> Done (should be okay when protected)
 
 TODO: Contemplate moving A and B to Vectors_of_Polynomials
 TODO: Improve access to names of classes
 TODO: Check plots for NoDetection class -> Done (Adjusted scale of x-axis for shock tube)
 TODO: Ask about shock tubes (course mesh vs fine mesh)
-TODO: Check instance variables in DG_Approximation -> Done
+TODO: Check instance variables in DG_Approximation -> Done (do for all else)
 TODO: Improve saving of plots
 TODO: Extend color options
 TODO: Implement type check for all kwargs and configs
 TODO: Make sure that self.cfl_number is not changed -> Done
+TODO: Contemplate having a dict with a params and just getting the necessary ones
 
 """
 import numpy as np
@@ -50,24 +51,24 @@ xi = Symbol('z')
 class DGScheme(object):
     def __init__(self, detector, **kwargs):
         # Unpack keyword arguments
-        self.wave_speed = kwargs.pop('wave_speed', 1)
-        self.polynom_degree = kwargs.pop('polynom_degree', 2)
-        self.cfl_number = kwargs.pop('cfl_number', 0.2)
-        self.num_grid_cells = kwargs.pop('num_grid_cells', 64)
-        self.final_time = kwargs.pop('final_time', 1)
-        self.left_bound = kwargs.pop('left_bound', -1)
-        self.right_bound = kwargs.pop('right_bound', 1)
-        self.verbose = kwargs.pop('verbose', False)
-        self.history_threshold = kwargs.pop('history_threshold', math.ceil(0.2/self.cfl_number))
-        self.detector = detector
-        self.detector_config = kwargs.pop('detector_config', {})
-        self.init_cond = kwargs.pop('init_cond', 'Sine')
-        self.init_config = kwargs.pop('init_config', {})
-        self.limiter = kwargs.pop('limiter', 'ModifiedMinMod')
-        self.limiter_config = kwargs.pop('limiter_config', {})
-        self.quadrature = kwargs.pop('quadrature', 'Gauss')
-        self.quadrature_config = kwargs.pop('quadrature_config', {})
-        self.update_scheme = kwargs.pop('update_scheme', 'SSPRK3')
+        self._wave_speed = kwargs.pop('wave_speed', 1)
+        self._polynom_degree = kwargs.pop('polynom_degree', 2)
+        self._cfl_number = kwargs.pop('cfl_number', 0.2)
+        self._num_grid_cells = kwargs.pop('num_grid_cells', 64)
+        self._final_time = kwargs.pop('final_time', 1)
+        self._left_bound = kwargs.pop('left_bound', -1)
+        self._right_bound = kwargs.pop('right_bound', 1)
+        self._verbose = kwargs.pop('verbose', False)
+        self._history_threshold = kwargs.pop('history_threshold', math.ceil(0.2/self._cfl_number))
+        self._detector = detector
+        self._detector_config = kwargs.pop('detector_config', {})
+        self._init_cond = kwargs.pop('init_cond', 'Sine')
+        self._init_config = kwargs.pop('init_config', {})
+        self._limiter = kwargs.pop('limiter', 'ModifiedMinMod')
+        self._limiter_config = kwargs.pop('limiter_config', {})
+        self._quadrature = kwargs.pop('quadrature', 'Gauss')
+        self._quadrature_config = kwargs.pop('quadrature_config', {})
+        self._update_scheme = kwargs.pop('update_scheme', 'SSPRK3')
 
         # Throw an error if there are extra keyword arguments
         if len(kwargs) > 0:
@@ -75,35 +76,35 @@ class DGScheme(object):
             raise ValueError('Unrecognized arguments: %s' % extra)
 
         # Make sure all classes actually exist
-        if not hasattr(Troubled_Cell_Detector, self.detector):
-            raise ValueError('Invalid detector: "%s"' % self.detector)
-        if not hasattr(Initial_Condition, self.init_cond):
-            raise ValueError('Invalid initial condition: "%s"' % self.init_cond)
-        if not hasattr(Limiter, self.limiter):
-            raise ValueError('Invalid limiter: "%s"' % self.limiter)
-        if not hasattr(Quadrature, self.quadrature):
-            raise ValueError('Invalid quadrature: "%s"' % self.quadrature)
-        if not hasattr(Update_Scheme, self.update_scheme):
-            raise ValueError('Invalid update scheme: "%s"' % self.update_scheme)
+        if not hasattr(Troubled_Cell_Detector, self._detector):
+            raise ValueError('Invalid detector: "%s"' % self._detector)
+        if not hasattr(Initial_Condition, self._init_cond):
+            raise ValueError('Invalid initial condition: "%s"' % self._init_cond)
+        if not hasattr(Limiter, self._limiter):
+            raise ValueError('Invalid limiter: "%s"' % self._limiter)
+        if not hasattr(Quadrature, self._quadrature):
+            raise ValueError('Invalid quadrature: "%s"' % self._quadrature)
+        if not hasattr(Update_Scheme, self._update_scheme):
+            raise ValueError('Invalid update scheme: "%s"' % self._update_scheme)
 
         self._reset()
 
         # Replace the string names with the actual class instances
         # (and add the instance variables for the quadrature)
-        self.init_cond = getattr(Initial_Condition, self.init_cond)(self.left_bound, self.right_bound, self.init_config)
-        self.limiter = getattr(Limiter, self.limiter)(self.limiter_config)
-        self.quadrature = getattr(Quadrature, self.quadrature)(self.quadrature_config)
-        self.detector = getattr(Troubled_Cell_Detector, self.detector)(
-            self.detector_config, self.mesh, self.wave_speed, self.polynom_degree, self.num_grid_cells,
-            self.final_time, self.left_bound, self.right_bound, self.basis, self.init_cond, self.quadrature)
-        self.update_scheme = getattr(Update_Scheme, self.update_scheme)(
-            self.detector, self.limiter, self.init_cond, self.mesh, self.wave_speed, self.polynom_degree,
-            self.num_grid_cells, self.final_time, self.history_threshold, self.left_bound, self.right_bound)
-
-        # print(self.detector.get_name())
-        # print(self.detector.__class__.__name__)
+        self._init_cond = getattr(Initial_Condition, self._init_cond)(self._left_bound, self._right_bound, self._init_config)
+        self._limiter = getattr(Limiter, self._limiter)(self._limiter_config)
+        self._quadrature = getattr(Quadrature, self._quadrature)(self._quadrature_config)
+        self._detector = getattr(Troubled_Cell_Detector, self._detector)(
+            self._detector_config, self._mesh, self._wave_speed, self._polynom_degree, self._num_grid_cells,
+            self._final_time, self._left_bound, self._right_bound, self._basis, self._init_cond, self._quadrature)
+        self._update_scheme = getattr(Update_Scheme, self._update_scheme)(
+            self._detector, self._limiter, self._init_cond, self._mesh, self._wave_speed, self._polynom_degree,
+            self._num_grid_cells, self._final_time, self._history_threshold, self._left_bound, self._right_bound)
+
+        # print(self._detector.get_name())
+        # print(self._detector.__class__.__name__)
         # print(Troubled_Cell_Detector.Boxplot.__bases__)
-        # print(self.detector.__class__)
+        # print(self._detector.__class__)
         # print(Troubled_Cell_Detector.WaveletDetector in Troubled_Cell_Detector.Boxplot.__mro__)
 
     def approximate(self):
@@ -115,41 +116,41 @@ class DGScheme(object):
 
         projection = self._do_initial_projection()
 
-        time_step = abs(self.cfl_number * self.cell_len / self.wave_speed)
+        time_step = abs(self._cfl_number * self._cell_len / self._wave_speed)
 
         current_time = 0
         iteration = 0
         troubled_cell_history = []
         time_history = []
-        while current_time < self.final_time:
+        while current_time < self._final_time:
             # Adjust for last cell
-            cfl_number = self.cfl_number
-            if current_time+time_step > self.final_time:
-                time_step = self.final_time-current_time
-                cfl_number = self.wave_speed * time_step / self.num_grid_cells
+            cfl_number = self._cfl_number
+            if current_time+time_step > self._final_time:
+                time_step = self._final_time-current_time
+                cfl_number = self._wave_speed * time_step / self._num_grid_cells
 
             # Update projection
-            projection, troubled_cells = self.update_scheme.step(projection, cfl_number, current_time)
+            projection, troubled_cells = self._update_scheme.step(projection, cfl_number, current_time)
 
             iteration += 1
 
-            if (iteration % self.history_threshold) == 0:
+            if (iteration % self._history_threshold) == 0:
                 troubled_cell_history.append(troubled_cells)
                 time_history.append(current_time)
 
             current_time += time_step
 
         # Plot exact/approximate results, errors, shock tubes and any detector-dependant plots
-        self.detector.plot_results(projection, troubled_cell_history, time_history, 'k-', 'y')
+        self._detector.plot_results(projection, troubled_cell_history, time_history, 'k-', 'y')
 
-        if self.verbose:
+        if self._verbose:
             plt.show()
 
     def save_plots(self):
-        name = self.init_cond.get_name() + '__' + self.detector.get_name() + '__' + self.limiter.get_name() \
-            + '__' + self.update_scheme.get_name() + '__' + self.quadrature.get_name() + '__final_time_' \
-            + str(self.final_time) + '__wave_speed_' + str(self.wave_speed) + '__number_of_cells_' \
-            + str(self.num_grid_cells) + '__polynomial_degree_' + str(self.polynom_degree)
+        name = self._init_cond.get_name() + '__' + self._detector.get_name() + '__' + self._limiter.get_name() \
+            + '__' + self._update_scheme.get_name() + '__' + self._quadrature.get_name() + '__final_time_' \
+            + str(self._final_time) + '__wave_speed_' + str(self._wave_speed) + '__number_of_cells_' \
+            + str(self._num_grid_cells) + '__polynomial_degree_' + str(self._polynom_degree)
 
         save_fig_1 = True
         if save_fig_1:
@@ -198,50 +199,50 @@ class DGScheme(object):
             os.makedirs('testfig/shock_tube')
 
         # Set additional necessary instance variables
-        self.interval_len = self.right_bound-self.left_bound
-        self.cell_len = self.interval_len / self.num_grid_cells
-        self.basis = OrthonormalLegendre(self.polynom_degree).get_vector(x)
+        self._interval_len = self._right_bound-self._left_bound
+        self._cell_len = self._interval_len / self._num_grid_cells
+        self._basis = OrthonormalLegendre(self._polynom_degree).get_vector(x)
 
         # Set additional necessary config parameters
-        self.limiter_config['cell_len'] = self.cell_len
+        self._limiter_config['cell_len'] = self._cell_len
 
         # Set mesh with one ghost point on each side
-        self.mesh = np.arange(self.left_bound - (3/2*self.cell_len), self.right_bound + (5/2*self.cell_len),
-                              self.cell_len)  # +3/2
+        self._mesh = np.arange(self._left_bound - (3/2*self._cell_len), self._right_bound + (5/2*self._cell_len),
+                              self._cell_len)  # +3/2
 
         # Set inverse mass matrix
         mass_matrix = []
-        for i in range(self.polynom_degree+1):
+        for i in range(self._polynom_degree+1):
             new_row = []
-            for j in range(self.polynom_degree+1):
+            for j in range(self._polynom_degree+1):
                 new_entry = 0.0
                 if i == j:
                     new_entry = 1.0
                 new_row.append(new_entry)
             mass_matrix.append(new_row)
-        self.inv_mass = np.array(mass_matrix)
+        self._inv_mass = np.array(mass_matrix)
 
     def _do_initial_projection(self):
         # Initialize matrix and set first entry to accommodate for ghost cell
         output_matrix = [0]
 
-        for cell in range(self.num_grid_cells):
+        for cell in range(self._num_grid_cells):
             new_row = []
-            eval_point = self.left_bound + (cell+0.5)*self.cell_len
-
-            for degree in range(self.polynom_degree + 1):
-                new_entry = sum(self.init_cond.calculate(eval_point
-                                                         + self.cell_len/2 * self.quadrature.get_eval_points()[point])
-                                * self.basis[degree].subs(x, self.quadrature.get_eval_points()[point])
-                                * self.quadrature.get_weights()[point]
-                                for point in range(self.quadrature.get_num_points()))
+            eval_point = self._left_bound + (cell+0.5)*self._cell_len
+
+            for degree in range(self._polynom_degree + 1):
+                new_entry = sum(self._init_cond.calculate(eval_point
+                                                         + self._cell_len/2 * self._quadrature.get_eval_points()[point])
+                                * self._basis[degree].subs(x, self._quadrature.get_eval_points()[point])
+                                * self._quadrature.get_weights()[point]
+                                for point in range(self._quadrature.get_num_points()))
                 new_row.append(np.float64(new_entry))
 
             new_row = np.array(new_row)
-            output_matrix.append(self.inv_mass @ new_row)
+            output_matrix.append(self._inv_mass @ new_row)
 
         # Set ghost cells to respective value
-        output_matrix[0] = output_matrix[self.num_grid_cells]
+        output_matrix[0] = output_matrix[self._num_grid_cells]
         output_matrix.append(output_matrix[1])
 
         print(np.array(output_matrix).shape)
diff --git a/Initial_Condition.py b/Initial_Condition.py
index 04c80c8fb7f1826c350046ba696f0b41678461fd..834f8fe5ac7cca0ccdef6c075a1671c1473bec45 100644
--- a/Initial_Condition.py
+++ b/Initial_Condition.py
@@ -8,9 +8,9 @@ import numpy as np
 
 class InitialCondition(object):
     def __init__(self, left_bound, right_bound, config):
-        self.left_bound = left_bound
-        self.right_bound = right_bound
-        self.interval_len = self.right_bound-self.left_bound
+        self._left_bound = left_bound
+        self._right_bound = right_bound
+        self._interval_len = self._right_bound-self._left_bound
 
         self.function_name = 'None'
 
@@ -18,10 +18,10 @@ class InitialCondition(object):
         return self.function_name
 
     def calculate(self, x):
-        while x < self.left_bound:
-            x = x + self.interval_len
-        while x > self.right_bound:
-            x = x - self.interval_len
+        while x < self._left_bound:
+            x = x + self._interval_len
+        while x > self._right_bound:
+            x = x - self._interval_len
         return self._get_point(x)
 
     def _get_point(self, x):
@@ -36,10 +36,10 @@ class Sine(InitialCondition):
         self.function_name = 'Sine'
 
         # Unpack necessary configurations
-        self.factor = config.pop('factor', 2)
+        self._factor = config.pop('factor', 2)
 
     def _get_point(self, x):
-        return np.sin(self.factor * np.pi * x)
+        return np.sin(self._factor * np.pi * x)
 
 
 class Box(InitialCondition):
@@ -68,28 +68,28 @@ class FourPeakWave(InitialCondition):
         self.function_name = 'FourPeakWave'
 
         # Set additional necessary parameter
-        self.alpha = 10
-        self.delta = 0.005
-        self.beta = np.log(2) / (36 * self.delta**2)
-        self.a = 0.5
-        self.z = -0.7
+        self._alpha = 10
+        self._delta = 0.005
+        self._beta = np.log(2) / (36 * self._delta**2)
+        self._a = 0.5
+        self._z = -0.7
 
     def _get_point(self, x):
         if (x >= -0.8) & (x <= -0.6):
-            return 1/6 * (self._G(x, self.z-self.delta) + self._G(x, self.z+self.delta) + 4 * self._G(x, self.z))
+            return 1/6 * (self._G(x, self._z-self._delta) + self._G(x, self._z+self._delta) + 4 * self._G(x, self._z))
         if (x >= -0.4) & (x <= -0.2):
             return 1
         if (x >= 0) & (x <= 0.2):
             return 1 - abs(10 * (x-0.1))
         if (x >= 0.4) & (x <= 0.6):
-            return 1/6 * (self._F(x, self.a-self.delta) + self._F(x, self.a+self.delta) + 4 * self._F(x, self.a))
+            return 1/6 * (self._F(x, self._a-self._delta) + self._F(x, self._a+self._delta) + 4 * self._F(x, self._a))
         return 0
 
     def _G(self, x, z):
-        return np.exp(-self.beta * (x-z)**2)
+        return np.exp(-self._beta * (x-z)**2)
 
     def _F(self, x, a):
-        return np.sqrt(max(1 - self.alpha**2 * (x-a)**2, 0))
+        return np.sqrt(max(1 - self._alpha**2 * (x-a)**2, 0))
 
 
 class Linear(InitialCondition):
@@ -100,10 +100,10 @@ class Linear(InitialCondition):
         self.function_name = 'Linear'
 
         # Unpack necessary configurations
-        self.factor = config.pop('factor', 1)
+        self._factor = config.pop('factor', 1)
 
     def _get_point(self, x):
-        return self.factor * x
+        return self._factor * x
 
 
 class LinearAbsolut(InitialCondition):
@@ -114,10 +114,10 @@ class LinearAbsolut(InitialCondition):
         self.function_name = 'LinearAbsolut'
 
         # Unpack necessary configurations
-        self.factor = config.pop('factor', 1)
+        self._factor = config.pop('factor', 1)
 
     def _get_point(self, x):
-        return self.factor * abs(x)
+        return self._factor * abs(x)
 
 
 class DiscontinuousConstant(InitialCondition):
@@ -128,9 +128,9 @@ class DiscontinuousConstant(InitialCondition):
         self.function_name = 'DiscontinuousConstant'
 
         # Unpack necessary configurations
-        self.x0 = config.pop('x0', 0)
-        self.left_factor = config.pop('left_factor', 1)
-        self.right_factor = config.pop('right_factor', 0.5)
+        self._x0 = config.pop('x0', 0)
+        self._left_factor = config.pop('left_factor', 1)
+        self._right_factor = config.pop('right_factor', 0.5)
 
     def _get_point(self, x):
-        return self.left_factor * (x <= self.x0) + self.right_factor * (x > self.x0)
+        return self._left_factor * (x <= self._x0) + self._right_factor * (x > self._x0)
diff --git a/Limiter.py b/Limiter.py
index a5033e70fb44d3cb9a519fb8f90ed8a1db3b0e9a..bedb510b0bbc06b311de3e317e71e7214ed98ee9 100644
--- a/Limiter.py
+++ b/Limiter.py
@@ -32,10 +32,10 @@ class MinMod(Limiter):
         super().__init__(config)
 
         # Unpack necessary configurations
-        self.erase_degree = config.pop('erase_degree', 0)
+        self._erase_degree = config.pop('erase_degree', 0)
 
         # Set name of function
-        self.function_name = 'MinMod' + str(self.erase_degree)
+        self.function_name = 'MinMod' + str(self._erase_degree)
 
     def apply(self, projection, cell):
         cell_slope = self._set_cell_slope(projection, cell)
@@ -46,7 +46,7 @@ class MinMod(Limiter):
 
         adapted_projection = projection[:, cell].copy()
         for i in range(len(adapted_projection)):
-            if i > self.erase_degree:
+            if i > self._erase_degree:
                 adapted_projection[i] = 0
         return adapted_projection
 
@@ -72,16 +72,16 @@ class ModifiedMinMod(MinMod):
         super().__init__(config)
 
         # Unpack necessary configurations
-        self.cell_len = config.pop('cell_len')
-        self.mod_factor = config.pop('mod_factor', 0)
+        self._cell_len = config.pop('cell_len')
+        self._mod_factor = config.pop('mod_factor', 0)
 
         # Set name of function
-        self.function_name = 'ModifiedMinMod' + str(self.erase_degree)
+        self.function_name = 'ModifiedMinMod' + str(self._erase_degree)
 
-        self.cell = 0
+        self._cell = 0
 
     def _determine_modification(self, projection, cell, cell_slope):
-        if abs(cell_slope) <= self.mod_factor*self.cell_len**2:
+        if abs(cell_slope) <= self._mod_factor*self._cell_len**2:
             return True
 
         return super()._determine_modification(projection, cell, cell_slope)
diff --git a/Quadrature.py b/Quadrature.py
index f7c6b19e818d1beecb065b32e77ef47054a7b48a..9cf793eb396922a201243db614f993bb58055d04 100644
--- a/Quadrature.py
+++ b/Quadrature.py
@@ -9,21 +9,21 @@ import numpy.polynomial.legendre as leg
 class Quadrature(object):
     def __init__(self, config):
         self.function_name = 'None'
-        self.eval_points = None
-        self.weights = None
-        self.num_eval_points = None
+        self._eval_points = None
+        self._weights = None
+        self._num_eval_points = None
 
     def get_name(self):
         return self.function_name
 
     def get_eval_points(self):
-        return self.eval_points
+        return self._eval_points
 
     def get_weights(self):
-        return self.weights
+        return self._weights
 
     def get_num_points(self):
-        return self.num_eval_points
+        return self._num_eval_points
 
 
 class Gauss(Quadrature):
@@ -31,9 +31,9 @@ class Gauss(Quadrature):
         super().__init__(config)
 
         # Unpack necessary configurations
-        self.num_eval_points = config.pop('num_eval_points', 6)
+        self._num_eval_points = config.pop('num_eval_points', 6)
 
-        self.eval_points, self.weights = leg.leggauss(self.num_eval_points)
+        self._eval_points, self._weights = leg.leggauss(self._num_eval_points)
 
         # Set name of function
-        self.function_name = 'Gauss' + str(self.num_eval_points)
+        self.function_name = 'Gauss' + str(self._num_eval_points)
diff --git a/Troubled_Cell_Detector.py b/Troubled_Cell_Detector.py
index 1c210b9d8b6be3fff66398902a0ef18e8b5509d6..327e24b97dfd0e17220e5415418d7c6135427612 100644
--- a/Troubled_Cell_Detector.py
+++ b/Troubled_Cell_Detector.py
@@ -19,18 +19,18 @@ xi = Symbol('z')
 class TroubledCellDetector(object):
     def __init__(self, config, mesh, wave_speed, polynom_degree, num_grid_cells, final_time, left_bound, right_bound,
                  basis, init_cond, quadrature):
-        self.mesh = mesh
-        self.wave_speed = wave_speed
-        self.polynom_degree = polynom_degree
-        self.num_grid_cells = num_grid_cells
-        self.final_time = final_time
-        self.left_bound = left_bound
-        self.right_bound = right_bound
-        self.interval_len = right_bound - left_bound
-        self.cell_len = self.interval_len / num_grid_cells
-        self.basis = basis
-        self.init_cond = init_cond
-        self.quadrature = quadrature
+        self._mesh = mesh
+        self._wave_speed = wave_speed
+        self._polynom_degree = polynom_degree
+        self._num_grid_cells = num_grid_cells
+        self._final_time = final_time
+        self._left_bound = left_bound
+        self._right_bound = right_bound
+        self._interval_len = right_bound - left_bound
+        self._cell_len = self._interval_len / num_grid_cells
+        self._basis = basis
+        self._init_cond = init_cond
+        self._quadrature = quadrature
         self.function_name = 'None'
 
     def get_name(self):
@@ -43,12 +43,12 @@ class TroubledCellDetector(object):
         self._plot_shock_tube(troubled_cell_history, time_history)
         max_error = self._plot_mesh(projection, color_exact, color_approx)
 
-        print("p =", self.polynom_degree)
-        print("N =", self.num_grid_cells)
+        print("p =", self._polynom_degree)
+        print("N =", self._num_grid_cells)
         print("maximum error =", max_error)
 
     def _plot_mesh(self, projection, color_exact, color_approx):
-        grid, exact = self._calculate_exact_solution(self.mesh[2:-2], self.cell_len)
+        grid, exact = self._calculate_exact_solution(self._mesh[2:-2], self._cell_len)
         approx = self._calculate_approximate_solution(projection[:, 1:-1])
 
         pointwise_error = np.abs(exact-approx)
@@ -90,7 +90,7 @@ class TroubledCellDetector(object):
             current_cells = troubled_cell_history[pos]
             for cell in current_cells:
                 plt.plot(cell, time_history[pos], 'k.')
-        plt.xlim((0, self.num_grid_cells//2))
+        plt.xlim((0, self._num_grid_cells//2))
         plt.xlabel('Cell')
         plt.ylabel('Time')
         plt.title('Shock Tubes')
@@ -98,15 +98,15 @@ class TroubledCellDetector(object):
     def _calculate_exact_solution(self, mesh, cell_len):
         grid = []
         exact = []
-        num_periods = np.floor(self.wave_speed * self.final_time / self.interval_len)
+        num_periods = np.floor(self._wave_speed * self._final_time / self._interval_len)
 
         for cell in range(len(mesh)):
-            eval_points = mesh[cell] + cell_len/2 * self.quadrature.get_eval_points()
+            eval_points = mesh[cell] + cell_len/2 * self._quadrature.get_eval_points()
 
             eval_values = []
             for point in range(len(eval_points)):
-                new_entry = self.init_cond.calculate(eval_points[point] - self.wave_speed*self.final_time
-                                                     + num_periods*self.interval_len)
+                new_entry = self._init_cond.calculate(eval_points[point] - self._wave_speed*self._final_time
+                                                     + num_periods*self._interval_len)
                 eval_values.append(new_entry)
 
             grid.append(eval_points)
@@ -118,15 +118,15 @@ class TroubledCellDetector(object):
         return grid, exact
 
     def _calculate_approximate_solution(self, projection):
-        points = self.quadrature.get_eval_points()
-        num_points = self.quadrature.get_num_points()
-        basis = self.basis
+        points = self._quadrature.get_eval_points()
+        num_points = self._quadrature.get_num_points()
+        basis = self._basis
 
         basis_matrix = [[basis[degree].subs(x, points[point]) for point in range(num_points)]
-                        for degree in range(self.polynom_degree+1)]
+                        for degree in range(self._polynom_degree+1)]
 
         approx = [[sum(projection[degree][cell] * basis_matrix[degree][point]
-                       for degree in range(self.polynom_degree+1))
+                       for degree in range(self._polynom_degree+1))
                    for point in range(num_points)]
                   for cell in range(len(projection[0]))]
 
@@ -153,23 +153,23 @@ class WaveletDetector(TroubledCellDetector):
                          basis, init_cond, quadrature)
 
         # Set fixed basis and wavelet vectors
-        self.basis = OrthonormalLegendre(self.polynom_degree).get_vector(x)
-        self.wavelet = AlpertsWavelet(self.polynom_degree).get_vector(x)
+        self._basis = OrthonormalLegendre(self._polynom_degree).get_vector(x)
+        self._wavelet = AlpertsWavelet(self._polynom_degree).get_vector(x)
 
         # Set additional necessary parameter
-        self.num_coarse_grid_cells = self.num_grid_cells//2
-        self.M1 = self._set_multiwavelet_matrix(xi, -0.5*(xi-1), True)
-        self.M2 = self._set_multiwavelet_matrix(xi, 0.5*(xi+1), False)
+        self._num_coarse_grid_cells = self._num_grid_cells//2
+        self._M1 = self._set_multiwavelet_matrix(xi, -0.5*(xi-1), True)
+        self._M2 = self._set_multiwavelet_matrix(xi, 0.5*(xi+1), False)
 
     def _set_multiwavelet_matrix(self, first_param, second_param, is_M1):
         matrix = []
-        for i in range(self.polynom_degree+1):
+        for i in range(self._polynom_degree+1):
             row = []
-            for j in range(self.polynom_degree+1):
-                entry = integrate(self.basis[i].subs(x, first_param) * self.wavelet[j].subs(x, second_param),
+            for j in range(self._polynom_degree+1):
+                entry = integrate(self._basis[i].subs(x, first_param) * self._wavelet[j].subs(x, second_param),
                                   (xi, -1, 1))
                 if is_M1:
-                    entry = entry * (-1)**(j + self.polynom_degree + 1)
+                    entry = entry * (-1)**(j + self._polynom_degree + 1)
                 row.append(np.float64(entry))
             matrix.append(row)
         return matrix
@@ -183,8 +183,8 @@ class WaveletDetector(TroubledCellDetector):
 
     def _calculate_wavelet_coeffs(self, projection):
         output_matrix = []
-        for i in range(self.num_coarse_grid_cells):
-            new_entry = 0.5*(projection[:, 2*i] @ self.M1 + projection[:, 2*i+1] @ self.M2)
+        for i in range(self._num_coarse_grid_cells):
+            new_entry = 0.5*(projection[:, 2*i] @ self._M1 + projection[:, 2*i+1] @ self._M2)
             output_matrix.append(new_entry)
         return np.transpose(np.array(output_matrix))
 
@@ -193,7 +193,7 @@ class WaveletDetector(TroubledCellDetector):
         super().plot_results(projection, troubled_cell_history, time_history, color_exact, color_approx)
 
     def _plot_mesh(self, projection, color_exact, color_approx):
-        grid, exact = self._calculate_exact_solution(self.mesh[2:-2], self.cell_len)
+        grid, exact = self._calculate_exact_solution(self._mesh[2:-2], self._cell_len)
         approx = self._calculate_approximate_solution(projection[:, 1:-1])
 
         pointwise_error = np.abs(exact-approx)
@@ -208,8 +208,8 @@ class WaveletDetector(TroubledCellDetector):
         return max_error
 
     def _plot_coarse_mesh(self, projection, color_exact, color_approx):
-        coarse_cell_len = 2*self.cell_len
-        coarse_mesh = np.arange(self.left_bound - (0.5*coarse_cell_len), self.right_bound + (1.5*coarse_cell_len),
+        coarse_cell_len = 2*self._cell_len
+        coarse_mesh = np.arange(self._left_bound - (0.5*coarse_cell_len), self._right_bound + (1.5*coarse_cell_len),
                                 coarse_cell_len)
 
         coarse_projection = self._calculate_coarse_projection(projection)
@@ -220,12 +220,12 @@ class WaveletDetector(TroubledCellDetector):
         self._plot_solution_and_approx(grid, exact, approx, color_exact, color_approx)
 
     def _plot_details(self, projection):
-        fine_mesh = self.mesh[2:-2]
+        fine_mesh = self._mesh[2:-2]
 
         fine_projection = projection[:, 1:-1]
         coarse_projection = self._calculate_coarse_projection(projection)
         multiwavelet_coeffs = self._calculate_wavelet_coeffs(projection)
-        wavelet = AlpertsWavelet(self.polynom_degree).get_vector(xi)
+        wavelet = AlpertsWavelet(self._polynom_degree).get_vector(xi)
 
 ########################################################################################################################
         # For later consideration
@@ -233,11 +233,11 @@ class WaveletDetector(TroubledCellDetector):
         # tic = timeit.default_timer()
         # averaged_projection1 = []
         # wavelet_projection1 = []
-        # for degree in range(self.polynom_degree + 1):
-        #     leftMesh = coarse_projection[degree] * self.basis[degree].subs(x, -1 / 2)
-        #     rightMesh = coarse_projection[degree] * self.basis[degree].subs(x, 1 / 2)
+        # for degree in range(self._polynom_degree + 1):
+        #     leftMesh = coarse_projection[degree] * self._basis[degree].subs(x, -1 / 2)
+        #     rightMesh = coarse_projection[degree] * self._basis[degree].subs(x, 1 / 2)
         #     leftTest = multiwavelet_coeffs[degree] * wavelet[degree].subs(xi, 1 / 2) \
-        #                * (-1)**(self.polynom_degree + 1 + degree)
+        #                * (-1)**(self._polynom_degree + 1 + degree)
         #     rightTest = multiwavelet_coeffs[degree] * wavelet[degree].subs(xi, 1 / 2)
         #     newRowMesh = []
         #     newRowTest = []
@@ -253,15 +253,15 @@ class WaveletDetector(TroubledCellDetector):
 ########################################################################################################################
 
         # tic = timeit.default_timer()
-        averaged_projection = [[coarse_projection[degree][cell] * self.basis[degree].subs(x, value)
-                                for cell in range(self.num_coarse_grid_cells)
+        averaged_projection = [[coarse_projection[degree][cell] * self._basis[degree].subs(x, value)
+                                for cell in range(self._num_coarse_grid_cells)
                                 for value in [-0.5, 0.5]]
-                               for degree in range(self.polynom_degree + 1)]
+                               for degree in range(self._polynom_degree + 1)]
 
         wavelet_projection = [[multiwavelet_coeffs[degree][cell] * wavelet[degree].subs(xi, 0.5) * value
-                               for cell in range(self.num_coarse_grid_cells)
-                               for value in [(-1) ** (self.polynom_degree + degree + 1), 1]]
-                              for degree in range(self.polynom_degree + 1)]
+                               for cell in range(self._num_coarse_grid_cells)
+                               for value in [(-1) ** (self._polynom_degree + degree + 1), 1]]
+                              for degree in range(self._polynom_degree + 1)]
         # toc = timeit.default_timer()
         # print("List:", toc-tic)
 
@@ -269,8 +269,8 @@ class WaveletDetector(TroubledCellDetector):
         # print(wavelet_projection1 == wavelet_projection)
 
         projected_coarse = np.sum(averaged_projection, axis=0)
-        projected_fine = np.sum([fine_projection[degree] * self.basis[degree].subs(x, 0)
-                                 for degree in range(self.polynom_degree + 1)], axis=0)
+        projected_fine = np.sum([fine_projection[degree] * self._basis[degree].subs(x, 0)
+                                 for degree in range(self._polynom_degree + 1)], axis=0)
         projected_wavelet_coeffs = np.sum(wavelet_projection, axis=0)
 
         plt.figure(4)
@@ -290,7 +290,7 @@ class WaveletDetector(TroubledCellDetector):
 
         # Calculate projection on coarse mesh
         output_matrix = []
-        for i in range(self.num_coarse_grid_cells):
+        for i in range(self._num_coarse_grid_cells):
             new_entry = 0.5*(projection[:, 2*i] @ basis_matrix_left + projection[:, 2*i+1] @ basis_matrix_right)
             output_matrix.append(new_entry)
         coarse_projection = np.transpose(np.array(output_matrix))
@@ -299,10 +299,10 @@ class WaveletDetector(TroubledCellDetector):
 
     def _set_basis_matrix(self, first_param, second_param):
         matrix = []
-        for i in range(self.polynom_degree+1):
+        for i in range(self._polynom_degree+1):
             row = []
-            for j in range(self.polynom_degree+1):
-                entry = integrate(self.basis[i].subs(x, first_param) * self.basis[j].subs(x, second_param), (xi, -1, 1))
+            for j in range(self._polynom_degree+1):
+                entry = integrate(self._basis[i].subs(x, first_param) * self._basis[j].subs(x, second_param), (xi, -1, 1))
                 row.append(np.float64(entry))
             matrix.append(row)
         return matrix
@@ -319,15 +319,15 @@ class Boxplot(WaveletDetector):
 
         # Unpack necessary configurations
         self.fold_len = config.pop('fold_len', 16)
-        self.whisker_len = config.pop('whisker_len', 3)
+        self._whisker_len = config.pop('whisker_len', 3)
 
     def _get_cells(self, multiwavelet_coeffs, projection):
-        indexed_coeffs = [[multiwavelet_coeffs[0, i], i]for i in range(self.num_coarse_grid_cells)]
+        indexed_coeffs = [[multiwavelet_coeffs[0, i], i]for i in range(self._num_coarse_grid_cells)]
 
-        if self.num_coarse_grid_cells < self.fold_len:
-            self.fold_len = self.num_coarse_grid_cells
+        if self._num_coarse_grid_cells < self.fold_len:
+            self.fold_len = self._num_coarse_grid_cells
 
-        num_folds = self.num_coarse_grid_cells//self.fold_len
+        num_folds = self._num_coarse_grid_cells//self.fold_len
         troubled_cells = []
 
         for fold in range(num_folds):
@@ -341,8 +341,8 @@ class Boxplot(WaveletDetector):
             third_quartile = (1-balance_factor) * sorted_fold[3*boundary_index-1][0]\
                 + balance_factor * sorted_fold[3*boundary_index][0]
 
-            lower_bound = first_quartile - self.whisker_len * (third_quartile-first_quartile)
-            upper_bound = third_quartile + self.whisker_len * (third_quartile-first_quartile)
+            lower_bound = first_quartile - self._whisker_len * (third_quartile-first_quartile)
+            upper_bound = third_quartile + self._whisker_len * (third_quartile-first_quartile)
 
             # Check for lower extreme outliers and add respective cells
             for cell in sorted_fold:
@@ -371,14 +371,14 @@ class Theoretical(WaveletDetector):
         self.function_name = 'Theoretical'
 
         # Unpack necessary configurations
-        self.cutoff_factor = config.pop('cutoff_factor', np.sqrt(2) * self.cell_len)
+        self._cutoff_factor = config.pop('cutoff_factor', np.sqrt(2) * self._cell_len)
         # comment to line above: or 2 or 3
 
     def _get_cells(self, multiwavelet_coeffs, projection):
         troubled_cells = []
-        max_avg = max(1, max(abs(projection[0][degree]) for degree in range(self.polynom_degree+1)))
+        max_avg = max(1, max(abs(projection[0][degree]) for degree in range(self._polynom_degree+1)))
 
-        for cell in range(self.num_coarse_grid_cells):
+        for cell in range(self._num_coarse_grid_cells):
             if self._is_troubled_cell(multiwavelet_coeffs, cell, max_avg):
                 troubled_cells.append(cell)
 
@@ -386,7 +386,7 @@ class Theoretical(WaveletDetector):
 
     def _is_troubled_cell(self, multiwavelet_coeffs, cell, max_avg):
         max_value = max(abs(multiwavelet_coeffs[degree][cell])
-                        for degree in range(self.polynom_degree+1))/max_avg
-        eps = self.cutoff_factor / (self.cell_len*self.num_coarse_grid_cells*2)
+                        for degree in range(self._polynom_degree+1))/max_avg
+        eps = self._cutoff_factor / (self._cell_len*self._num_coarse_grid_cells*2)
 
         return max_value > eps
diff --git a/Update_Scheme.py b/Update_Scheme.py
index 5510ed114bb2a1239532f07f6c13bc7beb7cee8d..599550e7e2e45dc384b768a91a2412f8fd2342e4 100644
--- a/Update_Scheme.py
+++ b/Update_Scheme.py
@@ -20,17 +20,17 @@ class UpdateScheme(object):
     def __init__(self, detector, limiter, init_cond, mesh, wave_speed, polynom_degree, num_grid_cells, final_time,
                  history_threshold, left_bound, right_bound):
         # Unpack positional arguments
-        self.detector = detector
-        self.limiter = limiter
-        self.init_cond = init_cond
-        self.mesh = mesh
-        self.wave_speed = wave_speed
-        self.polynom_degree = polynom_degree
-        self.num_grid_cells = num_grid_cells
-        self.final_time = final_time
-        self.history_threshold = history_threshold
-        self.left_bound = left_bound
-        self.right_bound = right_bound
+        self._detector = detector
+        self._limiter = limiter
+        self._init_cond = init_cond
+        self._mesh = mesh
+        self._wave_speed = wave_speed
+        self._polynom_degree = polynom_degree
+        self._num_grid_cells = num_grid_cells
+        self._final_time = final_time
+        self._history_threshold = history_threshold
+        self._left_bound = left_bound
+        self._right_bound = right_bound
 
         self._reset()
 
@@ -48,43 +48,43 @@ class UpdateScheme(object):
     def _reset(self):
         # Set additional necessary fixed instance variables
         self.name = 'None'
-        self.interval_len = self.right_bound-self.left_bound
-        self.cell_len = self.interval_len / self.num_grid_cells
+        self._interval_len = self._right_bound-self._left_bound
+        self._cell_len = self._interval_len / self._num_grid_cells
 
         # Set matrix A
         matrix = []
-        for i in range(self.polynom_degree+1):
+        for i in range(self._polynom_degree+1):
             new_row = []
-            for j in range(self.polynom_degree+1):
+            for j in range(self._polynom_degree+1):
                 new_entry = -1.0
                 if (j < i) & ((i+j) % 2 == 1):
                     new_entry = 1.0
                 new_row.append(new_entry*np.sqrt((i+0.5) * (j+0.5)))
             matrix.append(new_row)
-        self.A = np.array(matrix)  # former: inv_mass @ np.array(matrix)
+        self._A = np.array(matrix)  # former: inv_mass @ np.array(matrix)
 
         # Set matrix B
         matrix = []
-        for i in range(self.polynom_degree+1):
+        for i in range(self._polynom_degree+1):
             new_row = []
-            for j in range(self.polynom_degree+1):
+            for j in range(self._polynom_degree+1):
                 new_entry = np.sqrt((i+0.5) * (j+0.5)) * (-1.0)**i
                 new_row.append(new_entry)
             matrix.append(new_row)
-        self.B = np.array(matrix)  # former: inv_mass @ np.array(matrix)
+        self._B = np.array(matrix)  # former: inv_mass @ np.array(matrix)
 
     def _apply_limiter(self, current_projection):
-        troubled_cells = self.detector.get_cells(current_projection)
+        troubled_cells = self._detector.get_cells(current_projection)
 
         new_projection = current_projection.copy()
         for cell in troubled_cells:
-            new_projection[:,  cell] = self.limiter.apply(current_projection, cell)
+            new_projection[:,  cell] = self._limiter.apply(current_projection, cell)
 
         return new_projection, troubled_cells
 
     def _enforce_boundary_condition(self, current_projection):
-        current_projection[:, 0] = current_projection[:, self.num_grid_cells]
-        current_projection[:, self.num_grid_cells+1] = current_projection[:, 1]
+        current_projection[:, 0] = current_projection[:, self._num_grid_cells]
+        current_projection[:, self._num_grid_cells+1] = current_projection[:, 1]
         return current_projection
 
 
@@ -119,12 +119,12 @@ class SSPRK3(UpdateScheme):
         # Initialize vector and set first entry to accommodate for ghost cell
         right_hand_side = [0]
 
-        for j in range(self.num_grid_cells):
-            right_hand_side.append(2*(self.A @ current_projection[:, j+1]
-                                      + self.B @ current_projection[:, j]))
+        for j in range(self._num_grid_cells):
+            right_hand_side.append(2*(self._A @ current_projection[:, j+1]
+                                      + self._B @ current_projection[:, j]))
 
         # Set ghost cells to respective value
-        right_hand_side[0] = right_hand_side[self.num_grid_cells]
+        right_hand_side[0] = right_hand_side[self._num_grid_cells]
         right_hand_side.append(right_hand_side[1])
 
         return np.transpose(right_hand_side)
diff --git a/Vectors_of_Polynomials.py b/Vectors_of_Polynomials.py
index 07b597fbe3d53066a360fa9c4ef7037407313185..60bc2a7758129a5f4528a5314c9714e63a41af8a 100644
--- a/Vectors_of_Polynomials.py
+++ b/Vectors_of_Polynomials.py
@@ -8,7 +8,7 @@ import numpy as np
 
 class Vector(object):
     def __init__(self, polynom_degree):
-        self.polynom_degree = polynom_degree
+        self._polynom_degree = polynom_degree
 
     def get_vector(self, eval_points):
         pass
@@ -20,7 +20,7 @@ class Legendre(Vector):
 
     def _calculate_legendre_vector(self, eval_point):
         vector = []
-        for degree in range(self.polynom_degree+1):
+        for degree in range(self._polynom_degree+1):
             if degree == 0:
                 vector.append(1.0 + 0*eval_point)
             else:
@@ -35,12 +35,12 @@ class Legendre(Vector):
 class OrthonormalLegendre(Legendre):
     def get_vector(self, eval_point):
         leg_vector = self._calculate_legendre_vector(eval_point)
-        return [leg_vector[degree] * np.sqrt(degree+0.5) for degree in range(self.polynom_degree+1)]
+        return [leg_vector[degree] * np.sqrt(degree+0.5) for degree in range(self._polynom_degree+1)]
 
 
 class AlpertsWavelet(Vector):
     def get_vector(self, eval_point):
-        degree = self.polynom_degree
+        degree = self._polynom_degree
 
         if degree == 0:
             return [np.sqrt(0.5) + eval_point*0]