class Form(QDialog):

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.resultsLists = QTextBrowser()
        self.resultsInput = QLineEdit('Enter an expression and press return key')

        # Layout the application - vertical order
        layout = QVBoxLayout()
        layout.addWidget(self.resultsLists)
        layout.addWidget(self.resultsInput)

        self.setLayout(layout)


        # Define signal - signal for pressing enter
        # When the signal is set it calls the method compute
        self.resultsInput.returnPressed.connect(self.compute)

        # Force window to stay on top when start
        # self.setFocusPolicy(Qt.StrongFocus)
        self.setWindowFlags(Qt.WindowStaysOnTopHint)

        self.resultsInput.selectAll()
        self.resultsInput.setFocus()


    def compute(self):
        try:
            text = self.resultsInput.text()
            self.resultsLists.append('{0} = <b>{1}</b>'.format(text, eval(text)))

        except:
            self.resultsLists.append('<font color=red><b>Expression invalid</b></font>')
Exemple #2
0
class Form(QDialog):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)

        self.resultList = QTextBrowser()
        self.resultInput = QLineEdit(
            "Enter an expression and press Return key")

        layout = QVBoxLayout()
        layout.addWidget(self.resultList)
        layout.addWidget(self.resultInput)
        self.setLayout(layout)

        self.resultInput.selectAll()
        self.resultInput.setFocus()

        # New way of Connect the signal
        self.resultInput.returnPressed.connect(self.compute)
        # Old Way of connect signal. Does not throw any error
        #self.connect(self.resultInput,SIGNAL("returnPressed()"),self.compute)

    def compute(self):
        try:
            text = self.resultInput.text()
            self.resultList.append("{0} = <b> {1} </b>".format(
                text, eval(text)))
        except:
            self.resultList.append(
                "<font color=red /><b> Expression invalid </b>")
Exemple #3
0
class ErrorDialog(QDialog):

    def __init__(self, files_not_processed, parent=None):
        super(ErrorDialog, self).__init__(parent)

        self.files_not_processed = files_not_processed
        self.setMinimumWidth(600)
        self.setWindowTitle(u'Kaikkia tiedostoja ei pystytty mittaamaan')
        icon = QIcon()
        icon.addPixmap(
            QPixmap(":/Images/aktools_48x48.png"), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(icon)
        self.text_browser = QTextBrowser()
        self.label = QLabel(u'Seuraavissa tiedostoissa havaittiin virheitä:')
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.label)
        self.layout.addWidget(self.text_browser)
        self.setLayout(self.layout)
        self.list_files_not_processed()

    def list_files_not_processed(self):

        for i in self.files_not_processed:
            self.text_browser.append(i)
