Index: src/sas/sasgui/perspectives/calculator/__init__.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/__init__.py	(revision 5a405bda2da663894b6b32ab94768a91d60525a4)
+++ src/sas/sasgui/perspectives/calculator/__init__.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -2,5 +2,5 @@
 import os
 from distutils.filelist import findall
-from calculator import *
+from .calculator import *
 N_DIR = 12
 def get_data_path(media):
Index: src/sas/sasgui/perspectives/calculator/calculator.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/calculator.py	(revision 61bfd3677b70fdddc3b49008cbc8a8713a2baaa2)
+++ src/sas/sasgui/perspectives/calculator/calculator.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -12,5 +12,8 @@
 ################################################################################
 
+import logging
+
 import wx
+
 from sas.sasgui.guiframe.plugin_base import PluginBase
 from sas.sasgui.perspectives.calculator.data_operator import DataOperatorWindow
@@ -26,5 +29,4 @@
 from sas.sasgui.perspectives.calculator.image_viewer import ImageView
 from sas.sasgui.perspectives.calculator.pyconsole import PyConsole
-import logging
 
 logger = logging.getLogger(__name__)
Index: src/sas/sasgui/perspectives/calculator/collimation_editor.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/collimation_editor.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sasgui/perspectives/calculator/collimation_editor.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -1,12 +1,15 @@
 """
 """
-import wx
 import sys
 from copy import deepcopy
+
+import wx
+
 from sas.sascalc.dataloader.loader import Loader
 from sas.sascalc.dataloader.data_info import Aperture, Collimation
-from aperture_editor import ApertureDialog
-
 from sas.sasgui.guiframe.utils import check_float
+
+from .aperture_editor import ApertureDialog
+
 _BOX_WIDTH = 60
 
Index: src/sas/sasgui/perspectives/calculator/data_editor.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/data_editor.py	(revision 235f514ba93b57fa63e44309f182acef0b98bb55)
+++ src/sas/sasgui/perspectives/calculator/data_editor.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -7,9 +7,11 @@
 from sas.sascalc.dataloader.loader import Loader
 from sas.sascalc.dataloader.data_info import Data2D
-from detector_editor import DetectorDialog
-from collimation_editor import CollimationDialog
-from console import ConsoleDialog
 
 from sas.sasgui.guiframe.events import StatusEvent
+
+from .detector_editor import DetectorDialog
+from .collimation_editor import CollimationDialog
+from .console import ConsoleDialog
+
 
 
@@ -397,5 +399,5 @@
         if data is None:
             return
-        from sample_editor import SampleDialog
+        from .sample_editor import SampleDialog
         dlg = SampleDialog(parent=self, sample=data.sample)
         dlg.set_manager(self)
@@ -409,5 +411,5 @@
         if data is None:
             return
-        from source_editor import SourceDialog
+        from .source_editor import SourceDialog
         dlg = SourceDialog(parent=self, source=data.source)
         dlg.set_manager(self)
@@ -426,5 +428,5 @@
         wlist = '|'.join(cards)
 
-        dlg = wx.FileDialog(self, "Choose a file", location, "", wlist, wx.OPEN)
+        dlg = wx.FileDialog(self, "Choose a file", location, "", wlist, wx.FD_OPEN)
         if dlg.ShowModal() == wx.ID_OK:
             path = dlg.GetPath()
@@ -527,5 +529,5 @@
         try:
             #Load data
-            from load_thread import DataReader
+            from .load_thread import DataReader
             ## If a thread is already started, stop it
             if self.reader is not None and self.reader.isrunning():
@@ -535,6 +537,6 @@
                                     updatefn=None)
             self.reader.queue()
-        except:
-            msg = "Data Editor: %s" % (sys.exc_value)
+        except Exception as exc:
+            msg = "Data Editor: %s" % exc
             load_error(msg)
             return
