class Class_Scores():
    def __init__(self):
        read_Settings()

        from ronde_handler import Class_Rondes
        from inschrijving_handler import Class_Inschrijvingen
        self.RH = Class_Rondes()
        self.PH = Class_Inschrijvingen()

        global SUPERNR
        SUPERNR = self.RH.numberSuperRonde()

    def getImagesDir(self):
        return IMAGESDIR

    def getScanResults(self):
        try:
            with open(RONDEFILES + SCANRAW, 'rt') as fr:
                reader = csv.reader(fr)
                for row in reader:
                    yield row, IMAGESDIR + '{}_{}.jpg'.format(row[0], row[1])
        except:
            yield []

    def getAllScanResults(self):
        data = []
        for X, a in enumerate(self.getScanResults()):
            data.append(a)
        return data

    def validateScanResult(self, row):
        writer = csv.writer(open(RONDEFILES + SCANCONTROL, 'a+'))
        writer.writerow(row)
        del writer

    def clearImagesDir(self):
        files = os.listdir(IMAGESDIR)
        for filename in files:
            os.remove(IMAGESDIR + '/' + filename)

    def clearScoresDir(self):
        files = os.listdir(RONDEFILES)
        for filename in files:
            os.remove(RONDEFILES + '/' + filename)

    def cleanScanRaw(self):
        tmp = RONDEFILES + 'tmp.csv'
        with open(RONDEFILES + SCANCONTROL,
                  'rt') as fr, open(RONDEFILES + SCANRAW,
                                    'rt') as fr2, open(tmp, 'w') as fw:
            reader1 = csv.reader(fr)
            reader2 = csv.reader(fr2)
            writer = csv.writer(fw)
            checkcombo = []
            for row in reader1:
                if '999' in row[1]:
                    row[1] = '999'
                checkcombo.append('{}_{}'.format(row[0], row[1]))

            for row in reader2:
                combo = '{}_{}'.format(row[0], row[1])
                if not combo in checkcombo:
                    writer.writerow(row)
                else:
                    checkcombo.remove(combo)
        shutil.move(tmp, RONDEFILES + SCANRAW)

    def getUserRondes(self):
        files = os.listdir(RONDEFILES)
        result = []
        for RN, ronde in enumerate(self.RH.getRondeNames()):
            for file in files:
                if USERPREFIX in file and ronde in file:
                    result.append(
                        str(RN + 1) + '_' +
                        file.replace('.csv', '').replace(USERPREFIX, ''))
                    break
        return result

    def getScore(self, ronde, ploeg, scanner=0):
        if scanner == 1:
            filename = RONDEFILES + SCANRAW
        else:
            filename = RONDEFILES + USERPREFIX + self.RH.getRondenaam(
                ronde) + '.csv'
        with open(filename, 'rt') as fr:
            reader = csv.reader(fr)
            next(reader)
            for i, row in enumerate(reader):
                if int(row[1]) == int(ploeg) and int(row[0]) == int(ronde):
                    return row[2:]
        return []

    def getScoreRondeFinal(self, ronde, ploeg):

        filename = RONDEFILES + FINALPREFIX + self.RH.getRondenaam(
            ronde) + '.csv'
        with open(filename, 'rt') as fr:
            reader = csv.reader(fr)
            next(reader)
            for i, row in enumerate(reader):
                if int(row[1]) == int(ploeg) and int(row[0]) == int(ronde):
                    return row[2:]
        return []

    def setScore(self, ronde, ploeg, nieuweScore, scanner=0):
        if '999' in str(ploeg):
            ploeg = int(str(ploeg).replace('999', ''))
        if ronde > 0:
            tmp = RONDEFILES + 'tmp.csv'
            weggeschreven = False
            if scanner == 1:
                filename = RONDEFILES + SCANRAW
            else:
                filename = RONDEFILES + USERPREFIX + self.RH.getRondenaam(
                    ronde) + '.csv'
            with open(filename, 'rt') as fr, open(tmp, 'w') as fw:
                writer = csv.writer(fw)
                reader = csv.reader(fr)
                writer.writerow(next(reader))
                for i, row in enumerate(reader):
                    if int(row[1]) == int(ploeg) and int(row[0]) == int(ronde):
                        writer.writerow(row[0:2] + nieuweScore)
                        weggeschreven = True
                    else:
                        writer.writerow(row)
            if not weggeschreven:
                self.insertScore(ronde, ploeg, nieuweScore, USERPREFIX)
            else:
                shutil.move(tmp, filename)
        else:
            if len(nieuweScore) > 1:
                self.PH.setSchiftingBonus(ploeg, nieuweScore[0],
                                          nieuweScore[1])
            else:
                self.PH.setSchiftingBonus(ploeg, nieuweScore[0])

    def insertScore(self, ronde, ploeg, score, prefix):
        tmp = RONDEFILES + 'tmp.csv'
        filename = RONDEFILES + prefix + self.RH.getRondenaam(ronde) + '.csv'
        with open(filename, 'rt') as fr, open(tmp, 'w') as fw:
            writer = csv.writer(fw)
            reader = csv.reader(fr)
            writer.writerow(next(reader))
            ingevoegd = 0
            for i, row in enumerate(reader):
                if not 'Max/Gem' in row:
                    if ingevoegd == 0 and int(row[1]) > int(ploeg):
                        writer.writerow([ronde] + [ploeg] + score)
                        ingevoegd = 1
                elif ingevoegd == 0:
                    writer.writerow([ronde] + [ploeg] + score)
                    ingevoegd = 1

                writer.writerow(row)

            if ingevoegd == 0 and prefix == USERPREFIX:
                writer.writerow([ronde] + [ploeg] + score)
                ingevoegd = 1

        shutil.move(tmp, filename)

    def deleteScore(self, ronde, ploeg, prefix):
        tmp = RONDEFILES + 'tmp.csv'
        filename = RONDEFILES + prefix + self.RH.getRondenaam(ronde) + '.csv'
        with open(filename, 'rt') as fr, open(tmp, 'w') as fw:
            writer = csv.writer(fw)
            reader = csv.reader(fr)
            writer.writerow(next(reader))
            for i, row in enumerate(reader):
                if not 'Max/Gem' in row:
                    if not int(row[1]) == int(ploeg):
                        writer.writerow(row)
                else:
                    writer.writerow(row)
        shutil.move(tmp, filename)

    def getFinalScore(self, ploegnaamPositie):
        with open(SCOREBORD, 'rt') as fr:
            reader = csv.DictReader(fr)
            next(reader)
            for row in reader:
                if row['Ploegnaam'] == ploegnaamPositie or row['Pos'] == str(
                        ploegnaamPositie):
                    return row
        return ''

    def getFinalScores(self, positie, aantaldeelnemers, plusmin):
        result = []
        posities = list(
            map(
                str,
                range(max(1,
                          int(positie) - int(plusmin)),
                      min(aantaldeelnemers,
                          int(positie) + int(plusmin)) + 1)))
        with open(SCOREBORD, 'rt') as fr:
            reader = csv.reader(fr)
            for row in reader:
                if row[0] in posities:
                    result.append(row)
        return result

    def generateBonusOverview(self):
        #Bereken Score met originele thema
        #Bereken score voor al de andere thema's zet hiervoor al de thema's steeds eens op het zelfde voor alle ploegen en bereken opnieuw de score
        #Bekijk wat het beste resultaat was en schrijf dat in BONUSOVERVIEW
        #Zet de origineleBonusThemas terug in PLOEGINFO en maak opnieuw Final bestanden aan alsof er niets gebeurd is

        headers = [
            'TN', 'Ploegnaam', 'Origineel', 'OrigineelScore', 'Beste',
            'BesteScore', 'Maximum'
        ]
        origineleBonusThemas = []
        aantalPloegen = 0
        for ploeginfo in self.PH.getPloegenDict():
            origineleBonusThemas.append(ploeginfo['Bonus'])
            aantalPloegen = aantalPloegen + 1

        bonusScore = []
        for i in range(0, len(BONUSTHEMAS)):
            self.PH.setBonusses([i + 1] * len(origineleBonusThemas))
            self.makeFinal()
            score, maximum = self.calculateBonusScore(aantalPloegen)
            bonusScore.append(score)

        self.PH.setBonusses(origineleBonusThemas)
        self.makeFinal()
        eigenScore, maximum = self.calculateBonusScore(aantalPloegen)
        with open(BONUSOVERVIEW, 'w') as fw:
            writer = csv.writer(fw)
            writer.writerow(headers)
            for i, ploeginfo in enumerate(self.PH.getPloegenDict()):
                if ploeginfo['Aangemeld'] == '1':
                    start = [
                        ploeginfo['TN'], ploeginfo['Ploegnaam'],
                        ploeginfo['Bonus'], eigenScore[i]
                    ]
                    besteScore = eigenScore[i]
                    beste = ploeginfo['Bonus']
                    for index in range(0, len(BONUSTHEMAS)):
                        if bonusScore[index][i] > besteScore:
                            besteScore = bonusScore[index][i]
                            beste = index + 1
                else:
                    start = [
                        ploeginfo['TN'], ploeginfo['Ploegnaam'],
                        ploeginfo['Bonus'], 0
                    ]
                    besteScore = 0
                    beste = 0
                writer.writerow(start + [beste] + [besteScore] + [maximum])

    def calculateBonusScore(self, aantalPloegen):
        bonusscore = [0] * aantalPloegen
        maximum = 0
        filenames = os.listdir(RONDEFILES)
        with open(SCOREBORDINFO, 'rt') as fr:
            readerInfo = csv.DictReader(fr)
            for row in readerInfo:
                filename = FINALPREFIX + row['Ronde'] + '.csv'
                if filename in filenames and bool(
                        self.RH.isBonusRonde(row['Ronde'])):
                    with open(RONDEFILES + filename) as fr2:
                        reader = csv.DictReader(fr2)
                        for index, row in enumerate(reader):
                            if not '.' in row['TN']:
                                bonusscore[int(row['TN']) -
                                           1] = bonusscore[int(row['TN']) -
                                                           1] + int(
                                                               row['Bonus'])
                    maximum = maximum + 1

        return bonusscore, maximum

    def fromScannerToUser(self):
        #De SCANCONTROL sorteren volgens rondenummer
        #alles in SCANCONTORL omvromen naar rondefiles met userprefix
        #goed controleren op dubbele entries en ook toevoegen aan de rondefiles, niet overschrijven stel bijvoorbeeld dat een ronde in drie scanverwerkings wordt gedaan!
        #Scan CSV file wordt gewoon verwijderd!!!

        if SCANCONTROL in os.listdir(RONDEFILES):
            file = RONDEFILES + SCANCONTROL
            self.sorteer(file)

            with open(file, 'rt') as fr:
                reader = csv.reader(fr)
                currentRound = 9999
                mode = 'a'
                writer = None
                filename = ''
                for index, row in enumerate(reader):
                    row = list(map(int, row))
                    ronde = row[0]
                    ploeg = row[1]
                    score = row[2:]
                    if '999' in str(ploeg):
                        ploeg = int(str(ploeg).replace('999', ''))
                        row = [ronde] + [ploeg] + score
                    if not ronde == currentRound and ronde > 0:
                        #nieuweronde dus nieuwe file opendoen!
                        del writer
                        self.sorteerVerwijderDubbels(filename)
                        rondeNaam = self.RH.getRondenaam(ronde)
                        nieuw = not any(
                            fname.endswith(rondeNaam + '.csv')
                            for fname in os.listdir(RONDEFILES))
                        filename = RONDEFILES + USERPREFIX + rondeNaam + '.csv'
                        writer = csv.writer(open(filename, 'a'))
                        if nieuw:
                            header = ['RN', 'TN']
                            for i in range(0, len(score)):
                                header.append(i + 1)
                            writer.writerow(header)
                    if ronde > 0:
                        #rondefile verder aanvullen
                        writer.writerow(row)
                    else:
                        #schifting en bonus
                        if len(score) > 1:
                            self.PH.setSchiftingBonus(ploeg, score[0],
                                                      score[1])
                        else:
                            self.PH.setSchiftingBonus(ploeg, score[0])
                    currentRound = ronde
                del writer
                self.sorteerVerwijderDubbels(filename)

            self.cleanScanRaw()
            try:
                os.remove(file)
            except:
                print('{} , niet kunnen verwijderen'.format(file))

    def sorteerVerwijderDubbels(self, filename):
        if filename.endswith('.csv'):
            tmp = RONDEFILES + 'tmp.csv'
            with open(filename, mode='rt') as fr, open(tmp, 'w') as fw:
                writer = csv.writer(fw)
                reader = csv.reader(fr)
                writer.writerow(next(reader))
                sorted2 = sorted(reader, key=lambda row: (int(row[1])))
                for count, row in enumerate(sorted2):
                    writer.writerow(row)
            shutil.move(tmp, filename)

            with open(filename, mode='rt') as fr, open(tmp, 'w') as fw:
                writer = csv.writer(fw)
                data = list(csv.reader(fr))
                writer.writerow(data[0])
                for X in range(1, len(data) - 1):
                    if not data[X][1] == data[X + 1][1]:
                        #geen dubbele entry voor deze ploeg in deze ronde
                        writer.writerow(data[X])
                writer.writerow(data[len(data) - 1])
            shutil.move(tmp, filename)

    def checkAanwezigheden(self):
        aanwezig, afwezig = self.PH.aanwezigePloegen()
        nummers = []
        for ploeg in aanwezig:
            nummers.append(ploeg[0])
        originalNumbers = nummers
        ontbrekendeBestanden = []
        nietAanwezigeInvoer = []
        filenames = os.listdir(RONDEFILES)
        for count, filename in enumerate(filenames):
            if FINALPREFIX in filename:
                with open(RONDEFILES + filename, 'r') as fr:
                    data = list(csv.reader(fr))
                    ronde = data[1][0]
                    for X in range(1, len(data) - 1):
                        try:
                            index = nummers.index(int(data[X][1]))
                            del nummers[index]
                        except:
                            nietAanwezigeInvoer.append('{}_{}'.format(
                                ronde, data[X][1]))
                            pass
                    for i in nummers:
                        ontbrekendeBestanden.append('{}_{}'.format(ronde, i))

            aanwezig, afwezig = self.PH.aanwezigePloegen()
            nummers = []
            for ploeg in aanwezig:
                nummers.append(ploeg[0])

        #Verwijder de (foutieve) entry van ploegen die niet aanwezig zijn!
        for bestand in nietAanwezigeInvoer:
            ronde = list(map(int, bestand.split('_')))
            self.deleteScore(ronde[0], ronde[1], FINALPREFIX)
        #Voeg 0 toe bij de ontbrekende bestanden!
        for bestand in ontbrekendeBestanden:
            ronde = list(map(int, bestand.split('_')))
            NOQ, SUPER = self.RH.getVragenSuper(ronde[0])
            bonus = self.RH.isBonusRonde(ronde[0])
            self.insertScore(ronde[0], ronde[1],
                             [0] * (NOQ * (1 + 2 * SUPER) + bonus),
                             FINALPREFIX)

        return ontbrekendeBestanden, nietAanwezigeInvoer

    def makeFinal(self):
        #remove all files with FINALPREFIX
        #Check op aanwezigheden
        #voeg de bonusthema's toe!
        #Analyse van elke ronde op het einde (gemiddelde, aantalJuist per vraag)

        filenames = os.listdir(RONDEFILES)
        tmp = RONDEFILES + 'tmp.csv'
        for count, filename in enumerate(filenames):
            if FINALPREFIX in filename:
                os.remove(RONDEFILES + filename)

        geenBonus = []
        filenames = os.listdir(RONDEFILES)
        for count, filename in enumerate(filenames):
            if USERPREFIX in filename:
                with open(RONDEFILES + filename, 'r') as fr, open(tmp,
                                                                  'w') as fw:
                    writer = csv.writer(fw)
                    reader = csv.reader(fr)
                    header = next(reader)
                    currentRound = 0
                    bonusRonde = 0
                    superRonde = 0
                    totaalScore = []
                    JuisteAntwoorden = [0] * (len(header) - 2)
                    for index, row in enumerate(reader):
                        ronde = int(row[0])
                        if not currentRound == ronde:
                            bonusRonde = self.RH.isBonusRonde(ronde)
                            superRonde = self.RH.isSuperRonde(ronde)
                            if bonusRonde == 1:
                                header.append('Bonus')
                                JuisteAntwoorden.append(0)
                            writer.writerow(header)
                        if bonusRonde == 1:
                            schifting, bonus = self.PH.getSchiftingBonus(
                                int(row[1]))
                            if not bonus == 999:
                                if bonus > 0:
                                    row.append(row[bonus + 1])
                                else:
                                    if not int(row[1]) in geenBonus:
                                        geenBonus.append(int(row[1]))
                                    row.append(0)
                            else:
                                row.append(
                                    0
                                )  #de ploeg is niet aanwezig maar die wordt pas in checkAanwezigheden verwijderd
                        for i, score in enumerate(row[2:]):
                            JuisteAntwoorden[i] = JuisteAntwoorden[i] + int(
                                score)
                        writer.writerow(row)
                        if superRonde == 1:
                            tmpscore = list(map(int, row[2:]))
                            totaalScore.append(
                                sum(tmpscore[0:len(tmpscore):3]) +
                                2 * sum(tmpscore[1:len(tmpscore):3]) +
                                3 * sum(tmpscore[2:len(tmpscore):3]))
                        else:
                            totaalScore.append(sum(map(int, row[2:])))
                        currentRound = ronde

                    writer.writerow([len(JuisteAntwoorden)] +
                                    [round(statistics.mean(totaalScore), 2)] +
                                    JuisteAntwoorden + ['Max/Gem'])

                shutil.move(
                    tmp,
                    RONDEFILES + filename.replace(USERPREFIX, FINALPREFIX))
        aanwezig, _ = self.PH.aanwezigePloegen()
        geenSchifting = []
        for ploeg in aanwezig:
            schifting, bonus = self.PH.getSchiftingBonus(ploeg[0])
            if float(schifting) == 0:
                geenSchifting.append(ploeg[0])
        ontbreekt, fout = self.checkAanwezigheden()
        geenBonus = sorted(geenBonus)
        ontbreekt = sorted(ontbreekt)
        fout = sorted(fout)
        return geenBonus, geenSchifting, ontbreekt, fout

    def sorteer(self, filename):
        tmp = 'tmp.csv'
        with open(filename, 'rt') as fr, open(tmp, 'w+') as fw:
            writer = csv.writer(fw)
            reader = csv.reader(fr)
            writer.writerow(next(reader))  #header
            sorted2 = sorted(reader,
                             key=lambda row: (int(row[0]), int(row[1])))
            for count, row in enumerate(sorted2):
                writer.writerow(row)
        os.rename(tmp, filename)

    def collectAllInfo(self):
        #Zet de verschillende csv files per ronde samen in een groot bestand en sorteert dit dan zodat alles per ploeg en dan per ronde staat gerangschikt
        tmp = 'tmp.csv'
        with open(tmp, 'w') as fw:
            writer = csv.writer(fw)
            filenames = os.listdir(RONDEFILES)
            for file in filenames:
                if file.endswith('.csv') and file.startswith(FINALPREFIX):
                    with open(RONDEFILES + file, mode='rt') as fr:
                        reader = csv.reader(fr)
                        next(reader)
                        for row in reader:
                            if not 'Max/Gem' in row:
                                row = list(map(int, row))
                                if row[0] == SUPERNR:
                                    score = sum(row[2:len(row):3]) + 2 * sum(
                                        row[3:len(row):3]) + 3 * sum(
                                            row[4:len(row):3])
                                else:
                                    score = sum(row[2::])
                                writer.writerow([row[1], row[0], score])

        #sorteer volgens tafelnummer en dan volgens rondenummer
        with open(tmp, mode='rt') as fr, open(SCOREBORD, 'w') as fw:
            writer = csv.writer(fw)
            reader = csv.reader(fr)
            writer.writerow(['TN', 'RN', 'Score'])
            sorted2 = sorted(reader,
                             key=lambda row: (int(row[0]), int(row[1])))
            for row in sorted2:
                writer.writerow(row)

    def makeScorebordInfo(self):
        #Dit werkt enkel op basis van CollectAllInfo
        with open(SCOREBORD, mode='rt') as fr, open(SCOREBORDINFO, 'w') as fw:
            fields = ['RN', 'Ronde', 'Afkorting', 'Maximum']
            writer = csv.DictWriter(fw, fields)
            reader = csv.DictReader(fr)
            writer.writeheader()
            vorigePloeg = 0
            for i, row in enumerate(reader):
                if i > 0 and not int(row['TN']) == vorigePloeg:
                    break
                else:
                    rn = row['RN']
                    try:
                        info = self.RH.getRondeInfoDict(
                            rn
                        )  #Rondenr, rondenaam, Afkorting, NOQ, superronde, bonusronde, sheet
                    except NameError:
                        print(rn)
                        raise
                    maximum = int(
                        info['Aantal']) * (1 + 2 * int(info['Super'])) + int(
                            info['Bonus'])  #bonusronde + 1, superronde * 3
                    writer.writerow({
                        'RN': rn,
                        'Ronde': info['Ronde'],
                        'Afkorting': info['Afkorting'],
                        'Maximum': maximum
                    })
                    vorigePloeg = int(row['TN'])

    def setHeaders(self):
        global FIELDNAMES
        global ROW1

        FIELDNAMES = ['Pos', 'TN', 'Ploegnaam', 'Score', '%']
        ROW1 = ['0', '0', 'Maximum', '', '100']

        with open(SCOREBORDINFO, 'rt') as fr:
            readerInfo = csv.DictReader(fr)
            for row in readerInfo:
                FIELDNAMES.append(row['Afkorting'])
                ROW1.append(int(row['Maximum']))
        ROW1[3] = sum(ROW1[5:])
        FIELDNAMES.append('Schifting')
        ROW1.append(SCHIFTING)
        FIELDNAMES.append('NormSchifting')
        ROW1.append('')

    def generateScorebord(self, bonusGeneration):
        a = time.time()
        geenBonus, geenSchifting, ontbreekt, fout = self.makeFinal()
        print('makeFinal:', time.time() - a)
        self.collectAllInfo()
        self.makeScorebordInfo()
        self.setHeaders()

        geenScoresBeschikbaar = True

        tmp = 'tmp.csv'
        with open(SCOREBORD, mode='rt') as fr, open(tmp, 'w') as fw:
            writer = csv.writer(fw)
            reader = csv.DictReader(fr)
            writer.writerow(FIELDNAMES)
            writer.writerow(ROW1)

            vorigePloeg = 0
            ploegdata = ['']
            for i, row in enumerate(reader):
                if not int(row['TN']) == vorigePloeg and not 'Max/Gem' in row:
                    #nieuwe ploeg
                    if i > 0:
                        ploegdata[3] = sum(map(int, ploegdata[5:]))
                        ploegdata[4] = round(
                            ploegdata[3] / ROW1[FIELDNAMES.index('Score')] *
                            100, 2)
                        schiftingantwoord, Bonus = self.PH.getSchiftingBonus(
                            vorigePloeg)
                        schiftingnorm = round(
                            SCHIFTING /
                            (abs(float(schiftingantwoord) - SCHIFTING) +
                             0.0001), 3)
                        ploegdata.append(schiftingantwoord)
                        ploegdata.append(schiftingnorm)
                        writer.writerow(ploegdata)
                    try:
                        ploegnaam = self.PH.getPloegnaam(row['TN'])
                        ploegdata = ['', row['TN'], ploegnaam, '', '']
                        ploegdata.append(row['Score'])
                    except NameError:
                        print(row['TN'])
                else:
                    #zelfde ploeg
                    ploegdata.append(row['Score'])

                vorigePloeg = int(row['TN'])

            #moet dat hier staan?
            if len(ploegdata) > 1:
                ploegdata[3] = sum(map(int, ploegdata[5:]))
                ploegdata[4] = round(
                    ploegdata[3] / ROW1[FIELDNAMES.index('Score')] * 100, 2)
                schiftingantwoord, Bonus = self.PH.getSchiftingBonus(
                    vorigePloeg)
                schiftingnorm = round(
                    SCHIFTING /
                    (abs(float(schiftingantwoord) - SCHIFTING) + 0.0001), 3)
                ploegdata.append(schiftingantwoord)
                ploegdata.append(schiftingnorm)
                writer.writerow(ploegdata)
                geenScoresBeschikbaar = False

        maximumScore = 0
        gemiddeldeScore = 0
        gemiddeldes = []

        with open(SCOREBORDINFO, 'rt') as fr1:
            reader = csv.DictReader(fr1)
            for usedRound in reader:
                rondeNaam = usedRound['Ronde']
                maximumRondeScore = 0
                gemiddeldeRondeScore = 0
                eigenRondeScore = 0
                with open(RONDEFILES + FINALPREFIX + rondeNaam + '.csv',
                          'rt') as fr:
                    reader = csv.reader(fr)
                    for row in reader:
                        if 'Max/Gem' in row:
                            maximumRondeScore = row[0]
                            gemiddeldeRondeScore = round(float(row[1]), 1)
                            gemiddeldes.append(gemiddeldeRondeScore)

                maximumScore = int(maximumRondeScore) + maximumScore
                gemiddeldeScore = float(gemiddeldeRondeScore) + gemiddeldeScore

        try:

            newRow = [
                '0', '0', 'Gemiddelde',
                round(float(gemiddeldeScore), 2),
                round(float(gemiddeldeScore / maximumScore * 100), 2)
            ]
        except:
            newRow = [
                '0', '0', 'Gemiddelde',
                round(float(gemiddeldeScore), 2),
                round(float(0), 2)
            ]

        newRow = newRow + gemiddeldes
        newRow.append('')  #schifting
        newRow.append('')  #normschifting

        #sorteren
        if not geenScoresBeschikbaar:
            with open(tmp, mode='rt') as fr, open(SCOREBORD, 'w') as fw:
                writer = csv.writer(fw)
                reader = csv.reader(fr)
                writer.writerow(FIELDNAMES)
                writer.writerow(newRow)
                writer.writerow(ROW1)
                next(reader)
                next(reader)
                sorted2 = sorted(
                    reader,
                    key=lambda row:
                    (float(row[FIELDNAMES.index('Score')]),
                     float(row[FIELDNAMES.index('NormSchifting')])),
                    reverse=True)
                for positie, row in enumerate(sorted2):
                    writer.writerow([positie + 1] + row[1:])

        print('makeScorebord:', time.time() - a)
        if bonusGeneration:
            self.generateBonusOverview()
        print('generate BonusOverview:', time.time() - a)

        try:
            os.remove(tmp)
        except OSError:
            pass

        self.visualizeScorebord()
        return geenBonus, geenSchifting, ontbreekt, fout, SCOREHTMLFULL

    def getStatistics(self):
        mean = 0
        median = 0
        maximum = 0
        with open(SCOREBORD, mode='rt') as fr:
            reader = csv.reader(fr)
            row1 = next(reader)
            row1 = next(reader)
            row1 = next(reader)
            maximum = int(row1[3])
            row1 = next(reader)
            totalscores = [int(row1[3])]
            for i, row in enumerate(reader):
                totalscores.append(int(row[3]))
            mean = statistics.mean(totalscores)
            median = statistics.median(totalscores)
        return maximum, mean, median

    def visualizeScorebord(self):
        headers = ''
        body = ''

        with open(SCOREBORD,
                  mode='rt') as fr, open(RONDEFILES + FTPSCOREBORDPUBLIC,
                                         'w') as fw:
            reader = csv.reader(fr)
            writer = csv.writer(fw)
            row1 = next(reader)
            headerCSV = ['Pos']
            headerCSV.append('Ploegnaam')
            headerCSV.append('Tot')
            headers = headers + '"Pos"'
            headers = headers + ', "Ploegnaam"'
            headers = headers + ', "Tot"'
            for i in range(4, len(row1) - 1):
                headers = headers + ', "{}"'.format(row1[i])
                headerCSV.append(row1[i])
            writer.writerow(headerCSV)

            maximal = ''

            for i, row in enumerate(reader):
                newCSVRow = [row[0]]
                newRow = '"{}"'.format(row[0])
                ploegnaam = row[2]
                if len(ploegnaam) > 25:
                    ploegnaam = ploegnaam[:24] + '..'
                newRow = newRow + ', "{}"'.format(ploegnaam)
                newCSVRow.append(ploegnaam)
                newRow = newRow + ', "{}"'.format(row[3])
                newRow = newRow + ', "{}"'.format(row[4])
                newCSVRow.append(row[3])
                newCSVRow.append(row[4])
                for j in range(5,
                               len(row) - 1):  #norm schifting moet er niet in
                    newRow = newRow + ',' + row[j]
                    newCSVRow.append(row[j])
                if i == 1:  #maximum rij onderaan tabel steken (als footer)
                    maximal = newCSVRow
                else:
                    writer.writerow(newCSVRow)
                body = body + '[' + newRow + '],'

            writer.writerow(maximal)

        template = open(SCORETEMPLATEHTML).read()
        fullHTML = open(SCOREHTMLFULL, "w")
        template = template.replace('{BODY}', body)
        template = template.replace('{HEADERS}', headers)
        fullHTML.write(template)
        fullHTML.close()

        self.uploadScorebordLive()
        self.uploadScorebordPublic()

    def uploadScorebordPublic(self):
        ftp = ftplib.FTP(FTPSERVER)
        ftp.login(FTPUSER, FTPPASSWORD)
        #remote_path = "/htdocs/ScorebordFiles"
        ftp.cwd(FTPPATH)
        fh = open(RONDEFILES + FTPSCOREBORDPUBLIC, 'rb')
        ftp.storbinary('STOR ' + FTPSCOREBORDPUBLIC, fh)
        fh.close()

    def uploadScorebordLive(self):
        ftp = ftplib.FTP(FTPSERVER)
        ftp.login(FTPUSER, FTPPASSWORD)
        #remote_path = "/htdocs/ScorebordFiles"
        ftp.cwd(FTPPATH)
        fh = open(SCOREHTMLFULL, 'rb')
        ftp.storbinary('STOR ' + FTPSCOREBORDTIM, fh)
        fh.close()

    def uploadEvaluatieLive(self):
        ftp = ftplib.FTP(FTPSERVER)
        ftp.login(FTPUSER, FTPPASSWORD)
        ftp.cwd(FTPPATH)
        fh = open(EVALUATIE, 'rb')
        ftp.storbinary('STOR ' + FTPEVALUATIE, fh)
        fh.close()

    def generateEvaluatie(self):

        heleTekst = ''
        filenames = []
        rondenaam = []
        rondenummer = []
        aantalDeelnemers, _, _, _ = self.PH.aantalPloegen()

        with open(SCOREBORDINFO, 'rt') as fr:
            reader = csv.DictReader(fr)
            for row in reader:
                filenames.append(RONDEFILES + FINALPREFIX + row['Ronde'] +
                                 '.csv')
                rondenaam.append(row['Ronde'])
                rondenummer.append(int(row['RN']))

        antwoordLimiet = int(math.ceil(aantalDeelnemers * MOEILIJKTRESHOLD))
        with open(ANTWOORDEN, 'rt') as fr:
            reader = csv.reader(fr)
            antwoorden = list(reader)
        for index, file in enumerate(filenames):
            try:
                RNaam = rondenaam[index]
                RN = rondenummer[index]
                with open(file, 'rt') as fr:
                    reader = csv.reader(fr)
                    if 'Bonus' in next(reader):
                        compensatieBonus = 1
                    else:
                        compensatieBonus = 0
                    if self.RH.isSuperRonde(RN) == 1:
                        superronde = True
                    else:
                        superronde = False

                    eindstandPloeg = self.getFinalScore(1)
                    TN = int(eindstandPloeg['TN'])
                    scoreWinnaar = self.getScoreRondeFinal(RN, TN)

                    for row in reader:
                        if 'Max/Gem' in row:
                            aantalJuist = row[2:len(row) - 1]
                            aantalJuist = list(map(int, aantalJuist))
                            gemiddelde = row[1]
                            maximum = row[0]
                            rondeTekst = '<h2>' + RNaam + '</h2>'
                            rondeTekst = rondeTekst + '<h4>' + 'Gemiddelde score: ' + str(
                                gemiddelde) + '/' + str(maximum) + '</h4>'

                            #rondeTekst = rondeTekst + '<p>' + TABLELAYOUTOVERZICHT + '<thead>' + '<tr>' + HEADEROVERZICHTLEFT.format(HEADER = 'Nr.') + HEADEROVERZICHTCENTER.format(HEADER = 'Antwoord') + HEADEROVERZICHTLEFT.format(HEADER = '#Juist') + '</tr>' +'</thead>' + '<tbody>'
                            #rondeTekst = rondeTekst + TABLELAYOUTOVERZICHT.format(HEADER1 = 'Nr.', HEADER2 = 'Antwoord', HEADER3 = '#juist')
                            rondeTekst = rondeTekst + """<table border="0" align="center" width="70%"> <thead><tr><th width="10%"> Nr. </th><th width="80%">Antwoord</th><th width="10%">#Juist</th></tr></thead><tbody>"""

                            for i in range(0,
                                           len(aantalJuist) -
                                           compensatieBonus):
                                moeilijk = False
                                winnaarsfout = False

                                VN = i + 1
                                VNstr = str(VN)
                                if superronde:
                                    VNstr1 = str(int(i / 3) + 1)
                                    if i % 3 == 2:
                                        VNstr = VNstr1 + "c"
                                    elif i % 3 == 1:
                                        VNstr = VNstr1 + "b"
                                    else:
                                        VNstr = VNstr1 + "a"

                                if aantalJuist[i] <= antwoordLimiet:
                                    moeilijk = True

                                if int(scoreWinnaar[i]) == 0:
                                    winnaarsfout = True

                                if moeilijk:
                                    nieuwelijn = """<td  align="center">""" + '<B>' + VNstr + '</B>' + """</td><td  align="center">""" + '<B>' + str(
                                        antwoorden[RN - 1][VN]
                                    ) + '</B>' + """</td><td align="center">""" + '<B>' + str(
                                        aantalJuist[i]) + '</B>' + """</td>"""
                                    #nieuwelijn = '' + DATAOVERZICHTCENTER.format(DATA = '<B>' + VNstr + '</B>') + DATAOVERZICHTCENTER.format(DATA = '<B>' + str(antwoorden[RN-1][VN]) + '</B>') + DATAOVERZICHTCENTER.format(DATA = '<B>' + str(aantalJuist[i]) + '</B>')
                                else:
                                    #nieuwelijn = '' + DATAOVERZICHTCENTER.format(DATA = VNstr) + DATAOVERZICHTCENTER.format(DATA = antwoorden[RN-1][VN]) + DATAOVERZICHTCENTER.format(DATA = str(aantalJuist[i]))
                                    nieuwelijn = """<td  align="center">""" + VNstr + """</td><td  align="center">""" + str(
                                        antwoorden[RN - 1][VN]
                                    ) + """</td><td align="center">""" + str(
                                        aantalJuist[i]) + """</td>"""

                                if winnaarsfout:
                                    rondeTekst = rondeTekst + """<tr bgcolor="#FFCACA">""" + nieuwelijn + "</tr>"
                                else:
                                    rondeTekst = rondeTekst + "<tr>" + nieuwelijn + "</tr>"

                    heleTekst = heleTekst + rondeTekst + "</tbody>" + "</table>"

            except:
                print('Fout!')
                print(index, rondenaam, rondenummer)
                print(RNaam, RN, VN)
                pass

        maximum, gemiddelde, mediaan = self.getStatistics()
        atekst = """<table border="0" align="center" width="45%">
        <thead><tr><th width="40%"> Totaal </th><th width="30%"> """ + str(
            maximum) + """</th><th width="30%"> """ + str(
                round(maximum / maximum * 100, 2)) + """ % </th></tr></thead>
        <tbody>
        <tr><td  align="center">gemiddelde</td><td align="center">""" + str(
                    round(gemiddelde, 2)
                ) + """</td><td  align="center">""" + str(
                    round(gemiddelde / maximum * 100, 2)) + """ % </td></tr>
        <tr><td  align="center">mediaan</td><td align="center">""" + str(
                        mediaan) + """</td><td  align="center">""" + str(
                            round(mediaan / maximum * 100,
                                  2)) + """ % </td></tr>
        </tbody>
        </table>
        """

        template = open(EVALUATIETEMPLATE).read()
        text = template.format(TITEL=TITEL,
                               PERCENTAGE=MOEILIJKTRESHOLD * 100,
                               AANTAL=aantalDeelnemers,
                               TOTAAL_OVERZICHT=atekst,
                               RONDE_OVERZICHT=heleTekst)

        pdf = HTML2PDF()
        pdf.add_page()
        pdf.write_html(text)
        pdf.output(EVALUATIE)

        self.uploadEvaluatieLive()