class HighwayAnalyzeWidget(QWidget):
    def __init__(self):
        super(HighwayAnalyzeWidget,self).__init__()
        self.averageSimulationTime = 325.0
        mainLayout = QVBoxLayout()
        mainLayout.setAlignment(Qt.AlignTop|Qt.AlignHCenter)
        mainLayout.setSpacing(0)
        self.setLayout(mainLayout)
        topWidget = QWidget()
        self.topLayout = QHBoxLayout()
        self.topLayout.setSpacing(0)
        topWidget.setLayout(self.topLayout)
        topLeftWidget = QWidget()
        self.topLeftLayout = QVBoxLayout()
        topLeftWidget.setLayout(self.topLeftLayout)
        self.setupTopGroup()
        self.setupFilterGroup()
        self.topLayout.addWidget(topLeftWidget)
        self.layout().addWidget(topWidget)
        # Button and log
        buttonAndLogWidget = QWidget()
        buttonAndLogWidget.setLayout(QVBoxLayout())
        # Analyze the results BUTTON
        self.analyzeResultsButton = QPushButton('Analyze the results')
        self.analyzeResultsButton.clicked.connect(self.analyzeResults)
        self.analyzeResultsButton.setEnabled(False)
        buttonAndLogWidget.layout().addWidget(self.analyzeResultsButton)
        # LOG
        self.logText = QTextBrowser()
        self.logText.setFont(QFont('Century Gothic', 7))
        self.logText.setWordWrapMode(QTextOption.NoWrap)
        buttonAndLogWidget.layout().addWidget(self.logText)
        self.topLayout.addWidget(buttonAndLogWidget)
        self.results = []
        self.logFile = os.path.join(self.resultsPath(), 'analyze_'+os.uname()[1]+'.log')
        # Image
        self.picLabel = QLabel()
        self.picLabel.setAlignment(Qt.AlignHCenter)
        #self.picLabel.resize(800,600)
        self.picLabel.setMinimumSize(800,600)
        self.layout().addWidget(self.picLabel)
    def setupTopGroup(self):
        topGroup = QGroupBox("Simulation Results")
        self.resultsPathLineEdit = SimpleOption('resultsPath','Results Path','/home/thomas/Dropbox/Keio/research/results/')
        topGroupLayout = QVBoxLayout()
        topGroupLayout.setSpacing(0)
        topGroupLayout.setAlignment(Qt.AlignTop)
        topGroupLayout.addWidget(self.resultsPathLineEdit)
        self.loadResultsLabel = QLabel()
        self.loadResultsLabel.setAlignment(Qt.AlignHCenter)
        topGroupLayout.addWidget(self.loadResultsLabel)
        self.loadResultsButton = QPushButton("Load the results")
        self.loadResultsButton.clicked.connect(self.loadResults)
        topGroupLayout.addWidget(self.loadResultsButton)
        topGroup.setLayout(topGroupLayout)
        self.topLeftLayout.addWidget(topGroup)
    def resultsPath(self):
        return self.resultsPathLineEdit.getValue()
    def setupFilterGroup(self):
        filterGroup = QGroupBox('Filter the results')
        filterGroupLayout = QVBoxLayout()
        filterGroupLayout.setSpacing(0)
        filterGroupLayout.setAlignment(Qt.AlignTop)
        # Distribution Model
        self.filterDistribution = SimpleComboboxOption('dis','Speed Distribution Model',3, True, 'Uniform','Exponential','Normal','Log Normal')
        filterGroupLayout.addWidget(self.filterDistribution)
        self.filterDistribution.setVisible(False)
        # Number of results per point
        self.filterNb = SimpleSpinOption('simuNbMin', 'Minimum results for a given setting', 10, integer=True, checkable=True)
        self.filterNb.checkBox.setChecked(True)
        filterGroupLayout.addWidget(self.filterNb)
        # Filter the date
        dateWidget = QWidget()
        dateWidget.setLayout(QHBoxLayout())
        self.filterDate = QCheckBox('After')
        self.filterDate.setChecked(QSettings().value('filterDate','0')=='1')
        dateWidget.layout().addWidget(self.filterDate)
        self.filterDateYear = QComboBox()
        for m in xrange(2010,2012):
            self.filterDateYear.addItem(str(m))
        self.filterDateYear.setCurrentIndex(int(QSettings().value('dateYear', 1)))
        dateWidget.layout().addWidget(self.filterDateYear)
        dateWidget.layout().addWidget(QLabel('Year'))
        self.filterDateMonth = QComboBox()
        for m in xrange(1,13):
            self.filterDateMonth.addItem(str(m))
        self.filterDateMonth.setCurrentIndex(int(QSettings().value('dateMonth', 4)))
        dateWidget.layout().addWidget(self.filterDateMonth)
        dateWidget.layout().addWidget(QLabel('Month'))
        self.filterDateDay = QComboBox()
        for d in xrange(1,32):
            self.filterDateDay.addItem(str(d))
        self.filterDateDay.setCurrentIndex(int(QSettings().value('dateDay', 0)))
        dateWidget.layout().addWidget(self.filterDateDay)
        dateWidget.layout().addWidget(QLabel('Day'))
        filterGroupLayout.addWidget(dateWidget)
        filterGroup.setLayout(filterGroupLayout)
        self.topLeftLayout.addWidget(filterGroup)
        # Filter the scenario
        self.filterScenar = SimpleComboboxOption('scenar','Scenario',1, True, 'vanet-highway-test-thomas','vanet-highway-scenario2')
        filterGroupLayout.addWidget(self.filterScenar)
        # Filter gap
        self.filterGap = SimpleSpinOption('avgdistanalyze','Average Distance (m)',100, checkable=True)
        filterGroupLayout.addWidget(self.filterGap)
    def loadResults(self):
        self.loadResultsButton.setText('Loading the results...')
        self.loadResultsButton.setEnabled(False)
        self.results = []
        self.resultsThread = LoadResults(resultsPath=self.resultsPath())
        self.resultsThread.done.connect(self.loadResultsDone)
        self.resultsThread.error.connect(self.loadResultsError)
        self.resultsThread.start()
    @Slot(str)
    def loadResultsError(self, errorMsg):
        QMessageBox.critical(self, 'Error!', errorMsg)
        self.analyzeResultsButton.setEnabled(False)
    @Slot(dict)
    def loadResultsDone(self, results):
        self.results = results
        resultsNb = len(self.results)
        msg= 'Found %d Simulation Results\n(%d invalid files, %d simulations failed)' % (resultsNb, self.resultsThread.fileUnloadable, self.resultsThread.simulationFailed)
        self.loadResultsLabel.setText(msg)
        #self.calculateAverageSimulationTime()
        self.loadResultsButton.setText('Reload the results')
        self.loadResultsButton.setEnabled(True)
        self.analyzeResultsButton.setEnabled(True)
        if resultsNb>0:
            self.analyzeResults()
    def calculateAverageSimulationTime(self):
        totalTime = 0
        nb = 0
        for r in self.results:
            if 'simulationTime' in r:
                #print 'simu time: %s' % r['simulationTime']
                totalTime += int(r['simulationTime'])
                nb += 1
            #print 'from %s: [%3.3f,%3.3f]' % (r['filename'], r['settings']['prate'],r['results']['timeToReachDest'])
        if nb<=0:
            errorMsg= 'No simulation found with simulationTime'
            QMessageBox.critical(self, 'Error!', errorMsg)
            self.averageSimulationTime = 290.0
        else:
            self.averageSimulationTime= totalTime/nb
            self.loadResultsLabel.setText(self.loadResultsLabel.text()+'\nAverage simulation time: %3.0f'%self.averageSimulationTime)
    def fil(self, r):
        return self.checkDis(r) and self.checkDate(r) and self.checkGap(r) and self.checkScenario(r)
    def checkDis(self,r):
        return (not self.filterDistribution.checkBox.isChecked()) or r['settings']['dis']==self.filterDistribution.getValue()
    def checkDate(self, r):
        return (not self.filterDate.isChecked()) or (r['date'] >= datetime(int(self.filterDateYear.currentText()), int(self.filterDateMonth.currentText()), int(self.filterDateDay.currentText())))
    def checkScenario(self, r):
        return (not self.filterScenar.checkBox.isChecked()) or r['scenario']==self.filterScenar.getName()
    def checkGap(self, r):
        return (not self.filterGap.checkBox.isChecked()) or float(r['settings']['avgdist'])==float(self.filterGap.getValue())
    def analyzeResults(self):
        self.saveSettings()
        if len(self.results)<=0:
            QMessageBox.critical(self, 'Error!', 'No results loaded :s')
            return
        self.log("=== ANALYZING RESULTS ===")
        self.logText.clear()
        p=0
        meanValues = {}
        uniqueName = dateToFilename()
        gnuPlotDataFile =os.path.join(self.resultsPath(),'graphs/' + uniqueName+'.dat')
        with open(gnuPlotDataFile,'w') as data:
            while p<=100:
                nb = 0
                totalTimeToReachDest = 0
                totalSimulationTime  = 0
                for result in filter(lambda x: x['settings']['prate']==p and self.fil(x), self.results):
                    totalSimulationTime  += float(result['simulationTime'])
                    totalTimeToReachDest += float(result['results']['timeToReachDest'])
                    nb += 1
                if self.filterNb.checkBox.isChecked():
                    minNb = self.filterNb.getValue()
                else:
                    minNb = 0
                if nb>minNb:
                    meanSimulationTime  = float(1.0*totalSimulationTime/nb)
                    meanTimeToReachDest = float(1.0*totalTimeToReachDest/nb)
                    meanValues[p] = {'prate':p,
                                     'simuLationTime':meanSimulationTime,
                                     'simulationsNb':nb,
                                     'timeToReachDest':meanTimeToReachDest}
                    self.log(meanValues[p])
                    toPlot = '%s %s' % (p, meanValues[p]['timeToReachDest'])
                    #print toPlot
                    data.write(toPlot+'\n')
                p += 1
            data.close()
        if len(meanValues)>0:
            outputPic = 'graphs/' + uniqueName
            s = subprocess.Popen(['./toPlot.sh', outputPic, gnuPlotDataFile], cwd=self.resultsPath())
            s.wait()
            outputPicPath = os.path.join(self.resultsPath(),outputPic+'.svg')
            pic = QImage(outputPicPath)
            #pic = pic.scaled(QSize(640,480))
            self.picLabel.setPixmap(QPixmap(pic))
            #os.system(os.path.join(self.resultsPath(),'toPlot.sh'))
        else:
            QMessageBox.critical(self, 'Error!', 'No simulation satisfies the criteria...')
    def log(self, txt):
        toLog = str(txt)
        toLogFile = '%s | %s' % (datetime.now(), txt)
        with open(self.logFile, 'a') as logFile:
            logFile.write(toLogFile+'\n')
        self.logText.append(toLog)
    def saveSettings(self):
        QSettings().setValue('simuNbMin', self.filterNb.getValue())
        QSettings().setValue('avgdistanalyze', self.filterGap.getValue())
        QSettings().setValue('scenar', self.filterScenar.getValue())
        QSettings().setValue('dis', self.filterDistribution.getValue())
        QSettings().setValue('dateDay', self.filterDateDay.currentIndex())
        QSettings().setValue('dateMonth', self.filterDateMonth.currentIndex())
        QSettings().setValue('dateYear', self.filterDateYear.currentIndex())
        if self.filterDate.isChecked():
            QSettings().setValue('filterDate', '1')
        else:
            QSettings().setValue('filterDate', '0')