Index: src/sas/sasgui/perspectives/calculator/data_operator.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/data_operator.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sasgui/perspectives/calculator/data_operator.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -202,10 +202,9 @@
         else:
             text = name
-        state_list = self.get_datalist().values()
         name_list = []
-        for state in state_list:
+        for state in self.get_datalist().values():
             if state.data is None:
                 theory_list = state.get_theory()
-                theory, _ = theory_list.values()[0]
+                theory, _ = list(theory_list.values())[0]
                 d_name = str(theory.name)
             else:
@@ -393,9 +392,9 @@
         try:
             self.output = self.make_data_out(data1, data2)
-        except:
+        except Exception as exc:
             self._check_newname()
             self._set_textctrl_color(self.data1_cbox, 'pink')
             self._set_textctrl_color(self.data2_cbox, 'pink')
-            msg = "DataOperation: %s" % sys.exc_value
+            msg = "DataOperation: %s" % exc
             self.send_warnings(msg, 'error')
             self.output = None
@@ -411,5 +410,6 @@
         operator = self.operator_cbox.GetClientData(pos)
         try:
-            exec "output = data1 %s data2" % operator
+            output = eval("data1 %s data2" % operator,
+                          {"data1": data1, "data2": data2})
         except:
             raise
@@ -532,6 +532,5 @@
         self.data2_cbox.SetClientData(pos3, val)
         dnames = []
-        ids = self._data.keys()
-        for id in ids:
+        for id in self._data.keys():
             if id is not None:
                 if self._data[id].data is not None:
@@ -539,9 +538,9 @@
                 else:
                     theory_list = self._data[id].get_theory()
-                    theory, _ = theory_list.values()[0]
+                    theory, _ = list(theory_list.values())[0]
                     dnames.append(theory.name)
         ind = np.argsort(dnames)
         if len(ind) > 0:
-            val_list = np.array(self._data.values())[ind]
+            val_list = np.array(list(self._data.values()))[ind]
             for datastate in val_list:
                 data = datastate.data
@@ -588,11 +587,10 @@
         self.send_warnings('')
         self.data_namectr.SetBackgroundColour('white')
-        state_list = self.get_datalist().values()
         name = self.data_namectr.GetValue().strip()
         name_list = []
-        for state in state_list:
+        for state in self.get_datalist().values():
             if state.data is None:
                 theory_list = state.get_theory()
-                theory, _ = theory_list.values()[0]
+                theory, _ = list(theory_list.values())[0]
                 d_name = str(theory.name)
             else:
@@ -889,13 +887,12 @@
     def _onProperties(self, event):
         """
-        when clicking on Properties on context menu ,
-        The Property dialog is displayed
-        The user selects a transformation for x or y value and
-        a new plot is displayed
-        """
-        list = []
-        list = self.graph.returnPlottable()
-        if len(list.keys()) > 0:
-            first_item = list.keys()[0]
+        When clicking on Properties on context menu, the
+        Property dialog is displayed the user selects a
+        transformation for x or y value and a new plot is displayed
+        """
+        plottables = self.graph.returnPlottable()
+        if plottables:
+            # TODO: key order is random prior to py 3.7
+            first_item = list(plottables.keys())[0]
             if first_item.x != []:
                 from sas.sasgui.plottools.PropertyDialog import Properties
@@ -929,6 +926,4 @@
         and set the scale
         """
-        list = []
-        list = self.graph.returnPlottable()
         # Changing the scale might be incompatible with
         # currently displayed data (for instance, going
@@ -940,5 +935,5 @@
         _xscale = 'linear'
         _yscale = 'linear'
-        for item in list:
+        for item in self.graph.returnPlottable():
             item.setLabel(self.xLabel, self.yLabel)
             # control axis labels from the panel itself
Index: src/sas/sasgui/perspectives/calculator/density_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/density_panel.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sasgui/perspectives/calculator/density_panel.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -362,7 +362,7 @@
             self.molar_mass_ctl.SetValue(str(self._format_number(molar_mass)))
             self.output_ctl.SetValue(str(output))