Exemple #2
0
class Aanpassen(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Aanpassen, self).__init__(parent)
        uic.loadUi('code/ui/Aanpassen.ui', self)
        self.setWindowTitle('Scores aanpassen')

        self.show()
        self.setup()
        self.setFocus()
        self.qrcodeText.hide()

        self.rondeBox.currentIndexChanged.connect(self.nieuweRondeBox)
        self.NextBtn.clicked.connect(self.nextTafel)
        self.PreviousBtn.clicked.connect(self.previousTafel)
        self.qrcodeText.returnPressed.connect(self.qrGo)
        self.schiftingTxt.installEventFilter(self)

    def setup(self):
        from score_handler import Class_Scores
        from ronde_handler import Class_Rondes
        from inschrijving_handler import Class_Inschrijvingen
        self.RH = Class_Rondes()
        self.PH = Class_Inschrijvingen()
        self.SH = Class_Scores()

        self.fillComboBox()
        self.shortcut = ''
        self.schiftingfocus = False
        self.ronde = 0
        self.beschikbaar = False
        self.imageDir = self.SH.getImagesDir()
        self.currentRondeSettings = 99
        aanwezig, _ = self.PH.aanwezigePloegen()
        self.AanwezigePloegen = []
        for ploeg in aanwezig:
            self.AanwezigePloegen.append(int(ploeg[0]))
        self.AantalPloegen = len(self.AanwezigePloegen)

        self.TNIndex = 0
        self.updateRonde()

    def eventFilter(self, obj, event):
        if event.type() == QtCore.QEvent.FocusIn:
            if obj == self.schiftingTxt:
                self.schiftingfocus = True
                self.schiftingTxt.setFocusPolicy(QtCore.Qt.StrongFocus)
            elif not obj == self:
                self.setFocus()
        elif event.type() == QtCore.QEvent.FocusOut:
            if obj == self.schiftingTxt:
                self.schiftingfocus = False
                self.setFocus()
        return False

    def closeEvent(self, event):
        if not self.saveScore():
            msg = QtWidgets.QMessageBox()
            msg.setText(
                "Deze laatste score is niet geldig en werd niet opgeslagen!")
            msg.setWindowTitle("Opgelet")
            msg.exec()
        event.accept()

    def keyPressEvent(self, event):
        if type(event) == QtGui.QKeyEvent:
            if event.key() == QtCore.Qt.Key_Escape:
                self.close()
            elif event.key() == QtCore.Qt.Key_Return or event.key(
            ) == QtCore.Qt.Key_Enter:
                if not self.schiftingfocus and len(self.shortcut) > 1:
                    self.qrGo()
                else:
                    self.setFocus()
                self.shortcut = ''
            elif event.key() == QtCore.Qt.Key_Left:
                self.previousTafel()
            elif event.key() == QtCore.Qt.Key_Right:
                self.nextTafel()
            elif event.key() == QtCore.Qt.Key_Down:
                a = self.rondeBox.currentIndex()
                if a < len(self.comborondes) - 1:
                    self.rondeBox.setCurrentIndex(a + 1)
            elif event.key() == QtCore.Qt.Key_Up:
                a = self.rondeBox.currentIndex()
                if a > 0:
                    self.rondeBox.setCurrentIndex(a - 1)

            else:
                if event.text().isdigit() or event.text() == '_':
                    self.shortcut = self.shortcut + event.text()
            event.accept()
        else:
            event.ignore()

    def fillComboBox(self):
        self.rondeBox.addItem('0_Schifting&Bonus')
        self.comborondes = []
        self.comborondes.append(0)
        for ronde in self.SH.getUserRondes():
            self.rondeBox.addItem(ronde)
            a = ronde.split('_')
            self.comborondes.append(int(a[0]))
        self.rondeBox.setCurrentIndex(0)
        self.ronde = 0

    def nextTafel(self):
        if self.saveScore():
            if self.TNIndex < self.AantalPloegen - 1:
                self.TNIndex = self.TNIndex + 1
                self.updatePloeg()
            else:
                self.msgBox('Laatste ploeg',
                            'Dit is de laatste aanwezige ploeg')

    def previousTafel(self):
        if self.saveScore():
            if self.TNIndex > 0:
                self.TNIndex = self.TNIndex - 1
                self.updatePloeg()
            else:
                self.msgBox('Eerste ploeg', 'Dit is de eerste aanwezige ploeg')

    def qrGo(self):
        if self.saveScore():
            try:
                ronde, tafelnummer = map(int, self.shortcut.split('_'))
                try:
                    self.rondeBox.setCurrentIndex(
                        self.comborondes.index(ronde))
                    self.updateRonde()
                    try:
                        self.TNIndex = self.AanwezigePloegen.index(tafelnummer)
                        self.updatePloeg()
                    except:
                        self.msgBox('Error', 'Deze ploeg is niet aanwezig')
                except:
                    self.msgBox('Error', 'Deze ronde werd nog niet ingegeven')
            except:
                self.msgBox('Error', 'Geen geldige QR-code')

            self.qrcodeText.setText('')

    def nieuweRondeBox(self):
        if self.saveScore():
            self.updateRonde()
        self.setFocus()

    def updateRonde(self):
        dictronde = self.RH.getRondeInfoDict(
            self.comborondes[self.rondeBox.currentIndex()])
        if dictronde == '':
            self.ronde = 0
            if self.RH.numberBonusRondes() > 0:
                self.NOQ = 2
            else:
                self.NOQ = 1
        else:
            self.ronde = int(dictronde['RN'])
            self.NOQ = int(dictronde['Aantal']) * (
                1 + 2 * int(dictronde['Super'])
            )  #wordt enkel gebruikt indien er geen self.score beschikbaar is dus belangrijk voor superronde indien geen scan beschikbaar
        self.updatePloeg()

    def updatePloeg(self):
        self.Tafelnummer = int(self.AanwezigePloegen[self.TNIndex])
        self.tafelnummerTxt.setText(str(self.Tafelnummer))
        if self.ronde > 0:
            self.score = self.SH.getScore(self.ronde, self.Tafelnummer)
            if not len(self.score) > 0:
                self.score = [0] * self.NOQ
        else:
            self.score = self.PH.getSchiftingBonus(self.Tafelnummer)

        self.filename = self.imageDir + '{}_{}.jpg'.format(
            self.ronde, self.Tafelnummer)
        self.updateLayout()

    def saveScore(self):
        nieuwescore = []
        update = True
        if self.ronde > 0:
            for box in self.checkboxes:
                nieuwescore.append(int(box.isChecked()))

            if self.RH.isSuperRonde(self.ronde):
                for i in range(int(len(nieuwescore) / 3)):
                    if sum(nieuwescore[i * 3:i * 3 + 3]) > 1:
                        text = 'Geen geldige invoer voor een superronde: vraag {}'.format(
                            i + 1)
                        update = False
        else:
            nieuwescore.append(self.schiftingTxt.text())
            try:
                float(nieuwescore[0])
            except:
                text = 'Geen geldige schiftingsvraag!'
                update = False
            if len(self.checkboxes) > 0 and self.RH.numberBonusRondes() > 0:
                aantal = 0
                bonus = 0
                for i, box in enumerate(self.checkboxes):
                    if box.isChecked():
                        aantal = aantal + 1
                        bonus = i + 1
                nieuwescore.append(bonus)
                if not aantal == 1:
                    text = 'Geen geldig bonusthema!'
                    update = False

        if update:
            if not list(map(str, nieuwescore)) == list(map(str, self.score)):
                self.SH.setScore(self.ronde, self.Tafelnummer, nieuwescore)
        else:
            if self.beschikbaar or not list(map(str, nieuwescore)) == list(
                    map(str, self.score)):
                self.msgBox('Ongeldige score', text)
            else:
                return True
        return update

    def setImageLbl(self):
        try:
            pixmap = QtGui.QPixmap(self.filename)
            if not pixmap.isNull():
                pixmap = pixmap.scaled(self.imagesLbl.width(),
                                       self.imagesLbl.height(),
                                       QtCore.Qt.KeepAspectRatio)
                self.imagesLbl.setPixmap(pixmap)
                self.bescikbaar = True
            else:
                text = "Geen scan beschikbaar"
                font = QtGui.QFont("Arial", 20)
                metrics = QtGui.QFontMetricsF(font)
                rect = metrics.boundingRect(text)
                width = self.imagesLbl.width()
                heigth = self.imagesLbl.height()
                pos = QtCore.QPointF((width - rect.width()) / 2,
                                     (heigth - rect.height()) / 2)
                pixmap = QtGui.QPixmap(width, heigth)
                pixmap.fill(QtCore.Qt.white)
                painter = QtGui.QPainter()
                painter.begin(pixmap)
                painter.setPen(QtCore.Qt.black)
                painter.setFont(font)
                painter.drawText(pos, text)
                painter.end()
                self.imagesLbl.setPixmap(pixmap)
                self.beschikbaar = False

            self.imagesLbl.setAlignment(QtCore.Qt.AlignCenter)

        except:
            raise
            pass

    def updateBoxes(self):
        if self.ronde > 0:
            for i, box in enumerate(self.checkboxes):
                box.setChecked(int(self.score[i]))
        else:
            self.schiftingTxt.setText(str(self.score[0]))
            if self.NOQ == 2:
                bonusthema = int(self.score[1])
                for i, box in enumerate(self.checkboxes):
                    box.setChecked(i + 1 == bonusthema)

    def updateLayout(self):
        if not self.ronde == self.currentRondeSettings:
            #updatelayout
            self.checkboxes = []
            self.NOQ = len(self.score)
            try:
                self.superronde = self.RH.isSuperRonde(self.ronde)
            except:
                self.superronde = 0
                pass
            for box in self.checkboxes:
                box.hide()
                box.setChecked(0)

            self.hideQLayout(self.schiftingsvraag)
            if self.superronde == 1:
                index = 0
                for i in range(self.basicScores.count()):
                    box1 = self.basicScores.itemAt(i).widget()
                    box2 = self.superronde2.itemAt(i).widget()
                    box3 = self.superronde3.itemAt(i).widget()
                    if i < self.NOQ / 3:
                        box1.setText('{}a.'.format(i + 1))
                        box2.setText('{}b.'.format(i + 1))
                        box3.setText('{}c.'.format(i + 1))
                        self.checkboxes.append(box1)
                        self.checkboxes.append(box2)
                        self.checkboxes.append(box3)
                        box1.show()
                        box2.show()
                        box3.show()
                    else:
                        box1.hide()
                        box2.hide()
                        box3.hide()
            else:
                self.hideQLayout(self.superronde2)
                self.hideQLayout(self.superronde3)
                if self.NOQ < 3:
                    self.showQLayout(self.schiftingsvraag)
                    if self.NOQ == 2:
                        aantalThemas = 9
                        boxes = (self.basicScores.itemAt(i).widget()
                                 for i in range(self.basicScores.count()))
                        for i, box in enumerate(boxes):
                            if i < aantalThemas:
                                box.setText('{}.'.format(i + 1))
                                self.checkboxes.append(box)
                                box.show()
                            else:
                                box.hide()
                    self.hideQLayout(self.basicScores)
                    self.schiftingTxt.setText(str(self.score[0]))

                else:
                    boxes = (self.basicScores.itemAt(i).widget()
                             for i in range(self.basicScores.count()))
                    for i, box in enumerate(boxes):
                        if i < self.NOQ:
                            box.setText('{}.'.format(i + 1))
                            self.checkboxes.append(box)
                            box.show()
                        else:
                            box.hide()

        self.currentRondeSettings = self.ronde
        self.updateBoxes()  #check or uncheck
        self.setImageLbl()

    def hideQLayout(self, layout):
        items = (layout.itemAt(i).widget() for i in range(layout.count()))
        for i, item in enumerate(items):
            try:
                item.hide()
            except:
                pass

    def showQLayout(self, layout):
        items = (layout.itemAt(i).widget() for i in range(layout.count()))
        for i, item in enumerate(items):
            try:
                item.show()
            except:
                pass

    def msgBox(self, titel, tekst):
        msg = QtWidgets.QMessageBox()
        msg.setText(tekst)
        msg.setWindowTitle(titel)
        msg.exec()

    def allChecked(self, doeiets):
        #sluit deze GUI af en verwerk SCANCONTROL

        msg = QtWidgets.QMessageBox()
        msg.setText("Alle beschikbare scans zijn gecontroleerd!")
        msg.setWindowTitle("Klaar!")
        msg.exec()
        if doeiets:
            self.SH.fromScannerToUser()
        self.close()