class HighwaySimulatorGui(QMainWindow):
    def __init__(self):
        super(HighwaySimulatorGui, self).__init__()
        centralTab = QTabWidget()
        mainWidget = QWidget()
        self.resultsWidget = HighwayAnalyzeWidget()
        centralTab.addTab(mainWidget, 'Run')
        centralTab.addTab(self.resultsWidget, 'Analyze')
        self.setCentralWidget(centralTab)
        centralLayout = QVBoxLayout()
        #centralLayout.setSpacing(0)
        centralLayout.setAlignment(Qt.AlignTop)
        gridWidget = QWidget()
        gridLayout = QGridLayout()
        gridLayout.setSpacing(0)
        gridWidget.setLayout(gridLayout)
        mainWidget.setLayout(centralLayout)
        self.options = dict()
        # GENERAL
        generalGroup = QGroupBox('General Settings')
        generalGroup.setLayout(QVBoxLayout())
        generalGroup.layout().setSpacing(0)
        self.pathOption = SimpleOption('path','Output Path','/home/thomas/Dropbox/Keio/research/results/')
        generalGroup.layout().addWidget(self.pathOption)
        self.scenarioOption = SimpleComboboxOption('scenario','Scenario',1, False, 'vanet-highway-test-thomas','vanet-highway-scenario2')
        self.scenarioOption.combo.currentIndexChanged[int].connect(self.scenarioChanged)
        generalGroup.layout().addWidget(self.scenarioOption)
        self.options['time'] = SimpleSpinOption('time','Simulation Time (sec.)',1500,True)
        self.options['time'].setRange(0,3000)
        self.options['mix'] = SimpleSpinOption('mix','Percentage of cars compare to trucks (%)',80,True)
        self.options['mix'].setRange(0,100)
        self.options['gap'] = SimpleSpinOption('gap','Average Gap (m.)',5)
        self.options['gap'].setRange(1,2000)
        self.options['lane'] = SimpleSpinOption('lane','Number of Lanes',2,True)
        self.options['lane'].setRange(2,4)
        self.options['spl'] = SimpleSpinOption('spl','Speed Limit (km/h)',130,True)
        self.options['spl'].setRange(1,200)
        for widget in ('time','mix','gap','lane','spl'):
            generalGroup.layout().addWidget(self.options[widget])
        gridLayout.addWidget(generalGroup,0,0)
        # TRAFFIC
        trafficGroup = QGroupBox('Traffic Settings')
        trafficGroup.setLayout(QVBoxLayout())
        trafficGroup.layout().setSpacing(0)
        # m/s = (km/h)*1000/3600
        self.options['vel1'] = SimpleSpinOption('vel1','Average Speed (km/h)',105,True)
        self.options['vel1'].setRange(5,150)
        self.options['dis'] = SimpleComboboxOption('dis','Speed Distribution Model',3, False, 'Uniform','Exponential','Normal','Log Normal')
        self.options['spstd'] = SimpleSpinOption('spstd','Speed Distribution Variance',1.0)
        self.options['spstd'].setRange(0,50)
        self.options['flow1'] = SimpleSpinOption('flow1','Traffic Flow Mean (veh/s)',1.0)
        self.options['flow1'].setRange(0.1,50.0)
        self.options['std1'] = SimpleSpinOption('std1','Traffic Flow Variance',0.8)
        self.options['std1'].setRange(0.1,50.0)
        self.options['maxflow'] = SimpleSpinOption('maxflow','Traffic Maximum Flow (veh/s)',5)
        self.options['maxflow'].setRange(0.1,50.0)
        # Scenar 2
        self.options['avgdist'] = SimpleSpinOption('avgdist','Average Distance (m)',100)
        self.options['avgdist'].setRange(1,10000)
        self.options['avgspeed'] = SimpleSpinOption('avgspeed','Average Speed (km/h)',105)
        self.options['avgspeed'].setRange(1,10000)
        self.options['despeed'] = SimpleSpinOption('despeed','Desired Speed (km/h)',130)
        self.options['despeed'].setRange(1,10000)
        self.options['ambumaxspeed'] = SimpleSpinOption('ambumaxspeed','Ambu Max Speed (km/h)',165)
        self.options['ambumaxspeed'].setRange(1,10000)
        self.options['ambuinitspeed'] = SimpleSpinOption('ambuinitspeed','Ambu Initial Speed (km/h)',130)
        self.options['ambuinitspeed'].setRange(1,10000)
        for widget in ('vel1','dis','spstd','flow1','std1','maxflow',
                       'avgdist', 'avgspeed', 'despeed', 'ambumaxspeed', 'ambuinitspeed'):
            trafficGroup.layout().addWidget(self.options[widget])
        self.scenarioChanged(self.scenarioOption.combo.currentIndex())
        gridLayout.addWidget(trafficGroup,0,1)
        # VANET
        vanetGroup = QGroupBox('VANET Settings')
        vanetGroup.setLayout(QVBoxLayout())
        vanetGroup.layout().setSpacing(0)