-        except:
+        except Exception as exc:
             if self.base is not None:
-                msg = "Density/Volume Calculator: %s" % (sys.exc_value)
+                msg = "Density/Volume Calculator: %s" % exc
                 wx.PostEvent(self.base, StatusEvent(status=msg))
         if event is not None:
Index: src/sas/sasgui/perspectives/calculator/detector_editor.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/detector_editor.py	(revision a1b8fee73528559155793dd74cda07d0c32e9d72)
+++ src/sas/sasgui/perspectives/calculator/detector_editor.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -34,6 +34,6 @@
             self._do_layout()
             self.set_values()
-        except:
-            print("error", sys.exc_value)
+        except Exception as exc:
+            print("error", exc)
 
     def _define_structure(self):
Index: src/sas/sasgui/perspectives/calculator/gen_scatter_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/gen_scatter_panel.py	(revision 20fa5fe0c3e314a850432d5e463d03ceed3e453a)
+++ src/sas/sasgui/perspectives/calculator/gen_scatter_panel.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -228,7 +228,5 @@
         sizer.Add(unit_title, (iy, ix), (1, 1), \
                             wx.EXPAND | wx.ADJUST_MINSIZE, 0)
-        key_list = params.keys()
-        key_list.sort()
-        for param in key_list:
+        for param in sorted(params.keys()):
             iy += 1
             ix = 0
@@ -341,5 +339,4 @@
         ix = 0
         iy = 0
-        #key_list.sort()
         name = wx.StaticText(self, -1, 'No. of Qx (Qy) bins: ')
         sizer.Add(name, (iy, ix), (1, 1), \
@@ -509,5 +506,5 @@
         wildcard = '|'.join(wildcard)
         dlg = wx.FileDialog(self, "Choose a file", location,
-                            "", wildcard, wx.OPEN)
+                            "", wildcard, wx.FD_OPEN)
         if dlg.ShowModal() == wx.ID_OK:
             path = dlg.GetPath()
@@ -556,9 +553,9 @@
             self.reader.queue()
             #self.load_update()
-        except:
+        except Exception as exc:
             self.ext = None
             if self.parent.parent is None:
                 return
-            msg = "Generic SAS Calculator: %s" % (sys.exc_value)
+            msg = "Generic SAS Calculator: %s" % exc
             wx.PostEvent(self.parent.parent,
                           StatusEvent(status=msg, type='stop'))
@@ -774,6 +771,6 @@
             if output.pix_type == 'atom':
                 # Get atom names not in the list
-                a_names = [symb  for symb in pix_symbol \
-                           if symb not in color_dic.keys()]
+                a_names = [symb  for symb in pix_symbol
+                           if symb not in color_dic]
                 a_name = a_names[0]
                 for name in a_names:
@@ -898,6 +895,6 @@
             cal_out.queue()
 
-        except:
-            msg = "%s." % sys.exc_value
+        except Exception as exc:
+            msg = "%s." % exc
             status_type = 'stop'
             self._status_info(msg, status_type)
@@ -1344,6 +1341,6 @@
             self.sld_data.is_data = False
             self.sld_data.filename = "Default SLD Profile"
-        except:
-            msg = "OMF Panel: %s" % sys.exc_value
+        except Exception as exc:
+            msg = "OMF Panel: %s" % exc
             infor = 'Error'
             #logger.error(msg)
@@ -1441,14 +1438,9 @@
             raise
         sld_key_list = self._get_slds_key_list(omfdata)
-        # Dic is not sorted
-        key_list = [key for key in sld_key_list.keys()]
-        # Sort here
-        key_list.sort()
         is_data = self.sld_data.is_data
         sizer = wx.GridBagSizer(2, 3)
         ix = 0
         iy = -1