#        self.options['prate'] = SimpleSpinOption('prate','Penetration Rate of VANET (%)',100,True)
#        self.options['prate'].setRange(0,100)
        self.options['prate'] = 0 # start with 0
        self.options['pw'] = SimpleSpinOption('pw','Transmission Power (dBm)',21.5)
        self.options['pw'].setRange(10,50)
        #for widget in ('prate','pw'):
        for widget in ('pw',):
            vanetGroup.layout().addWidget(self.options[widget])
        gridLayout.addWidget(vanetGroup,1,0)
        # BATCH SETTINGS
        batchGroup = QGroupBox("Batch Settings")
        batchGroup.setLayout(QVBoxLayout())
        self.gapPrateOption = SimpleSpinOption('gapPrate', 'VANET percentage rate gap', 10, integer=True)
        self.sameSimuTimesOption = SimpleSpinOption('sameSimuTimes', 'How many times the same simulation', 100, integer=True)
        batchGroup.layout().setSpacing(0)
        batchGroup.layout().addWidget(self.gapPrateOption)
        batchGroup.layout().addWidget(self.sameSimuTimesOption)
        gridLayout.addWidget(batchGroup,1,1)
        # START SIMU
        centralLayout.addWidget(gridWidget)
        self.startButton = QPushButton('START')
        self.startButton.clicked.connect(self.startSimu)
        centralLayout.addWidget(self.startButton)
        self.progressBar    = QProgressBar()
        centralLayout.addWidget(self.progressBar)
        self.shutdownWhenDone = QCheckBox('Shutdown when done')
        self.actionWhenDone = QComboBox()
        self.actionWhenDone.addItems(['When finished... do nothing', 'When finished... shutdown the computer', 'When finished... Re-run the simulations!'])
        self.actionWhenDone.setCurrentIndex(int(QSettings().value('actionWhenDone', 0)))
        centralLayout.addWidget(self.actionWhenDone)
        self.infoLabel = QLabel()
        centralLayout.addWidget(self.infoLabel)
        # LOG
        self.logText = QTextBrowser()
        self.logText.setFont(QFont('Century Gothic', 7))
        centralLayout.addWidget(self.logText)
        self.setWindowTitle('Nishimura Lab | Highway Simulation')
        #self.resize(520,len(self.options)*60+100)
        #self.resultFile = open('/home/thomas/Dropbox/Keio/research/results/summary.txt', 'a')
        #self.resultFile = os.path.join(self.pathOption.getValue(), 'summary.txt')
        self.logFile = os.path.join(self.pathOption.getValue(), 'results_'+os.uname()[1]+'.log')
    @Slot(int)
    def scenarioChanged(self, index):
        #print index
        scenar1options = ['gap', 'vel1', 'dis', 'flow1', 'std1','spstd', 'maxflow']
        scenar2options = ['avgdist', 'avgspeed', 'despeed', 'ambumaxspeed', 'ambuinitspeed']
        if index==0: # first scenario
            scenar1 = True
            scenar2 = False
        else:
            scenar1 = False
            scenar2 = True
        for option in scenar1options:
            self.options[option].setVisible(scenar1)
        for option in scenar2options:
            self.options[option].setVisible(scenar2)
    def log(self, txt):
        toLog = '%s | %s' % (datetime.now(), txt)
        with open(self.logFile, 'a') as logFile:
            logFile.write(toLog+'\n')
        self.logText.append(toLog)
    def blockUi(self):
        self.startButton.setEnabled(False)
        self.scenarioOption.setEnabled(False)
        for option in self.options:
            if option!='prate':
                self.options[option].setEnabled(False)
    def releaseUi(self):
        self.startButton.setEnabled(True)
        self.scenarioOption.setEnabled(True)
        self.startButton.setText('START')
        for option in self.options:
            if option!='prate':
                self.options[option].setEnabled(True)
    def startSimu(self):
        self.log("=== SIMULATIONS START ===")
        self.logText.clear()
        self.startTime = datetime.now()
        self.simulations = []
        #self.nextPrate = 0
        self.gapPrate  = self.gapPrateOption.getValue()
        self.sameSimuTimes = self.sameSimuTimesOption.getValue()
        #self.nextSimu   = 0
        self.blockUi()
        self.simulationsDone = 0
        #output = self.pathOption.getValue() + dateToFilename(d) + '_results.txt'
        pRate = 0
        self.simulationsTotal = 0