-        for key in key_list:
-            value = sld_key_list[key]
+        for key, value in sorted(sld_key_list.items()):
             iy += 1
             ix = 0
@@ -1485,5 +1477,5 @@
         ix = 0
         iy = -1
-        for key, value in key_list.iteritems():
+        for key, value in sorted(key_list.items()):
             iy += 1
             ix = 0
@@ -1520,6 +1512,5 @@
         ix = 0
         iy = -1
-        #key_list.sort()
-        for key, value in key_list.iteritems():
+        for key, value in sorted(key_list.items()):
             iy += 1
             ix = 0
Index: src/sas/sasgui/perspectives/calculator/image_viewer.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/image_viewer.py	(revision 412e9e8b8f844bae61656ffb2a2d0c1c53e6e8de)
+++ src/sas/sasgui/perspectives/calculator/image_viewer.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -95,12 +95,14 @@
         if location is None:
             location = os.getcwd()
-        wildcard="Images (*.bmp;*.gif;*jpeg,*jpg;*.png;*tif;*.tiff)|*bmp;\
-            *.gif; *.jpg; *.jpeg;*png;*.png;*.tif;*.tiff|"\
-            "Bitmap (*.bmp)|*.bmp|"\
-            "GIF (*.gif)|*.gif|"\
-            "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|"\
-            "PNG (*.png)|*.png|"\
-            "TIFF (*.tif;*.tiff)|*.tif;*tiff|"\
-            "All Files (*.*)|*.*|"
+        wildcard="|".join((
+            "Images (*.bmp;*.gif;*jpeg,*jpg;*.png;*tif;*.tiff)"
+                "|*bmp;*.gif;*.jpg;*.jpeg;*png;*.png;*.tif;*.tiff",
+            "Bitmap (*.bmp)|*.bmp",
+            "GIF (*.gif)|*.gif",
+            "JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg",
+            "PNG (*.png)|*.png",
+            "TIFF (*.tif;*.tiff)|*.tif;*tiff",
+            "All Files (*.*)|*.*",
+            ))
 
         dlg = wx.FileDialog(self.parent, "Image Viewer: Choose an image file",
Index: src/sas/sasgui/perspectives/calculator/kiessig_calculator_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/kiessig_calculator_panel.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sasgui/perspectives/calculator/kiessig_calculator_panel.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -12,10 +12,10 @@
 import sys
 
+from sas.sascalc.calculator.kiessig_calculator import KiessigThicknessCalculator
 from sas.sasgui.guiframe.panel_base import PanelBase
-from sas.sascalc.calculator.kiessig_calculator import KiessigThicknessCalculator
-from calculator_widgets import OutputTextCtrl
-from calculator_widgets import InputTextCtrl
 from sas.sasgui.perspectives.calculator import calculator_widgets as widget
 from sas.sasgui.guiframe.documentation_window import DocumentationWindow
+from .calculator_widgets import OutputTextCtrl
+from .calculator_widgets import InputTextCtrl
 
 _BOX_WIDTH = 77
Index: src/sas/sasgui/perspectives/calculator/model_editor.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/model_editor.py	(revision 9bf40e7da42d4112c3098b54d9c3b12081500c84)
+++ src/sas/sasgui/perspectives/calculator/model_editor.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -578,5 +578,5 @@
         self.base = base
         self.path = path
-        self.font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
+        self.font = wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT)
         self.font.SetPointSize(10)
         self.reader = None
@@ -781,5 +781,5 @@
             if item.count("_") < 1:
                 try:
-                    exec "float(math.%s)" % item
+                    exec("float(math.%s)" % item)
                     self.math_combo.Append(str(item))
                 except Exception:
Index: src/sas/sasgui/perspectives/calculator/resolcal_thread.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/resolcal_thread.py	(revision 20fa5fe0c3e314a850432d5e463d03ceed3e453a)
+++ src/sas/sasgui/perspectives/calculator/resolcal_thread.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -46,7 +46,7 @@
         executing computation
         """
-        self.image = map(self.func, self.qx, self.qy,
-                        self.qx_min, self.qx_max,
-                        self.qy_min, self.qy_max)[0]
+        self.image = list(map(self.func, self.qx, self.qy,
+                              self.qx_min, self.qx_max,
+                              self.qy_min, self.qy_max))[0]
         elapsed = time.time() - self.starttime
 
Index: src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py	(revision 1cf490b648906629e67d57ec00ad3cd52e08523f)
+++ src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -148,5 +148,5 @@
         # Custom sorting
         source_list = []
-        for key, _ in self.source_mass.iteritems():
+        for key, _ in self.source_mass.items():
             name_source = str(key)
             source_list.append(name_source)
@@ -667,4 +667,10 @@
         Execute the computation of resolution
         """
+        # Clone the event before CallAfter; the event seems
+        # to delete the event when it is done processing, so
+        # the original will not be available when the call
+        # after method starts.
+        if event is not None:
+            event = event.Clone()
         wx.CallAfter(self.on_compute_call, event)
 
@@ -753,5 +759,5 @@
             wx.MessageBox(msg, 'Warning')
             return
-            #raise ValueError, "Invalid Q Input..."
+            #raise ValueError("Invalid Q Input...")
 
         # Validate the q inputs
@@ -934,5 +940,5 @@
     def _sigma_strings(self):
         """
-        Recode sigmas as strins
+        Recode sigmas as strings
         """
         sigma_r = self.format_number(self.resolution.sigma_1)
@@ -1082,5 +1088,5 @@
                 msg = "The numbers must be one or two (separated by ',')..."
                 self._status_info(msg, 'stop')
-                raise RuntimeError, msg
+                raise RuntimeError(msg)
 
         return new_string
@@ -1099,6 +1105,6 @@
                 value = float(string_split[ind])
                 new_string.append(value)
-            except:
-                logger.error(sys.exc_value)
+            except Exception as exc:
+                logger.error(exc)
 
         return new_string
@@ -1141,6 +1147,6 @@
                         out = self._string2inputlist(string)
                         return out
-                except:
-                    logger.error(sys.exc_value)
+                except Exception as exc:
+                    logger.error(exc)
 
     def _on_xy_coordinate(self, event=None):
@@ -1269,5 +1275,5 @@
             try:
                 basename = os.path.basename(path)
-                if basename not in self.spectrum_dic.keys():
+                if basename not in self.spectrum_dic:
                     self.spectrum_cb.Append(basename)
                 self.spectrum_dic[basename] = self._read_file(path)
@@ -1286,5 +1292,5 @@
         dlg = wx.FileDialog(self,
                             "Choose a wavelength spectrum file: Intensity vs. wavelength",
-                            self.parent.parent.get_save_location() , "", "*.*", wx.OPEN)
+                            self.parent.parent.get_save_location() , "", "*.*", wx.FD_OPEN)
         path = None
         if dlg.ShowModal() == wx.ID_OK:
@@ -1318,7 +1324,7 @@
                     wavelength.append(wave)
                     intensity.append(intens)
-                except:
+                except Exception as exc:
                     # Skip non-data lines
-                    logger.error(sys.exc_value)
+                    logger.error(exc)
 
             return [wavelength, intensity]
Index: src/sas/sasgui/perspectives/calculator/sld_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/sld_panel.py	(revision fe09e9bb0ad6caa9284d13a5c7dfdfc420d0c28b)
+++ src/sas/sasgui/perspectives/calculator/sld_panel.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -363,8 +363,11 @@
 
         """
+        # TODO: use periodictable.elements object
+        #    energy = xray_energy(periodictable.elements[element].K_alpha)
+        # TODO: code is very similar to sld helper
         myformula = formula(str(element))
         if len(myformula.atoms) != 1:
             return
-        element = myformula.atoms.keys()[0]
+        element = list(myformula.atoms.keys())[0]
         energy = xray_energy(element.K_alpha)
 
@@ -413,4 +416,7 @@
                     msg += "Error for wavelength value :expect float"
             elif (self.xray_source == 'Element'):
+                # TODO: use periodictable.elements instead of exec() hacks
+                #     if self.xray_source_input not in periodictable.elements:
+                #         ...
                 try:
                     import periodictable
@@ -447,9 +453,12 @@
 
         """
+        # TODO: use periodictable.elements object
+        #    energy = xray_energy(periodictable.elements[element].K_alpha)
         element_formula = formula(str(element))
         if len(element_formula.atoms) != 1:
             return
-        element = element_formula.atoms.keys()[0]
+        element = list(element_formula.atoms.keys())[0]
         energy = xray_energy(element.K_alpha)
+
         atom = molecule_formula.atoms
         return xray_sld_from_atoms(atom, density=density, energy=energy)
@@ -505,7 +514,7 @@
             #self.wavelength_ctl.SetValue(str(self.wavelength))
             #self.wavelength_ctl.SetValue(str(self.wavelength))
-        except:
+        except Exception as exc:
             if self.base is not None:
-                msg = "SLD Calculator: %s" % (sys.exc_value)
+                msg = "SLD Calculator: %s" % exc
                 wx.PostEvent(self.base, StatusEvent(status=msg))
         if event is not None:
Index: src/sas/sasgui/perspectives/calculator/slit_length_calculator_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/slit_length_calculator_panel.py	(revision d78861987017138f4c36cc97a261c26e80c03f64)
+++ src/sas/sasgui/perspectives/calculator/slit_length_calculator_panel.py	(revision 5251ec6db8aae214addfa0a5a1da16820994958b)
@@ -17,8 +17,8 @@
 from sas.sasgui.guiframe.events import StatusEvent
 from sas.sascalc.calculator.slit_length_calculator import SlitlengthCalculator
-from calculator_widgets import OutputTextCtrl
-from calculator_widgets import InterActiveOutputTextCtrl
 from sas.sasgui.perspectives.calculator import calculator_widgets as widget
 from sas.sasgui.guiframe.documentation_window import DocumentationWindow
+from .calculator_widgets import OutputTextCtrl
+from .calculator_widgets import InterActiveOutputTextCtrl
 
 _BOX_WIDTH = 76
@@ -163,5 +163,5 @@
 
         dlg = wx.FileDialog(self, "Choose a file", location,
-                            "", wildcard, wx.OPEN)
+                            "", wildcard, wx.FD_OPEN)
         if dlg.ShowModal() == wx.ID_OK:
             path = dlg.GetPath()
@@ -223,8 +223,8 @@
             self.reader.queue()
             self.load_update()
-        except:
+        except Exception as exc:
             if self.parent.parent is None:
                 return
-            msg = "Slit Length Calculator: %s" % (sys.exc_value)
+            msg = "Slit Length Calculator: %s" % exc
             wx.PostEvent(self.parent.parent,
                           StatusEvent(status=msg, type='stop'))
@@ -264,12 +264,12 @@
             if x == [] or  x is None or y == [] or y is None:
                 msg = "The current data is empty please check x and y"
-                raise ValueError, msg
+                raise ValueError(msg)
             slit_length_calculator = SlitlengthCalculator()
             slit_length_calculator.set_data(x=x, y=y)
             slit_length = slit_length_calculator.calculate_slit_length()
-        except:
+        except Exception as exc:
             if self.parent.parent is None:
                 return
-            msg = "Slit Size Calculator: %s" % (sys.exc_value)
+            msg = "Slit Size Calculator: %s" % exc
             wx.PostEvent(self.parent.parent,
                           StatusEvent(status=msg, type='stop'))