#        print 'sameSimuTimes: %d'%self.sameSimuTimes
#        print 'gapPrate: %d'%self.gapPrate
        while pRate <= 100:
            simu = 0
            self.options['prate'] = pRate
            while simu<self.sameSimuTimes:
                waf = WafThread(self.options, self.pathOption.getValue(), self.scenarioOption.getName())
                waf.setAutoDelete(True)
                waf.simuDone.connect(self.wafDone)
                self.simulations.append(waf)
                QThreadPool.globalInstance().start(waf)
                self.simulationsTotal += 1
                simu += 1
            pRate += self.gapPrate
        runningSimulations = 'Running %d Simulations...' % self.simulationsTotal
        self.startButton.setText(runningSimulations)
        self.log(runningSimulations)
        self.progressBar.setRange(0,self.simulationsTotal)
        self.progressBar.setValue(0)
        # 300 seconds per task average
        roughTime = self.simulationsTotal*self.resultsWidget.averageSimulationTime/QThreadPool.globalInstance().maxThreadCount()
        self.infoLabel.setText('Rough time estimation: %s' % formatTimeLeft(roughTime))
    @Slot(str)
    def wafDone(self, outputPath):
        #print 'thread done!\nReceived:'
        self.simulationsDone += 1
        simulationsLeft = self.simulationsTotal-self.simulationsDone
        with open(outputPath,'r') as out:
            r = json.loads(out.read())
            out.close()
            if 'timeToReachDest' in r['results']:
                try:
                    result = "%3.3d\t%f" % (int(r['settings']['prate']),float(r['results']['timeToReachDest']))
                except TypeError, e:
                    result = 'PYTHON ERROR: %s | File: %s' % (e, outputPath)
                    print result
                    print r
            else: